diff --git a/.appveyor.yml b/.appveyor.yml index 0a25dceab43a46..8f1ece33139105 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -48,6 +48,7 @@ for: - 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 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 6c35dbcf831a92..1bf7db40ade99d 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -22,3 +22,7 @@ f28287d34c03f472ffe90ea262bdde9affd4b965 # Make benchmark indentation consistent fc4acf8cae82e5196186d3278d831f2438479d91 + +# Make prism_compile.c indentation consistent +40b2c8e5e7e6e5f83cee9276dc9c1922a69292d6 +d2c5867357ed88eccc28c2b3bd4a46e206e7ff85 diff --git a/.github/actions/slack/action.yml b/.github/actions/slack/action.yml index d1dd7f5def8105..c98be085a88656 100644 --- a/.github/actions/slack/action.yml +++ b/.github/actions/slack/action.yml @@ -36,3 +36,4 @@ runs: } env: SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }} + if: ${{github.event_name == 'push' && startsWith(github.repository, 'ruby/')}} diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml index 2f5ece83280727..1d43e299c6db26 100644 --- a/.github/workflows/annocheck.yml +++ b/.github/workflows/annocheck.yml @@ -65,7 +65,7 @@ jobs: - run: id working-directory: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -116,7 +116,7 @@ jobs: - uses: ./.github/actions/slack with: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 50176b3eb0d8bc..1c2dcf4ebd5fae 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -55,12 +55,12 @@ jobs: - ruby-3.2 steps: - - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0 + - uses: ruby/setup-ruby@52b8784594ec115fd17094752708121dc5dabb47 # v1.154.0 with: ruby-version: ${{ matrix.ruby }} bundler: none - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - uses: ./.github/actions/setup/ubuntu @@ -78,4 +78,4 @@ jobs: with: label: ${{ matrix.ruby }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 8c78e3905b1fda..9da28908f887b5 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - uses: ./.github/actions/setup/directories @@ -116,4 +116,4 @@ jobs: - uses: ./.github/actions/slack with: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index ac065faaa0165c..a3b70b54fc07d6 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -47,7 +47,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - uses: ./.github/actions/setup/ubuntu if: ${{ contains(matrix.os, 'ubuntu') }} @@ -70,4 +70,4 @@ jobs: with: label: ${{ matrix.os }} / Dependencies need to update SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml index e64a93189371bb..3bd1b062a49751 100644 --- a/.github/workflows/check_misc.yml +++ b/.github/workflows/check_misc.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - uses: ./.github/actions/setup/directories with: @@ -103,4 +103,4 @@ jobs: - uses: ./.github/actions/slack with: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index dcf3ee87062c54..66f95f2ef5186f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -54,7 +54,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - name: Install libraries uses: ./.github/actions/setup/ubuntu diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index f39d3090cc22bc..e5b71a074fd2b6 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -144,7 +144,7 @@ jobs: - { 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-support, env: { append_configure: '--disable-jit-support' } } + - { name: disable-jit, env: { append_configure: '--disable-yjit --disable-rjit' } } - { 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' } } @@ -234,7 +234,7 @@ jobs: - run: id working-directory: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -286,7 +286,7 @@ jobs: with: label: ${{ matrix.entry.name }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 30c30e46265c4e..ca5e5d9aa794bd 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -56,7 +56,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -103,7 +103,7 @@ jobs: with: label: ${{ matrix.test_task }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index df24ff394e0c51..3e174787a8c96a 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -68,7 +68,7 @@ jobs: steps: - name: Set up Ruby & MSYS2 - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0 + uses: ruby/setup-ruby@52b8784594ec115fd17094752708121dc5dabb47 # v1.154.0 with: ruby-version: ${{ matrix.base_ruby }} @@ -99,7 +99,7 @@ jobs: $result working-directory: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -153,7 +153,7 @@ jobs: with: label: ${{ matrix.msystem }} / ${{ matrix.test_task }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/rjit-bindgen.yml b/.github/workflows/rjit-bindgen.yml index 6a6769b92afc8d..cee149d73f4cac 100644 --- a/.github/workflows/rjit-bindgen.yml +++ b/.github/workflows/rjit-bindgen.yml @@ -49,11 +49,11 @@ jobs: steps: - name: Set up Ruby - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0 + uses: ruby/setup-ruby@52b8784594ec115fd17094752708121dc5dabb47 # v1.154.0 with: ruby-version: '3.1' - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -81,7 +81,7 @@ jobs: - uses: ./.github/actions/slack with: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/rjit.yml b/.github/workflows/rjit.yml index 66a6805abce2b1..8a642fb92b37b8 100644 --- a/.github/workflows/rjit.yml +++ b/.github/workflows/rjit.yml @@ -58,7 +58,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -110,7 +110,7 @@ jobs: with: label: ${{ matrix.run_opts }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index c6a4110af1b994..7d369da5088cbc 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -32,7 +32,7 @@ jobs: steps: - name: 'Checkout code' - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: persist-credentials: false diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml index 77677c98596807..8d8d8fa563c0fe 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -45,9 +45,9 @@ jobs: - ruby-3.2 steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 - - uses: ruby/setup-ruby@250fcd6a742febb1123a77a841497ccaa8b9e939 # v1.152.0 + - uses: ruby/setup-ruby@52b8784594ec115fd17094752708121dc5dabb47 # v1.154.0 with: ruby-version: ${{ matrix.ruby }} bundler: none @@ -63,4 +63,4 @@ jobs: with: label: ${{ matrix.ruby }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 66b0228102c023..0548e1b420cb40 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -64,7 +64,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -100,8 +100,8 @@ jobs: - 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' }} + ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`} + ${{ !contains(matrix.test_task, 'bundle') && 'RUBYOPT=-w' || '' }} timeout-minutes: 40 env: RUBY_TESTOPTS: '-q --tty=no' @@ -123,7 +123,7 @@ jobs: with: label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 3be9bf8d1ed380..e43e6a6832fd01 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -63,7 +63,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -132,7 +132,7 @@ jobs: with: label: ${{ matrix.entry.name }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b686cea295eac1..b4d159a9f46f66 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -108,7 +108,7 @@ jobs: Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH shell: pwsh - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -147,9 +147,14 @@ jobs: 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: >- @@ -177,7 +182,7 @@ jobs: with: label: VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index 45c7a224441356..4a3d4dc61a9f2e 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -37,7 +37,7 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 # For now we can't run cargo test --offline because it complains about the # capstone dependency, even though the dependency is optional @@ -61,7 +61,7 @@ jobs: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 # Check that we don't have linting errors in release mode, too - run: cargo clippy --all-targets --all-features @@ -118,7 +118,7 @@ jobs: )}} steps: - - uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 + - uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0 with: sparse-checkout-cone-mode: false sparse-checkout: /.github @@ -158,11 +158,11 @@ jobs: run: ./miniruby --yjit -v | grep "+YJIT" - name: make ${{ matrix.test_task }} - run: make -s -j ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" 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" MSPECOPT=--debug YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" YJIT_BINDGEN_DIFF_OPTS="$YJIT_BINDGEN_DIFF_OPTS" timeout-minutes: 60 env: RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: '' + TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'rbs' PRECHECK_BUNDLED_GEMS: 'no' SYNTAX_SUGGEST_TIMEOUT: '5' YJIT_BINDGEN_DIFF_OPTS: '--exit-code' @@ -179,7 +179,7 @@ jobs: with: label: ${{ matrix.test_task }} ${{ matrix.configure }} SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() && github.event_name == 'push' }} + if: ${{ failure() }} defaults: run: diff --git a/.gitignore b/.gitignore index 631a489eeff1f8..1ef1e76edd90a1 100644 --- a/.gitignore +++ b/.gitignore @@ -255,13 +255,17 @@ lcov*.info # /wasm/ /wasm/tests/*.wasm -# YARP -/lib/yarp/mutation_visitor.rb -/lib/yarp/node.rb -/lib/yarp/serialize.rb -/yarp/api_node.c -/yarp/ast.h -/yarp/node.c -/yarp/prettyprint.c -/yarp/serialize.c -/yarp/token_type.c +# prism +/lib/prism/compiler.rb +/lib/prism/dispatcher.rb +/lib/prism/dsl.rb +/lib/prism/mutation_compiler.rb +/lib/prism/node.rb +/lib/prism/serialize.rb +/lib/prism/visitor.rb +/prism/api_node.c +/prism/ast.h +/prism/node.c +/prism/prettyprint.c +/prism/serialize.c +/prism/token_type.c diff --git a/.travis.yml b/.travis.yml index 11ae8a9b4567f7..bfae9130f3b873 100644 --- a/.travis.yml +++ b/.travis.yml @@ -87,7 +87,13 @@ env: - &s390x-linux name: s390x-linux arch: s390x + dist: jammy compiler: gcc + 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 diff --git a/NEWS.md b/NEWS.md index cb44183265372a..cbfbc2a09e5a6c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -38,11 +38,10 @@ Note: We're only listing outstanding class updates. * MatchData#named_captures now accepts optional `symbolize_names` keyword. [[Feature #19591]] -* String +* Module - * 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]] + * Module#set_temporary_name added for setting a temporary name for a + module. [[Feature #19521]] * ObjectSpace::WeakKeyMap @@ -50,11 +49,6 @@ Note: We're only listing outstanding class updates. The class use equality semantic to lookup keys like a regular hash, but it doesn't hold strong references on the keys. [[Feature #18498]] -* Module - - * Module#set_temporary_name added for setting a temporary name for a - module. [[Feature #19521]] - * Process.warmup * Notify the Ruby virtual machine that the boot sequence is finished, @@ -62,17 +56,31 @@ Note: We're only listing outstanding class updates. for long running applications. The actual optimizations performed are entirely implementation specific and may change in the future without notice. [[Feature #18885]] +* Process::Status + + * Process::Status#& and Process::Status#>> are deprecated. [[Bug #19868]] + * 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]] +* 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]] + ## Stdlib updates * RubyGems and Bundler warn if users require gem that is scheduled to become the bundled gems in the future version of Ruby. [[Feature #19351]] [[Feature #19776]] [[Feature #19843]] +* 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]] + * Random::Formatter#alphanumeric is extended to accept optional `chars` keyword argument. [[Feature #18183]] @@ -87,7 +95,9 @@ The following default gems are updated. * fileutils 1.7.1 * irb 1.8.1 * nkf 0.1.3 +* openssl 3.2.0 * optparse 0.4.0.pre.1 +* prism 0.13.0 * psych 5.1.0 * reline 0.3.8 * stringio 3.0.9 @@ -96,7 +106,6 @@ The following default gems are updated. * time 0.2.2 * timeout 0.4.0 * uri 0.12.2 -* yarp 0.11.0 The following bundled gems are updated. @@ -105,7 +114,8 @@ The following bundled gems are updated. * rexml 3.2.6 * rss 0.3.0 * net-imap 0.3.7 -* rbs 3.2.1 +* net-smtp 0.4.0 +* rbs 3.2.2 * typeprof 0.21.8 * debug 1.8.0 @@ -160,9 +170,14 @@ changelog for details of the default gems or bundled gems. * The default value for `--yjit-exec-mem-size` is changed from 64 to 128. * More thorough testing and multiple bug fixes +### MJIT + +* MJIT is removed. + * `--disable-jit-support` is removed. Consider using `--disable-yjit --disable-rjit` instead. + ### RJIT -* Introduced a pure-Ruby JIT compiler RJIT and replaced MJIT. +* 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. @@ -171,6 +186,7 @@ changelog for details of the default gems or bundled gems. [Feature #18183]: https://bugs.ruby-lang.org/issues/18183 [Feature #18498]: https://bugs.ruby-lang.org/issues/18498 [Feature #18885]: https://bugs.ruby-lang.org/issues/18885 +[Bug #19012]: https://bugs.ruby-lang.org/issues/19012 [Bug #19150]: https://bugs.ruby-lang.org/issues/19150 [Feature #19314]: https://bugs.ruby-lang.org/issues/19314 [Feature #19347]: https://bugs.ruby-lang.org/issues/19347 @@ -182,3 +198,4 @@ changelog for details of the default gems or bundled gems. [Feature #19776]: https://bugs.ruby-lang.org/issues/19776 [Feature #19785]: https://bugs.ruby-lang.org/issues/19785 [Feature #19843]: https://bugs.ruby-lang.org/issues/19843 +[Bug #19868]: https://bugs.ruby-lang.org/issues/19868 diff --git a/addr2line.c b/addr2line.c index 7956cc457aace3..2a69dd0966d922 100644 --- a/addr2line.c +++ b/addr2line.c @@ -144,7 +144,7 @@ void *alloca(); #define DW_LNE_define_file 0x03 #define DW_LNE_set_discriminator 0x04 /* DWARF4 */ -#define kprintf(...) fprintf(stderr, "" __VA_ARGS__) +#define kprintf(...) fprintf(errout, "" __VA_ARGS__) typedef struct line_info { const char *dirname; @@ -254,7 +254,7 @@ sleb128(const char **p) } static const char * -get_nth_dirname(unsigned long dir, const char *p) +get_nth_dirname(unsigned long dir, const char *p, FILE *errout) { if (!dir--) { return ""; @@ -271,10 +271,14 @@ get_nth_dirname(unsigned long dir, const char *p) 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); +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 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) +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) { int i; const char *p = filenames; @@ -283,9 +287,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); + parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index, errout); line->filename = path; - parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL); + parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL, errout); line->dirname = path; } else { @@ -307,7 +311,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); + line->dirname = get_nth_dirname(dir, include_directories, errout); } } } @@ -316,7 +320,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) + obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) { int i; addr += obj->base_addr - obj->vmaddr; @@ -325,7 +329,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); + fill_filename(file, format, version, include_directories, filenames, &lines[i], obj, errout); lines[i].line = line; } } @@ -350,7 +354,7 @@ struct LineNumberProgramHeader { }; static int -parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header) +parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header, FILE *errout) { const char *p = *pp; header->unit_length = *(uint32_t *)p; @@ -396,7 +400,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); + p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL, errout); header->filenames = p; } else { @@ -423,7 +427,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) + obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) { const char *p = (const char *)*debug_line; struct LineNumberProgramHeader header; @@ -440,7 +444,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)) + if (parse_debug_line_header(obj, &p, &header, errout)) return -1; is_stmt = header.default_is_stmt; @@ -451,7 +455,7 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line, header.version, \ header.include_directories, \ header.filenames, \ - obj, lines, offset); \ + obj, lines, offset, errout); \ /*basic_block = prologue_end = epilogue_begin = 0;*/ \ } while (0) @@ -551,11 +555,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) + obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) { 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)) + if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset, errout)) return -1; } if (debug_line != debug_line_end) { @@ -568,7 +572,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); + obj_info_t **objp, line_info_t *lines, int offset, FILE *errout); static void append_obj(obj_info_t **objp) @@ -596,7 +600,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) + obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) { static const char global_debug_dir[] = "/usr/lib/debug"; const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1; @@ -622,13 +626,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); + fill_lines(num_traces, traces, 0, objp, lines, offset, errout); } // 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) + obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) { static const char global_debug_dir[] = "/usr/lib/debug/.build-id/"; const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1; @@ -653,7 +657,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); + fill_lines(num_traces, traces, 0, objp, lines, offset, errout); } #endif @@ -1079,13 +1083,13 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader) } static int -di_read_debug_line_cu(DebugInfoReader *reader) +di_read_debug_line_cu(DebugInfoReader *reader, FILE *errout) { const char *p; struct LineNumberProgramHeader header; p = (const char *)reader->debug_line_cu_end; - if (parse_debug_line_header(reader->obj, &p, &header)) + if (parse_debug_line_header(reader->obj, &p, &header, errout)) return -1; reader->debug_line_cu_end = (char *)header.cu_end; @@ -1186,7 +1190,7 @@ debug_info_reader_read_addr_value_member(DebugInfoReader *reader, DebugInfoValue static bool -debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v) +debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v, FILE *errout) { switch (form) { case DW_FORM_addr: @@ -1369,7 +1373,7 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa /* find abbrev in current compilation unit */ static const char * -di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) +di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout) { const char *p; if (abbrev_number < ABBREV_TABLE_SIZE) { @@ -1394,7 +1398,7 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) #if 0 static void -hexdump0(const unsigned char *p, size_t n) +hexdump0(const unsigned char *p, size_t n, FILE *errout) { size_t i; kprintf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); @@ -1415,10 +1419,10 @@ hexdump0(const unsigned char *p, size_t n) kprintf("\n"); } } -#define hexdump(p,n) hexdump0((const unsigned char *)p, n) +#define hexdump(p,n,e) hexdump0((const unsigned char *)p, n, e) static void -div_inspect(DebugInfoValue *v) +div_inspect(DebugInfoValue *v, FILE *errout) { switch (v->type) { case VAL_uint: @@ -1432,14 +1436,14 @@ div_inspect(DebugInfoValue *v) break; case VAL_data: kprintf("%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size); - hexdump(v->as.ptr, 16); + hexdump(v->as.ptr, 16, errout); break; } } #endif static DIE * -di_read_die(DebugInfoReader *reader, DIE *die) +di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout) { uint64_t abbrev_number = uleb128(&reader->p); if (abbrev_number == 0) { @@ -1447,7 +1451,7 @@ di_read_die(DebugInfoReader *reader, DIE *die) return NULL; } - if (!(reader->q = di_find_abbrev(reader, abbrev_number))) return NULL; + if (!(reader->q = di_find_abbrev(reader, abbrev_number, errout))) return NULL; die->pos = reader->p - reader->obj->debug_info.ptr - 1; die->tag = (int)uleb128(&reader->q); /* tag */ @@ -1459,26 +1463,26 @@ di_read_die(DebugInfoReader *reader, DIE *die) } static DebugInfoValue * -di_read_record(DebugInfoReader *reader, DebugInfoValue *vp) +di_read_record(DebugInfoReader *reader, DebugInfoValue *vp, FILE *errout) { 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)) return NULL; + if (!debug_info_reader_read_value(reader, form, vp, errout)) return NULL; return vp; } static bool -di_skip_records(DebugInfoReader *reader) +di_skip_records(DebugInfoReader *reader, FILE *errout) { for (;;) { DebugInfoValue v = {{0}}; 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)) return false; + if (!debug_info_reader_read_value(reader, form, &v, errout)) return false; } } @@ -1491,7 +1495,8 @@ typedef struct addr_header { } addr_header_t; static bool -addr_header_init(obj_info_t *obj, addr_header_t *header) { +addr_header_init(obj_info_t *obj, addr_header_t *header, FILE *errout) +{ const char *p = obj->debug_addr.ptr; header->ptr = p; @@ -1536,7 +1541,8 @@ typedef struct rnglists_header { } rnglists_header_t; static bool -rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) { +rnglists_header_init(obj_info_t *obj, rnglists_header_t *header, FILE *errout) +{ const char *p = obj->debug_rnglists.ptr; if (!p) return true; @@ -1603,7 +1609,7 @@ 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) +read_dw_form_addr(DebugInfoReader *reader, const char **ptr, FILE *errout) { const char *p = *ptr; *ptr = p + reader->address_size; @@ -1615,7 +1621,7 @@ read_dw_form_addr(DebugInfoReader *reader, const char **ptr) } static uintptr_t -ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header) +ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header, FILE *errout) { if (ptr->high_pc_set) { if (ptr->ranges_set || !ptr->low_pc_set) { @@ -1668,15 +1674,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); + base = read_dw_form_addr(reader, &p, errout); base_valid = true; break; case DW_RLE_start_end: - from = (uintptr_t)read_dw_form_addr(reader, &p); - to = (uintptr_t)read_dw_form_addr(reader, &p); + from = (uintptr_t)read_dw_form_addr(reader, &p, errout); + to = (uintptr_t)read_dw_form_addr(reader, &p, errout); break; case DW_RLE_start_length: - from = (uintptr_t)read_dw_form_addr(reader, &p); + from = (uintptr_t)read_dw_form_addr(reader, &p, errout); to = from + uleb128(&p); break; } @@ -1710,7 +1716,7 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h #if 0 static void -ranges_inspect(DebugInfoReader *reader, ranges_t *ptr) +ranges_inspect(DebugInfoReader *reader, ranges_t *ptr, FILE *errout) { if (ptr->high_pc_set) { if (ptr->ranges_set || !ptr->low_pc_set) { @@ -1740,7 +1746,7 @@ ranges_inspect(DebugInfoReader *reader, ranges_t *ptr) #endif static int -di_read_cu(DebugInfoReader *reader) +di_read_cu(DebugInfoReader *reader, FILE *errout) { uint64_t unit_length; uint16_t version; @@ -1775,15 +1781,15 @@ di_read_cu(DebugInfoReader *reader) reader->level = 0; di_read_debug_abbrev_cu(reader); - if (di_read_debug_line_cu(reader)) return -1; + if (di_read_debug_line_cu(reader, errout)) return -1; do { DIE die; - if (!di_read_die(reader, &die)) continue; + if (!di_read_die(reader, &die, errout)) continue; if (die.tag != DW_TAG_compile_unit) { - if (!di_skip_records(reader)) return -1; + if (!di_skip_records(reader, errout)) return -1; break; } @@ -1795,7 +1801,7 @@ di_read_cu(DebugInfoReader *reader) /* enumerate abbrev */ for (;;) { DebugInfoValue v = {{0}}; - if (!di_read_record(reader, &v)) break; + if (!di_read_record(reader, &v, errout)) break; switch (v.at) { case DW_AT_low_pc: // clang may output DW_AT_addr_base after DW_AT_low_pc. @@ -1821,7 +1827,7 @@ di_read_cu(DebugInfoReader *reader) case VAL_addr: { addr_header_t header = {0}; - if (!addr_header_init(reader->obj, &header)) return -1; + if (!addr_header_init(reader->obj, &header, errout)) return -1; reader->current_low_pc = read_addr(&header, reader->current_addr_base, low_pc.as.addr_idx); } break; @@ -1832,7 +1838,7 @@ di_read_cu(DebugInfoReader *reader) } static void -read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line) +read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line, FILE *errout) { const char *p = reader->p; const char *q = reader->q; @@ -1857,12 +1863,12 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o default: goto finish; } - if (!di_read_die(reader, &die)) goto finish; + if (!di_read_die(reader, &die, errout)) goto finish; /* enumerate abbrev */ for (;;) { DebugInfoValue v = {{0}}; - if (!di_read_record(reader, &v)) break; + if (!di_read_record(reader, &v, errout)) break; switch (v.at) { case DW_AT_name: line->sname = get_cstr_value(&v); @@ -1878,25 +1884,26 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o static bool debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, - line_info_t *lines, int offset) { + line_info_t *lines, int offset, FILE *errout) +{ addr_header_t addr_header = {0}; - if (!addr_header_init(reader->obj, &addr_header)) return false; + if (!addr_header_init(reader->obj, &addr_header, errout)) return false; rnglists_header_t rnglists_header = {0}; - if (!rnglists_header_init(reader->obj, &rnglists_header)) return false; + if (!rnglists_header_init(reader->obj, &rnglists_header, errout)) return false; while (reader->p < reader->cu_end) { DIE die; ranges_t ranges = {0}; line_info_t line = {0}; - if (!di_read_die(reader, &die)) continue; + if (!di_read_die(reader, &die, errout)) continue; /* kprintf("%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)) return false; + if (!di_skip_records(reader, errout)) return false; continue; } @@ -1904,15 +1911,15 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, for (;;) { DebugInfoValue v = {{0}}; /* ptrdiff_t pos = reader->p - reader->p0; */ - if (!di_read_record(reader, &v)) break; + 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); */ + /* div_inspect(&v, errout); */ 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); + 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); break; case DW_AT_call_line: line.line = (int)v.as.uint64; @@ -1928,16 +1935,16 @@ 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); + read_abstract_origin(reader, v.form, v.as.uint64, &line, errout); break; /* goto skip_die; */ } } - /* ranges_inspect(reader, &ranges); */ + /* ranges_inspect(reader, &ranges, errout); */ /* kprintf("%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); + uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header, errout); if (saddr == UINTPTR_MAX) return false; 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); */ @@ -1976,7 +1983,10 @@ 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) { +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) +{ int i, j; int entry_format_count = *(uint8_t *)p++; const char *entry_format = p; @@ -1996,7 +2006,7 @@ parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t DebugInfoValue v = {{0}}; unsigned long dw_lnct = uleb128(&format); unsigned long dw_form = uleb128(&format); - if (!debug_info_reader_read_value(&reader, dw_form, &v)) return 0; + if (!debug_info_reader_read_value(&reader, dw_form, &v, errout)) return 0; 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) @@ -2041,7 +2051,7 @@ uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr) /* 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) + obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) { int i, j; char *shstr; @@ -2202,8 +2212,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink, 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)) goto use_symtab; - if (!debug_info_read(&reader, num_traces, traces, lines, offset)) + if (di_read_cu(&reader, errout)) goto use_symtab; + if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout)) goto use_symtab; } } @@ -2244,14 +2254,14 @@ fill_lines(int num_traces, void **traces, int check_debuglink, if (gnu_debuglink_shdr && check_debuglink) { follow_debuglink(file + gnu_debuglink_shdr->sh_offset, num_traces, traces, - objp, lines, offset); + objp, lines, offset, errout); } 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); + objp, lines, offset, errout); } goto finish; } @@ -2259,7 +2269,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, if (parse_debug_line(num_traces, traces, obj->debug_line.ptr, obj->debug_line.size, - obj, lines, offset) == -1) + obj, lines, offset, errout) == -1) goto fail; finish: @@ -2271,7 +2281,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, /* 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) + obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) { # ifdef __LP64__ # define LP(x) x##_64 @@ -2472,8 +2482,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink, DebugInfoReader reader; debug_info_reader_init(&reader, obj); while (reader.p < reader.pend) { - if (di_read_cu(&reader)) goto fail; - if (!debug_info_read(&reader, num_traces, traces, lines, offset)) + if (di_read_cu(&reader, errout)) goto fail; + if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout)) goto fail; } } @@ -2481,7 +2491,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, if (parse_debug_line(num_traces, traces, obj->debug_line.ptr, obj->debug_line.size, - obj, lines, offset) == -1) + obj, lines, offset, errout) == -1) goto fail; return dladdr_fbase; @@ -2494,7 +2504,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, #if defined(__FreeBSD__) || defined(__DragonFly__) # include #endif -/* ssize_t main_exe_path(void) +/* ssize_t main_exe_path(FILE *errout) * * store the path of the main executable to `binary_filename`, * and returns strlen(binary_filename). @@ -2502,7 +2512,7 @@ fill_lines(int num_traces, void **traces, int check_debuglink, */ #if defined(__linux__) || defined(__NetBSD__) static ssize_t -main_exe_path(void) +main_exe_path(FILE *errout) { # if defined(__linux__) # define PROC_SELF_EXE "/proc/self/exe" @@ -2516,7 +2526,7 @@ main_exe_path(void) } #elif defined(__FreeBSD__) || defined(__DragonFly__) static ssize_t -main_exe_path(void) +main_exe_path(FILE *errout) { int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; size_t len = PATH_MAX; @@ -2530,7 +2540,7 @@ main_exe_path(void) } #elif defined(HAVE_LIBPROC_H) static ssize_t -main_exe_path(void) +main_exe_path(FILE *errout) { int len = proc_pidpath(getpid(), binary_filename, PATH_MAX); if (len == 0) return 0; @@ -2542,7 +2552,7 @@ main_exe_path(void) #endif static void -print_line0(line_info_t *line, void *address) +print_line0(line_info_t *line, void *address, FILE *errout) { uintptr_t addr = (uintptr_t)address; uintptr_t d = addr - line->saddr; @@ -2583,16 +2593,16 @@ print_line0(line_info_t *line, void *address) } static void -print_line(line_info_t *line, void *address) +print_line(line_info_t *line, void *address, FILE *errout) { - print_line0(line, address); + print_line0(line, address, errout); if (line->next) { - print_line(line->next, NULL); + print_line(line->next, NULL, errout); } } void -rb_dump_backtrace_with_lines(int num_traces, void **traces) +rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout) { int i; /* async-signal unsafe */ @@ -2604,14 +2614,14 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces) #ifdef HAVE_MAIN_EXE_PATH char *main_path = NULL; /* used on printing backtrace */ ssize_t len; - if ((len = main_exe_path()) > 0) { + if ((len = main_exe_path(errout)) > 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); + addr = fill_lines(num_traces, traces, 1, &obj, lines, -1, errout); if (addr != (uintptr_t)-1) { dladdr_fbases[0] = (void *)addr; } @@ -2648,7 +2658,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces) lines[i].saddr = (uintptr_t)info.dli_saddr; } strlcpy(binary_filename, path, PATH_MAX); - if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1) + if (fill_lines(num_traces, traces, 1, &obj, lines, i, errout) == (uintptr_t)-1) break; } next_line: @@ -2657,7 +2667,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces) /* output */ for (i = 0; i < num_traces; i++) { - print_line(&lines[i], traces[i]); + print_line(&lines[i], traces[i], errout); /* FreeBSD's backtrace may show _start and so on */ if (lines[i].sname && strcmp("main", lines[i].sname) == 0) diff --git a/addr2line.h b/addr2line.h index f09b6658001d1e..ff8e476b929f16 100644 --- a/addr2line.h +++ b/addr2line.h @@ -12,8 +12,10 @@ #if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)) +#include + void -rb_dump_backtrace_with_lines(int num_traces, void **traces); +rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout); #endif /* USE_ELF */ diff --git a/ast.c b/ast.c index 4bd3784fbae9ae..b63b5c31737490 100644 --- a/ast.c +++ b/ast.c @@ -331,14 +331,14 @@ rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...) } static VALUE -dump_block(rb_ast_t *ast, const NODE *node) +dump_block(rb_ast_t *ast, const struct RNode_BLOCK *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 = node->nd_next, 1)); + (node = RNODE_BLOCK(node->nd_next), 1)); if (node->nd_next) { rb_ary_push(ary, NEW_CHILD(ast, node->nd_next)); } @@ -347,13 +347,13 @@ dump_block(rb_ast_t *ast, const NODE *node) } static VALUE -dump_array(rb_ast_t *ast, const NODE *node) +dump_array(rb_ast_t *ast, const struct RNode_LIST *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 = node->nd_next; + node = RNODE_LIST(node->nd_next); rb_ary_push(ary, NEW_CHILD(ast, node->nd_head)); } rb_ary_push(ary, NEW_CHILD(ast, node->nd_next)); @@ -391,67 +391,67 @@ node_children(rb_ast_t *ast, const NODE *node) enum node_type type = nd_type(node); switch (type) { case NODE_BLOCK: - return dump_block(ast, node); + return dump_block(ast, RNODE_BLOCK(node)); case NODE_IF: - return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else); + return rb_ary_new_from_node_args(ast, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else); case NODE_UNLESS: - return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else); + return rb_ary_new_from_node_args(ast, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else); case NODE_CASE: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body); case NODE_CASE2: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body); case NODE_CASE3: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body); case NODE_WHEN: - return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next); + return rb_ary_new_from_node_args(ast, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next); case NODE_IN: - return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next); + return rb_ary_new_from_node_args(ast, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next); case NODE_WHILE: case NODE_UNTIL: - return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body), - RBOOL(node->nd_state)); + 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)); case NODE_ITER: case NODE_FOR: - return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body); case NODE_FOR_MASGN: - return rb_ary_new_from_node_args(ast, 1, node->nd_var); + return rb_ary_new_from_node_args(ast, 1, RNODE_FOR_MASGN(node)->nd_var); case NODE_BREAK: case NODE_NEXT: case NODE_RETURN: - return rb_ary_new_from_node_args(ast, 1, node->nd_stts); + return rb_ary_new_from_node_args(ast, 1, RNODE_BREAK(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, node->nd_body); + return rb_ary_new_from_node_args(ast, 1, RNODE_BEGIN(node)->nd_body); case NODE_RESCUE: - return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_resq, node->nd_else); + return rb_ary_new_from_node_args(ast, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else); case NODE_RESBODY: - return rb_ary_new_from_node_args(ast, 3, node->nd_args, node->nd_body, node->nd_head); + return rb_ary_new_from_node_args(ast, 3, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_head); case NODE_ENSURE: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr); + return rb_ary_new_from_node_args(ast, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr); case NODE_AND: case NODE_OR: { VALUE ary = rb_ary_new(); while (1) { - rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st)); - if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type)) + 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)) break; - node = node->nd_2nd; + node = RNODE_AND(node)->nd_2nd; } - rb_ary_push(ary, NEW_CHILD(ast, node->nd_2nd)); + rb_ary_push(ary, NEW_CHILD(ast, RNODE_AND(node)->nd_2nd)); return ary; } case NODE_MASGN: - 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); + 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); } else { - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value), - NEW_CHILD(ast, node->nd_head), + return rb_ary_new_from_args(3, NEW_CHILD(ast, RNODE_MASGN(node)->nd_value), + NEW_CHILD(ast, RNODE_MASGN(node)->nd_head), no_name_rest()); } case NODE_LASGN: @@ -459,138 +459,138 @@ node_children(rb_ast_t *ast, const NODE *node) case NODE_IASGN: case NODE_CVASGN: case NODE_GASGN: - 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"))); + if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node))) { + 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(node->nd_vid), NEW_CHILD(ast, node->nd_value)); + return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(ast, RNODE_LASGN(node)->nd_value)); case NODE_CDECL: - if (node->nd_vid) { - return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value)); + 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)); } - 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)); + 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)); case NODE_OP_ASGN1: - 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)); + 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_ARGSCAT(RNODE_OP_ASGN1(node)->nd_args)->nd_head), + NEW_CHILD(ast, RNODE_ARGSCAT(RNODE_OP_ASGN1(node)->nd_args)->nd_body)); case NODE_OP_ASGN2: - 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)); + 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)); case NODE_OP_ASGN_AND: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP), - NEW_CHILD(ast, node->nd_value)); + 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)); case NODE_OP_ASGN_OR: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idOROP), - NEW_CHILD(ast, node->nd_value)); + 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)); case NODE_OP_CDECL: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), - ID2SYM(node->nd_aid), - NEW_CHILD(ast, node->nd_value)); + 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)); case NODE_CALL: case NODE_OPCALL: case NODE_QCALL: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), - ID2SYM(node->nd_mid), - NEW_CHILD(ast, node->nd_args)); + 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_FCALL: - return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), - NEW_CHILD(ast, node->nd_args)); + return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node)->nd_mid), + NEW_CHILD(ast, RNODE_FCALL(node)->nd_args)); case NODE_VCALL: - return rb_ary_new_from_args(1, ID2SYM(node->nd_mid)); + return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node)->nd_mid)); case NODE_SUPER: - return rb_ary_new_from_node_args(ast, 1, node->nd_args); + return rb_ary_new_from_node_args(ast, 1, RNODE_SUPER(node)->nd_args); case NODE_ZSUPER: return rb_ary_new_from_node_args(ast, 0); case NODE_LIST: case NODE_VALUES: - return dump_array(ast, node); + return dump_array(ast, RNODE_LIST(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, node->nd_head); + return rb_ary_new_from_node_args(ast, 1, RNODE_HASH(node)->nd_head); case NODE_YIELD: - return rb_ary_new_from_node_args(ast, 1, node->nd_head); + return rb_ary_new_from_node_args(ast, 1, RNODE_YIELD(node)->nd_head); case NODE_LVAR: case NODE_DVAR: - return rb_ary_new_from_args(1, var_name(node->nd_vid)); + return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node)->nd_vid)); case NODE_IVAR: case NODE_CONST: case NODE_CVAR: case NODE_GVAR: - return rb_ary_new_from_args(1, ID2SYM(node->nd_vid)); + return rb_ary_new_from_args(1, ID2SYM(RNODE_IVAR(node)->nd_vid)); case NODE_NTH_REF: - snprintf(name, sizeof(name), "$%ld", node->nd_nth); + snprintf(name, sizeof(name), "$%ld", RNODE_NTH_REF(node)->nd_nth); return rb_ary_new_from_args(1, ID2SYM(rb_intern(name))); case NODE_BACK_REF: name[0] = '$'; - name[1] = (char)node->nd_nth; + name[1] = (char)RNODE_BACK_REF(node)->nd_nth; name[2] = '\0'; return rb_ary_new_from_args(1, ID2SYM(rb_intern(name))); case NODE_MATCH2: - if (node->nd_args) { - return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args); + 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); } - return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value); + return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value); case NODE_MATCH3: - return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value); + return rb_ary_new_from_node_args(ast, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value); case NODE_MATCH: case NODE_LIT: case NODE_STR: case NODE_XSTR: - return rb_ary_new_from_args(1, node->nd_lit); + return rb_ary_new_from_args(1, RNODE_LIT(node)->nd_lit); case NODE_ONCE: - return rb_ary_new_from_node_args(ast, 1, node->nd_body); + return rb_ary_new_from_node_args(ast, 1, RNODE_ONCE(node)->nd_body); case NODE_DSTR: case NODE_DXSTR: case NODE_DREGX: case NODE_DSYM: { - NODE *n = node->nd_next; + struct RNode_LIST *n = RNODE_DSTR(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, node->nd_lit, head, next); + return rb_ary_new_from_args(3, RNODE_DSTR(node)->nd_lit, head, next); } case NODE_EVSTR: - return rb_ary_new_from_node_args(ast, 1, node->nd_body); + return rb_ary_new_from_node_args(ast, 1, RNODE_EVSTR(node)->nd_body); case NODE_ARGSCAT: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body); case NODE_ARGSPUSH: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body); case NODE_SPLAT: - return rb_ary_new_from_node_args(ast, 1, node->nd_head); + return rb_ary_new_from_node_args(ast, 1, RNODE_SPLAT(node)->nd_head); case NODE_BLOCK_PASS: - return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body); case NODE_DEFN: - return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn)); + return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(ast, RNODE_DEFN(node)->nd_defn)); case NODE_DEFS: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn)); + 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)); case NODE_ALIAS: - return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd); + return rb_ary_new_from_node_args(ast, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd); case NODE_VALIAS: - return rb_ary_new_from_args(2, ID2SYM(node->nd_alias), ID2SYM(node->nd_orig)); + return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig)); case NODE_UNDEF: - return rb_ary_new_from_node_args(ast, 1, node->nd_undef); + return rb_ary_new_from_node_args(ast, 1, RNODE_UNDEF(node)->nd_undef); case NODE_CLASS: - return rb_ary_new_from_node_args(ast, 3, node->nd_cpath, node->nd_super, node->nd_body); + return rb_ary_new_from_node_args(ast, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body); case NODE_MODULE: - return rb_ary_new_from_node_args(ast, 2, node->nd_cpath, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body); case NODE_SCLASS: - return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_body); + return rb_ary_new_from_node_args(ast, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body); case NODE_COLON2: - return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_head), ID2SYM(node->nd_mid)); + return rb_ary_new_from_args(2, NEW_CHILD(ast, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid)); case NODE_COLON3: - return rb_ary_new_from_args(1, ID2SYM(node->nd_mid)); + return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node)->nd_mid)); case NODE_DOT2: case NODE_DOT3: case NODE_FLIP2: case NODE_FLIP3: - return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end); + return rb_ary_new_from_node_args(ast, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end); case NODE_SELF: return rb_ary_new_from_node_args(ast, 0); case NODE_NIL: @@ -602,26 +602,26 @@ 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, node->nd_head); + return rb_ary_new_from_node_args(ast, 1, RNODE_DEFINED(node)->nd_head); case NODE_POSTEXE: - return rb_ary_new_from_node_args(ast, 1, node->nd_body); + return rb_ary_new_from_node_args(ast, 1, RNODE_POSTEXE(node)->nd_body); case NODE_ATTRASGN: - return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_args)); + 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)); case NODE_LAMBDA: - return rb_ary_new_from_node_args(ast, 1, node->nd_body); + return rb_ary_new_from_node_args(ast, 1, RNODE_LAMBDA(node)->nd_body); case NODE_OPT_ARG: - return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next); + return rb_ary_new_from_node_args(ast, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next); case NODE_KW_ARG: - return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next); + return rb_ary_new_from_node_args(ast, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next); case NODE_POSTARG: - if (NODE_NAMED_REST_P(node->nd_1st)) { - return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd); + 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); } return rb_ary_new_from_args(2, no_name_rest(), - NEW_CHILD(ast, node->nd_2nd)); + NEW_CHILD(ast, RNODE_POSTARG(node)->nd_2nd)); case NODE_ARGS: { - struct rb_args_info *ainfo = node->nd_ainfo; + struct rb_args_info *ainfo = RNODE_ARGS(node)->nd_ainfo; return rb_ary_new_from_args(10, INT2NUM(ainfo->pre_args_num), NEW_CHILD(ast, ainfo->pre_init), @@ -638,48 +638,51 @@ node_children(rb_ast_t *ast, const NODE *node) } case NODE_SCOPE: { - rb_ast_id_table_t *tbl = node->nd_tbl; + rb_ast_id_table_t *tbl = RNODE_SCOPE(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->nd_args), NEW_CHILD(ast, node->nd_body)); + return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, RNODE_SCOPE(node)->nd_args), NEW_CHILD(ast, RNODE_SCOPE(node)->nd_body)); } case NODE_ARYPTN: { - struct rb_ary_pattern_info *apinfo = node->nd_apinfo; + struct rb_ary_pattern_info *apinfo = RNODE_ARYPTN(node)->nd_apinfo; VALUE rest = rest_arg(ast, apinfo->rest_arg); return rb_ary_new_from_args(4, - NEW_CHILD(ast, node->nd_pconst), + NEW_CHILD(ast, RNODE_ARYPTN(node)->nd_pconst), NEW_CHILD(ast, apinfo->pre_args), rest, NEW_CHILD(ast, apinfo->post_args)); } case NODE_FNDPTN: { - struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo; + struct rb_fnd_pattern_info *fpinfo = RNODE_FNDPTN(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, node->nd_pconst), + NEW_CHILD(ast, RNODE_FNDPTN(node)->nd_pconst), pre_rest, NEW_CHILD(ast, fpinfo->args), post_rest); } case NODE_HSHPTN: { - VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) : - NEW_CHILD(ast, node->nd_pkwrestarg); + 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); return rb_ary_new_from_args(3, - NEW_CHILD(ast, node->nd_pconst), - NEW_CHILD(ast, node->nd_pkwargs), + NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pconst), + NEW_CHILD(ast, RNODE_HSHPTN(node)->nd_pkwargs), kwrest); } case NODE_ERROR: return rb_ary_new_from_node_args(ast, 0); case NODE_ARGS_AUX: + case NODE_DEF_TEMP: + case NODE_RIPPER: + case NODE_RIPPER_VALUES: case NODE_LAST: break; } diff --git a/benchmark/range_bsearch_bignum.yml b/benchmark/range_bsearch_bignum.yml new file mode 100644 index 00000000000000..5730c93fcfb016 --- /dev/null +++ b/benchmark/range_bsearch_bignum.yml @@ -0,0 +1,10 @@ +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 new file mode 100644 index 00000000000000..8d7bedb662e007 --- /dev/null +++ b/benchmark/range_bsearch_endpointless.yml @@ -0,0 +1,21 @@ +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 new file mode 100644 index 00000000000000..59416531b9abd0 --- /dev/null +++ b/benchmark/range_bsearch_fixnum.yml @@ -0,0 +1,10 @@ +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_overlap.yml b/benchmark/range_overlap.yml new file mode 100644 index 00000000000000..700a00053c84aa --- /dev/null +++ b/benchmark/range_overlap.yml @@ -0,0 +1,19 @@ +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/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb index 948e2d7809ee24..59fdae651f307d 100644 --- a/bootstraptest/test_syntax.rb +++ b/bootstraptest/test_syntax.rb @@ -535,8 +535,8 @@ def assert_syntax_error expected, code, message = '' 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 "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_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_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_yjit.rb b/bootstraptest/test_yjit.rb index 82fd1e13766c6b..f5cfaabe72cb0b 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,3 +1,15 @@ +# 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 defined?(RubyVM::RJIT) && RubyVM::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: diff --git a/class.c b/class.c index cfd7ce55f54d28..1dc69150ab34a3 100644 --- a/class.c +++ b/class.c @@ -496,6 +496,7 @@ copy_tables(VALUE clone, VALUE orig) rb_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx); RCLASS_CVC_TBL(clone) = rb_cvc_tbl_dup; } + rb_id_table_free(RCLASS_M_TBL(clone)); RCLASS_M_TBL(clone) = 0; if (!RB_TYPE_P(clone, T_ICLASS)) { st_data_t id; @@ -1153,16 +1154,10 @@ rb_define_module_id_under(VALUE outer, ID id) return module; } -VALUE -rb_iclass_alloc(VALUE klass) -{ - return class_alloc(T_ICLASS, klass); -} - VALUE rb_include_class_new(VALUE module, VALUE super) { - VALUE klass = rb_iclass_alloc(rb_cClass); + VALUE klass = class_alloc(T_ICLASS, rb_cClass); RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); @@ -1439,7 +1434,7 @@ ensure_origin(VALUE klass) { VALUE origin = RCLASS_ORIGIN(klass); if (origin == klass) { - origin = rb_iclass_alloc(klass); + origin = class_alloc(T_ICLASS, klass); RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); RCLASS_SET_SUPER(klass, origin); RCLASS_SET_ORIGIN(klass, origin); diff --git a/common.mk b/common.mk index d55d1788aa8e01..b8ae911ef2129e 100644 --- a/common.mk +++ b/common.mk @@ -45,8 +45,8 @@ RUN_OPTS = --disable-gems # GITPULLOPTIONS = --no-tags -YARP_SRCDIR = $(srcdir)/yarp -INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(YARP_SRCDIR) -I$(UNICODE_HDR_DIR) +PRISM_SRCDIR = $(srcdir)/prism +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(PRISM_SRCDIR) -I$(UNICODE_HDR_DIR) $(incflags) GEM_HOME = GEM_PATH = @@ -83,37 +83,39 @@ ENC_MK = enc.mk MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \ RUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BOOTSTRAPRUBY)" $(mflags) -YARP_FILES = yarp/api_node.$(OBJEXT) \ - yarp/api_pack.$(OBJEXT) \ - yarp/diagnostic.$(OBJEXT) \ - yarp/enc/yp_big5.$(OBJEXT) \ - yarp/enc/yp_euc_jp.$(OBJEXT) \ - yarp/enc/yp_gbk.$(OBJEXT) \ - yarp/enc/yp_shift_jis.$(OBJEXT) \ - yarp/enc/yp_tables.$(OBJEXT) \ - yarp/enc/yp_unicode.$(OBJEXT) \ - yarp/enc/yp_windows_31j.$(OBJEXT) \ - yarp/extension.$(OBJEXT) \ - yarp/node.$(OBJEXT) \ - yarp/pack.$(OBJEXT) \ - yarp/prettyprint.$(OBJEXT) \ - yarp/regexp.$(OBJEXT) \ - yarp/serialize.$(OBJEXT) \ - yarp/token_type.$(OBJEXT) \ - yarp/unescape.$(OBJEXT) \ - yarp/util/yp_buffer.$(OBJEXT) \ - yarp/util/yp_char.$(OBJEXT) \ - yarp/util/yp_constant_pool.$(OBJEXT) \ - yarp/util/yp_list.$(OBJEXT) \ - yarp/util/yp_memchr.$(OBJEXT) \ - yarp/util/yp_newline_list.$(OBJEXT) \ - yarp/util/yp_state_stack.$(OBJEXT) \ - yarp/util/yp_string.$(OBJEXT) \ - yarp/util/yp_string_list.$(OBJEXT) \ - yarp/util/yp_strncasecmp.$(OBJEXT) \ - yarp/util/yp_strpbrk.$(OBJEXT) \ - yarp/yarp.$(OBJEXT) \ - yarp/yarp_init.$(OBJEXT) +PRISM_BUILD_DIR = prism + +PRISM_FILES = prism/api_node.$(OBJEXT) \ + prism/api_pack.$(OBJEXT) \ + prism/diagnostic.$(OBJEXT) \ + prism/enc/pm_big5.$(OBJEXT) \ + prism/enc/pm_euc_jp.$(OBJEXT) \ + prism/enc/pm_gbk.$(OBJEXT) \ + prism/enc/pm_shift_jis.$(OBJEXT) \ + prism/enc/pm_tables.$(OBJEXT) \ + prism/enc/pm_unicode.$(OBJEXT) \ + prism/enc/pm_windows_31j.$(OBJEXT) \ + prism/extension.$(OBJEXT) \ + prism/node.$(OBJEXT) \ + prism/pack.$(OBJEXT) \ + prism/prettyprint.$(OBJEXT) \ + prism/regexp.$(OBJEXT) \ + prism/serialize.$(OBJEXT) \ + prism/token_type.$(OBJEXT) \ + prism/unescape.$(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) \ @@ -188,7 +190,7 @@ COMMONOBJS = array.$(OBJEXT) \ vm_sync.$(OBJEXT) \ vm_trace.$(OBJEXT) \ weakmap.$(OBJEXT) \ - $(YARP_FILES) \ + $(PRISM_FILES) \ $(YJIT_OBJ) \ $(YJIT_LIBOBJ) \ $(COROUTINE_OBJ) \ @@ -197,50 +199,70 @@ COMMONOBJS = array.$(OBJEXT) \ $(BUILTIN_TRANSOBJS) \ $(MISSING) -$(YARP_FILES): $(YARP_BUILD_DIR)/.time $(YARP_BUILD_DIR)/enc/.time $(YARP_BUILD_DIR)/util/.time +$(PRISM_FILES): $(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/enc/.time $(PRISM_BUILD_DIR)/util/.time -$(YARP_BUILD_DIR)/.time $(YARP_BUILD_DIR)/enc/.time $(YARP_BUILD_DIR)/util/.time: +$(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/enc/.time $(PRISM_BUILD_DIR)/util/.time: $(Q) $(MAKEDIRS) $(@D) @$(NULLCMD) > $@ -main: $(srcdir)/lib/yarp/mutation_visitor.rb -srcs: $(srcdir)/lib/yarp/mutation_visitor.rb -$(srcdir)/lib/yarp/mutation_visitor.rb: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/lib/yarp/mutation_visitor.rb.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb lib/yarp/mutation_visitor.rb $(srcdir)/lib/yarp/mutation_visitor.rb - -main: $(srcdir)/lib/yarp/node.rb -srcs: $(srcdir)/lib/yarp/node.rb -$(srcdir)/lib/yarp/node.rb: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/lib/yarp/node.rb.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb lib/yarp/node.rb $(srcdir)/lib/yarp/node.rb - -main: $(srcdir)/lib/yarp/serialize.rb -srcs: $(srcdir)/lib/yarp/serialize.rb -$(srcdir)/lib/yarp/serialize.rb: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/lib/yarp/serialize.rb.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb lib/yarp/serialize.rb $(srcdir)/lib/yarp/serialize.rb - -srcs: yarp/api_node.c -yarp/api_node.c: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/ext/yarp/api_node.c.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb ext/yarp/api_node.c $@ - -srcs: yarp/ast.h -yarp/ast.h: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/include/yarp/ast.h.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb include/yarp/ast.h $@ - -srcs: yarp/node.c -yarp/node.c: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/src/node.c.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb src/node.c $@ - -srcs: yarp/prettyprint.c -yarp/prettyprint.c: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/src/prettyprint.c.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb src/prettyprint.c $@ - -srcs: yarp/serialize.c -yarp/serialize.c: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/src/serialize.c.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb src/serialize.c $@ - -srcs: yarp/token_type.c -yarp/token_type.c: $(YARP_SRCDIR)/config.yml $(YARP_SRCDIR)/templates/template.rb $(YARP_SRCDIR)/templates/src/token_type.c.erb - $(Q) $(BASERUBY) $(YARP_SRCDIR)/templates/template.rb src/token_type.c $@ +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) \ @@ -690,8 +712,11 @@ 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 2> $(NULL) || $(NULLCMD) + -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine yjit \ + $(PRISM_BUILD_DIR)/*/ $(PRISM_BUILD_DIR) tmp \ + 2> $(NULL) || $(NULLCMD) bin/clean-runnable:: PHONY $(Q)$(CHDIR) bin 2>$(NULL) && $(RM) $(PROGRAM) $(WPROGRAM) $(GORUBY)$(EXEEXT) bin/*.$(DLEXT) 2>$(NULL) || $(NULLCMD) @@ -1288,7 +1313,7 @@ $(REVISION_H)$(yes_baseruby:yes=~disabled~): # uncommon.mk: $(REVISION_H) # $(MKFILES): $(REVISION_H) -$(DOT_WAIT)ripper_srcs: $(RIPPER_SRCS) +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 @@ -1830,7 +1855,7 @@ update-man-date: PHONY ChangeLog: $(ECHO) Generating $@ -$(Q) $(BASERUBY) -I"$(tooldir)/lib" -rvcs \ - -e 'VCS.detect(ARGV[0]).export_changelog("@", nil, nil, ARGV[1])' \ + -e 'VCS.detect(ARGV[0]).export_changelog(path: ARGV[1])' \ "$(srcdir)" $@ HELP_EXTRA_TASKS = "" @@ -3182,26 +3207,26 @@ 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)/yarp/defines.h -compile.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -compile.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -compile.$(OBJEXT): $(top_srcdir)/yarp/node.h -compile.$(OBJEXT): $(top_srcdir)/yarp/pack.h -compile.$(OBJEXT): $(top_srcdir)/yarp/parser.h -compile.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -compile.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -compile.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -compile.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -compile.$(OBJEXT): $(top_srcdir)/yarp/yarp_compiler.c +compile.$(OBJEXT): $(top_srcdir)/prism/defines.h +compile.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h +compile.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +compile.$(OBJEXT): $(top_srcdir)/prism/node.h +compile.$(OBJEXT): $(top_srcdir)/prism/pack.h +compile.$(OBJEXT): $(top_srcdir)/prism/parser.h +compile.$(OBJEXT): $(top_srcdir)/prism/prism.h +compile.$(OBJEXT): $(top_srcdir)/prism/regexp.h +compile.$(OBJEXT): $(top_srcdir)/prism/unescape.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_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 @@ -3384,6 +3409,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)}re.h compile.$(OBJEXT): {$(VPATH)}regex.h compile.$(OBJEXT): {$(VPATH)}ruby_assert.h @@ -3399,9 +3428,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)}yarp/ast.h -compile.$(OBJEXT): {$(VPATH)}yarp/version.h -compile.$(OBJEXT): {$(VPATH)}yarp/yarp.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 @@ -6322,6 +6348,7 @@ 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 @@ -6514,6 +6541,7 @@ 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 @@ -8229,25 +8257,25 @@ 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)/yarp/defines.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/node.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/pack.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/parser.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -iseq.$(OBJEXT): $(top_srcdir)/yarp/yarp.h +iseq.$(OBJEXT): $(top_srcdir)/prism/defines.h +iseq.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h +iseq.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +iseq.$(OBJEXT): $(top_srcdir)/prism/node.h +iseq.$(OBJEXT): $(top_srcdir)/prism/pack.h +iseq.$(OBJEXT): $(top_srcdir)/prism/parser.h +iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h +iseq.$(OBJEXT): $(top_srcdir)/prism/regexp.h +iseq.$(OBJEXT): $(top_srcdir)/prism/unescape.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_strpbrk.h iseq.$(OBJEXT): {$(VPATH)}assert.h iseq.$(OBJEXT): {$(VPATH)}atomic.h iseq.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -8428,6 +8456,9 @@ iseq.$(OBJEXT): {$(VPATH)}missing.h iseq.$(OBJEXT): {$(VPATH)}node.h 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)}ractor.h iseq.$(OBJEXT): {$(VPATH)}rjit.h iseq.$(OBJEXT): {$(VPATH)}ruby_assert.h @@ -8442,9 +8473,6 @@ iseq.$(OBJEXT): {$(VPATH)}util.h iseq.$(OBJEXT): {$(VPATH)}vm_callinfo.h iseq.$(OBJEXT): {$(VPATH)}vm_core.h iseq.$(OBJEXT): {$(VPATH)}vm_opts.h -iseq.$(OBJEXT): {$(VPATH)}yarp/ast.h -iseq.$(OBJEXT): {$(VPATH)}yarp/version.h -iseq.$(OBJEXT): {$(VPATH)}yarp/yarp.h iseq.$(OBJEXT): {$(VPATH)}yjit.h load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h load.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h @@ -11292,6 +11320,1071 @@ 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/enc/pm_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/pack.h +prism/api_node.$(OBJEXT): $(top_srcdir)/prism/parser.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/unescape.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_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/enc/pm_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/pack.h +prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/parser.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/unescape.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_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_list.h +prism/diagnostic.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_ascii.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_ascii.$(OBJEXT): $(top_srcdir)/prism/enc/pm_ascii.c +prism/enc/pm_ascii.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_ascii.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_big5.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_big5.$(OBJEXT): $(top_srcdir)/prism/enc/pm_big5.c +prism/enc/pm_big5.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_big5.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_euc_jp.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_euc_jp.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_euc_jp.$(OBJEXT): $(top_srcdir)/prism/enc/pm_euc_jp.c +prism/enc/pm_euc_jp.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_gbk.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_gbk.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_gbk.$(OBJEXT): $(top_srcdir)/prism/enc/pm_gbk.c +prism/enc/pm_gbk.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_1.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_1.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_1.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_1.c +prism/enc/pm_iso_8859_1.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_10.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_10.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_10.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_10.c +prism/enc/pm_iso_8859_10.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_11.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_11.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_11.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_11.c +prism/enc/pm_iso_8859_11.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_13.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_13.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_13.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_13.c +prism/enc/pm_iso_8859_13.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_14.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_14.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_14.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_14.c +prism/enc/pm_iso_8859_14.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_15.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_15.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_15.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_15.c +prism/enc/pm_iso_8859_15.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_16.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_16.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_16.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_16.c +prism/enc/pm_iso_8859_16.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_2.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_2.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_2.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_2.c +prism/enc/pm_iso_8859_2.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_3.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_3.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_3.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_3.c +prism/enc/pm_iso_8859_3.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_4.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_4.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_4.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_4.c +prism/enc/pm_iso_8859_4.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_5.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_5.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_5.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_5.c +prism/enc/pm_iso_8859_5.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_6.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_6.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_6.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_6.c +prism/enc/pm_iso_8859_6.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_7.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_7.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_7.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_7.c +prism/enc/pm_iso_8859_7.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_8.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_8.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_8.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_8.c +prism/enc/pm_iso_8859_8.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_iso_8859_9.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_iso_8859_9.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_iso_8859_9.$(OBJEXT): $(top_srcdir)/prism/enc/pm_iso_8859_9.c +prism/enc/pm_iso_8859_9.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_koi8_r.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_koi8_r.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_koi8_r.$(OBJEXT): $(top_srcdir)/prism/enc/pm_koi8_r.c +prism/enc/pm_koi8_r.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_shared.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_shared.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_shared.$(OBJEXT): $(top_srcdir)/prism/enc/pm_shared.c +prism/enc/pm_shared.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_shift_jis.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_shift_jis.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_shift_jis.$(OBJEXT): $(top_srcdir)/prism/enc/pm_shift_jis.c +prism/enc/pm_shift_jis.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_tables.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_tables.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_tables.$(OBJEXT): $(top_srcdir)/prism/enc/pm_tables.c +prism/enc/pm_tables.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_unicode.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_unicode.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_unicode.$(OBJEXT): $(top_srcdir)/prism/enc/pm_unicode.c +prism/enc/pm_unicode.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_windows_1251.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_windows_1251.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_windows_1251.$(OBJEXT): $(top_srcdir)/prism/enc/pm_windows_1251.c +prism/enc/pm_windows_1251.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_windows_1252.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_windows_1252.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_windows_1252.$(OBJEXT): $(top_srcdir)/prism/enc/pm_windows_1252.c +prism/enc/pm_windows_1252.$(OBJEXT): {$(VPATH)}config.h +prism/enc/pm_windows_31j.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/enc/pm_windows_31j.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/enc/pm_windows_31j.$(OBJEXT): $(top_srcdir)/prism/enc/pm_windows_31j.c +prism/enc/pm_windows_31j.$(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/enc/pm_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/pack.h +prism/extension.$(OBJEXT): $(top_srcdir)/prism/parser.h +prism/extension.$(OBJEXT): $(top_srcdir)/prism/prism.h +prism/extension.$(OBJEXT): $(top_srcdir)/prism/regexp.h +prism/extension.$(OBJEXT): $(top_srcdir)/prism/unescape.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_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/enc/pm_encoding.h +prism/node.$(OBJEXT): $(top_srcdir)/prism/node.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/unescape.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_strpbrk.h +prism/node.$(OBJEXT): {$(VPATH)}config.h +prism/node.$(OBJEXT): {$(VPATH)}prism/ast.h +prism/node.$(OBJEXT): {$(VPATH)}prism/node.c +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/enc/pm_encoding.h +prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/parser.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): {$(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/enc/pm_encoding.h +prism/prism.$(OBJEXT): $(top_srcdir)/prism/node.h +prism/prism.$(OBJEXT): $(top_srcdir)/prism/pack.h +prism/prism.$(OBJEXT): $(top_srcdir)/prism/parser.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/unescape.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_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/enc/pm_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): {$(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/enc/pm_encoding.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/node.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/pack.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/parser.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/prism.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/regexp.h +prism/serialize.$(OBJEXT): $(top_srcdir)/prism/unescape.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_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/unescape.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/diagnostic.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/enc/pm_encoding.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/node.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/pack.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/parser.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/prism.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/regexp.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/unescape.c +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/unescape.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_state_stack.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_string_list.h +prism/unescape.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h +prism/unescape.$(OBJEXT): {$(VPATH)}config.h +prism/unescape.$(OBJEXT): {$(VPATH)}prism/ast.h +prism/unescape.$(OBJEXT): {$(VPATH)}prism/version.h +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/enc/pm_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): {$(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_strpbrk.$(OBJEXT): $(top_srcdir)/prism/defines.h +prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/enc/pm_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_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/enc/pm_encoding.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/extension.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/node.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/pack.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/parser.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/prism.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/regexp.h +prism_init.$(OBJEXT): $(top_srcdir)/prism/unescape.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_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 @@ -18900,1070 +19993,6 @@ weakmap.$(OBJEXT): {$(VPATH)}thread_native.h weakmap.$(OBJEXT): {$(VPATH)}vm_core.h weakmap.$(OBJEXT): {$(VPATH)}vm_opts.h weakmap.$(OBJEXT): {$(VPATH)}weakmap.c -yarp/api_node.$(OBJEXT): $(hdrdir)/ruby.h -yarp/api_node.$(OBJEXT): $(hdrdir)/ruby/ruby.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/extension.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/api_node.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/api_node.$(OBJEXT): {$(VPATH)}assert.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/assume.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/bool.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/limits.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -yarp/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -yarp/api_node.$(OBJEXT): {$(VPATH)}config.h -yarp/api_node.$(OBJEXT): {$(VPATH)}defines.h -yarp/api_node.$(OBJEXT): {$(VPATH)}encoding.h -yarp/api_node.$(OBJEXT): {$(VPATH)}intern.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/abi.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/anyargs.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/assume.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/const.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/error.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/format.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/cast.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/config.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/constant_p.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/robject.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/ctype.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/dllexport.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/dosish.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/error.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/eval.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/event.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/fl_type.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/gc.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/glob.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/globals.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/extension.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/feature.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/has/warning.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/array.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/class.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/error.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/file.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/io.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/load.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/object.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/process.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/random.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/range.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/re.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/string.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/time.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/interpreter.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/iterator.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/memory.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/method.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/module.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/newobj.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/scan_args.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/special_consts.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/static_assert.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/stdalign.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/stdbool.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/symbol.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/value.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/value_type.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/variable.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/warning_push.h -yarp/api_node.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -yarp/api_node.$(OBJEXT): {$(VPATH)}missing.h -yarp/api_node.$(OBJEXT): {$(VPATH)}onigmo.h -yarp/api_node.$(OBJEXT): {$(VPATH)}oniguruma.h -yarp/api_node.$(OBJEXT): {$(VPATH)}st.h -yarp/api_node.$(OBJEXT): {$(VPATH)}subst.h -yarp/api_node.$(OBJEXT): {$(VPATH)}yarp/api_node.c -yarp/api_node.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/api_node.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/api_pack.$(OBJEXT): $(hdrdir)/ruby.h -yarp/api_pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/api_pack.c -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/extension.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/api_pack.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}assert.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/limits.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}config.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}defines.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}encoding.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}intern.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/abi.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/anyargs.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/assume.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/const.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/error.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/format.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/cast.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/config.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/constant_p.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/robject.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/ctype.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/dllexport.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/dosish.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/error.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/eval.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/event.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/fl_type.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/gc.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/glob.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/globals.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/extension.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/feature.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/has/warning.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/array.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/class.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/object.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/process.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/random.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/range.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/re.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/string.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/time.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/interpreter.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/iterator.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/memory.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/method.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/module.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/newobj.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/stdalign.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/stdbool.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/symbol.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/value.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/value_type.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/variable.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}missing.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}onigmo.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}oniguruma.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}st.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}subst.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/api_pack.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/diagnostic.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/diagnostic.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.c -yarp/diagnostic.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/diagnostic.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/diagnostic.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_ascii.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_ascii.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_ascii.c -yarp/enc/yp_ascii.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_ascii.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_big5.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_big5.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_big5.c -yarp/enc/yp_big5.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_big5.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_euc_jp.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_euc_jp.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_euc_jp.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_euc_jp.c -yarp/enc/yp_euc_jp.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_gbk.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_gbk.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_gbk.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_gbk.c -yarp/enc/yp_gbk.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_1.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_1.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_1.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_1.c -yarp/enc/yp_iso_8859_1.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_10.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_10.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_10.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_10.c -yarp/enc/yp_iso_8859_10.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_11.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_11.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_11.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_11.c -yarp/enc/yp_iso_8859_11.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_13.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_13.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_13.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_13.c -yarp/enc/yp_iso_8859_13.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_14.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_14.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_14.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_14.c -yarp/enc/yp_iso_8859_14.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_15.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_15.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_15.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_15.c -yarp/enc/yp_iso_8859_15.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_16.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_16.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_16.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_16.c -yarp/enc/yp_iso_8859_16.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_2.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_2.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_2.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_2.c -yarp/enc/yp_iso_8859_2.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_3.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_3.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_3.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_3.c -yarp/enc/yp_iso_8859_3.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_4.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_4.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_4.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_4.c -yarp/enc/yp_iso_8859_4.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_5.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_5.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_5.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_5.c -yarp/enc/yp_iso_8859_5.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_6.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_6.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_6.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_6.c -yarp/enc/yp_iso_8859_6.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_7.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_7.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_7.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_7.c -yarp/enc/yp_iso_8859_7.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_8.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_8.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_8.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_8.c -yarp/enc/yp_iso_8859_8.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_iso_8859_9.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_iso_8859_9.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_iso_8859_9.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_iso_8859_9.c -yarp/enc/yp_iso_8859_9.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_koi8_r.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_koi8_r.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_koi8_r.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_koi8_r.c -yarp/enc/yp_koi8_r.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_shared.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_shared.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_shared.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_shared.c -yarp/enc/yp_shared.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_shift_jis.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_shift_jis.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_shift_jis.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_shift_jis.c -yarp/enc/yp_shift_jis.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_tables.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_tables.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_tables.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_tables.c -yarp/enc/yp_tables.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_unicode.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_unicode.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_unicode.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_unicode.c -yarp/enc/yp_unicode.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_windows_1251.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_windows_1251.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_windows_1251.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_windows_1251.c -yarp/enc/yp_windows_1251.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_windows_1252.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_windows_1252.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_windows_1252.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_windows_1252.c -yarp/enc/yp_windows_1252.$(OBJEXT): {$(VPATH)}config.h -yarp/enc/yp_windows_31j.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/enc/yp_windows_31j.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/enc/yp_windows_31j.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_windows_31j.c -yarp/enc/yp_windows_31j.$(OBJEXT): {$(VPATH)}config.h -yarp/extension.$(OBJEXT): $(hdrdir)/ruby.h -yarp/extension.$(OBJEXT): $(hdrdir)/ruby/ruby.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/extension.c -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/extension.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/extension.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/extension.$(OBJEXT): {$(VPATH)}assert.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/assume.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/bool.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/limits.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -yarp/extension.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -yarp/extension.$(OBJEXT): {$(VPATH)}config.h -yarp/extension.$(OBJEXT): {$(VPATH)}defines.h -yarp/extension.$(OBJEXT): {$(VPATH)}encoding.h -yarp/extension.$(OBJEXT): {$(VPATH)}intern.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/abi.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/anyargs.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/assume.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/const.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/error.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/format.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/cast.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/config.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/constant_p.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/robject.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/ctype.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/dllexport.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/dosish.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/error.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/eval.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/event.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/fl_type.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/gc.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/glob.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/globals.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/extension.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/feature.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/has/warning.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/array.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/class.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/error.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/file.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/io.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/load.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/object.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/process.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/random.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/range.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/re.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/select.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/string.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/time.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/interpreter.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/iterator.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/memory.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/method.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/module.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/newobj.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/scan_args.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/special_consts.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/static_assert.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/stdalign.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/stdbool.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/symbol.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/value.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/value_type.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/variable.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/warning_push.h -yarp/extension.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -yarp/extension.$(OBJEXT): {$(VPATH)}missing.h -yarp/extension.$(OBJEXT): {$(VPATH)}onigmo.h -yarp/extension.$(OBJEXT): {$(VPATH)}oniguruma.h -yarp/extension.$(OBJEXT): {$(VPATH)}st.h -yarp/extension.$(OBJEXT): {$(VPATH)}subst.h -yarp/extension.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/extension.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/node.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/node.$(OBJEXT): {$(VPATH)}config.h -yarp/node.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/node.$(OBJEXT): {$(VPATH)}yarp/node.c -yarp/pack.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/pack.$(OBJEXT): $(top_srcdir)/yarp/pack.c -yarp/pack.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/pack.$(OBJEXT): {$(VPATH)}config.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/prettyprint.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/prettyprint.$(OBJEXT): {$(VPATH)}config.h -yarp/prettyprint.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/prettyprint.$(OBJEXT): {$(VPATH)}yarp/prettyprint.c -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/regexp.c -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/regexp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/regexp.$(OBJEXT): {$(VPATH)}config.h -yarp/regexp.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/serialize.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/serialize.$(OBJEXT): {$(VPATH)}config.h -yarp/serialize.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/serialize.$(OBJEXT): {$(VPATH)}yarp/serialize.c -yarp/serialize.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/token_type.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/token_type.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/token_type.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/token_type.$(OBJEXT): {$(VPATH)}config.h -yarp/token_type.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/token_type.$(OBJEXT): {$(VPATH)}yarp/token_type.c -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/unescape.c -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/unescape.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/unescape.$(OBJEXT): {$(VPATH)}config.h -yarp/unescape.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/unescape.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/util/yp_buffer.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_buffer.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.c -yarp/util/yp_buffer.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/util/yp_buffer.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_char.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_char.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.c -yarp/util/yp_char.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/util/yp_char.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/util/yp_char.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_constant_pool.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_constant_pool.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.c -yarp/util/yp_constant_pool.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/util/yp_constant_pool.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_list.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.c -yarp/util/yp_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/util/yp_list.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.c -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/util/yp_memchr.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/util/yp_memchr.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_memchr.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/util/yp_newline_list.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_newline_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.c -yarp/util/yp_newline_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/util/yp_newline_list.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_state_stack.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_state_stack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.c -yarp/util/yp_state_stack.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/util/yp_state_stack.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_string.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_string.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.c -yarp/util/yp_string.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/util/yp_string.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_string_list.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_string_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/util/yp_string_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.c -yarp/util/yp_string_list.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/util/yp_string_list.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_strncasecmp.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_strncasecmp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strncasecmp.c -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.c -yarp/util/yp_strpbrk.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/util/yp_strpbrk.$(OBJEXT): {$(VPATH)}config.h -yarp/util/yp_strpbrk.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/version.h -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/yarp.c -yarp/yarp.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/yarp.$(OBJEXT): {$(VPATH)}config.h -yarp/yarp.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/yarp.$(OBJEXT): {$(VPATH)}yarp/version.h -yarp/yarp_init.$(OBJEXT): $(hdrdir)/ruby.h -yarp/yarp_init.$(OBJEXT): $(hdrdir)/ruby/ruby.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/defines.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/diagnostic.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/enc/yp_encoding.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/extension.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/node.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/pack.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/parser.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/regexp.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/unescape.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_buffer.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_char.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_constant_pool.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_list.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_memchr.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_newline_list.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_state_stack.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_string_list.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/util/yp_strpbrk.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/yarp.h -yarp/yarp_init.$(OBJEXT): $(top_srcdir)/yarp/yarp_init.c -yarp/yarp_init.$(OBJEXT): {$(VPATH)}assert.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/assume.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/bool.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/limits.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}config.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}defines.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}encoding.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}intern.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/abi.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/anyargs.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/assume.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/const.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/error.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/format.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/cast.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/config.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/constant_p.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/robject.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/ctype.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/dllexport.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/dosish.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/error.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/eval.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/event.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/fl_type.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/gc.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/glob.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/globals.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/extension.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/feature.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/has/warning.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/array.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/class.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/error.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/file.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/io.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/load.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/object.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/process.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/random.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/range.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/re.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/select.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/string.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/time.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/interpreter.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/iterator.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/memory.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/method.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/module.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/newobj.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/scan_args.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/special_consts.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/static_assert.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/stdalign.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/stdbool.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/symbol.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/value.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/value_type.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/variable.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/warning_push.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}missing.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}onigmo.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}oniguruma.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}st.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}subst.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}yarp/ast.h -yarp/yarp_init.$(OBJEXT): {$(VPATH)}yarp/version.h 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 diff --git a/compile.c b/compile.c index 02b0927cdcd3fe..c6309f56cb3f8b 100644 --- a/compile.c +++ b/compile.c @@ -44,7 +44,7 @@ #include "builtin.h" #include "insns.inc" #include "insns_info.inc" -#include "yarp/yarp.h" +#include "prism/prism.h" #undef RUBY_UNTYPED_DATA_WARNING #define RUBY_UNTYPED_DATA_WARNING 0 @@ -334,10 +334,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) \ +#define COMPILE_RECV(anchor, desc, node, recv) \ (private_recv_p(node) ? \ (ADD_INSN(anchor, node, putself), VM_CALL_FCALL) : \ - COMPILE(anchor, desc, node->nd_recv) ? 0 : -1) + COMPILE(anchor, desc, recv) ? 0 : -1) #define OPERAND_AT(insn, idx) \ (((INSN*)(insn))->operands[(idx)]) @@ -754,8 +754,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, node->nd_tbl); - iseq_set_arguments(iseq, ret, node->nd_args); + iseq_set_local_table(iseq, RNODE_SCOPE(node)->nd_tbl); + iseq_set_arguments(iseq, ret, RNODE_SCOPE(node)->nd_args); switch (ISEQ_BODY(iseq)->type) { case ISEQ_TYPE_BLOCK: @@ -770,7 +770,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", node->nd_body)); + CHECK(COMPILE(ret, "block body", RNODE_SCOPE(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; @@ -783,23 +783,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", node->nd_body)); + CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(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 = node->nd_body; + ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(node)->nd_body; ADD_TRACE(ret, RUBY_EVENT_CALL); - CHECK(COMPILE(ret, "scoped node", node->nd_body)); - ISEQ_COMPILE_DATA(iseq)->root_node = node->nd_body; + CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body)); + ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(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", node->nd_body)); + CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body)); break; } } @@ -857,17 +857,17 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) return iseq_setup(iseq, ret); } -typedef struct yp_compile_context { - yp_parser_t *parser; - struct yp_compile_context *previous; +typedef struct pm_compile_context { + pm_parser_t *parser; + struct pm_compile_context *previous; ID *constants; st_table *index_lookup_table; -} yp_compile_context_t; +} pm_compile_context_t; -static VALUE rb_translate_yarp(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_compile_context_t *compile_context); +static VALUE rb_translate_prism(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context); VALUE -rb_iseq_compile_yarp_node(rb_iseq_t * iseq, const yp_node_t *yarp_pointer, yp_parser_t *parser) +rb_iseq_compile_prism_node(rb_iseq_t * iseq, const pm_node_t *node, pm_parser_t *parser) { DECL_ANCHOR(ret); INIT_ANCHOR(ret); @@ -875,21 +875,18 @@ rb_iseq_compile_yarp_node(rb_iseq_t * iseq, const yp_node_t *yarp_pointer, yp_pa ID *constants = calloc(parser->constant_pool.size, sizeof(ID)); rb_encoding *encoding = rb_enc_find(parser->encoding.name); - for (size_t index = 0; index < parser->constant_pool.capacity; index++) { - yp_constant_t constant = parser->constant_pool.constants[index]; - - if (constant.id != 0) { - constants[constant.id - 1] = rb_intern3((const char *) constant.start, constant.length, encoding); - } + 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); } - yp_compile_context_t compile_context = { + pm_compile_context_t compile_context = { .parser = parser, .previous = NULL, .constants = constants }; - CHECK(rb_translate_yarp(iseq, yarp_pointer, ret, &compile_context)); + CHECK(rb_translate_prism(iseq, node, ret, &compile_context)); free(constants); CHECK(iseq_setup_insn(iseq, ret)); @@ -1821,14 +1818,14 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, while (node) { kw++; - node = node->nd_next; + node = RNODE_KW_ARG(node)->nd_next; } arg_size += kw; keyword->bits_start = arg_size++; node = args->kw_args; while (node) { - const NODE *val_node = node->nd_body->nd_value; + const NODE *val_node = RNODE_LASGN(RNODE_KW_ARG(node)->nd_body)->nd_value; VALUE dv; if (val_node == NODE_SPECIAL_REQUIRED_KEYWORD) { @@ -1837,7 +1834,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, else { switch (nd_type(val_node)) { case NODE_LIT: - dv = val_node->nd_lit; + dv = RNODE_LIT(val_node)->nd_lit; break; case NODE_NIL: dv = Qnil; @@ -1857,12 +1854,12 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, rb_ary_push(default_values, dv); } - node = node->nd_next; + node = RNODE_KW_ARG(node)->nd_next; } keyword->num = kw; - if (args->kw_rest_arg->nd_vid != 0) { + if (RNODE_DVAR(args->kw_rest_arg)->nd_vid != 0) { keyword->rest_start = arg_size++; body->param.flags.has_kwrest = TRUE; } @@ -1893,7 +1890,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 = node_args->nd_ainfo; + struct rb_args_info *args = RNODE_ARGS(node_args)->nd_ainfo; ID rest_id = 0; int last_comma = 0; ID block_id = 0; @@ -1924,8 +1921,8 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons 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)); - node = node->nd_next; + NO_CHECK(COMPILE_POPPED(optargs, "optarg", RNODE_OPT_ARG(node)->nd_body)); + node = RNODE_OPT_ARG(node)->nd_next; i += 1; } @@ -2422,7 +2419,12 @@ 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); - body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body)); + 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->call_data = ZALLOC_N(struct rb_call_data, body->ci_size); ISEQ_COMPILE_DATA(iseq)->ci_index = 0; @@ -2561,8 +2563,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]; - struct rb_call_data *cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++]; assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size); + struct rb_call_data *cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++]; cd->ci = source_ci; cd->cc = vm_cc_empty(); generated_iseq[code_index + 1 + j] = (VALUE)cd; @@ -4022,16 +4024,16 @@ all_string_result_p(const NODE *node) case NODE_STR: case NODE_DSTR: return TRUE; case NODE_IF: case NODE_UNLESS: - 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); + 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); return FALSE; case NODE_AND: case NODE_OR: - if (!node->nd_2nd) - return all_string_result_p(node->nd_1st); - if (!all_string_result_p(node->nd_1st)) + 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)) return FALSE; - return all_string_result_p(node->nd_2nd); + return all_string_result_p(RNODE_AND(node)->nd_2nd); default: return FALSE; } @@ -4040,8 +4042,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 NODE *list = node->nd_next; - VALUE lit = node->nd_lit; + const struct RNode_LIST *list = RNODE_DSTR(node)->nd_next; + VALUE lit = RNODE_DSTR(node)->nd_lit; LINK_ELEMENT *first_lit = 0; int cnt = 0; @@ -4062,7 +4064,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(head->nd_lit); + lit = rb_fstring(RNODE_STR(head)->nd_lit); ADD_INSN1(ret, head, putobject, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); lit = Qnil; @@ -4071,7 +4073,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons CHECK(COMPILE(ret, "each string", head)); } cnt++; - list = list->nd_next; + list = (struct RNode_LIST *)list->nd_next; } if (NIL_P(lit) && first_lit) { ELEM_REMOVE(first_lit); @@ -4086,12 +4088,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", node->nd_head, - (node->nd_next ? 1 : popped))); - node = node->nd_next; + CHECK(COMPILE_(ret, "BLOCK body", RNODE_BLOCK(node)->nd_head, + (RNODE_BLOCK(node)->nd_next ? 1 : popped))); + node = RNODE_BLOCK(node)->nd_next; } if (node) { - CHECK(COMPILE_(ret, "BLOCK next", node->nd_next, popped)); + CHECK(COMPILE_(ret, "BLOCK next", RNODE_BLOCK(node)->nd_next, popped)); } return COMPILE_OK; } @@ -4100,8 +4102,8 @@ static int compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) { int cnt; - if (!node->nd_next) { - VALUE lit = rb_fstring(node->nd_lit); + if (!RNODE_DSTR(node)->nd_next) { + VALUE lit = rb_fstring(RNODE_DSTR(node)->nd_lit); ADD_INSN1(ret, node, putstring, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); } @@ -4117,7 +4119,7 @@ compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) { int cnt; CHECK(compile_dstr_fragments(iseq, ret, node, &cnt)); - ADD_INSN2(ret, node, toregexp, INT2FIX(node->nd_cflag), INT2FIX(cnt)); + ADD_INSN2(ret, node, toregexp, INT2FIX(RNODE_DREGX(node)->nd_cflag), INT2FIX(cnt)); return COMPILE_OK; } @@ -4135,7 +4137,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", node->nd_beg)); + CHECK(COMPILE(ret, "flip2 beg", RNODE_FLIP2(node)->nd_beg)); ADD_INSNL(ret, node, branchunless, else_label); ADD_INSN1(ret, node, putobject, Qtrue); ADD_INSN1(ret, node, setspecial, key); @@ -4145,7 +4147,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", node->nd_end)); + CHECK(COMPILE(ret, "flip2 end", RNODE_FLIP2(node)->nd_end)); ADD_INSNL(ret, node, branchunless, then_label); ADD_INSN1(ret, node, putobject, Qfalse); ADD_INSN1(ret, node, setspecial, key); @@ -4155,9 +4157,10 @@ 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 *const ret, const NODE *cond, +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) @@ -4176,28 +4179,39 @@ compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond, return COMPILE_OK; } if (!label->refcnt) { - ADD_INSN(seq, cond, putnil); - } - else { - ADD_LABEL(seq, label); + 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 *const ret, const NODE *cond, +compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, LABEL *then_label, LABEL *else_label) { + int ok; + DECL_ANCHOR(ignore); + again: switch (nd_type(cond)) { case NODE_AND: - CHECK(compile_logical(iseq, ret, cond->nd_1st, NULL, else_label)); - cond = cond->nd_2nd; + 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; case NODE_OR: - CHECK(compile_logical(iseq, ret, cond->nd_1st, then_label, NULL)); - cond = cond->nd_2nd; + 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; case NODE_LIT: /* NODE_LIT is always true */ case NODE_TRUE: @@ -4264,7 +4278,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *co static int keyword_node_p(const NODE *const node) { - return nd_type_p(node, NODE_HASH) && (node->nd_brace & HASH_BRACE) != HASH_BRACE; + return nd_type_p(node, NODE_HASH) && (RNODE_HASH(node)->nd_brace & HASH_BRACE) != HASH_BRACE; } static int @@ -4277,22 +4291,22 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, RUBY_ASSERT(kw_arg_ptr != NULL); RUBY_ASSERT(flag != NULL); - if (root_node->nd_head && nd_type_p(root_node->nd_head, NODE_LIST)) { - const NODE *node = root_node->nd_head; + 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; int seen_nodes = 0; while (node) { - const NODE *key_node = node->nd_head; + const NODE *key_node = RNODE_LIST(node)->nd_head; seen_nodes++; assert(nd_type_p(node, NODE_LIST)); - if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(key_node->nd_lit)) { + if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(RNODE_LIT(key_node)->nd_lit)) { /* can be keywords */ } else { if (flag) { *flag |= VM_CALL_KW_SPLAT; - if (seen_nodes > 1 || node->nd_next->nd_next) { + if (seen_nodes > 1 || RNODE_LIST(RNODE_LIST(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. @@ -4302,14 +4316,14 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } return FALSE; } - node = node->nd_next; /* skip value node */ - node = node->nd_next; + node = RNODE_LIST(node)->nd_next; /* skip value node */ + node = RNODE_LIST(node)->nd_next; } /* may be keywords */ - node = root_node->nd_head; + node = RNODE_HASH(root_node)->nd_head; { - int len = (int)node->nd_alen / 2; + int len = (int)RNODE_LIST(node)->as.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; @@ -4318,10 +4332,10 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, *kw_arg_ptr = kw_arg; - 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; + 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; NO_CHECK(COMPILE(ret, "keyword values", val_node)); } assert(i == len); @@ -4336,17 +4350,17 @@ compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, NODE **k { int len = 0; - for (; node; len++, node = node->nd_next) { + for (; node; len++, node = RNODE_LIST(node)->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_args", node, NODE_LIST, -1); } - if (node->nd_next == NULL && keyword_node_p(node->nd_head)) { /* last node is kwnode */ - *kwnode_ptr = node->nd_head; + 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; } else { - RUBY_ASSERT(!keyword_node_p(node->nd_head)); - NO_CHECK(COMPILE_(ret, "array element", node->nd_head, FALSE)); + RUBY_ASSERT(!keyword_node_p(RNODE_LIST(node)->nd_head)); + NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, FALSE)); } } @@ -4383,15 +4397,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(node->nd_lit); + lit = rb_str_dup(RNODE_STR(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(node->nd_lit); + return rb_fstring(RNODE_STR(node)->nd_lit); } default: - return node->nd_lit; + return RNODE_LIT(node)->nd_lit; } } @@ -4410,8 +4424,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 = node->nd_next) { - NO_CHECK(COMPILE_(ret, "array element", node->nd_head, popped)); + for (; node; node = RNODE_LIST(node)->nd_next) { + NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, popped)); } return 1; } @@ -4470,10 +4484,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(node->nd_head, iseq)) { + if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq)) { /* count the elements that are optimizable */ - 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) + 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) count++; if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) { @@ -4481,8 +4495,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 = node->nd_next) - rb_ary_push(ary, static_literal_value(node->nd_head, iseq)); + for (; count; count--, node = RNODE_LIST(node)->nd_next) + rb_ary_push(ary, static_literal_value(RNODE_LIST(node)->nd_head, iseq)); OBJ_FREEZE(ary); /* Emit optimized code */ @@ -4500,15 +4514,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 = node->nd_next) { + for (; count; count--, node = RNODE_LIST(node)->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_array", node, NODE_LIST, -1); } - NO_CHECK(COMPILE_(ret, "array element", node->nd_head, 0)); + NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, 0)); stack_len++; - if (!node->nd_next && keyword_node_p(node->nd_head)) { + if (!RNODE_LIST(node)->nd_next && keyword_node_p(RNODE_LIST(node)->nd_head)) { /* Reached the end, and the last element is a keyword */ FLUSH_CHUNK(newarraykwsplat); return 1; @@ -4546,7 +4560,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 node->nd_head && static_literal_node_p(node->nd_head, iseq) && static_literal_node_p(node->nd_next->nd_head, 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); } static int @@ -4554,7 +4568,7 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth { const NODE *line_node = node; - node = node->nd_head; + node = RNODE_HASH(node)->nd_head; if (!node || nd_type_p(node, NODE_ZLIST)) { if (!popped) { @@ -4566,8 +4580,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 = node->nd_next) { - NO_CHECK(COMPILE_(ret, "hash element", node->nd_head, popped)); + for (; node; node = RNODE_LIST(node)->nd_next) { + NO_CHECK(COMPILE_(ret, "hash element", RNODE_LIST(node)->nd_head, popped)); } return 1; } @@ -4620,8 +4634,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 = node->nd_next->nd_next; - for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = node_tmp->nd_next->nd_next) + 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) count++; if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_hash_len) { @@ -4629,10 +4643,10 @@ 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 = node->nd_next->nd_next) { + for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { VALUE elem[2]; - elem[0] = static_literal_value(node->nd_head, iseq); - elem[1] = static_literal_value(node->nd_next->nd_head, iseq); + 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); rb_ary_cat(ary, elem, 2); } VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2); @@ -4659,16 +4673,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 = node->nd_next->nd_next) { + for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_hash", node, NODE_LIST, -1); } - if (node->nd_head) { + if (RNODE_LIST(node)->nd_head) { /* Normal key-value pair */ - NO_CHECK(COMPILE_(anchor, "hash key element", node->nd_head, 0)); - NO_CHECK(COMPILE_(anchor, "hash value element", node->nd_next->nd_head, 0)); + 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)); stack_len += 2; /* If there are many pushed elements, flush them to avoid stack overflow */ @@ -4678,10 +4692,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 = node->nd_next->nd_head; - int empty_kw = nd_type_p(kw, NODE_LIT) && RB_TYPE_P(kw->nd_lit, T_HASH); /* foo( ..., **{}, ...) */ + 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( ..., **{}, ...) */ int first_kw = first_chunk && stack_len == 0; /* foo(1,2,3, **kw, ...) */ - int last_kw = !node->nd_next->nd_next; /* foo( ..., **kw) */ + int last_kw = !RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next; /* foo( ..., **kw) */ int only_kw = last_kw && first_kw; /* foo(1,2,3, **kw) */ if (empty_kw) { @@ -4744,7 +4758,7 @@ rb_node_case_when_optimizable_literal(const NODE *const node) { switch (nd_type(node)) { case NODE_LIT: { - VALUE v = node->nd_lit; + VALUE v = RNODE_LIT(node)->nd_lit; double ival; if (RB_FLOAT_TYPE_P(v) && modf(RFLOAT_VALUE(v), &ival) == 0.0) { @@ -4765,7 +4779,7 @@ rb_node_case_when_optimizable_literal(const NODE *const node) case NODE_FALSE: return Qfalse; case NODE_STR: - return rb_fstring(node->nd_lit); + return rb_fstring(RNODE_LIT(node)->nd_lit); } return Qundef; } @@ -4775,7 +4789,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 = vals->nd_head; + const NODE *val = RNODE_LIST(vals)->nd_head; VALUE lit = rb_node_case_when_optimizable_literal(val); if (UNDEF_P(lit)) { @@ -4786,8 +4800,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", val->nd_lit); - lit = rb_fstring(val->nd_lit); + debugp_param("nd_lit", RNODE_STR(val)->nd_lit); + lit = rb_fstring(RNODE_STR(val)->nd_lit); ADD_INSN1(cond_seq, val, putobject, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); } @@ -4799,7 +4813,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, ADD_INSN1(cond_seq, vals, topn, INT2FIX(1)); ADD_CALL(cond_seq, vals, idEqq, INT2FIX(1)); ADD_INSNL(cond_seq, val, branchif, l1); - vals = vals->nd_next; + vals = RNODE_LIST(vals)->nd_next; } return only_special_literals; } @@ -4817,19 +4831,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", vals->nd_head)); + CHECK(COMPILE(cond_seq, "when splat", RNODE_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, vals->nd_head, l1, only_special_literals, literals)); - CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals)); + 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)); break; case NODE_ARGSPUSH: - CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals)); + CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSPUSH(vals)->nd_head, l1, only_special_literals, literals)); ADD_INSN (cond_seq, line_node, dup); - CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body)); + CHECK(COMPILE(cond_seq, "when argspush body", RNODE_ARGSPUSH(vals)->nd_body)); ADD_INSN1(cond_seq, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE)); ADD_INSNL(cond_seq, line_node, branchif, l1); break; @@ -5049,7 +5063,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const break; } case NODE_CDECL: - if (!node->nd_vid) { + if (!RNODE_CDECL(node)->nd_vid) { /* Special handling only needed for expr::C, not for C */ INSN *iobj; @@ -5087,8 +5101,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, lhsn->nd_next)); - CHECK(compile_massign_lhs(iseq, ret, ret, ret, ret, lhsn->nd_head, NULL, 0)); + 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)); } return COMPILE_OK; } @@ -5118,31 +5132,29 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } while (lhsn) { - const NODE *ln = lhsn->nd_head; + const NODE *ln = RNODE_LIST(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(ln->nd_vid); + MEMORY(RNODE_LASGN(ln)->nd_vid); break; default: return 0; } - lhsn = lhsn->nd_next; + lhsn = RNODE_LIST(lhsn)->nd_next; llen++; } while (rhsn) { if (llen <= rlen) { - NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", RNODE_LIST(rhsn)->nd_head)); } else { - NO_CHECK(COMPILE(ret, "masgn val", rhsn->nd_head)); + NO_CHECK(COMPILE(ret, "masgn val", RNODE_LIST(rhsn)->nd_head)); } - rhsn = rhsn->nd_next; + rhsn = RNODE_LIST(rhsn)->nd_next; rlen++; } @@ -5159,9 +5171,9 @@ 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 = node->nd_value; - const NODE *splatn = node->nd_args; - const NODE *lhsn = node->nd_head; + 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 *lhsn_count = lhsn; int lhs_splat = (splatn && NODE_NAMED_REST_P(splatn)) ? 1 : 0; @@ -5171,20 +5183,20 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs while (lhsn_count) { llen++; - lhsn_count = lhsn_count->nd_next; + lhsn_count = RNODE_LIST(lhsn_count)->nd_next; } while (lhsn) { - CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, lhsn->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level)); + CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(lhsn)->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level)); lpos++; - lhsn = lhsn->nd_next; + lhsn = RNODE_LIST(lhsn)->nd_next; } if (lhs_splat) { if (nd_type_p(splatn, NODE_POSTARG)) { /*a, b, *r, p1, p2 */ - const NODE *postn = splatn->nd_2nd; - const NODE *restn = splatn->nd_1st; - int plen = (int)postn->nd_alen; + 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; int ppos = 0; int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); @@ -5194,9 +5206,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, postn->nd_head, state, (plen - ppos) + state->lhs_level)); + CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(postn)->nd_head, state, (plen - ppos) + state->lhs_level)); ppos++; - postn = postn->nd_next; + postn = RNODE_LIST(postn)->nd_next; } } else { @@ -5222,7 +5234,7 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs static int compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { - if (!popped || node->nd_args || !compile_massign_opt(iseq, ret, node->nd_value, node->nd_head)) { + if (!popped || RNODE_MASGN(node)->nd_args || !compile_massign_opt(iseq, ret, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head)) { struct masgn_state state; state.lhs_level = popped ? 0 : 1; state.nested = 0; @@ -5271,15 +5283,15 @@ collect_const_segments(rb_iseq_t *iseq, const NODE *node) for (;;) { switch (nd_type(node)) { case NODE_CONST: - rb_ary_unshift(arr, ID2SYM(node->nd_vid)); + rb_ary_unshift(arr, ID2SYM(RNODE_CONST(node)->nd_vid)); return arr; case NODE_COLON3: - rb_ary_unshift(arr, ID2SYM(node->nd_mid)); + rb_ary_unshift(arr, ID2SYM(RNODE_COLON3(node)->nd_mid)); rb_ary_unshift(arr, ID2SYM(idNULL)); return arr; case NODE_COLON2: - rb_ary_unshift(arr, ID2SYM(node->nd_mid)); - node = node->nd_head; + rb_ary_unshift(arr, ID2SYM(RNODE_COLON2(node)->nd_mid)); + node = RNODE_COLON2(node)->nd_head; break; default: return Qfalse; @@ -5293,22 +5305,22 @@ compile_const_prefix(rb_iseq_t *iseq, const NODE *const node, { switch (nd_type(node)) { case NODE_CONST: - debugi("compile_const_prefix - colon", node->nd_vid); + debugi("compile_const_prefix - colon", RNODE_CONST(node)->nd_vid); ADD_INSN1(body, node, putobject, Qtrue); - ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_vid)); + ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid)); break; case NODE_COLON3: - debugi("compile_const_prefix - colon3", node->nd_mid); + debugi("compile_const_prefix - colon3", RNODE_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(node->nd_mid)); + ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid)); break; case NODE_COLON2: - CHECK(compile_const_prefix(iseq, node->nd_head, pref, body)); - debugi("compile_const_prefix - colon2", node->nd_mid); + CHECK(compile_const_prefix(iseq, RNODE_COLON2(node)->nd_head, pref, body)); + debugi("compile_const_prefix - colon2", RNODE_COLON2(node)->nd_mid); ADD_INSN1(body, node, putobject, Qfalse); - ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_mid)); + ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON2(node)->nd_mid)); break; default: CHECK(COMPILE(pref, "const colon2 prefix", node)); @@ -5325,9 +5337,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 (cpath->nd_head) { + else if (RNODE_COLON2(cpath)->nd_head) { /* Bar::Foo */ - NO_CHECK(COMPILE(ret, "nd_else->nd_head", cpath->nd_head)); + NO_CHECK(COMPILE(ret, "nd_else->nd_head", RNODE_COLON2(cpath)->nd_head)); return VM_DEFINECLASS_FLAG_SCOPED; } else { @@ -5341,9 +5353,9 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath) static inline int private_recv_p(const NODE *node) { - if (nd_type_p(node->nd_recv, NODE_SELF)) { - NODE *self = node->nd_recv; - return self->nd_state != 0; + if (nd_type_p(RNODE_CALL(node)->nd_recv, NODE_SELF)) { + NODE *self = RNODE_CALL(node)->nd_recv; + return RNODE_SELF(self)->nd_state != 0; } return 0; } @@ -5385,13 +5397,13 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *vals = node; do { - defined_expr0(iseq, ret, vals->nd_head, lfinish, Qfalse, false); + defined_expr0(iseq, ret, RNODE_LIST(vals)->nd_head, lfinish, Qfalse, false); if (!lfinish[1]) { lfinish[1] = NEW_LABEL(line); } ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - } while ((vals = vals->nd_next) != NULL); + } while ((vals = RNODE_LIST(vals)->nd_next) != NULL); } /* fall through */ case NODE_STR: @@ -5412,47 +5424,47 @@ 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(node->nd_vid), get_ivar_ic_value(iseq,node->nd_vid), PUSH_VAL(DEFINED_IVAR)); + ID2SYM(RNODE_IVAR(node)->nd_vid), get_ivar_ic_value(iseq,RNODE_IVAR(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(node->nd_vid), PUSH_VAL(DEFINED_GVAR)); + ID2SYM(RNODE_GVAR(node)->nd_vid), PUSH_VAL(DEFINED_GVAR)); return; case NODE_CVAR: ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CVAR), - ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_CVAR)); + ID2SYM(RNODE_CVAR(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(node->nd_vid), PUSH_VAL(DEFINED_CONST)); + ID2SYM(RNODE_CONST(node)->nd_vid), PUSH_VAL(DEFINED_CONST)); return; case NODE_COLON2: if (!lfinish[1]) { lfinish[1] = NEW_LABEL(line); } - defined_expr0(iseq, ret, node->nd_head, lfinish, Qfalse, false); + defined_expr0(iseq, ret, RNODE_COLON2(node)->nd_head, lfinish, Qfalse, false); ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", node->nd_head)); + NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", RNODE_COLON2(node)->nd_head)); - if (rb_is_const_id(node->nd_mid)) { + if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) { ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CONST_FROM), - ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_CONST)); + ID2SYM(RNODE_COLON2(node)->nd_mid), PUSH_VAL(DEFINED_CONST)); } else { ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD), - ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(RNODE_COLON2(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(node->nd_mid), PUSH_VAL(DEFINED_CONST)); + INT2FIX(DEFINED_CONST_FROM), ID2SYM(RNODE_COLON3(node)->nd_mid), PUSH_VAL(DEFINED_CONST)); return; /* method dispatch */ @@ -5465,7 +5477,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 (node->nd_args || explicit_receiver) { + if (RNODE_CALL(node)->nd_args || explicit_receiver) { if (!lfinish[1]) { lfinish[1] = NEW_LABEL(line); } @@ -5473,31 +5485,31 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, lfinish[2] = NEW_LABEL(line); } } - if (node->nd_args) { - defined_expr0(iseq, ret, node->nd_args, lfinish, Qfalse, false); + if (RNODE_CALL(node)->nd_args) { + defined_expr0(iseq, ret, RNODE_CALL(node)->nd_args, lfinish, Qfalse, false); ADD_INSNL(ret, line_node, branchunless, lfinish[1]); } if (explicit_receiver) { - defined_expr0(iseq, ret, node->nd_recv, lfinish, Qfalse, true); - switch (nd_type(node->nd_recv)) { + defined_expr0(iseq, ret, RNODE_CALL(node)->nd_recv, lfinish, Qfalse, true); + switch (nd_type(RNODE_CALL(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, node->nd_recv, nd_type(node->nd_recv), line_node, 0, true); + compile_call(iseq, ret, RNODE_CALL(node)->nd_recv, nd_type(RNODE_CALL(node)->nd_recv), line_node, 0, true); break; default: ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - NO_CHECK(COMPILE(ret, "defined/recv", node->nd_recv)); + NO_CHECK(COMPILE(ret, "defined/recv", RNODE_CALL(node)->nd_recv)); break; } if (keep_result) { ADD_INSN(ret, line_node, dup); } ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD), - ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(RNODE_CALL(node)->nd_mid), PUSH_VAL(DEFINED_METHOD)); } else { ADD_INSN(ret, line_node, putself); @@ -5505,7 +5517,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(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(RNODE_CALL(node)->nd_mid), PUSH_VAL(DEFINED_METHOD)); } return; } @@ -5520,7 +5532,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((node->nd_nth << 1) | (type == NODE_BACK_REF)), + INT2FIX((RNODE_BACK_REF(node)->nd_nth << 1) | (type == NODE_BACK_REF)), PUSH_VAL(DEFINED_GVAR)); return; @@ -5596,7 +5608,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 (!node->nd_head) { + if (!RNODE_DEFINED(node)->nd_head) { VALUE str = rb_iseq_defined_string(DEFINED_NIL); ADD_INSN1(ret, line_node, putobject, str); } @@ -5606,7 +5618,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, node->nd_head, lfinish, needstr); + defined_expr(iseq, ret, RNODE_DEFINED(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); @@ -5735,10 +5747,10 @@ check_keyword(const NODE *node) /* This check is essentially a code clone of compile_keyword_arg. */ if (nd_type_p(node, NODE_LIST)) { - while (node->nd_next) { - node = node->nd_next; + while (RNODE_LIST(node)->nd_next) { + node = RNODE_LIST(node)->nd_next; } - node = node->nd_head; + node = RNODE_LIST(node)->nd_head; } return keyword_node_p(node); @@ -5750,9 +5762,9 @@ keyword_node_single_splat_p(NODE *kwnode) { RUBY_ASSERT(keyword_node_p(kwnode)); - NODE *node = kwnode->nd_head; - return node->nd_head == NULL && - node->nd_next->nd_next == NULL; + 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 @@ -5782,7 +5794,7 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, } case NODE_SPLAT: { // f(*a) - NO_CHECK(COMPILE(args, "args (splat)", argn->nd_head)); + 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); @@ -5790,19 +5802,19 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, } case NODE_ARGSCAT: { if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT; - int argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL); + int argc = setup_args_core(iseq, args, RNODE_ARGSCAT(argn)->nd_head, 1, NULL, NULL); - if (nd_type_p(argn->nd_body, NODE_LIST)) { - int rest_len = compile_args(iseq, args, argn->nd_body, &kwnode); + 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(argn->nd_body)); - NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body)); + 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(argn->nd_head, NODE_LIST)) { + if (nd_type_p(RNODE_ARGSCAT(argn)->nd_head, NODE_LIST)) { ADD_INSN1(args, argn, splatarray, Qtrue); argc += 1; } @@ -5824,21 +5836,21 @@ setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, } case NODE_ARGSPUSH: { if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT; - int argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL); + int argc = setup_args_core(iseq, args, RNODE_ARGSPUSH(argn)->nd_head, 1, NULL, NULL); - if (nd_type_p(argn->nd_body, NODE_LIST)) { - int rest_len = compile_args(iseq, args, argn->nd_body, &kwnode); + 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(argn->nd_body)) { - kwnode = argn->nd_body; + if (keyword_node_p(RNODE_ARGSPUSH(argn)->nd_body)) { + kwnode = RNODE_ARGSPUSH(argn)->nd_body; } else { - NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body)); + NO_CHECK(COMPILE(args, "args (cat: splat)", RNODE_ARGSPUSH(argn)->nd_body)); ADD_INSN1(args, argn, newarray, INT2FIX(1)); ADD_INSN(args, argn, concatarray); } @@ -5871,7 +5883,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", argn->nd_body)); + NO_CHECK(COMPILE(arg_block, "block", RNODE_BLOCK_PASS(argn)->nd_body)); *flag |= VM_CALL_ARGS_BLOCKARG; @@ -5885,7 +5897,7 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, dup_rest = 0; } } - ret = INT2FIX(setup_args_core(iseq, args, argn->nd_head, dup_rest, flag, keywords)); + ret = INT2FIX(setup_args_core(iseq, args, RNODE_BLOCK_PASS(argn)->nd_head, dup_rest, flag, keywords)); ADD_SEQ(args, arg_block); } else { @@ -5925,19 +5937,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 = vars->nd_next) { + for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) { INSN *cap; - if (vars->nd_next) { + if (RNODE_BLOCK(vars)->nd_next) { ADD_INSN(ret, line_node, dup); } last = ret->last; - NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(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 (!vars->nd_next && vars == node) { + if (!RNODE_BLOCK(vars)->nd_next && vars == node) { /* only one name */ DECL_ANCHOR(nom); @@ -5958,9 +5970,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 = vars->nd_next) { + for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) { last = ret->last; - NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(vars)->nd_head)); last = last->next; /* putobject :var */ ((INSN*)last)->insn_id = BIN(putnil); ((INSN*)last)->operand_size = 0; @@ -5974,7 +5986,7 @@ optimizable_range_item_p(const NODE *n) if (!n) return FALSE; switch (nd_type(n)) { case NODE_LIT: - return RB_INTEGER_TYPE_P(n->nd_lit); + return RB_INTEGER_TYPE_P(RNODE_LIT(n)->nd_lit); case NODE_NIL: return TRUE; default: @@ -5985,8 +5997,8 @@ 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 ? node->nd_body : node->nd_else; - const NODE *const node_else = type == NODE_IF ? node->nd_else : node->nd_body; + 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; const int line = nd_line(node); const NODE *line_node = node; @@ -5999,7 +6011,7 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int else_label = NEW_LABEL(line); end_label = 0; - compile_branch_condition(iseq, cond_seq, node->nd_cond, then_label, else_label); + compile_branch_condition(iseq, cond_seq, RNODE_IF(node)->nd_cond, then_label, else_label); ADD_SEQ(ret, cond_seq); if (then_label->refcnt && else_label->refcnt) { @@ -6079,11 +6091,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", node->nd_head)); + CHECK(COMPILE(head, "case base", RNODE_CASE(node)->nd_head)); branches = decl_branch_base(iseq, node, "case"); - node = node->nd_body; + node = RNODE_CASE(node)->nd_body; EXPECT_NODE("NODE_CASE", node, NODE_WHEN, COMPILE_NG); type = nd_type(node); line = nd_line(node); @@ -6103,14 +6115,14 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod add_trace_branch_coverage( iseq, body_seq, - node->nd_body ? node->nd_body : node, + RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node, branch_id++, "when", branches); - CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped)); + CHECK(COMPILE_(body_seq, "when body", RNODE_WHEN(node)->nd_body, popped)); ADD_INSNL(body_seq, line_node, jump, endlabel); - vals = node->nd_head; + vals = RNODE_WHEN(node)->nd_head; if (vals) { switch (nd_type(vals)) { case NODE_LIST: @@ -6131,7 +6143,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 = node->nd_next; + node = RNODE_WHEN(node)->nd_next; if (!node) { break; } @@ -6176,7 +6188,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 = orig_node->nd_body; + const NODE *node = RNODE_CASE2(orig_node)->nd_body; LABEL *endlabel; DECL_ANCHOR(body_seq); VALUE branches = Qfalse; @@ -6194,14 +6206,14 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no add_trace_branch_coverage( iseq, body_seq, - node->nd_body ? node->nd_body : node, + RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node, branch_id++, "when", branches); - CHECK(COMPILE_(body_seq, "when", node->nd_body, popped)); + CHECK(COMPILE_(body_seq, "when", RNODE_WHEN(node)->nd_body, popped)); ADD_INSNL(body_seq, node, jump, endlabel); - vals = node->nd_head; + vals = RNODE_WHEN(node)->nd_head; if (!vals) { EXPECT_NODE_NONULL("NODE_WHEN", node, NODE_LIST, COMPILE_NG); } @@ -6209,12 +6221,12 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no case NODE_LIST: while (vals) { LABEL *lnext; - val = vals->nd_head; + val = RNODE_LIST(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 = vals->nd_next; + vals = RNODE_LIST(vals)->nd_next; } break; case NODE_SPLAT: @@ -6228,7 +6240,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 = node->nd_next; + node = RNODE_WHEN(node)->nd_next; } /* else */ add_trace_branch_coverage( @@ -6320,10 +6332,10 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c * match_failed: * goto unmatched */ - struct rb_ary_pattern_info *apinfo = node->nd_apinfo; + struct rb_ary_pattern_info *apinfo = RNODE_ARYPTN(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 pre_args_num = apinfo->pre_args ? rb_long2int(RNODE_LIST(apinfo->pre_args)->as.nd_alen) : 0; + const int post_args_num = apinfo->post_args ? rb_long2int(RNODE_LIST(apinfo->post_args)->as.nd_alen) : 0; const int min_argc = pre_args_num + post_args_num; const int use_rest_num = apinfo->rest_arg && (NODE_NAMED_REST_P(apinfo->rest_arg) || @@ -6364,8 +6376,8 @@ 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, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (2) */, false)); - args = args->nd_next; + 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; } if (apinfo->rest_arg) { @@ -6402,8 +6414,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, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (4) */, false)); - args = args->nd_next; + 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; } ADD_INSN(ret, line_node, pop); @@ -6481,9 +6493,9 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c * match_failed: * goto unmatched */ - struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo; + struct rb_fnd_pattern_info *fpinfo = RNODE_FNDPTN(node)->nd_fpinfo; const NODE *args = fpinfo->args; - const int args_num = fpinfo->args ? rb_long2int(fpinfo->args->nd_alen) : 0; + const int args_num = fpinfo->args ? rb_long2int(RNODE_LIST(fpinfo->args)->as.nd_alen) : 0; LABEL *match_failed, *type_error, *deconstruct, *deconstructed; match_failed = NEW_LABEL(line); @@ -6536,8 +6548,8 @@ 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, args->nd_head, next_loop, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (5) */, false)); - args = args->nd_next; + 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; } if (NODE_NAMED_REST_P(fpinfo->pre_rest_arg)) { @@ -6668,12 +6680,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 (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); + 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); while (kw_args) { - rb_ary_push(keys, kw_args->nd_head->nd_lit); - kw_args = kw_args->nd_next->nd_next; + 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; } } @@ -6700,28 +6712,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 (node->nd_pkwrestarg) { + if (RNODE_HSHPTN(node)->nd_pkwrestarg) { ADD_SEND(ret, line_node, rb_intern("dup"), INT2FIX(0)); } - if (node->nd_pkwargs) { + if (RNODE_HSHPTN(node)->nd_pkwargs) { int i; int keys_num; const NODE *args; - args = node->nd_pkwargs->nd_head; + args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head; if (args) { DECL_ANCHOR(match_values); INIT_ANCHOR(match_values); - keys_num = rb_long2int(args->nd_alen) / 2; + keys_num = rb_long2int(RNODE_LIST(args)->as.nd_alen) / 2; for (i = 0; i < keys_num; i++) { - NODE *key_node = args->nd_head; - NODE *value_node = args->nd_next->nd_head; + NODE *key_node = RNODE_LIST(args)->nd_head; + NODE *value_node = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_head; VALUE key; if (!nd_type_p(key_node, NODE_LIT)) { UNKNOWN_NODE("NODE_IN", key_node, COMPILE_NG); } - key = key_node->nd_lit; + key = RNODE_LIT(key_node)->nd_lit; ADD_INSN(ret, line_node, dup); ADD_INSN1(ret, line_node, putobject, key); @@ -6750,9 +6762,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, node->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1)); // (8) + ADD_SEND(match_values, line_node, RNODE_HSHPTN(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 = args->nd_next->nd_next; + args = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_next; } ADD_SEQ(ret, match_values); } @@ -6766,8 +6778,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 (node->nd_pkwrestarg) { - if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) { + if (RNODE_HSHPTN(node)->nd_pkwrestarg) { + if (RNODE_HSHPTN(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) { @@ -6777,7 +6789,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, node->nd_pkwrestarg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (11) */, false)); + 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)); } } @@ -6834,7 +6846,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 = node->nd_vid; + ID id = RNODE_LASGN(node)->nd_vid; int idx = ISEQ_BODY(body->local_iseq)->local_table_size - get_local_var_idx(iseq, id); if (in_alt_pattern) { @@ -6852,7 +6864,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 = node->nd_vid; + ID id = RNODE_DASGN(node)->nd_vid; idx = get_dyna_var_idx(iseq, id, &lv, &ls); @@ -6878,8 +6890,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, node->nd_body, unmatched, in_single_pattern, in_alt_pattern, base_index, use_deconstructed_cache)); - CHECK(COMPILE(ret, "case in if", node->nd_cond)); + 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)); if (in_single_pattern) { LABEL *match_succeeded; match_succeeded = NEW_LABEL(line); @@ -6916,15 +6928,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 = node->nd_head; - if (! (nd_type_p(n, NODE_LIST) && n->nd_alen == 2)) { + n = RNODE_HASH(node)->nd_head; + if (! (nd_type_p(n, NODE_LIST) && RNODE_LIST(n)->as.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, 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)); + 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)); ADD_INSN(ret, line_node, putnil); ADD_LABEL(ret, match_failed); @@ -6938,13 +6950,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, node->nd_1st, match_succeeded, fin, in_single_pattern, true, base_index + 1 /* (1) */, use_deconstructed_cache)); + 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)); 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, node->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache)); + CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_OR(node)->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache)); break; } default: @@ -6967,9 +6979,9 @@ iseq_compile_pattern_constant(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD { const NODE *line_node = node; - if (node->nd_pconst) { + if (RNODE_ARYPTN(node)->nd_pconst) { ADD_INSN(ret, line_node, dup); // (1) - CHECK(COMPILE(ret, "constant", node->nd_pconst)); // (2) + CHECK(COMPILE(ret, "constant", RNODE_ARYPTN(node)->nd_pconst)); // (2) if (in_single_pattern) { ADD_INSN1(ret, line_node, dupn, INT2FIX(2)); } @@ -7172,12 +7184,12 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no branches = decl_branch_base(iseq, node, "case"); - node = node->nd_body; + node = RNODE_CASE3(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 = !node->nd_next; + single_pattern = !RNODE_IN(node)->nd_next; endlabel = NEW_LABEL(line); elselabel = NEW_LABEL(line); @@ -7191,7 +7203,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", orig_node->nd_head)); + CHECK(COMPILE(head, "case base", RNODE_CASE3(orig_node)->nd_head)); ADD_SEQ(ret, head); /* case VAL */ @@ -7207,14 +7219,14 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no add_trace_branch_coverage( iseq, body_seq, - node->nd_body ? node->nd_body : node, + RNODE_IN(node)->nd_body ? RNODE_IN(node)->nd_body : node, branch_id++, "in", branches); - CHECK(COMPILE_(body_seq, "in body", node->nd_body, popped)); + CHECK(COMPILE_(body_seq, "in body", RNODE_IN(node)->nd_body, popped)); ADD_INSNL(body_seq, line_node, jump, endlabel); - pattern = node->nd_head; + pattern = RNODE_IN(node)->nd_head; if (pattern) { int pat_line = nd_line(pattern); LABEL *next_pat = NEW_LABEL(pat_line); @@ -7229,7 +7241,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no return COMPILE_NG; } - node = node->nd_next; + node = RNODE_IN(node)->nd_next; if (!node) { break; } @@ -7354,7 +7366,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 (node->nd_state == 1) { + if (RNODE_WHILE(node)->nd_state == 1) { ADD_INSNL(ret, line_node, jump, next_label); } else { @@ -7373,27 +7385,27 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in add_trace_branch_coverage( iseq, ret, - node->nd_body ? node->nd_body : node, + RNODE_WHILE(node)->nd_body ? RNODE_WHILE(node)->nd_body : node, 0, "body", branches); - CHECK(COMPILE_POPPED(ret, "while body", node->nd_body)); + CHECK(COMPILE_POPPED(ret, "while body", RNODE_WHILE(node)->nd_body)); ADD_LABEL(ret, next_label); /* next */ if (type == NODE_WHILE) { - compile_branch_condition(iseq, ret, node->nd_cond, + compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond, redo_label, end_label); } else { /* until */ - compile_branch_condition(iseq, ret, node->nd_cond, + compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond, end_label, redo_label); } ADD_LABEL(ret, end_label); ADD_ADJUST_RESTORE(ret, adjust_label); - if (UNDEF_P(node->nd_state)) { + if (UNDEF_P(RNODE_WHILE(node)->nd_state)) { /* ADD_INSN(ret, line_node, putundef); */ COMPILE_ERROR(ERROR_ARGS "unsupported: putundef"); return COMPILE_NG; @@ -7435,18 +7447,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)", node->nd_iter)); + CHECK(COMPILE(ret, "iter caller (for)", RNODE_FOR(node)->nd_iter)); ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq = - NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), + NEW_CHILD_ISEQ(RNODE_FOR(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(node->nd_body, make_name_for_block(iseq), + NEW_CHILD_ISEQ(RNODE_ITER(node)->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); - CHECK(COMPILE(ret, "iter caller", node->nd_iter)); + CHECK(COMPILE(ret, "iter caller", RNODE_ITER(node)->nd_iter)); } { @@ -7490,7 +7502,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 = node->nd_var; + const NODE *var = RNODE_FOR_MASGN(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)); @@ -7525,7 +7537,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)", node->nd_stts, + CHECK(COMPILE_(ret, "break val (while/until)", RNODE_BREAK(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); @@ -7560,7 +7572,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)", node->nd_stts)); + CHECK(COMPILE(ret, "break val (block)", RNODE_BREAK(node)->nd_stts)); ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_BREAK)); if (popped) { ADD_INSN(ret, line_node, pop); @@ -7583,7 +7595,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?", node->nd_stts)); + CHECK(COMPILE(ret, "next val/valid syntax?", RNODE_NEXT(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); @@ -7597,7 +7609,7 @@ 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", node->nd_stts)); + CHECK(COMPILE(ret, "next val", RNODE_NEXT(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); @@ -7632,7 +7644,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", node->nd_stts)); + CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts)); ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_NEXT)); if (popped) { @@ -7744,7 +7756,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(node->nd_resq, + const rb_iseq_t *rescue = NEW_CHILD_ISEQ(RNODE_RESCUE(node)->nd_resq, rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label), ISEQ_TYPE_RESCUE, line); @@ -7756,14 +7768,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", node->nd_head)); + CHECK(COMPILE(ret, "rescue head", RNODE_RESCUE(node)->nd_head)); } ISEQ_COMPILE_DATA(iseq)->in_rescue = prev_in_rescue; ADD_LABEL(ret, lend); - if (node->nd_else) { + if (RNODE_RESCUE(node)->nd_else) { ADD_INSN(ret, line_node, pop); - CHECK(COMPILE(ret, "rescue else", node->nd_else)); + CHECK(COMPILE(ret, "rescue else", RNODE_RESCUE(node)->nd_else)); } ADD_INSN(ret, line_node, nop); ADD_LABEL(ret, lcont); @@ -7791,16 +7803,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 = resq->nd_args; + narg = RNODE_RESBODY(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", narg->nd_head)); + CHECK(COMPILE(ret, "rescue arg", RNODE_LIST(narg)->nd_head)); ADD_INSN1(ret, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE)); ADD_INSNL(ret, line_node, branchif, label_hit); - narg = narg->nd_next; + narg = RNODE_LIST(narg)->nd_next; } break; case NODE_SPLAT: @@ -7825,14 +7837,14 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, ADD_LABEL(ret, label_hit); ADD_TRACE(ret, RUBY_EVENT_RESCUE); - if (nd_type(resq->nd_body) == NODE_BEGIN && resq->nd_body->nd_body == NULL) { + 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(resq->nd_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", resq->nd_body)); + CHECK(COMPILE(ret, "resbody body", RNODE_RESBODY(resq)->nd_body)); } if (ISEQ_COMPILE_DATA(iseq)->option->tailcall_optimization) { @@ -7840,7 +7852,7 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, } ADD_INSN(ret, line_node, leave); ADD_LABEL(ret, label_miss); - resq = resq->nd_head; + resq = RNODE_RESBODY(resq)->nd_head; } return COMPILE_OK; } @@ -7851,7 +7863,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(node->nd_ensr, + const rb_iseq_t *ensure = NEW_CHILD_ISEQ(RNODE_ENSURE(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); @@ -7864,17 +7876,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", node->nd_ensr)); + CHECK(COMPILE_POPPED(ensr, "ensure ensr", RNODE_ENSURE(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, node->nd_ensr); + push_ensure_entry(iseq, &enl, &er, RNODE_ENSURE(node)->nd_ensr); ADD_LABEL(ret, lstart); - CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave))); + CHECK(COMPILE_(ret, "ensure head", RNODE_ENSURE(node)->nd_head, (popped | last_leave))); ADD_LABEL(ret, lend); ADD_SEQ(ret, ensr); if (!popped && last_leave) ADD_INSN(ret, line_node, putnil); @@ -7903,7 +7915,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 = node->nd_stts; + const NODE *retval = RNODE_RETURN(node)->nd_stts; LABEL *splabel = 0; while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) { @@ -8012,13 +8024,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE /* optimization shortcut * "literal".freeze -> opt_str_freeze("literal") */ - if (node->nd_recv && nd_type_p(node->nd_recv, NODE_STR) && - (node->nd_mid == idFreeze || node->nd_mid == idUMinus) && - node->nd_args == NULL && + if (RNODE_CALL(node)->nd_recv && nd_type_p(RNODE_CALL(node)->nd_recv, NODE_STR) && + (RNODE_CALL(node)->nd_mid == idFreeze || RNODE_CALL(node)->nd_mid == idUMinus) && + RNODE_CALL(node)->nd_args == NULL && ISEQ_COMPILE_DATA(iseq)->current_block == NULL && ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { - VALUE str = rb_fstring(node->nd_recv->nd_lit); - if (node->nd_mid == idUMinus) { + VALUE str = rb_fstring(RNODE_STR(RNODE_CALL(node)->nd_recv)->nd_lit); + if (RNODE_CALL(node)->nd_mid == idUMinus) { ADD_INSN2(ret, line_node, opt_str_uminus, str, new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE)); } @@ -8035,14 +8047,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 (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) && + if (RNODE_CALL(node)->nd_mid == idAREF && !private_recv_p(node) && RNODE_CALL(node)->nd_args && + nd_type_p(RNODE_CALL(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_CALL(node)->nd_args)->as.nd_alen == 1 && + nd_type_p(RNODE_LIST(RNODE_CALL(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(node->nd_args->nd_head->nd_lit); - CHECK(COMPILE(ret, "recv", node->nd_recv)); + VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_CALL(node)->nd_args)->nd_head)->nd_lit); + CHECK(COMPILE(ret, "recv", RNODE_CALL(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); @@ -8085,12 +8097,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 (recv->nd_mid == rb_intern("__builtin")) { + if (RNODE_VCALL(recv)->nd_mid == rb_intern("__builtin")) { return name; } break; case NODE_CONST: - if (recv->nd_vid == rb_intern("Primitive")) { + if (RNODE_CONST(recv)->nd_vid == rb_intern("Primitive")) { return name; } break; @@ -8180,13 +8192,13 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) if (!node) goto no_arg; while (node) { if (!nd_type_p(node, NODE_LIST)) goto bad_arg; - const NODE *next = node->nd_next; + const NODE *next = RNODE_LIST(node)->nd_next; - node = node->nd_head; + node = RNODE_LIST(node)->nd_head; if (!node) goto no_arg; if (!nd_type_p(node, NODE_LIT)) goto bad_arg; - symbol = node->nd_lit; + symbol = RNODE_LIT(node)->nd_lit; if (!SYMBOL_P(symbol)) goto non_symbol_arg; string = rb_sym_to_s(symbol); @@ -8220,11 +8232,11 @@ compile_builtin_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, c { if (!node) goto no_arg; if (!nd_type_p(node, NODE_LIST)) goto bad_arg; - if (node->nd_next) goto too_many_arg; - node = node->nd_head; + if (RNODE_LIST(node)->nd_next) goto too_many_arg; + node = RNODE_LIST(node)->nd_head; if (!node) goto no_arg; if (!nd_type_p(node, NODE_LIT)) goto bad_arg; - VALUE name = node->nd_lit; + VALUE name = RNODE_LIT(node)->nd_lit; if (!SYMBOL_P(name)) goto non_symbol_arg; if (!popped) { compile_lvar(iseq, ret, line_node, SYM2ID(name)); @@ -8248,8 +8260,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 && node->nd_cond == cond_node) { - return node->nd_body; + if (nd_type(node) == NODE_IF && RNODE_IF(node)->nd_cond == cond_node) { + return RNODE_IF(node)->nd_body; } else { rb_bug("mandatory_node: can't find mandatory node"); @@ -8263,8 +8275,11 @@ 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, }; - NODE args_node; - rb_node_init(&args_node, NODE_ARGS, 0, 0, (VALUE)&args); + rb_node_args_t args_node; + rb_node_init(RNODE(&args_node), NODE_ARGS); + args_node.not_used = 0; + args_node.not_used2 = 0; + args_node.nd_ainfo = &args; // local table without non-mandatory parameters const int skip_local_size = ISEQ_BODY(iseq)->param.size - ISEQ_BODY(iseq)->param.lead_num; @@ -8285,11 +8300,14 @@ 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]; } - NODE scope_node; - rb_node_init(&scope_node, NODE_SCOPE, (VALUE)tbl, (VALUE)mandatory_node(iseq, node), (VALUE)&args_node); + 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 = RNODE(&args_node); rb_ast_body_t ast = { - .root = &scope_node, + .root = RNODE(&scope_node), .frozen_string_literal = -1, .coverage_enabled = -1, .script_lines = ISEQ_BODY(iseq)->variable.script_lines, @@ -8309,7 +8327,7 @@ 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 = node->nd_args; + NODE *args_node = RNODE_QCALL(node)->nd_args; if (parent_block != NULL) { COMPILE_ERROR(ERROR_ARGS_AT(line_node) "should not call builtins here."); @@ -8412,7 +8430,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co */ DECL_ANCHOR(recv); DECL_ANCHOR(args); - ID mid = node->nd_mid; + ID mid = RNODE_CALL(node)->nd_mid; VALUE argc; unsigned int flag = 0; struct rb_callinfo_kwarg *keywords = NULL; @@ -8491,7 +8509,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, node->nd_recv, mid)) != NULL) { + (builtin_func = iseq_builtin_function_name(type, RNODE_CALL(node)->nd_recv, mid)) != NULL) { return compile_builtin_function_call(iseq, ret, node, line_node, popped, parent_block, args, builtin_func); } @@ -8501,16 +8519,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(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)); + nd_type_p(RNODE_CALL(node)->nd_recv, NODE_LVAR) && + iseq_block_param_id_p(iseq, RNODE_LVAR(RNODE_CALL(node)->nd_recv)->nd_vid, &idx, &level)) { + ADD_INSN2(recv, RNODE_CALL(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", node->nd_recv)); + CHECK(COMPILE(recv, "recv", RNODE_CALL(node)->nd_recv)); } if (type == NODE_QCALL) { @@ -8524,7 +8542,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, node->nd_args, &flag, &keywords); + argc = setup_args(iseq, args, RNODE_CALL(node)->nd_args, &flag, &keywords); CHECK(!NIL_P(argc)); } else { @@ -8561,7 +8579,7 @@ 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 = node->nd_mid; + ID id = RNODE_OP_ASGN1(node)->nd_mid; int boff = 0; /* @@ -8590,9 +8608,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); + asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node, RNODE_OP_ASGN1(node)->nd_recv); CHECK(asgnflag != -1); - switch (nd_type(node->nd_args->nd_head)) { + switch (nd_type(RNODE_OP_ASGN1(node)->nd_args->nd_head)) { case NODE_ZLIST: argc = INT2FIX(0); break; @@ -8600,7 +8618,7 @@ 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, node->nd_args->nd_head, &flag, NULL); + argc = setup_args(iseq, ret, RNODE_OP_ASGN1(node)->nd_args->nd_head, &flag, NULL); CHECK(!NIL_P(argc)); } ADD_INSN1(ret, node, dupn, FIXNUM_INC(argc, 1 + boff)); @@ -8628,7 +8646,7 @@ 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 args->body: ", node->nd_args->nd_body)); + CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", RNODE_OP_ASGN1(node)->nd_args->nd_body)); if (!popped) { ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff)); } @@ -8662,7 +8680,7 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node ADD_LABEL(ret, lfin); } else { - CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body)); + CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", RNODE_OP_ASGN1(node)->nd_args->nd_body)); ADD_SEND(ret, node, id, INT2FIX(1)); if (!popped) { ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff)); @@ -8696,8 +8714,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 = node->nd_next->nd_mid; - ID vid = node->nd_next->nd_vid, aid = rb_id_attrset(vid); + ID atype = RNODE_OP_ASGN2(node)->nd_mid; + ID vid = RNODE_OP_ASGN2(node)->nd_vid, aid = rb_id_attrset(vid); int asgnflag; LABEL *lfin = NEW_LABEL(line); LABEL *lcfin = NEW_LABEL(line); @@ -8755,9 +8773,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); + asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node, RNODE_OP_ASGN2(node)->nd_recv); CHECK(asgnflag != -1); - if (node->nd_next->nd_aid) { + if (RNODE_OP_ASGN2(node)->nd_aid) { lskip = NEW_LABEL(line); ADD_INSN(ret, node, dup); ADD_INSNL(ret, node, branchnil, lskip); @@ -8778,7 +8796,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", node->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, swap); ADD_INSN1(ret, node, topn, INT2FIX(1)); @@ -8794,7 +8812,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", node->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value)); ADD_SEND(ret, node, atype, INT2FIX(1)); if (!popped) { ADD_INSN(ret, node, swap); @@ -8820,21 +8838,21 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node LABEL *lassign = 0; ID mid; - switch (nd_type(node->nd_head)) { + switch (nd_type(RNODE_OP_CDECL(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", node->nd_head->nd_head)); + CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", RNODE_COLON2(RNODE_OP_CDECL(node)->nd_head)->nd_head)); break; default: COMPILE_ERROR(ERROR_ARGS "%s: invalid node in NODE_OP_CDECL", - ruby_node_name(nd_type(node->nd_head))); + ruby_node_name(nd_type(RNODE_OP_CDECL(node)->nd_head))); return COMPILE_NG; } - mid = node->nd_head->nd_mid; + mid = RNODE_COLON2(RNODE_OP_CDECL(node)->nd_head)->nd_mid; /* cref */ - if (node->nd_aid == idOROP) { + if (RNODE_OP_CDECL(node)->nd_aid == idOROP) { lassign = NEW_LABEL(line); ADD_INSN(ret, node, dup); /* cref cref */ ADD_INSN3(ret, node, defined, INT2FIX(DEFINED_CONST_FROM), @@ -8845,17 +8863,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 (node->nd_aid == idOROP || node->nd_aid == idANDOP) { + if (RNODE_OP_CDECL(node)->nd_aid == idOROP || RNODE_OP_CDECL(node)->nd_aid == idANDOP) { lfin = NEW_LABEL(line); if (!popped) ADD_INSN(ret, node, dup); /* cref [obj] obj */ - if (node->nd_aid == idOROP) + if (RNODE_OP_CDECL(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", node->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", RNODE_OP_CDECL(node)->nd_value)); /* cref value */ if (popped) ADD_INSN1(ret, node, topn, INT2FIX(1)); /* cref value cref */ @@ -8869,9 +8887,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", node->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", RNODE_OP_CDECL(node)->nd_value)); /* cref obj value */ - ADD_CALL(ret, node, node->nd_aid, INT2FIX(1)); + ADD_CALL(ret, node, RNODE_OP_CDECL(node)->nd_aid, INT2FIX(1)); /* cref value */ ADD_INSN(ret, node, swap); /* value cref */ if (!popped) { @@ -8890,11 +8908,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(node->nd_head, NODE_IVAR)) { + if (type == NODE_OP_ASGN_OR && !nd_type_p(RNODE_OP_ASGN_OR(node)->nd_head, NODE_IVAR)) { LABEL *lfinish[2]; lfinish[0] = lfin; lfinish[1] = 0; - defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse); + defined_expr(iseq, ret, RNODE_OP_ASGN_OR(node)->nd_head, lfinish, Qfalse); lassign = lfinish[1]; if (!lassign) { lassign = NEW_LABEL(line); @@ -8905,7 +8923,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", node->nd_head)); + CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", RNODE_OP_ASGN_OR(node)->nd_head)); if (!popped) { ADD_INSN(ret, node, dup); @@ -8923,7 +8941,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", node->nd_value, popped)); + CHECK(COMPILE_(ret, "NODE_OP_ASGN_AND/OR#nd_value", RNODE_OP_ASGN_OR(node)->nd_value, popped)); ADD_LABEL(ret, lfin); return COMPILE_OK; } @@ -8941,7 +8959,7 @@ 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, node->nd_args, &flag, &keywords); + VALUE vargc = setup_args(iseq, args, RNODE_SUPER(node)->nd_args, &flag, &keywords); CHECK(!NIL_P(vargc)); argc = FIX2INT(vargc); } @@ -9073,8 +9091,8 @@ compile_yield(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i default: /* valid */; } - if (node->nd_head) { - argc = setup_args(iseq, args, node->nd_head, &flag, &keywords); + if (RNODE_YIELD(node)->nd_head) { + argc = setup_args(iseq, args, RNODE_YIELD(node)->nd_head, &flag, &keywords); CHECK(!NIL_P(argc)); } else { @@ -9108,17 +9126,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, node->nd_lit); + ADD_INSN1(recv, node, putobject, RNODE_MATCH(node)->nd_lit); ADD_INSN2(val, node, getspecial, INT2FIX(0), INT2FIX(0)); break; case NODE_MATCH2: - CHECK(COMPILE(recv, "receiver", node->nd_recv)); - CHECK(COMPILE(val, "value", node->nd_value)); + CHECK(COMPILE(recv, "receiver", RNODE_MATCH2(node)->nd_recv)); + CHECK(COMPILE(val, "value", RNODE_MATCH2(node)->nd_value)); break; case NODE_MATCH3: - CHECK(COMPILE(recv, "receiver", node->nd_value)); - CHECK(COMPILE(val, "value", node->nd_recv)); + CHECK(COMPILE(recv, "receiver", RNODE_MATCH3(node)->nd_value)); + CHECK(COMPILE(val, "value", RNODE_MATCH3(node)->nd_recv)); break; } @@ -9126,8 +9144,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 (node->nd_args) { - compile_named_capture_assign(iseq, ret, node->nd_args); + if (RNODE_MATCH2(node)->nd_args) { + compile_named_capture_assign(iseq, ret, RNODE_MATCH2(node)->nd_args); } if (popped) { @@ -9139,7 +9157,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(node->nd_mid)) { + if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) { /* constant */ VALUE segments; if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache && @@ -9169,8 +9187,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", node->nd_head)); - ADD_CALL(ret, node, node->nd_mid, INT2FIX(1)); + CHECK(COMPILE(ret, "colon2#nd_head", RNODE_COLON2(node)->nd_head)); + ADD_CALL(ret, node, RNODE_COLON2(node)->nd_mid, INT2FIX(1)); } if (popped) { ADD_INSN(ret, node, pop); @@ -9181,19 +9199,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", node->nd_mid); + debugi("colon3#nd_mid", RNODE_COLON3(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(node->nd_mid)); + VALUE segments = rb_ary_new_from_args(2, ID2SYM(idNULL), ID2SYM(RNODE_COLON3(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(node->nd_mid)); + ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid)); } if (popped) { @@ -9206,13 +9224,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 = node->nd_beg; - const NODE *e = node->nd_end; + const NODE *b = RNODE_DOT2(node)->nd_beg; + const NODE *e = RNODE_DOT2(node)->nd_end; if (optimizable_range_item_p(b) && optimizable_range_item_p(e)) { if (!popped) { - 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 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 val = rb_range_new(bv, ev, excl); ADD_INSN1(ret, node, putobject, val); RB_OBJ_WRITTEN(iseq, Qundef, val); @@ -9261,7 +9279,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 = node->nd_body->nd_value; + const NODE *default_value = RNODE_DASGN(RNODE_KW_ARG(node)->nd_body)->nd_value; if (default_value == NODE_SPECIAL_REQUIRED_KEYWORD) { /* required argument. do nothing */ @@ -9285,7 +9303,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", node->nd_body)); + CHECK(COMPILE_POPPED(ret, "keyword default argument", RNODE_KW_ARG(node)->nd_body)); ADD_LABEL(ret, end_label); } return COMPILE_OK; @@ -9297,7 +9315,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 = node->nd_mid; + ID mid = RNODE_ATTRASGN(node)->nd_mid; VALUE argc; LABEL *else_label = NULL; VALUE branches = Qfalse; @@ -9305,16 +9323,16 @@ 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) && 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) && + 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) && 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(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)); + 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)); if (!popped) { ADD_INSN(ret, node, swap); ADD_INSN1(ret, node, topn, INT2FIX(1)); @@ -9328,10 +9346,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, node->nd_args, &flag, NULL); + argc = setup_args(iseq, args, RNODE_ATTRASGN(node)->nd_args, &flag, NULL); CHECK(!NIL_P(argc)); - int asgnflag = COMPILE_RECV(recv, "recv", node); + int asgnflag = COMPILE_RECV(recv, "recv", node, RNODE_ATTRASGN(node)->nd_recv); CHECK(asgnflag != -1); flag |= (unsigned int)asgnflag; @@ -9468,7 +9486,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", node->nd_body, popped)); + CHECK(COMPILE_(ret, "NODE_BEGIN", RNODE_BEGIN(node)->nd_body, popped)); break; } case NODE_RESCUE: @@ -9484,7 +9502,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", node->nd_1st)); + CHECK(COMPILE(ret, "nd_1st", RNODE_OR(node)->nd_1st)); if (!popped) { ADD_INSN(ret, node, dup); } @@ -9497,7 +9515,7 @@ 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", node->nd_2nd, popped)); + CHECK(COMPILE_(ret, "nd_2nd", RNODE_OR(node)->nd_2nd, popped)); ADD_LABEL(ret, end_label); break; } @@ -9508,11 +9526,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_LASGN:{ - ID id = node->nd_vid; + ID id = RNODE_LASGN(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", node->nd_value)); + CHECK(COMPILE(ret, "rvalue", RNODE_LASGN(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); @@ -9522,8 +9540,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 = node->nd_vid; - CHECK(COMPILE(ret, "dvalue", node->nd_value)); + ID id = RNODE_DASGN(node)->nd_vid; + CHECK(COMPILE(ret, "dvalue", RNODE_DASGN(node)->nd_value)); debugi("dassn id", rb_id2str(id) ? id : '*'); if (!popped) { @@ -9541,27 +9559,27 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_GASGN:{ - CHECK(COMPILE(ret, "lvalue", node->nd_value)); + CHECK(COMPILE(ret, "lvalue", RNODE_GASGN(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } - ADD_INSN1(ret, node, setglobal, ID2SYM(node->nd_vid)); + ADD_INSN1(ret, node, setglobal, ID2SYM(RNODE_GASGN(node)->nd_vid)); break; } case NODE_IASGN:{ - CHECK(COMPILE(ret, "lvalue", node->nd_value)); + CHECK(COMPILE(ret, "lvalue", RNODE_IASGN(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } ADD_INSN2(ret, node, setinstancevariable, - ID2SYM(node->nd_vid), - get_ivar_ic_value(iseq,node->nd_vid)); + ID2SYM(RNODE_IASGN(node)->nd_vid), + get_ivar_ic_value(iseq,RNODE_IASGN(node)->nd_vid)); break; } case NODE_CDECL:{ - if (node->nd_vid) { - CHECK(COMPILE(ret, "lvalue", node->nd_value)); + if (RNODE_CDECL(node)->nd_vid) { + CHECK(COMPILE(ret, "lvalue", RNODE_CDECL(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); @@ -9569,11 +9587,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(node->nd_vid)); + ADD_INSN1(ret, node, setconstant, ID2SYM(RNODE_CDECL(node)->nd_vid)); } else { - compile_cpath(ret, iseq, node->nd_else); - CHECK(COMPILE(ret, "lvalue", node->nd_value)); + compile_cpath(ret, iseq, RNODE_CDECL(node)->nd_else); + CHECK(COMPILE(ret, "lvalue", RNODE_CDECL(node)->nd_value)); ADD_INSN(ret, node, swap); if (!popped) { @@ -9581,18 +9599,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(node->nd_else->nd_mid)); + ADD_INSN1(ret, node, setconstant, ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid)); } break; } case NODE_CVASGN:{ - CHECK(COMPILE(ret, "cvasgn val", node->nd_value)); + CHECK(COMPILE(ret, "cvasgn val", RNODE_CVASGN(node)->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } ADD_INSN2(ret, node, setclassvariable, - ID2SYM(node->nd_vid), - get_cvar_ic_value(iseq,node->nd_vid)); + ID2SYM(RNODE_CVASGN(node)->nd_vid), + get_cvar_ic_value(iseq, RNODE_CVASGN(node)->nd_vid)); break; } case NODE_OP_ASGN1: @@ -9640,10 +9658,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no COMPILE_ERROR(ERROR_ARGS "NODE_VALUES: must not be popped"); } while (n) { - CHECK(COMPILE(ret, "values item", n->nd_head)); - n = n->nd_next; + CHECK(COMPILE(ret, "values item", RNODE_VALUES(n)->nd_head)); + n = RNODE_VALUES(n)->nd_next; } - ADD_INSN1(ret, node, newarray, INT2FIX(node->nd_alen)); + ADD_INSN1(ret, node, newarray, INT2FIX(RNODE_VALUES(node)->nd_alen)); break; } case NODE_HASH: @@ -9657,18 +9675,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, node->nd_vid); + compile_lvar(iseq, ret, node, RNODE_LVAR(node)->nd_vid); } break; } case NODE_DVAR:{ int lv, idx, ls; - debugi("nd_vid", node->nd_vid); + debugi("nd_vid", RNODE_DVAR(node)->nd_vid); if (!popped) { - idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls); + idx = get_dyna_var_idx(iseq, RNODE_DVAR(node)->nd_vid, &lv, &ls); if (idx < 0) { COMPILE_ERROR(ERROR_ARGS "unknown dvar (%"PRIsVALUE")", - rb_id2str(node->nd_vid)); + rb_id2str(RNODE_DVAR(node)->nd_vid)); goto ng; } ADD_GETLOCAL(ret, node, ls - idx, lv); @@ -9676,34 +9694,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(node->nd_vid)); + ADD_INSN1(ret, node, getglobal, ID2SYM(RNODE_GVAR(node)->nd_vid)); if (popped) { ADD_INSN(ret, node, pop); } break; } case NODE_IVAR:{ - debugi("nd_vid", node->nd_vid); + debugi("nd_vid", RNODE_IVAR(node)->nd_vid); if (!popped) { ADD_INSN2(ret, node, getinstancevariable, - ID2SYM(node->nd_vid), - get_ivar_ic_value(iseq,node->nd_vid)); + ID2SYM(RNODE_IVAR(node)->nd_vid), + get_ivar_ic_value(iseq, RNODE_IVAR(node)->nd_vid)); } break; } case NODE_CONST:{ - debugi("nd_vid", node->nd_vid); + debugi("nd_vid", RNODE_CONST(node)->nd_vid); if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) { body->ic_size++; - VALUE segments = rb_ary_new_from_args(1, ID2SYM(node->nd_vid)); + VALUE segments = rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(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(node->nd_vid)); + ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid)); } if (popped) { @@ -9714,26 +9732,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(node->nd_vid), - get_cvar_ic_value(iseq,node->nd_vid)); + ID2SYM(RNODE_CVAR(node)->nd_vid), + get_cvar_ic_value(iseq, RNODE_CVAR(node)->nd_vid)); } break; } case NODE_NTH_REF:{ if (!popped) { - if (!node->nd_nth) { + if (!RNODE_NTH_REF(node)->nd_nth) { ADD_INSN(ret, node, putnil); break; } ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */, - INT2FIX(node->nd_nth << 1)); + INT2FIX(RNODE_NTH_REF(node)->nd_nth << 1)); } break; } case NODE_BACK_REF:{ if (!popped) { ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */, - INT2FIX(0x01 | (node->nd_nth << 1))); + INT2FIX(0x01 | (RNODE_BACK_REF(node)->nd_nth << 1))); } break; } @@ -9743,17 +9761,17 @@ 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", node->nd_lit); + debugp_param("lit", RNODE_LIT(node)->nd_lit); if (!popped) { - ADD_INSN1(ret, node, putobject, node->nd_lit); - RB_OBJ_WRITTEN(iseq, Qundef, node->nd_lit); + ADD_INSN1(ret, node, putobject, RNODE_LIT(node)->nd_lit); + RB_OBJ_WRITTEN(iseq, Qundef, RNODE_LIT(node)->nd_lit); } break; } case NODE_STR:{ - debugp_param("nd_lit", node->nd_lit); + debugp_param("nd_lit", RNODE_STR(node)->nd_lit); if (!popped) { - VALUE lit = node->nd_lit; + VALUE lit = RNODE_STR(node)->nd_lit; if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) { lit = rb_fstring(lit); ADD_INSN1(ret, node, putstring, lit); @@ -9785,7 +9803,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(node->nd_lit); + VALUE str = rb_fstring(RNODE_XSTR(node)->nd_lit); ADD_INSN1(ret, node, putobject, str); RB_OBJ_WRITTEN(iseq, Qundef, str); ADD_CALL(ret, node, idBackquote, INT2FIX(1)); @@ -9806,7 +9824,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_EVSTR: - CHECK(compile_evstr(iseq, ret, node->nd_body, popped)); + CHECK(compile_evstr(iseq, ret, RNODE_EVSTR(node)->nd_body, popped)); break; case NODE_DREGX:{ compile_dregx(iseq, ret, node); @@ -9819,7 +9837,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_ONCE:{ int ic_index = body->ise_size++; const rb_iseq_t *block_iseq; - block_iseq = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line); + block_iseq = NEW_CHILD_ISEQ(RNODE_ONCE(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); @@ -9831,36 +9849,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", node->nd_head)); + CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); - CHECK(COMPILE(ret, "argscat body", node->nd_body)); + CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); } else { - CHECK(COMPILE(ret, "argscat head", node->nd_head)); - CHECK(COMPILE(ret, "argscat body", node->nd_body)); + CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head)); + CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body)); ADD_INSN(ret, node, concatarray); } break; } case NODE_ARGSPUSH:{ if (popped) { - CHECK(COMPILE(ret, "argspush head", node->nd_head)); + CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); - CHECK(COMPILE_(ret, "argspush body", node->nd_body, popped)); + CHECK(COMPILE_(ret, "argspush body", RNODE_ARGSPUSH(node)->nd_body, popped)); } else { - CHECK(COMPILE(ret, "argspush head", node->nd_head)); - CHECK(compile_array_1(iseq, ret, node->nd_body)); + CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head)); + CHECK(compile_array_1(iseq, ret, RNODE_ARGSPUSH(node)->nd_body)); ADD_INSN(ret, node, concatarray); } break; } case NODE_SPLAT:{ - CHECK(COMPILE(ret, "splat", node->nd_head)); + CHECK(COMPILE(ret, "splat", RNODE_SPLAT(node)->nd_head)); ADD_INSN1(ret, node, splatarray, Qtrue); if (popped) { @@ -9869,8 +9887,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_DEFN:{ - ID mid = node->nd_mid; - const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn, + ID mid = RNODE_DEFN(node)->nd_mid; + const rb_iseq_t *method_iseq = NEW_ISEQ(RNODE_DEFN(node)->nd_defn, rb_id2str(mid), ISEQ_TYPE_METHOD, line); @@ -9885,13 +9903,13 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_DEFS:{ - ID mid = node->nd_mid; - const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(node->nd_defn, + ID mid = RNODE_DEFS(node)->nd_mid; + const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(RNODE_DEFS(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", node->nd_recv)); + CHECK(COMPILE(ret, "defs: recv", RNODE_DEFS(node)->nd_recv)); ADD_INSN2(ret, node, definesmethod, ID2SYM(mid), singleton_method_iseq); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_method_iseq); @@ -9903,8 +9921,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", node->nd_1st)); - CHECK(COMPILE(ret, "alias arg2", node->nd_2nd)); + CHECK(COMPILE(ret, "alias arg1", RNODE_ALIAS(node)->nd_1st)); + CHECK(COMPILE(ret, "alias arg2", RNODE_ALIAS(node)->nd_2nd)); ADD_SEND(ret, node, id_core_set_method_alias, INT2FIX(3)); if (popped) { @@ -9914,8 +9932,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(node->nd_alias)); - ADD_INSN1(ret, node, putobject, ID2SYM(node->nd_orig)); + ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_alias)); + ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_orig)); ADD_SEND(ret, node, id_core_set_variable_alias, INT2FIX(2)); if (popped) { @@ -9926,7 +9944,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", node->nd_undef)); + CHECK(COMPILE(ret, "undef arg", RNODE_UNDEF(node)->nd_undef)); ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2)); if (popped) { @@ -9935,15 +9953,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(node->nd_body, - rb_str_freeze(rb_sprintf("", rb_id2str(node->nd_cpath->nd_mid))), + const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(RNODE_CLASS(node)->nd_body, + rb_str_freeze(rb_sprintf("", rb_id2str(RNODE_COLON2(RNODE_CLASS(node)->nd_cpath)->nd_mid))), ISEQ_TYPE_CLASS, line); const int flags = VM_DEFINECLASS_TYPE_CLASS | - (node->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) | - compile_cpath(ret, iseq, node->nd_cpath); + (RNODE_CLASS(node)->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) | + compile_cpath(ret, iseq, RNODE_CLASS(node)->nd_cpath); - CHECK(COMPILE(ret, "super", node->nd_super)); - ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags)); + CHECK(COMPILE(ret, "super", RNODE_CLASS(node)->nd_super)); + ADD_INSN3(ret, node, defineclass, ID2SYM(RNODE_COLON2(RNODE_CLASS(node)->nd_cpath)->nd_mid), class_iseq, INT2FIX(flags)); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq); if (popped) { @@ -9952,14 +9970,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(node->nd_body, - rb_str_freeze(rb_sprintf("", rb_id2str(node->nd_cpath->nd_mid))), + const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(RNODE_MODULE(node)->nd_body, + rb_str_freeze(rb_sprintf("", rb_id2str(RNODE_COLON2(RNODE_MODULE(node)->nd_cpath)->nd_mid))), ISEQ_TYPE_CLASS, line); const int flags = VM_DEFINECLASS_TYPE_MODULE | - compile_cpath(ret, iseq, node->nd_cpath); + compile_cpath(ret, iseq, RNODE_MODULE(node)->nd_cpath); ADD_INSN (ret, node, putnil); /* dummy */ - ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags)); + ADD_INSN3(ret, node, defineclass, ID2SYM(RNODE_COLON2(RNODE_MODULE(node)->nd_cpath)->nd_mid), module_iseq, INT2FIX(flags)); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq); if (popped) { @@ -9969,10 +9987,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(node->nd_body, rb_fstring_lit("singleton class"), + const rb_iseq_t *singleton_class = NEW_ISEQ(RNODE_SCLASS(node)->nd_body, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, line); - CHECK(COMPILE(ret, "sclass#recv", node->nd_recv)); + CHECK(COMPILE(ret, "sclass#recv", RNODE_SCLASS(node)->nd_recv)); ADD_INSN (ret, node, putnil); CONST_ID(singletonclass, "singletonclass"); ADD_INSN3(ret, node, defineclass, @@ -10050,7 +10068,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, node->nd_body); + rb_iseq_new_with_callback_new_callback(build_postexe_iseq, RNODE_POSTEXE(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); @@ -10081,7 +10099,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(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); + const rb_iseq_t *block = NEW_CHILD_ISEQ(RNODE_LAMBDA(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)); @@ -12293,7 +12311,13 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->icvarc_size = icvarc_size; load_body->ise_size = ise_size; load_body->ic_size = ic_size; - load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body)); + + 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; + } 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); @@ -13354,4 +13378,4 @@ rb_iseq_ibf_load_extra_data(VALUE str) return extra_str; } -#include "yarp/yarp_compiler.c" +#include "prism_compile.c" diff --git a/configure.ac b/configure.ac index 122e0617929999..fc468389daeffc 100644 --- a/configure.ac +++ b/configure.ac @@ -967,9 +967,10 @@ AS_IF([test "x$OPT_DIR" != x], [ LDFLAGS="${LDFLAGS:+$LDFLAGS }$val" DLDFLAGS="${DLDFLAGS:+$DLDFLAGS }$val" LDFLAGS_OPTDIR="$val" - CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }"`echo "$OPT_DIR" | tr "${PATH_SEPARATOR}" '\012' | + INCFLAGS="${INCFLAGS:+$INCFLAGS }"`echo "$OPT_DIR" | tr "${PATH_SEPARATOR}" '\012' | sed '/^$/d;s|^|-I|;s|$|/include|' | tr '\012' ' ' | sed 's/ *$//'` ]) +AC_SUBST(incflags, "$INCFLAGS") test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $ARCH_FLAG\"" test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\"" @@ -2078,6 +2079,7 @@ 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) diff --git a/defs/gmake.mk b/defs/gmake.mk index 155122376ad025..8bb42588e43650 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -193,15 +193,22 @@ $(SCRIPTBINDIR): $(Q) mkdir $@ .PHONY: commit -commit: $(if $(filter commit,$(MAKECMDGOALS)),$(filter-out commit,$(MAKECMDGOALS))) up +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) @$(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) srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \ - BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" \ + $(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)" \ VCSUP="" ENC_MK=.top-enc.mk REVISION_FORCE=PHONY CONFIGURE="$(CONFIGURE)" -f - \ update-src srcs all-incs @@ -407,6 +414,17 @@ endif .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 @@ -511,8 +529,12 @@ matz: up 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),) -ripper_srcs: $(addprefix $(DOT_WAIT) ,$(RIPPER_SRCS)) +.NOTPARALLEL: ripper_srcs else ripper_src = $(foreach r,$(RIPPER_SRCS),$(eval $(value r): | $(value ripper_src))\ diff --git a/dir.c b/dir.c index 4dbdc44e8a6e34..9c9f594a78d395 100644 --- a/dir.c +++ b/dir.c @@ -3357,7 +3357,7 @@ dir_s_each_child(int argc, VALUE *argv, VALUE io) * "main.rb" * * If no block is given, returns an enumerator. - */ + */ static VALUE dir_each_child_m(VALUE dir) { diff --git a/doc/contributing/documentation_guide.md b/doc/contributing/documentation_guide.md index 6cb2b8d7dc434b..25a5fa167398bd 100644 --- a/doc/contributing/documentation_guide.md +++ b/doc/contributing/documentation_guide.md @@ -216,16 +216,21 @@ may not render them properly. In particular, avoid building tables with HTML tags (, etc.). -Alternatives are: - -- The GFM (GitHub Flavored Markdown) table extension, - which is enabled by default. See - {GFM tables extension}[https://github.github.com/gfm/#tables-extension-]. +Alternatives: - 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. + using spaces and punctuation to format the text; + note that {text markup}[rdoc-ref:RDoc::MarkupReference@Text+Markup] + will not be honored: + + - 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]. ## Documenting Classes and Modules diff --git a/doc/encodings.rdoc b/doc/encodings.rdoc index f5e718b3cda57e..914f5d3afa4b6b 100644 --- a/doc/encodings.rdoc +++ b/doc/encodings.rdoc @@ -138,7 +138,7 @@ 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]. +see {Script Encoding}[rdoc-ref:encodings.rdoc@Script+Encoding]. 's'.encoding # => # diff --git a/doc/globals.rdoc b/doc/globals.rdoc index 1d7cda69f952a6..2b4f6bd7cf52cd 100644 --- a/doc/globals.rdoc +++ b/doc/globals.rdoc @@ -1,69 +1,422 @@ -# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*- - -== Pre-defined global variables - -$!:: The Exception object set by Kernel#raise. -$@:: The same as $!.backtrace. -$~:: 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 $LOAD_PATH.resolve_feature_path(feature) - 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 -d 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 -d 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 -w or -v switch. - Setting this to a true value enables warnings as if -w or -v 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 -a is set. Read-only variable. -$-i:: In in-place-edit mode, this variable holds the extension, otherwise +nil+. -$-l:: True if option -l is set. Read-only variable. -$-p:: True if option -p 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 __END__. -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 ruby --version, a String describing various aspects of the Ruby implementation. +== 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 + +==== $! (\Exception) + +Contains the Exception object set by Kernel#raise: + + begin + raise RuntimeError.new('Boo!') + rescue RuntimeError + p $! + end + +Output: + + # + +English - $ERROR_INFO + +==== $@ (Backtrace) + +Same as $!.backtrace; +returns an array of backtrace positions: + + begin + raise RuntimeError.new('Boo!') + rescue RuntimeError + pp $@.take(4) + end + +Output: + + ["(irb):338:in `'", + "/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 - $ERROR_POSITION. + +=== 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]. + +==== $~ (\MatchData) + +MatchData object created from the match; +thread-local and frame-local. + +English - $LAST_MATCH_INFO. + +==== $& (Matched Substring) + +The matched string. + +English - $MATCH. + +==== $` (Pre-Match Substring) + +The string to the left of the match. + +English - $PREMATCH. + +==== $' (Post-Match Substring) + +The string to the right of the match. + +English - $POSTMATCH. + +==== $+ (Last Matched Group) + +The last group matched. + +English - $LAST_PAREN_MATCH. + +==== $1, $2, \Etc. (Matched Group) + +For $_n_ the _nth_ group of the match. + +No \English. + +=== Separators + +==== $/ (Input Record Separator) + +An input record separator, initially newline. + +English - $INPUT_RECORD_SEPARATOR, $RS. + +Aliased as $-0. + +==== $; (Input Field Separator) + +An input field separator, initially +nil+. + +English - $FIELD_SEPARATOR, $FS. + +Aliased as $-F. + +==== $\\ (Output Record Separator) + +An output record separator, initially +nil+. + +English - $OUTPUT_RECORD_SEPARATOR, $ORS. + +=== Streams + +==== $stdin (Standard Input) + +The current standard input stream; initially: + + $stdin # => #> + +==== $stdout (Standard Output) + +The current standard output stream; initially: + + $stdout # => #> + +==== $stderr (Standard Error) + +The current standard error stream; initially: + + $stderr # => #> + +==== $< (\ARGF or $stdin) + +Points to stream ARGF if not empty, else to stream $stdin; read-only. + +English - $DEFAULT_INPUT. + +==== $> (Default Standard Output) + +An output stream, initially $stdout. + +English - $DEFAULT_OUTPUT + +==== $. (Input Position) + +The input position (line number) in the most recently read stream. + +English - $INPUT_LINE_NUMBER, $NR + +==== $_ (Last Read Line) + +The line (string) from the most recently read stream. + +English - $LAST_READ_LINE. + +=== Processes + +==== $0 + +Initially, contains the name of the script being executed; +may be reassigned. + +==== $* (\ARGV) + +Points to ARGV. + +English - $ARGV. + +==== $$ (Process ID) + +The process ID of the current process. Same as Process.pid. + +English - $PROCESS_ID, $PID. + +==== $? (Child Status) + +Initially +nil+, otherwise the Process::Status object +created for the most-recently exited child process; +thread-local. + +English - $CHILD_STATUS. + +==== $LOAD_PATH (Load Path) + +Contains the array of paths to be searched +by Kernel#load and Kernel#require. + +Singleton method $LOAD_PATH.resolve_feature_path(feature) +returns: + +- [:rb, _path_], where +path+ is the path to the Ruby file + to be loaded for the given +feature+. +- [:so+ _path_], 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 $: and $-I. + +==== $LOADED_FEATURES + +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 $". + +=== Debugging + +==== $FILENAME + +The value returned by method ARGF.filename. + +==== $DEBUG + +Initially +true+ if command-line option -d or --debug is given, +otherwise initially +false+; +may be set to either value in the running program. + +When +true+, prints each raised exception to $stderr. + +Aliased as $-d. + +==== $VERBOSE + +Initially +true+ if command-line option -v or -w 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 $-v and $-w. + +=== Other Variables + +==== $-a + +Whether command-line option -a was given; read-only. + +==== $-i + +Contains the extension given with command-line option -i, +or +nil+ if none. + +An alias of ARGF.inplace_mode. + +==== $-l + +Whether command-line option -l was set; read-only. + +==== $-p + +Whether command-line option -p was given; read-only. + +=== Deprecated + +==== $= + +==== $, + +== Pre-Defined Global Constants + +== Streams + +==== STDIN + +The standard input stream (the default value for $stdin): + + STDIN # => #> + +==== STDOUT + +The standard output stream (the default value for $stdout): + + STDOUT # => #> + +==== STDERR + +The standard error stream (the default value for $stderr): + + STDERR # => #> + +=== Enviroment + +==== 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 +$stdin if no files were given, "-" is given, or after +all files have been read. + +==== ARGV + +An array of the given command-line arguments. + +==== TOPLEVEL_BINDING + +The Binding of the top level scope: + + TOPLEVEL_BINDING # => # + +==== RUBY_VERSION + +The Ruby version: + + RUBY_VERSION # => "3.2.2" + +==== RUBY_RELEASE_DATE + +The release date string: + + RUBY_RELEASE_DATE # => "2023-03-30" + +==== RUBY_PLATFORM + +The platform identifier: + + RUBY_PLATFORM # => "x86_64-linux" + +==== RUBY_PATCHLEVEL + +The integer patch level for this Ruby: + + RUBY_PATCHLEVEL # => 53 + +For a development build the patch level will be -1. + +==== RUBY_REVISION + +The git commit hash for this Ruby: + + RUBY_REVISION # => "e51014f9c05aa65cbf203442d37fef7c12390015" + +==== RUBY_COPYRIGHT + +The copyright string: + + RUBY_COPYRIGHT + # => "ruby - Copyright (C) 1993-2023 Yukihiro Matsumoto" + +==== RUBY_ENGINE + +The name of the Ruby implementation: + + RUBY_ENGINE # => "ruby" + +==== RUBY_ENGINE_VERSION + +The version of the Ruby implementation: + + RUBY_ENGINE_VERSION # => "3.2.2" + +==== RUBY_DESCRIPTION + +The description of the Ruby implementation: + + RUBY_DESCRIPTION + # => "ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]" + +=== Embedded \Data + +==== DATA + +Defined if and only if the program has this line: + + __END__ + +When defined, DATA is a File object +containing the lines following the __END__, +positioned at the first of those lines: + + p DATA + DATA.each_line { |line| p line } + __END__ + Foo + Bar + Baz + +Output: + + # + "Foo\n" + "Bar\n" + "Baz\n" diff --git a/doc/maintainers.md b/doc/maintainers.md index 11f729f9515c56..d6026b6ce38253 100644 --- a/doc/maintainers.md +++ b/doc/maintainers.md @@ -165,7 +165,10 @@ have commit right, others don't. * https://rubygems.org/gems/ipaddr #### lib/irb.rb, lib/irb/* -* aycabta +* Stan Lo (st0012) +* Tomoya Ishida (tompng) +* Mari Imaizumi (ima1zumi) +* Hitoshi Hasumi (hasumikin) * https://github.com/ruby/irb * https://rubygems.org/gems/irb @@ -249,7 +252,10 @@ have commit right, others don't. * https://rubygems.org/gems/rdoc #### lib/reline.rb, lib/reline/* -* aycabta +* Tomoya Ishida (tompng) +* Mari Imaizumi (ima1zumi) +* Stan Lo (st0012) +* Hitoshi Hasumi (hasumikin) * https://github.com/ruby/reline * https://rubygems.org/gems/reline diff --git a/doc/syntax.rdoc b/doc/syntax.rdoc index 5895673f36a8f9..6ca58435126e4c 100644 --- a/doc/syntax.rdoc +++ b/doc/syntax.rdoc @@ -37,3 +37,6 @@ 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/operators.rdoc b/doc/syntax/operators.rdoc new file mode 100644 index 00000000000000..f972309412add9 --- /dev/null +++ b/doc/syntax/operators.rdoc @@ -0,0 +1,75 @@ += Operators + +In Ruby, operators such as +, 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 (&&, ||, +and, and or) do not always result in a boolean value. +Similar to blocks, it's the last evaluated expression that defines the result +of the operation. + +=== &&, and + +Both &&/and operators provide short-circuiting by executing each +side of the operator, left to right, and stopping at the first occurence of a +falsey expression. The expression that defines the result is the last one +executed, whether it be the final expression, or the first occurence 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, c was initialized, but not defined. + +=== ||, or + +The means by which ||/or 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/yjit/yjit.md b/doc/yjit/yjit.md index 8aac4ec555e7a5..05bc37a3f0f114 100644 --- a/doc/yjit/yjit.md +++ b/doc/yjit/yjit.md @@ -165,7 +165,7 @@ YJIT supports all command-line options supported by upstream CRuby, but also add - `--yjit`: enable YJIT (disabled by default) - `--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-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 64 MiB in Ruby 3.2, 128 MiB in Ruby 3.3+) - `--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-trace-exits`: produce a Marshal dump of backtraces from specific exits. Automatically enables `--yjit-stats` (must configure and build with `--enable-yjit=stats` to use this) @@ -186,11 +186,60 @@ ruby 3.3.0dev (2023-01-31T15:11:10Z master 2a0bf269c9) +YJIT dev [x86_64-darwin2 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 +## 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 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 + +It's helpful to call the same code as many times as possible before a process restarts. +If a process is killed too frequently, the time taken for compiling methods may outweigh +the speedup obtained by compiling them. + +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. + +## 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 + +`--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.2. You should multiply that by the number +of worker processes to estimate the worst case memory overhead. + +Running code GC adds overhead, but it could be still faster than recovering from a whole process killed by OOM. + +## Code Optimization Tips This section contains tips on writing Ruby code that will run as fast as possible on YJIT. Some of this advice is based on current limitations of YJIT, while other advice is broadly applicable. It probably won't be practical to apply these tips everywhere in your codebase. You should ideally start by profiling your application using a tool such as [stackprof](https://github.com/tmm1/stackprof) so that you can determine which methods make up most of the execution time. You can then refactor the specific methods that make up the largest fractions of the execution time. We do not recommend modifying your entire codebase based on the current limitations of YJIT. -- Use exceptions for error recovery only, not as part of normal control-flow - Avoid redefining basic integer operations (i.e. +, -, <, >, etc.) - Avoid redefining the meaning of `nil`, equality, etc. - Avoid allocating objects in the hot parts of your code @@ -198,7 +247,7 @@ This section contains tips on writing Ruby code that will run as fast as possibl - Avoid classes that wrap objects if you can - 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 `integer.times` +- Use while loops if you can, instead of C methods like `Array#each` - This is not idiomatic Ruby, but could help in hot methods - CRuby method calls are costly. Avoid things such as methods that only return a value from a hash or return a constant. diff --git a/enc/depend b/enc/depend index 47a20e957acdb5..12ddbc223a9afe 100644 --- a/enc/depend +++ b/enc/depend @@ -58,12 +58,8 @@ TRANSCLEANOBJS = <%=cleanobjs.map {|clean| LIBTRANS=enc/libtrans.$(LIBEXT) UNICODE_HDR_DIR = --missing-unicode-header-dir-- -encs: all -% if MODULE_TYPE == :static -all: libenc libtrans -% else -all: enc trans -%end +encs all: <%= MODULE_TYPE == :static ? "lib" : "mod" %>encs +modencs: enc trans libencs: libenc libtrans enc: $(ENCSOS) libenc: $(LIBENC) diff --git a/enum.c b/enum.c index 355170cc3ecb68..7f15836ba87e77 100644 --- a/enum.c +++ b/enum.c @@ -4936,11 +4936,11 @@ enum_compact(VALUE obj) * - #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. + * 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. + * 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. + * 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. * diff --git a/error.c b/error.c index cd031120e2acfb..878ec81d13f323 100644 --- a/error.c +++ b/error.c @@ -23,6 +23,10 @@ # include #endif +#ifdef HAVE_SYS_WAIT_H +# include +#endif + #if defined __APPLE__ # include #endif @@ -34,12 +38,14 @@ #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" @@ -622,18 +628,239 @@ 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) +bug_report_file(const char *file, int line, rb_pid_t *pid) { char buf[REPORT_BUG_BUFSIZ]; - FILE *out = stderr; + const char *report = crash_report; + if (!report) report = getenv("RUBY_CRASH_REPORT"); + FILE *out = open_report_path(report, buf, sizeof(buf), pid); int len = err_position_0(buf, sizeof(buf), file, line); - if ((ssize_t)fwrite(buf, 1, len, out) == (ssize_t)len || - (ssize_t)fwrite(buf, 1, len, (out = stdout)) == (ssize_t)len) { - return out; + 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; } return NULL; @@ -740,7 +967,7 @@ bug_report_begin_valist(FILE *out, const char *fmt, va_list args) } while (0) static void -bug_report_end(FILE *out) +bug_report_end(FILE *out, rb_pid_t pid) { /* call additional bug reporters */ { @@ -751,26 +978,45 @@ bug_report_end(FILE *out) } } postscript_dump(out); + finish_report(out, pid); } #define report_bug(file, line, fmt, ctx) do { \ - FILE *out = bug_report_file(file, line); \ + rb_pid_t pid = -1; \ + FILE *out = bug_report_file(file, line, &pid); \ if (out) { \ bug_report_begin(out, fmt); \ - rb_vm_bugreport(ctx); \ - bug_report_end(out); \ + rb_vm_bugreport(ctx, out); \ + bug_report_end(out, pid); \ } \ } while (0) \ #define report_bug_valist(file, line, fmt, ctx, args) do { \ - FILE *out = bug_report_file(file, line); \ + rb_pid_t pid = -1; \ + FILE *out = bug_report_file(file, line, &pid); \ if (out) { \ bug_report_begin_valist(out, fmt, args); \ - rb_vm_bugreport(ctx); \ - bug_report_end(out); \ + rb_vm_bugreport(ctx, out); \ + bug_report_end(out, pid); \ } \ } 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) @@ -881,8 +1127,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); - bug_report_end(out); + rb_vm_bugreport(NULL, out); + bug_report_end(out, -1); die(); } @@ -3256,7 +3502,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(); + rb_print_backtrace(stderr); die(); } diff --git a/ext/-test-/string/set_len.c b/ext/-test-/string/set_len.c index 219cea404cffe5..049da2cdb5c085 100644 --- a/ext/-test-/string/set_len.c +++ b/ext/-test-/string/set_len.c @@ -7,8 +7,18 @@ bug_str_set_len(VALUE str, VALUE len) return str; } +static VALUE +bug_str_append(VALUE str, VALUE addendum) +{ + StringValue(addendum); + rb_str_modify_expand(str, RSTRING_LEN(addendum)); + memcpy(RSTRING_END(str), RSTRING_PTR(addendum), RSTRING_LEN(addendum)); + return str; +} + void Init_string_set_len(VALUE klass) { rb_define_method(klass, "set_len", bug_str_set_len, 1); + rb_define_method(klass, "append", bug_str_append, 1); } diff --git a/ext/date/date_core.c b/ext/date/date_core.c index f2baf4fcea813d..f4b390584bc793 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -8726,8 +8726,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}[doc/strftime_formatting.rdoc]. + * For other formats, + * see {Formats for Dates and Times}[rdoc-ref:strftime_formatting.rdoc]: * */ static VALUE diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb index cf8b5223bb85d5..2d85b3eea5215f 100644 --- a/ext/fiddle/extconf.rb +++ b/ext/fiddle/extconf.rb @@ -63,6 +63,11 @@ def enable_debug_build_flag(flags) 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/objspace/objspace.c b/ext/objspace/objspace.c index e8762d1be6f5bb..393bf1daaa999a 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -493,6 +493,9 @@ count_nodes(int argc, VALUE *argv, VALUE os) COUNT_NODE(NODE_ARYPTN); COUNT_NODE(NODE_FNDPTN); COUNT_NODE(NODE_HSHPTN); + COUNT_NODE(NODE_DEF_TEMP); + COUNT_NODE(NODE_RIPPER); + COUNT_NODE(NODE_RIPPER_VALUES); COUNT_NODE(NODE_ERROR); #undef COUNT_NODE case NODE_LAST: break; diff --git a/ext/openssl/History.md b/ext/openssl/History.md index 1e0df7dd8739c0..bd7b1ec1b1f9cb 100644 --- a/ext/openssl/History.md +++ b/ext/openssl/History.md @@ -1,3 +1,43 @@ +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 ============= diff --git a/ext/openssl/lib/openssl/version.rb b/ext/openssl/lib/openssl/version.rb index 4163f550642b49..9315a79381dffd 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.1.0" + VERSION = "3.2.0" end diff --git a/ext/openssl/openssl.gemspec b/ext/openssl/openssl.gemspec index 674dc20debf05b..2765f554016ee8 100644 --- a/ext/openssl/openssl.gemspec +++ b/ext/openssl/openssl.gemspec @@ -1,10 +1,10 @@ Gem::Specification.new do |spec| spec.name = "openssl" - spec.version = "3.1.0" + spec.version = "3.2.0" spec.authors = ["Martin Bosslet", "SHIBATA Hiroshi", "Zachary Scott", "Kazuki Yamaguchi"] spec.email = ["ruby-core@ruby-lang.org"] - spec.summary = %q{OpenSSL provides SSL, TLS and general purpose cryptography.} - spec.description = %q{It wraps the OpenSSL library.} + 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.homepage = "https://github.com/ruby/openssl" spec.license = "Ruby" diff --git a/ext/ripper/ripper_init.c.tmpl b/ext/ripper/ripper_init.c.tmpl index 40c583eeaebcb4..fc399f47f13d7f 100644 --- a/ext/ripper/ripper_init.c.tmpl +++ b/ext/ripper/ripper_init.c.tmpl @@ -1,3 +1,4 @@ +%# -*- c -*- #include "ruby/ruby.h" #include "ruby/encoding.h" #include "internal.h" @@ -13,7 +14,6 @@ #include "ripper_init.h" #define STR_NEW2(ptr) rb_enc_str_new((ptr),strlen(ptr),rb_ruby_parser_enc(p)) -#define NODE_RIPPER NODE_CDECL #define RIPPER_VERSION "0.1.0" ID id_warn, id_warning, id_gets, id_assoc; @@ -61,7 +61,7 @@ ripper_get_id(VALUE v) 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; + return RNODE_RIPPER(nd)->nd_vid; } VALUE @@ -72,7 +72,7 @@ ripper_get_value(VALUE v) 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; + return RNODE_RIPPER(nd)->nd_rval; } static VALUE diff --git a/ext/ripper/tools/dsl.rb b/ext/ripper/tools/dsl.rb index 49ff51711f00ff..3c43cf5140de05 100644 --- a/ext/ripper/tools/dsl.rb +++ b/ext/ripper/tools/dsl.rb @@ -6,11 +6,18 @@ # v1 = dispatch0(stmts_new); # v2 = dispatch0(void_stmt); # $$ = dispatch2(stmts_add, v1, v2); - -$dollar = "$$" -alias $$ $dollar +# +# - 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_.]*\])/.source + NOT_REF_PATTERN = /(?>\#.*|[^\"$@]*|"(?>\\.|[^\"])*")/.source + def initialize(code, options) @events = {} @error = options.include?("error") @@ -18,19 +25,15 @@ def initialize(code, options) if options.include?("final") @final = "p->result" else - @final = (options.grep(/\A\$(?:\$|\d+)\z/)[0] || "$$") + @final = (options.grep(/\A\$#{NAME_PATTERN}\z/o)[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/preproc.rb b/ext/ripper/tools/preproc.rb index 07ef627cf34f2e..a98a60e31927e6 100644 --- a/ext/ripper/tools/preproc.rb +++ b/ext/ripper/tools/preproc.rb @@ -59,10 +59,9 @@ def prelude(f, out) when /\A%%/ out << "%%\n" return - when /\A%token/, /\A} / - out << line.sub(/<\w+>/, '') - when /\A%type/ - out << line.sub(/<\w+>/, '') + when /\A%token/, /\A%type/, /\A} / + # types in %union which have corresponding set_yylval_* macro. + out << line.sub(/<(?:node|num|id)>/, '') when /^enum lex_state_(?:bits|e) \{/ lex_state_def = true out << line diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index e89a1d780cf996..1feb9231db9b1a 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -603,7 +603,7 @@ strio_to_read(VALUE self) * eof? -> true or false * * Returns +true+ if positioned at end-of-stream, +false+ otherwise; - * see {Position}[rdoc-ref:File@Position]. + * see {Position}[rdoc-ref:IO@Position]. * * Raises IOError if the stream is not opened for reading. */ diff --git a/file.c b/file.c index 4a5c8a8f8aa965..1b526219284e81 100644 --- a/file.c +++ b/file.c @@ -1773,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 * */ @@ -6531,7 +6531,7 @@ const char ruby_null_device[] = * \Class \File extends module FileTest, supporting such singleton methods * as File.exist?. * - * === About the Examples + * == About the Examples * * Many examples here use these variables: * diff --git a/gc.c b/gc.c index 871afcb22ce1b3..e36e4c7ecdfa26 100644 --- a/gc.c +++ b/gc.c @@ -60,6 +60,15 @@ # endif #endif +#ifdef HAVE_MALLOC_TRIM +# include + +# ifdef __EMSCRIPTEN__ +/* malloc_trim is defined in emscripten/emmalloc.h on emscripten. */ +# include +# endif +#endif + #if !defined(PAGE_SIZE) && defined(HAVE_SYS_USER_H) /* LIST_HEAD conflicts with sys/queue.h on macOS */ # include @@ -694,6 +703,8 @@ 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; @@ -893,6 +904,9 @@ 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; struct { @@ -1044,6 +1058,7 @@ struct heap_page { short total_slots; short free_slots; short final_slots; + short pinned_slots; struct { unsigned int before_sweep : 1; unsigned int has_remembered_objects : 1; @@ -1372,7 +1387,7 @@ total_freed_objects(rb_objspace_t *objspace) #define is_incremental_marking(objspace) ((objspace)->flags.during_incremental_marking != FALSE) #define will_be_incremental_marking(objspace) ((objspace)->rgengc.need_major_gc != GPR_FLAG_NONE) #define GC_INCREMENTAL_SWEEP_SLOT_COUNT 2048 -#define GC_INCREMENTAL_SWEEP_POOL_SLOT_COUT 1024 +#define GC_INCREMENTAL_SWEEP_POOL_SLOT_COUNT 1024 #define is_lazy_sweeping(objspace) (GC_ENABLE_LAZY_SWEEP && has_sweeping_pages(objspace)) #define using_local_limits(objspace) (objspace != ruby_single_main_objspace && !objspace->flags.during_global_gc) @@ -2054,7 +2069,8 @@ rb_objspace_free(rb_objspace_t *objspace) } if (heap_pages_sorted) { size_t i; - for (i = 0; i < heap_allocated_pages; ++i) { + size_t total_heap_pages = heap_allocated_pages; + for (i = 0; i < total_heap_pages; ++i) { heap_page_free(objspace, heap_pages_sorted[i]); } free(heap_pages_sorted); @@ -4216,12 +4232,7 @@ obj_free(rb_objspace_t *objspace, VALUE obj) } #endif - if (RHASH_ST_TABLE_P(obj)) { - st_table *tab = RHASH_ST_TABLE(obj); - - free(tab->bins); - free(tab->entries); - } + rb_hash_free(obj); break; case T_REGEXP: if (RANY(obj)->as.regexp.ptr) { @@ -6596,12 +6607,27 @@ 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 + ); + } +#endif + 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); @@ -6761,7 +6787,7 @@ gc_sweep_step(rb_objspace_t *objspace, rb_size_pool_t *size_pool, rb_heap_t *hea size_pool->freed_slots += ctx.freed_slots; size_pool->empty_slots += ctx.empty_slots; - if (pooled_slots < GC_INCREMENTAL_SWEEP_POOL_SLOT_COUT) { + if (pooled_slots < GC_INCREMENTAL_SWEEP_POOL_SLOT_COUNT) { heap_add_poolpage(objspace, heap, sweep_page); pooled_slots += free_slots; } @@ -7856,7 +7882,10 @@ gc_pin(rb_objspace_t *objspace, VALUE obj) GC_ASSERT(is_markable_object(obj)); if (UNLIKELY(objspace->flags.during_compacting)) { if (LIKELY(during_gc)) { - MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj); + if (!MARKED_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj)) { + GET_HEAP_PAGE(obj)->pinned_slots++; + MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj); + } } } } @@ -8811,7 +8840,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(); /* C backtrace will help to debug */ + rb_print_backtrace(stderr); /* C backtrace will help to debug */ data->err_count++; } @@ -10216,7 +10245,7 @@ rb_gc_register_address(VALUE *addr) if (0 && !SPECIAL_CONST_P(obj)) { rb_warn("Object is assigned to registering address already: %"PRIsVALUE, rb_obj_class(obj)); - rb_print_backtrace(); + rb_print_backtrace(stderr); } } @@ -11090,6 +11119,10 @@ rb_gc_prepare_heap(void) rb_objspace_each_objects(gc_set_candidate_object_i, NULL); gc_start_internal(NULL, Qtrue, Qtrue, Qtrue, Qtrue, Qfalse, Qtrue); free_empty_pages(); + +#if defined(HAVE_MALLOC_TRIM) && !defined(RUBY_ALTERNATIVE_MALLOC_HEADER) + malloc_trim(0); +#endif } static int @@ -11292,6 +11325,18 @@ 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) { @@ -11305,7 +11350,7 @@ compare_free_slots(const void *left, const void *right, void *dummy) } static void -gc_sort_heap_by_empty_slots(rb_objspace_t *objspace) +gc_sort_heap_by_compare_func(rb_objspace_t *objspace, gc_compact_compare_func compare_func) { for (int j = 0; j < SIZE_POOL_COUNT; j++) { rb_size_pool_t *size_pool = &size_pools[j]; @@ -11325,7 +11370,7 @@ gc_sort_heap_by_empty_slots(rb_objspace_t *objspace) /* 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_free_slots, NULL); + ruby_qsort(page_list, total_pages, sizeof(struct heap_page *), compare_func, NULL); /* Reset the eden heap */ ccan_list_head_init(&SIZE_POOL_EDEN_HEAP(size_pool)->pages); @@ -12282,7 +12327,7 @@ gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE do } if (RTEST(toward_empty)) { - gc_sort_heap_by_empty_slots(objspace); + objspace->rcompactor.compare_func = compare_free_slots; } } RB_VM_LOCK_LEAVE(); @@ -12292,6 +12337,7 @@ 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 @@ -15112,7 +15158,7 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU { const rb_method_entry_t *me = &RANY(obj)->as.imemo.ment; - APPEND_F(":%s (%s%s%s%s) type:%s alias:%d owner:%p defined_class:%p", + APPEND_F(":%s (%s%s%s%s) type:%s aliased:%d owner:%p defined_class:%p", rb_id2name(me->called_id), METHOD_ENTRY_VISI(me) == METHOD_VISI_PUBLIC ? "pub" : METHOD_ENTRY_VISI(me) == METHOD_VISI_PRIVATE ? "pri" : "pro", @@ -15120,7 +15166,7 @@ rb_raw_obj_info_buitin_type(char *const buff, const size_t buff_size, const VALU METHOD_ENTRY_CACHED(me) ? ",cc" : "", METHOD_ENTRY_INVALIDATED(me) ? ",inv" : "", me->def ? rb_method_type_name(me->def->type) : "NULL", - me->def ? me->def->alias_count : -1, + me->def ? me->def->aliased : -1, (void *)me->owner, // obj_info(me->owner), (void *)me->defined_class); //obj_info(me->defined_class))); diff --git a/gems/bundled_gems b/gems/bundled_gems index a12fd3bac3e2cf..f166619f75c341 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -14,10 +14,10 @@ rss 0.3.0 https://github.com/ruby/rss net-ftp 0.2.0 https://github.com/ruby/net-ftp net-imap 0.3.7 https://github.com/ruby/net-imap net-pop 0.1.2 https://github.com/ruby/net-pop -net-smtp 0.3.3 https://github.com/ruby/net-smtp +net-smtp 0.4.0 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.2.1 https://github.com/ruby/rbs +rbs 3.2.2 https://github.com/ruby/rbs 33813a60752624d58dfe5ae770b39bfaf29fbaf1 typeprof 0.21.8 https://github.com/ruby/typeprof debug 1.8.0 https://github.com/ruby/debug 927587afb6aac69b358b86a01f602d207053e8d2 racc 1.7.1 https://github.com/ruby/racc diff --git a/hash.c b/hash.c index 323f7f6f689c5c..b0919511900ed3 100644 --- a/hash.c +++ b/hash.c @@ -686,9 +686,8 @@ ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key) return ar_find_entry_hint(hash, hint, key); } -//old one static inline void -ar_free_and_clear_table(VALUE hash) +hash_ar_free_and_clear_table(VALUE hash) { RHASH_AR_TABLE_CLEAR(hash); @@ -716,7 +715,7 @@ ar_try_convert_table(VALUE hash) st_add_direct(new_tab, pair->key, pair->val); } - ar_free_and_clear_table(hash); + hash_ar_free_and_clear_table(hash); RHASH_ST_TABLE_SET(hash, new_tab); } @@ -743,7 +742,7 @@ ar_force_convert_table(VALUE hash, const char *file, int line) ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i); st_add_direct(new_tab, pair->key, pair->val); } - ar_free_and_clear_table(hash); + hash_ar_free_and_clear_table(hash); } RHASH_ST_TABLE_SET(hash, new_tab); @@ -1162,7 +1161,7 @@ ar_clear(VALUE hash) } static void -st_free_and_clear_table(VALUE hash) +hash_st_free(VALUE hash) { HASH_ASSERT(RHASH_ST_TABLE_P(hash)); @@ -1170,10 +1169,24 @@ st_free_and_clear_table(VALUE hash) free(tab->bins); free(tab->entries); +} + +static void +hash_st_free_and_clear_table(VALUE hash) +{ + hash_st_free(hash); RHASH_ST_CLEAR(hash); } +void +rb_hash_free(VALUE hash) +{ + if (RHASH_ST_TABLE_P(hash)) { + hash_st_free(hash); + } +} + typedef int st_foreach_func(st_data_t, st_data_t, st_data_t); struct foreach_safe_arg { @@ -1963,7 +1976,8 @@ rb_hash_rehash(VALUE hash) if (RHASH_AR_TABLE_P(hash)) { tmp = hash_alloc(0); rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); - ar_free_and_clear_table(hash); + + hash_ar_free_and_clear_table(hash); ar_copy(hash, tmp); } else if (RHASH_ST_TABLE_P(hash)) { @@ -1975,6 +1989,7 @@ rb_hash_rehash(VALUE hash) rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp); + hash_st_free(hash); RHASH_ST_TABLE_SET(hash, tbl); RHASH_ST_CLEAR(tmp); } @@ -2907,10 +2922,10 @@ rb_hash_replace(VALUE hash, VALUE hash2) COPY_DEFAULT(hash, hash2); if (RHASH_AR_TABLE_P(hash)) { - ar_free_and_clear_table(hash); + hash_ar_free_and_clear_table(hash); } else { - st_free_and_clear_table(hash); + hash_st_free_and_clear_table(hash); } hash_copy(hash, hash2); @@ -6985,7 +7000,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. * diff --git a/include/ruby/internal/encoding/string.h b/include/ruby/internal/encoding/string.h index 6ed7ca1c90d8fc..2b9dfe4f318621 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_enc_str_new(), except it additionally takes an encoding. + * Identical to rb_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 1ce9a30e6fa9dc..cd37f4461afc38 100644 --- a/include/ruby/internal/error.h +++ b/include/ruby/internal/error.h @@ -481,7 +481,7 @@ VALUE *rb_ruby_debug_ptr(void); */ #define ruby_debug (*rb_ruby_debug_ptr()) -/* reports if `-W' specified */ +/* reports if $VERBOSE is true */ RBIMPL_ATTR_NONNULL((1)) RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2) /** @@ -496,7 +496,8 @@ 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 `-W` flag. + * @note This function is affected by the value of $VERBOSE, it does + * nothing unless $VERBOSE is true. * @param[in] fmt Format specifier string compatible with rb_sprintf(). * * @internal @@ -521,7 +522,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 `-W` flag. + * @note This function is affected by the value of $VERBOSE. * @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(). @@ -534,19 +535,20 @@ 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 `-W` flag. + * @note This function is affected by the value of $VERBOSE. * @param[in] fmt Format specifier string compatible with rb_sprintf(). */ void rb_sys_warning(const char *fmt, ...); -/* reports always */ +/* reports if $VERBOSE is not nil (so if it is true or false) */ RBIMPL_ATTR_COLD() RBIMPL_ATTR_NONNULL((1)) RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 1, 2) /** - * Identical to rb_warning(), except it reports always regardless of runtime - * `-W` flag. + * Identical to rb_warning(), except it reports unless $VERBOSE is nil. * + * @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, ...); @@ -555,8 +557,7 @@ RBIMPL_ATTR_COLD() RBIMPL_ATTR_NONNULL((2)) RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3) /** - * Identical to rb_category_warning(), except it reports always regardless of - * runtime `-W` flag. + * Identical to rb_category_warning(), except it reports unless $VERBOSE is nil. * * @param[in] cat Category e.g. deprecated. * @param[in] fmt Format specifier string compatible with rb_sprintf(). @@ -566,8 +567,7 @@ 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 always regardless of - * runtime `-W` flag. + * Identical to rb_compile_warning(), except it reports unless $VERBOSE is nil. * * @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/intern/bignum.h b/include/ruby/internal/intern/bignum.h index 43d68018de9e77..4ba48264faa918 100644 --- a/include/ruby/internal/intern/bignum.h +++ b/include/ruby/internal/intern/bignum.h @@ -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/memory_view.h b/include/ruby/memory_view.h index 1ddca2d46f0663..42309d5afc3756 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. */ - unsigned native_size_p: 1; + bool native_size_p; /** Endian of the component */ - unsigned little_endian_p: 1; + bool little_endian_p; /** The component's offset. */ size_t offset; diff --git a/include/ruby/thread.h b/include/ruby/thread.h index 3753a4c06abee2..d6a543af916146 100644 --- a/include/ruby/thread.h +++ b/include/ruby/thread.h @@ -243,7 +243,7 @@ typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t; * @return An opaque pointer to the hook, to unregister it later. * @note This functionality is a noop on Windows. * @note The callback will be called without the GVL held, except for the - RESUMED event. + * RESUMED event. * @warning This function MUST not be called from a thread event callback. */ rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook( diff --git a/inits.c b/inits.c index 701ed856b0dbe3..a114b780aab408 100644 --- a/inits.c +++ b/inits.c @@ -22,7 +22,6 @@ rb_call_inits(void) { CALL(default_shapes); CALL(Thread_Mutex); - CALL(Method); CALL(RandomSeedCore); CALL(encodings); CALL(sym); @@ -76,7 +75,7 @@ rb_call_inits(void) CALL(ast); CALL(gc_stress); CALL(shape); - CALL(YARP); + CALL(Prism); // enable builtin loading CALL(builtin); diff --git a/internal/class.h b/internal/class.h index b9ff53a6b0903c..9bc1caf6a99bad 100644 --- a/internal/class.h +++ b/internal/class.h @@ -119,7 +119,6 @@ VALUE rb_module_s_alloc(VALUE klass); void rb_module_set_initialized(VALUE module); void rb_module_check_initializable(VALUE module); VALUE rb_make_metaclass(VALUE, VALUE); -VALUE rb_iclass_alloc(VALUE klass); VALUE rb_include_class_new(VALUE, VALUE); void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE); void rb_class_detach_subclasses(VALUE); @@ -206,7 +205,7 @@ RCLASS_SET_SUPER(VALUE klass, VALUE super) static inline void RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent) { - assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE || klass == rb_mRubyVMFrozenCore); + 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); diff --git a/internal/cmdlineopt.h b/internal/cmdlineopt.h index 3b678b1edd1d24..e79b99334597b0 100644 --- a/internal/cmdlineopt.h +++ b/internal/cmdlineopt.h @@ -28,6 +28,8 @@ typedef struct ruby_cmdline_options { struct rb_rjit_options rjit; #endif + const char *crash_report; + signed int sflag: 2; unsigned int xflag: 1; unsigned int warning: 1; diff --git a/internal/hash.h b/internal/hash.h index d1848e540801b4..fe859cb716b95b 100644 --- a/internal/hash.h +++ b/internal/hash.h @@ -87,6 +87,7 @@ 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); 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); diff --git a/internal/vm.h b/internal/vm.h index 0ae14a061475c4..af5d4f66b740cf 100644 --- a/internal/vm.h +++ b/internal/vm.h @@ -59,6 +59,8 @@ VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements); 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); + /* vm_eval.c */ VALUE rb_current_realfilepath(void); VALUE rb_check_block_call(VALUE, ID, int, const VALUE *, rb_block_call_func_t, VALUE); @@ -96,7 +98,7 @@ int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID i void rb_clear_constant_cache(void); /* vm_dump.c */ -void rb_print_backtrace(void); +void rb_print_backtrace(FILE *); /* vm_backtrace.c */ VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval); @@ -104,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(void); +void rb_backtrace_print_as_bugreport(FILE*); int rb_backtrace_p(VALUE obj); VALUE rb_backtrace_to_str_ary(VALUE obj); VALUE rb_backtrace_to_location_ary(VALUE obj); diff --git a/io.c b/io.c index f0432142d38db9..dd42423c251cdd 100644 --- a/io.c +++ b/io.c @@ -170,6 +170,7 @@ 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; @@ -4356,22 +4357,28 @@ rb_io_set_lineno(VALUE io, VALUE lineno) return lineno; } -/* - * 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. - */ - +/* :nodoc: */ static VALUE -rb_io_readline(int argc, VALUE *argv, VALUE io) +io_readline(rb_execution_context_t *ec, VALUE io, VALUE sep, VALUE lim, VALUE chomp) { - VALUE line = rb_io_gets_m(argc, argv, 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); if (NIL_P(line)) { rb_eof_error(); @@ -5574,12 +5581,9 @@ clear_codeconv(rb_io_t *fptr) clear_writeconv(fptr); } -void -rb_io_fptr_finalize_internal(void *ptr) +static void +rb_io_fptr_cleanup_all(rb_io_t *fptr) { - rb_io_t *fptr = ptr; - - if (!ptr) return; fptr->pathv = Qnil; if (0 <= fptr->fd) rb_io_fptr_cleanup(fptr, TRUE); @@ -5587,7 +5591,14 @@ rb_io_fptr_finalize_internal(void *ptr) free_io_buffer(&fptr->rbuf); free_io_buffer(&fptr->wbuf); clear_codeconv(fptr); - free(fptr); +} + +void +rb_io_fptr_finalize_internal(void *ptr) +{ + if (!ptr) return; + rb_io_fptr_cleanup_all(ptr); + free(ptr); } #undef rb_io_fptr_finalize @@ -7951,6 +7962,60 @@ 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, @@ -10467,11 +10532,9 @@ rb_f_backquote(VALUE obj, VALUE str) if (NIL_P(port)) return rb_str_new(0,0); GetOpenFile(port, fptr); - rb_obj_hide(port); result = read_all(fptr, remain_size(fptr), Qnil); rb_io_close(port); - RFILE(port)->fptr = NULL; - rb_io_fptr_finalize(fptr); + rb_io_fptr_cleanup_all(fptr); RB_GC_GUARD(port); return result; @@ -14625,11 +14688,16 @@ 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 STDIN, i.e. the data - * piped to your script. For example: + * If +ARGV+ is empty, ARGF acts as if it contained "-" that + * makes ARGF read from STDIN, i.e. the data piped or typed 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" */ /* @@ -14716,7 +14784,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 internal encoding. + * which may control conversion between external and internal encoding. * * == Basic \IO * @@ -15358,7 +15426,6 @@ 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); diff --git a/io.rb b/io.rb index 40873ea4fdbd10..549c5e62bdb281 100644 --- a/io.rb +++ b/io.rb @@ -120,4 +120,17 @@ def read_nonblock(len, buf = nil, exception: true) 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 d987b8fa38e3cf..942ab268ae592d 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -289,6 +289,111 @@ static const rb_data_type_t rb_io_buffer_type = { .flags = RUBY_TYPED_FREE_IMMEDIATELY, }; +// Extract an offset argument, which must be a positive integer. +static inline size_t +io_buffer_extract_offset(VALUE argument) +{ + if (rb_int_negative_p(argument)) { + rb_raise(rb_eArgError, "Offset can't be negative!"); + } + + return NUM2SIZET(argument); +} + +// 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 +io_buffer_extract_length(VALUE argument) +{ + if (rb_int_negative_p(argument)) { + rb_raise(rb_eArgError, "Length can't be negative!"); + } + + return NUM2SIZET(argument); +} + +// 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) +{ + if (rb_int_negative_p(argument)) { + rb_raise(rb_eArgError, "Size can't be negative!"); + } + + return NUM2SIZET(argument); +} + +// 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 +// invalid; in that case, an ArgumentError exception will be raised. +static inline size_t +io_buffer_default_length(const struct rb_io_buffer *buffer, size_t offset) +{ + if (offset > buffer->size) { + rb_raise(rb_eArgError, "The given offset is bigger than the buffer size!"); + } + + // Note that the "length" is computed by the size the offset. + return buffer->size - offset; +} + +// Extract the optional length and offset arguments, returning the buffer. +// The length and offset are optional, but if they are provided, they must be +// positive integers. If the length is not provided, the default length is +// computed from the buffer size and offset. If the offset is not provided, it +// defaults to zero. +static inline struct rb_io_buffer * +io_buffer_extract_length_offset(VALUE self, int argc, VALUE argv[], size_t *length, size_t *offset) +{ + struct rb_io_buffer *buffer = NULL; + TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); + + if (argc >= 2) { + *offset = io_buffer_extract_offset(argv[1]); + } + else { + *offset = 0; + } + + if (argc >= 1 && !NIL_P(argv[0])) { + *length = io_buffer_extract_length(argv[0]); + } + else { + *length = io_buffer_default_length(buffer, *offset); + } + + return buffer; +} + +// Extract the optional offset and length arguments, returning the buffer. +// 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) { + *offset = io_buffer_extract_offset(argv[0]); + } + else { + *offset = 0; + } + + if (argc >= 2) { + *length = io_buffer_extract_length(argv[1]); + } + else { + *length = io_buffer_default_length(buffer, *offset); + } + + return buffer; +} + VALUE rb_io_buffer_type_allocate(VALUE self) { @@ -521,7 +626,7 @@ io_buffer_map(int argc, VALUE *argv, VALUE klass) size_t size; if (argc >= 2 && !RB_NIL_P(argv[1])) { - size = RB_NUM2SIZE(argv[1]); + size = io_buffer_extract_size(argv[1]); } else { rb_off_t file_size = rb_file_size(io); @@ -540,6 +645,7 @@ io_buffer_map(int argc, VALUE *argv, VALUE klass) } } + // This is the file offset, not the buffer offset: rb_off_t offset = 0; if (argc >= 3) { offset = NUM2OFFT(argv[2]); @@ -601,9 +707,8 @@ rb_io_buffer_initialize(int argc, VALUE *argv, VALUE self) TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); size_t size; - if (argc > 0) { - size = RB_NUM2SIZE(argv[0]); + size = io_buffer_extract_size(argv[0]); } else { size = RUBY_IO_BUFFER_DEFAULT_SIZE; @@ -1156,8 +1261,9 @@ VALUE rb_io_buffer_free_locked(VALUE self) static inline void io_buffer_validate_range(struct rb_io_buffer *buffer, size_t offset, size_t length) { + // We assume here that offset + length won't overflow: if (offset + length > buffer->size) { - rb_raise(rb_eArgError, "Specified offset+length exceeds buffer size!"); + rb_raise(rb_eArgError, "Specified offset+length is bigger than the buffer size!"); } } @@ -1183,7 +1289,7 @@ rb_io_buffer_slice(struct rb_io_buffer *buffer, VALUE self, size_t offset, size_ } /* - * call-seq: slice([offset = 0, [length]]) -> io_buffer + * call-seq: slice([offset, [length]]) -> io_buffer * * Produce another IO::Buffer which is a slice (or view into) the current one * starting at +offset+ bytes and going for +length+ bytes. @@ -1243,29 +1349,8 @@ io_buffer_slice(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 0, 2); - struct rb_io_buffer *buffer = NULL; - TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); - - size_t offset = 0, length = 0; - - if (argc > 0) { - if (rb_int_negative_p(argv[0])) { - rb_raise(rb_eArgError, "Offset can't be negative!"); - } - - offset = NUM2SIZET(argv[0]); - } - - if (argc > 1) { - if (rb_int_negative_p(argv[1])) { - rb_raise(rb_eArgError, "Length can't be negative!"); - } - - length = NUM2SIZET(argv[1]); - } - else { - length = buffer->size - offset; - } + size_t offset, length; + struct rb_io_buffer *buffer = io_buffer_extract_offset_length(self, argc, argv, &offset, &length); return rb_io_buffer_slice(buffer, self, offset, length); } @@ -1493,7 +1578,7 @@ rb_io_buffer_resize(VALUE self, size_t size) static VALUE io_buffer_resize(VALUE self, VALUE size) { - rb_io_buffer_resize(self, NUM2SIZET(size)); + rb_io_buffer_resize(self, io_buffer_extract_size(size)); return self; } @@ -1756,7 +1841,7 @@ io_buffer_get_value(VALUE self, VALUE type, VALUE _offset) { const void *base; size_t size; - size_t offset = NUM2SIZET(_offset); + size_t offset = io_buffer_extract_offset(_offset); rb_io_buffer_get_bytes_for_reading(self, &base, &size); @@ -1778,7 +1863,7 @@ io_buffer_get_value(VALUE self, VALUE type, VALUE _offset) static VALUE io_buffer_get_values(VALUE self, VALUE buffer_types, VALUE _offset) { - size_t offset = NUM2SIZET(_offset); + size_t offset = io_buffer_extract_offset(_offset); const void *base; size_t size; @@ -1799,6 +1884,40 @@ io_buffer_get_values(VALUE self, VALUE buffer_types, VALUE _offset) return array; } +// Extract a count argument, which must be a positive integer. +// Count is generally considered relative to the number of things. +static inline size_t +io_buffer_extract_count(VALUE argument) +{ + if (rb_int_negative_p(argument)) { + rb_raise(rb_eArgError, "Count can't be negative!"); + } + + return NUM2SIZET(argument); +} + +static inline void +io_buffer_extract_offset_count(ID buffer_type, size_t size, int argc, VALUE *argv, size_t *offset, size_t *count) +{ + if (argc >= 1) { + *offset = io_buffer_extract_offset(argv[0]); + } + else { + *offset = 0; + } + + if (argc >= 2) { + *count = io_buffer_extract_count(argv[1]); + } + else { + if (*offset > size) { + rb_raise(rb_eArgError, "The given offset is bigger than the buffer size!"); + } + + *count = (size - *offset) / io_buffer_buffer_type_size(buffer_type); + } +} + /* * call-seq: * each(buffer_type, [offset, [count]]) {|offset, value| ...} -> self @@ -1835,21 +1954,8 @@ io_buffer_each(int argc, VALUE *argv, VALUE self) buffer_type = RB_IO_BUFFER_DATA_TYPE_U8; } - size_t offset; - if (argc >= 2) { - offset = NUM2SIZET(argv[1]); - } - else { - offset = 0; - } - - size_t count; - if (argc >= 3) { - count = NUM2SIZET(argv[2]); - } - else { - count = (size - offset) / io_buffer_buffer_type_size(buffer_type); - } + size_t offset, count; + io_buffer_extract_offset_count(buffer_type, size, argc-1, argv+1, &offset, &count); for (size_t i = 0; i < count; i++) { size_t current_offset = offset; @@ -1888,21 +1994,8 @@ io_buffer_values(int argc, VALUE *argv, VALUE self) buffer_type = RB_IO_BUFFER_DATA_TYPE_U8; } - size_t offset; - if (argc >= 2) { - offset = NUM2SIZET(argv[1]); - } - else { - offset = 0; - } - - size_t count; - if (argc >= 3) { - count = NUM2SIZET(argv[2]); - } - else { - count = (size - offset) / io_buffer_buffer_type_size(buffer_type); - } + size_t offset, count; + io_buffer_extract_offset_count(buffer_type, size, argc-1, argv+1, &offset, &count); VALUE array = rb_ary_new_capa(count); @@ -1941,21 +2034,8 @@ io_buffer_each_byte(int argc, VALUE *argv, VALUE self) rb_io_buffer_get_bytes_for_reading(self, &base, &size); - size_t offset; - if (argc >= 2) { - offset = NUM2SIZET(argv[1]); - } - else { - offset = 0; - } - - size_t count; - if (argc >= 3) { - count = NUM2SIZET(argv[2]); - } - else { - count = (size - offset); - } + size_t offset, count; + io_buffer_extract_offset_count(RB_IO_BUFFER_DATA_TYPE_U8, size, argc-1, argv+1, &offset, &count); for (size_t i = 0; i < count; i++) { unsigned char *value = (unsigned char *)base + i + offset; @@ -2031,7 +2111,7 @@ io_buffer_set_value(VALUE self, VALUE type, VALUE _offset, VALUE value) { void *base; size_t size; - size_t offset = NUM2SIZET(_offset); + size_t offset = io_buffer_extract_offset(_offset); rb_io_buffer_get_bytes_for_writing(self, &base, &size); @@ -2071,7 +2151,7 @@ io_buffer_set_values(VALUE self, VALUE buffer_types, VALUE _offset, VALUE values rb_raise(rb_eArgError, "Argument buffer_types and values should have the same length!"); } - size_t offset = NUM2SIZET(_offset); + size_t offset = io_buffer_extract_offset(_offset); void *base; size_t size; @@ -2096,7 +2176,7 @@ io_buffer_memcpy(struct rb_io_buffer *buffer, size_t offset, const void *source_ io_buffer_validate_range(buffer, offset, length); if (source_offset + length > source_size) { - rb_raise(rb_eArgError, "The computed source range exceeds the size of the source!"); + rb_raise(rb_eArgError, "The computed source range exceeds the size of the source buffer!"); } memcpy((unsigned char*)base+offset, (unsigned char*)source_base+source_offset, length); @@ -2106,21 +2186,18 @@ io_buffer_memcpy(struct rb_io_buffer *buffer, size_t offset, const void *source_ static VALUE io_buffer_copy_from(struct rb_io_buffer *buffer, const void *source_base, size_t source_size, int argc, VALUE *argv) { - size_t offset; + size_t offset = 0; size_t length; size_t source_offset; // The offset we copy into the buffer: if (argc >= 1) { - offset = NUM2SIZET(argv[0]); - } - else { - offset = 0; + offset = io_buffer_extract_offset(argv[0]); } // The offset we start from within the string: if (argc >= 3) { - source_offset = NUM2SIZET(argv[2]); + source_offset = io_buffer_extract_offset(argv[2]); if (source_offset > source_size) { rb_raise(rb_eArgError, "The given source offset is bigger than the source itself!"); @@ -2132,7 +2209,7 @@ io_buffer_copy_from(struct rb_io_buffer *buffer, const void *source_base, size_t // The length we are going to copy: if (argc >= 2 && !RB_NIL_P(argv[1])) { - length = NUM2SIZET(argv[1]); + length = io_buffer_extract_length(argv[1]); } else { // Default to the source offset -> source size: @@ -2229,7 +2306,7 @@ rb_io_buffer_initialize_copy(VALUE self, VALUE source) * * buffer = IO::Buffer.new(2) * buffer.copy(IO::Buffer.for('test'), 0) - * # in `copy': Specified offset+length exceeds source size! (ArgumentError) + * # in `copy': Specified offset+length is bigger than the buffer size! (ArgumentError) */ static VALUE io_buffer_copy(int argc, VALUE *argv, VALUE self) @@ -2267,31 +2344,20 @@ io_buffer_get_string(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 0, 3); - struct rb_io_buffer *buffer = NULL; - TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); + size_t offset, length; + struct rb_io_buffer *buffer = io_buffer_extract_offset_length(self, argc, argv, &offset, &length); const void *base; size_t size; io_buffer_get_bytes_for_reading(buffer, &base, &size); - size_t offset = 0; - size_t length = size; - rb_encoding *encoding = rb_ascii8bit_encoding(); - - if (argc >= 1) { - offset = NUM2SIZET(argv[0]); - } - - if (argc >= 2 && !RB_NIL_P(argv[1])) { - length = NUM2SIZET(argv[1]); - } - else { - length = size - offset; - } - + rb_encoding *encoding; if (argc >= 3) { encoding = rb_find_encoding(argv[2]); } + else { + encoding = rb_ascii8bit_encoding(); + } io_buffer_validate_range(buffer, offset, length); @@ -2340,14 +2406,14 @@ io_buffer_set_string(int argc, VALUE *argv, VALUE self) void rb_io_buffer_clear(VALUE self, uint8_t value, 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); + void *base; size_t size; + io_buffer_get_bytes_for_writing(buffer, &base, &size); - rb_io_buffer_get_bytes_for_writing(self, &base, &size); - - if (offset + length > size) { - rb_raise(rb_eArgError, "The given offset + length out of bounds!"); - } + io_buffer_validate_range(buffer, offset, length); memset((char*)base + offset, value, length); } @@ -2388,26 +2454,13 @@ io_buffer_clear(int argc, VALUE *argv, VALUE self) { rb_check_arity(argc, 0, 3); - struct rb_io_buffer *buffer = NULL; - TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); - uint8_t value = 0; if (argc >= 1) { value = NUM2UINT(argv[0]); } - size_t offset = 0; - if (argc >= 2) { - offset = NUM2SIZET(argv[1]); - } - - size_t length; - if (argc >= 3) { - length = NUM2SIZET(argv[2]); - } - else { - length = buffer->size - offset; - } + size_t offset, length; + io_buffer_extract_offset_length(self, argc-1, argv+1, &offset, &length); rb_io_buffer_clear(self, value, offset, length); @@ -2486,35 +2539,6 @@ io_buffer_blocking_region(struct rb_io_buffer *buffer, rb_blocking_function_t *f } } -static inline struct rb_io_buffer * -io_buffer_extract_arguments(VALUE self, int argc, VALUE argv[], size_t *length, size_t *offset) -{ - struct rb_io_buffer *buffer = NULL; - TypedData_Get_Struct(self, struct rb_io_buffer, &rb_io_buffer_type, buffer); - - *offset = 0; - if (argc >= 2) { - if (rb_int_negative_p(argv[1])) { - rb_raise(rb_eArgError, "Offset can't be negative!"); - } - - *offset = NUM2SIZET(argv[1]); - } - - if (argc >= 1 && !NIL_P(argv[0])) { - if (rb_int_negative_p(argv[0])) { - rb_raise(rb_eArgError, "Length can't be negative!"); - } - - *length = NUM2SIZET(argv[0]); - } - else { - *length = buffer->size - *offset; - } - - return buffer; -} - struct io_buffer_read_internal_argument { // The file descriptor to read from: int descriptor; @@ -2626,7 +2650,7 @@ io_buffer_read(int argc, VALUE *argv, VALUE self) VALUE io = argv[0]; size_t length, offset; - io_buffer_extract_arguments(self, argc-1, argv+1, &length, &offset); + io_buffer_extract_length_offset(self, argc-1, argv+1, &length, &offset); return rb_io_buffer_read(self, io, length, offset); } @@ -2751,7 +2775,7 @@ io_buffer_pread(int argc, VALUE *argv, VALUE self) rb_off_t from = NUM2OFFT(argv[1]); size_t length, offset; - io_buffer_extract_arguments(self, argc-2, argv+2, &length, &offset); + io_buffer_extract_length_offset(self, argc-2, argv+2, &length, &offset); return rb_io_buffer_pread(self, io, from, length, offset); } @@ -2860,7 +2884,7 @@ io_buffer_write(int argc, VALUE *argv, VALUE self) VALUE io = argv[0]; size_t length, offset; - io_buffer_extract_arguments(self, argc-1, argv+1, &length, &offset); + io_buffer_extract_length_offset(self, argc-1, argv+1, &length, &offset); return rb_io_buffer_write(self, io, length, offset); } @@ -2986,7 +3010,7 @@ io_buffer_pwrite(int argc, VALUE *argv, VALUE self) rb_off_t from = NUM2OFFT(argv[1]); size_t length, offset; - io_buffer_extract_arguments(self, argc-2, argv+2, &length, &offset); + io_buffer_extract_length_offset(self, argc-2, argv+2, &length, &offset); return rb_io_buffer_pwrite(self, io, from, length, offset); } diff --git a/iseq.c b/iseq.c index ff9d9d06a2fc89..20fa2905ee3a75 100644 --- a/iseq.c +++ b/iseq.c @@ -44,7 +44,7 @@ #include "builtin.h" #include "insns.inc" #include "insns_info.inc" -#include "yarp/yarp.h" +#include "prism/prism.h" VALUE rb_cISeq; static VALUE iseqw_new(const rb_iseq_t *iseq); @@ -189,7 +189,11 @@ rb_iseq_free(const rb_iseq_t *iseq) ruby_xfree((void *)body->mark_bits.list); } + ruby_xfree(body->variable.original_iseq); + if (body->param.keyword != NULL) { + if (body->param.keyword->table != &body->local_table[body->param.keyword->bits_start - body->param.keyword->num]) + ruby_xfree((void *)body->param.keyword->table); ruby_xfree((void *)body->param.keyword->default_values); ruby_xfree((void *)body->param.keyword); } @@ -936,10 +940,10 @@ 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_yarp_node(rb_iseq_t * iseq, const yp_node_t * yarp_pointer, yp_parser_t *parser); +VALUE rb_iseq_compile_prism_node(rb_iseq_t * iseq, const pm_node_t *node, pm_parser_t *parser); rb_iseq_t * -yp_iseq_new_with_opt(yp_node_t *node, yp_parser_t *parser, VALUE name, VALUE path, VALUE realpath, +pm_iseq_new_with_opt(pm_node_t *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) { @@ -950,17 +954,18 @@ yp_iseq_new_with_opt(yp_node_t *node, yp_parser_t *parser, VALUE name, VALUE pat if (!option) option = &COMPILE_OPTION_DEFAULT; if (node) { - yp_line_column_t start_line_col = yp_newline_list_line_column(&(parser->newline_list), node->location.start); - yp_line_column_t end_line_col= yp_newline_list_line_column(&(parser->newline_list), node->location.end); + pm_line_column_t start_line_col = pm_newline_list_line_column(&parser->newline_list, node->location.start); + pm_line_column_t end_line_col = pm_newline_list_line_column(&parser->newline_list, node->location.end); + code_loc = (rb_code_location_t) { .beg_pos = { - .lineno = (int)start_line_col.line, - .column = (int)start_line_col.column + .lineno = (int) start_line_col.line, + .column = (int) start_line_col.column + }, + .end_pos = { + .lineno = (int) end_line_col.line, + .column = (int) end_line_col.column }, - .end_pos = { - .lineno = (int)end_line_col.line, - .column = (int)end_line_col.column - }, }; } @@ -969,7 +974,7 @@ yp_iseq_new_with_opt(yp_node_t *node, yp_parser_t *parser, VALUE name, VALUE pat prepare_iseq_build(iseq, name, path, realpath, first_lineno, &code_loc, node_id, parent, isolated_depth, type, script_lines, option); - rb_iseq_compile_yarp_node(iseq, node, parser); + rb_iseq_compile_prism_node(iseq, node, parser); finish_iseq_build(iseq); @@ -1385,7 +1390,7 @@ iseqw_s_compile(int argc, VALUE *argv, VALUE self) } static VALUE -iseqw_s_compile_yarp(int argc, VALUE *argv, VALUE self) +iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self) { VALUE src, file = Qnil, path = Qnil, line = Qnil, opt = Qnil; int i; @@ -1408,17 +1413,17 @@ iseqw_s_compile_yarp(int argc, VALUE *argv, VALUE self) rb_iseq_t *iseq = iseq_alloc(); - yp_parser_t parser; + pm_parser_t parser; size_t len = RSTRING_LEN(src); VALUE name = rb_fstring_lit(""); - yp_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), len, ""); + pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), len, ""); - yp_node_t *node = yp_parse(&parser); + pm_node_t *node = pm_parse(&parser); int first_lineno = NUM2INT(line); - yp_line_column_t start_loc = yp_newline_list_line_column(&parser.newline_list, node->location.start); - yp_line_column_t end_loc = yp_newline_list_line_column(&parser.newline_list, node->location.end); + pm_line_column_t start_loc = pm_newline_list_line_column(&parser.newline_list, node->location.start); + pm_line_column_t end_loc = pm_newline_list_line_column(&parser.newline_list, node->location.end); rb_code_location_t node_location; node_location.beg_pos.lineno = (int)start_loc.line; @@ -1437,11 +1442,11 @@ iseqw_s_compile_yarp(int argc, VALUE *argv, VALUE self) prepare_iseq_build(iseq, name, file, path, first_lineno, &node_location, node_id, parent, 0, (enum rb_iseq_type)iseq_type, Qnil, &option); - rb_iseq_compile_yarp_node(iseq, node, &parser); + rb_iseq_compile_prism_node(iseq, node, &parser); finish_iseq_build(iseq); - yp_node_destroy(&parser, node); - yp_parser_free(&parser); + pm_node_destroy(&parser, node); + pm_parser_free(&parser); return iseqw_new(iseq); } @@ -4018,7 +4023,7 @@ 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_yarp", iseqw_s_compile_yarp, -1); + rb_define_singleton_method(rb_cISeq, "compile_prism", iseqw_s_compile_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/kernel.rb b/kernel.rb index 43d1abec31118e..c6b3e44000edc6 100644 --- a/kernel.rb +++ b/kernel.rb @@ -117,6 +117,15 @@ def tap # # 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? return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)' @@ -132,15 +141,6 @@ def then # # "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? return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)' diff --git a/lib/base64.gemspec b/lib/base64.gemspec index 44a2ce1fd1ef2b..c013b7c1c25dad 100644 --- a/lib/base64.gemspec +++ b/lib/base64.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |spec| 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.3.0") + spec.required_ruby_version = Gem::Requirement.new(">= 2.4") spec.licenses = ["Ruby", "BSD-2-Clause"] spec.metadata["homepage_uri"] = spec.homepage diff --git a/lib/bundler.rb b/lib/bundler.rb index f83268e9cda14d..ee08a2dab8b683 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -515,7 +515,16 @@ def read_file(file) end def safe_load_marshal(data) - load_marshal(data, :marshal_proc => SafeMarshal.proc) + 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 end def load_gemspec(file, validate = false) diff --git a/lib/bundler/build_metadata.rb b/lib/bundler/build_metadata.rb index 8bffb2fae760c5..29fa833588a680 100644 --- a/lib/bundler/build_metadata.rb +++ b/lib/bundler/build_metadata.rb @@ -29,7 +29,7 @@ def self.git_commit_sha # 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 = Dir.chdir(git_dir) { `git rev-parse --short HEAD`.strip.freeze } + return @git_commit_sha = IO.popen(%w[git rev-parse --short HEAD], { :chdir => git_dir }, &:read).strip.freeze end @git_commit_sha ||= "unknown" diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb index cc1f37f0c33d66..85c49f510a301e 100644 --- a/lib/bundler/cli/check.rb +++ b/lib/bundler/cli/check.rb @@ -29,7 +29,7 @@ def run 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 #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} present" + Bundler.ui.error "This bundle has been frozen, but there is no #{SharedHelpers.relative_lockfile_path} present" exit 1 else Bundler.load.lock(:preserve_unknown_sections => true) unless options[:"dry-run"] diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb index 1645283a2c7ab3..4ec61cec5dbe0c 100644 --- a/lib/bundler/cli/gem.rb +++ b/lib/bundler/cli/gem.rb @@ -233,9 +233,7 @@ def run end if use_git - Dir.chdir(target) do - `git add .` - end + IO.popen(%w[git add .], { :chdir => target }, &:read) end # Open gemspec in editor diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index c71bcf159f0861..f7228db6232fab 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -28,8 +28,8 @@ def run flag = "--deployment flag" if options[:deployment] flag ||= "--frozen flag" if options[:frozen] flag ||= "deployment setting" - 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 " \ + raise ProductionError, "The #{flag} requires a lockfile. Please make " \ + "sure you have checked your #{SharedHelpers.relative_lockfile_path} into version control " \ "before deploying." end diff --git a/lib/bundler/cli/open.rb b/lib/bundler/cli/open.rb index 8522ec92d69f04..87c1c3b1dbda56 100644 --- a/lib/bundler/cli/open.rb +++ b/lib/bundler/cli/open.rb @@ -18,13 +18,11 @@ def run 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 - 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 + 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(" ")}'") end end end diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb index 564530a98cdf1a..3c18ce71391b41 100644 --- a/lib/bundler/definition.rb +++ b/lib/bundler/definition.rb @@ -405,13 +405,13 @@ def ensure_equivalent_gemfile_and_lockfile(explicit_flag = false) 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 #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} to version control.\n" + msg << "\n\nRun `bundle install` elsewhere and add the updated #{SharedHelpers.relative_gemfile_path} 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 #{Bundler.default_gemfile.relative_path_from(SharedHelpers.pwd)} " \ + msg << "If this is a development machine, remove the #{SharedHelpers.relative_lockfile_path} " \ "freeze by running `#{suggested_command}`." if suggested_command end diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb index 4f8b6f605d2985..f6cb198e383c4c 100644 --- a/lib/bundler/env.rb +++ b/lib/bundler/env.rb @@ -40,11 +40,11 @@ def self.report(options = {}) out << "\n## Gemfile\n" gemfiles.each do |gemfile| - out << "\n### #{Pathname.new(gemfile).relative_path_from(SharedHelpers.pwd)}\n\n" + out << "\n### #{SharedHelpers.relative_path_to(gemfile)}\n\n" out << "```ruby\n" << read_file(gemfile).chomp << "\n```\n" end - out << "\n### #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}\n\n" + out << "\n### #{SharedHelpers.relative_path_to(Bundler.default_lockfile)}\n\n" out << "```\n" << read_file(Bundler.default_lockfile).chomp << "\n```\n" end diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index 9b64a3c771b408..5c1eac415e7a33 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -111,7 +111,7 @@ def fetch_spec(spec) spec_file_name = "#{spec.join "-"}.gemspec" uri = Bundler::URI.parse("#{remote_uri}#{Gem::MARSHAL_SPEC_DIR}#{spec_file_name}.rz") - if uri.scheme == "file" + spec = 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) @@ -119,6 +119,8 @@ def fetch_spec(spec) 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." diff --git a/lib/bundler/fetcher/base.rb b/lib/bundler/fetcher/base.rb index 62cc75add8f360..99c6343c9a9ec7 100644 --- a/lib/bundler/fetcher/base.rb +++ b/lib/bundler/fetcher/base.rb @@ -38,9 +38,9 @@ def api_fetcher? private - def log_specs(debug_msg) + def log_specs(&block) if Bundler.ui.debug? - Bundler.ui.debug debug_msg + Bundler.ui.debug yield else Bundler.ui.info ".", false end diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb index 6786a841f56b02..dc30443e27a542 100644 --- a/lib/bundler/fetcher/compact_index.rb +++ b/lib/bundler/fetcher/compact_index.rb @@ -35,7 +35,7 @@ def specs_for_names(gem_names) 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) diff --git a/lib/bundler/fetcher/dependency.rb b/lib/bundler/fetcher/dependency.rb index 18b606abb66192..0b807c9a4b2fc7 100644 --- a/lib/bundler/fetcher/dependency.rb +++ b/lib/bundler/fetcher/dependency.rb @@ -24,7 +24,7 @@ def api_fetcher? 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/gem_version_promoter.rb b/lib/bundler/gem_version_promoter.rb index d281f46eeb3e13..c7eacd193049a3 100644 --- a/lib/bundler/gem_version_promoter.rb +++ b/lib/bundler/gem_version_promoter.rb @@ -101,7 +101,7 @@ def sort_dep_specs(specs, package) next 1 if b_pre && !a_pre end - if major? + if major? || locked_version.nil? a <=> b elsif either_version_older_than_locked?(a, b, locked_version) a <=> b @@ -117,7 +117,7 @@ def sort_dep_specs(specs, package) end def either_version_older_than_locked?(a, b, locked_version) - locked_version && (a.version < locked_version || b.version < locked_version) + a.version < locked_version || b.version < locked_version end def segments_do_not_match?(a, b, level) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 6a20302322f608..6a17d45eaf9aca 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -19,14 +19,14 @@ def self.build def initialize @sources = [] @cache = {} - @specs = Hash.new {|h, k| h[k] = {} } + @specs = {} @duplicates = {} end def initialize_copy(o) @sources = o.sources.dup @cache = {} - @specs = Hash.new {|h, k| h[k] = {} } + @specs = {} @duplicates = {} o.specs.each do |name, hash| @@ -46,14 +46,11 @@ def empty? true end - def search_all(name) - all_matches = specs_by_name(name) # always returns a new Array - dupes = @duplicates[name] - all_matches.concat(dupes) if dupes - @sources.each do |source| - all_matches.concat(source.search_all(name)) - end - all_matches + 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) } end # Search this index's specs, and any source indexes that this index knows @@ -63,11 +60,14 @@ def search(query) return results unless @sources.any? @sources.each do |source| - results.concat(source.search(query)) + results = safe_concat(results, source.search(query)) end - results.uniq(&:full_name) + results.uniq!(&:full_name) unless results.empty? # avoid modifying frozen EMPTY_SEARCH + results end + alias_method :[], :search + def local_search(query) case query when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query) @@ -78,11 +78,8 @@ def local_search(query) end end - alias_method :[], :search - def add(spec) - @specs[spec.name][spec.full_name] = spec - spec + (@specs[spec.name] ||= {}).store(spec.full_name, spec) end alias_method :<<, :add @@ -170,16 +167,25 @@ def add_source(index) 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) - specs_by_name(name).select {|spec| spec.version == version } + results = @specs[name]&.values + return EMPTY_SEARCH unless results + results.select! {|spec| spec.version == version } + results end def specs_by_name(name) - @specs[name].values + @specs[name]&.values || EMPTY_SEARCH end EMPTY_SEARCH = [].freeze @@ -190,11 +196,11 @@ def search_by_spec(spec) end def find_by_spec(spec) - @specs[spec.name][spec.full_name] + @specs[spec.name]&.fetch(spec.full_name, nil) end def exist?(spec) - @specs[spec.name].key?(spec.full_name) + @specs[spec.name]&.key?(spec.full_name) end end end diff --git a/lib/bundler/installer/standalone.rb b/lib/bundler/installer/standalone.rb index a019fbd3b8f5ef..fed3d8c410e890 100644 --- a/lib/bundler/installer/standalone.rb +++ b/lib/bundler/installer/standalone.rb @@ -55,7 +55,7 @@ def gem_path(path, spec) if spec.source.instance_of?(Source::Path) && spec.source.path.absolute? full_path else - Pathname.new(full_path).relative_path_from(Bundler.root.join(bundler_path)).to_s + SharedHelpers.relative_path_to(full_path, :from => Bundler.root.join(bundler_path)) end rescue TypeError error_message = "#{spec.name} #{spec.version} has an invalid gemspec" diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb index 7360a3675261e7..31f57f14e8d506 100644 --- a/lib/bundler/lockfile_parser.rb +++ b/lib/bundler/lockfile_parser.rb @@ -23,13 +23,15 @@ class LockfileParser Gem::Version.create("1.13") => [PLUGIN].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) - lockfile_contents.scan(/^\w[\w ]*$/).uniq + sections = lockfile_contents.scan(/^\w[\w ]*$/) + sections.uniq! + sections end def self.unknown_sections_in_lockfile(lockfile_contents) @@ -38,7 +40,7 @@ def self.unknown_sections_in_lockfile(lockfile_contents) def self.sections_to_ignore(base_version = nil) base_version &&= base_version.release - base_version ||= Gem::Version.create("1.0".dup) + base_version ||= Gem::Version.create("1.0") attributes = [] SECTIONS_BY_VERSION_INTRODUCED.each do |version, introduced| next if version <= base_version @@ -61,36 +63,36 @@ def initialize(lockfile) @platforms = [] @sources = [] @dependencies = {} - @state = nil + @parse_method = nil @specs = {} if lockfile.match?(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/) - 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." + raise LockfileError, "Your lockfile contains merge conflicts.\n" \ + "Run `git checkout HEAD -- #{SharedHelpers.relative_lockfile_path}` first to get a clean lock." end - lockfile.split(/(?:\r?\n)+/).each do |line| + lockfile.split(/(?:\r?\n)+/) do |line| if SOURCE.include?(line) - @state = :source + @parse_method = :parse_source parse_source(line) elsif line == DEPENDENCIES - @state = :dependency + @parse_method = :parse_dependency elsif line == PLATFORMS - @state = :platform + @parse_method = :parse_platform elsif line == RUBY - @state = :ruby + @parse_method = :parse_ruby elsif line == BUNDLED - @state = :bundled_with + @parse_method = :parse_bundled_with elsif /^[^\s]/.match?(line) - @state = nil - elsif @state - send("parse_#{@state}", line) + @parse_method = nil + elsif @parse_method + send(@parse_method, line) end 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 #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` " \ + raise LockfileError, "Your lockfile is unreadable. Run `rm #{SharedHelpers.relative_lockfile_path}` " \ "and then `bundle install` to generate a new lockfile." end @@ -110,21 +112,9 @@ def may_include_redundant_platform_specific_gems? def parse_source(line) case line when SPECS - 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 + return unless TYPES.key?(@type) + @current_source = TYPES[@type].from_lock(@opts) + @sources << @current_source when OPTIONS value = $2 value = true if value == "true" @@ -161,11 +151,11 @@ 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(",").map(&:strip) if version + version = version.split(",").each(&:strip!) if version dep = Bundler::Dependency.new(name, version) @@ -189,11 +179,13 @@ def parse_dependency(line) def parse_spec(line) return unless line =~ NAME_VERSION spaces = $1 - name = $2 + name = -$2 version = $3 - platform = $4 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) @@ -202,7 +194,7 @@ def parse_spec(line) @specs[@current_spec.full_name] = @current_spec elsif spaces.size == 6 - version = version.split(",").map(&:strip) if version + version = version.split(",").each(&:strip!) if version dep = Gem::Dependency.new(name, version) @current_spec.dependencies << dep end @@ -213,13 +205,14 @@ def parse_platform(line) end def parse_bundled_with(line) - line = line.strip + line.strip! return unless Gem::Version.correct?(line) @bundler_version = Gem::Version.create(line) end def parse_ruby(line) - @ruby_version = line.strip + line.strip! + @ruby_version = line end end end diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index f3caff8963c720..e6aaa6b464aeb9 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -197,7 +197,7 @@ def source(name) # @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 source_from_lock(locked_opts) + def from_lock(locked_opts) src = source(locked_opts["type"]) src.new(locked_opts.merge("uri" => locked_opts["remote"])) diff --git a/lib/bundler/ruby_dsl.rb b/lib/bundler/ruby_dsl.rb index 542dbac1e4627a..95151898ff60eb 100644 --- a/lib/bundler/ruby_dsl.rb +++ b/lib/bundler/ruby_dsl.rb @@ -10,13 +10,8 @@ def ruby(*ruby_version) raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil? if options[:file] - raise GemfileError, "Cannot specify version when using the file option" if ruby_version.any? - file_content = Bundler.read_file(Bundler.root.join(options[:file])) - if /^ruby\s+(.*)$/.match(file_content) # match .tool-versions files - ruby_version << $1.split("#", 2).first.strip # remove trailing comment - else - ruby_version << file_content.strip - end + raise GemfileError, "Do not pass version argument when using :file option" unless ruby_version.empty? + ruby_version << normalize_ruby_file(options[:file]) end if options[:engine] == "ruby" && options[:engine_version] && @@ -25,5 +20,26 @@ def ruby(*ruby_version) end @ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[: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 + def normalize_ruby_file(filename) + file_content = Bundler.read_file(Bundler.root.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 + end + end end end diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb index d6f179cc96f6dc..81e1f5e0e31e26 100644 --- a/lib/bundler/rubygems_integration.rb +++ b/lib/bundler/rubygems_integration.rb @@ -253,21 +253,23 @@ def replace_require(specs) rescue GemfileNotFound "inline Gemfile" end - be = ::Gem::BUNDLED_GEMS::SINCE[name] > RUBY_VERSION ? "will be" : "is" - message = "#{name} #{be} not part of the default gems since Ruby #{::Gem::BUNDLED_GEMS::SINCE[name]}." \ - " Add #{name} to your #{target_file}." - location = caller_locations(1,1)[0]&.path - if 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 + if ::Gem::BUNDLED_GEMS::SINCE[name] + be = ::Gem::BUNDLED_GEMS::SINCE[name] > RUBY_VERSION ? "will be" : "is" + message = "#{name} #{be} not part of the default gems since Ruby #{::Gem::BUNDLED_GEMS::SINCE[name]}." \ + " Add #{name} to your #{target_file}." + location = caller_locations(1,1)[0]&.path + if 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 + message += " Also contact author of #{caller_gem} to add #{name} into its gemspec." end - message += " Also contact author of #{caller_gem} to add #{name} into its gemspec." + warn message, :uplevel => 1 end - warn message, :uplevel => 1 end end kernel_class.send(:no_warning_require, file) @@ -496,7 +498,9 @@ def fetch_specs(remote, name) fetcher = gem_remote_fetcher fetcher.headers = { "X-Gemfile-Source" => remote.original_uri.to_s } if remote.original_uri string = fetcher.fetch_path(path) - Bundler.safe_load_marshal(string) + 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 rescue Gem::RemoteFetcher::FetchError # it's okay for prerelease to fail raise unless name == "prerelease_specs" diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index 92b4a6a4e37787..d14ce40dc42c90 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -97,6 +97,8 @@ def initialize(root = nil) @global_config = load_config(global_config_file) @temporary = {} + + @key_cache = {} end def [](name) @@ -312,7 +314,7 @@ def validate! end def key_for(key) - self.class.key_for(key) + @key_cache[key] ||= self.class.key_for(key) end private @@ -344,12 +346,12 @@ def split_specific_setting_for(name) end def is_bool(name) - name = name.to_s + name = self.class.key_to_s(name) BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name)) end def is_string(name) - name = name.to_s + name = self.class.key_to_s(name) STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.") end @@ -365,11 +367,11 @@ def to_bool(value) end def is_num(key) - NUMBER_KEYS.include?(key.to_s) + NUMBER_KEYS.include?(self.class.key_to_s(key)) end def is_array(key) - ARRAY_KEYS.include?(key.to_s) + ARRAY_KEYS.include?(self.class.key_to_s(key)) end def is_credential(key) @@ -392,7 +394,7 @@ def array_to_s(array) end def set_key(raw_key, value, hash, file) - raw_key = raw_key.to_s + raw_key = self.class.key_to_s(raw_key) value = array_to_s(value) if is_array(raw_key) key = key_for(raw_key) @@ -412,7 +414,7 @@ def set_key(raw_key, value, hash, file) end def converted_value(value, key) - key = key.to_s + key = self.class.key_to_s(key) if is_array(key) to_array(value) @@ -472,17 +474,16 @@ def load_config(config_file) valid_file = file.exist? && !file.size.zero? return {} unless valid_file serializer_class.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("-", "___") + # string hash keys are frozen + k = k.gsub("-", "___") end - config[new_k] = v + config[k] = v config end end @@ -512,7 +513,7 @@ def serializer_class 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.gsub(".", "__") + key = key_to_s(key).gsub(".", "__") key.gsub!("-", "___") key.upcase! @@ -536,5 +537,34 @@ def self.normalize_uri(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 Bundler::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 Bundler::URI::HTTP + key.to_s + else + raise ArgumentError, "Invalid key: #{key.inspect}" + end + end + end end end diff --git a/lib/bundler/shared_helpers.rb b/lib/bundler/shared_helpers.rb index d1d4e1d07a5bf0..165982ad0a23cb 100644 --- a/lib/bundler/shared_helpers.rb +++ b/lib/bundler/shared_helpers.rb @@ -197,6 +197,21 @@ 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 diff --git a/lib/bundler/source/git/git_proxy.rb b/lib/bundler/source/git/git_proxy.rb index 53a9a78ddf3a87..bb3ca062c37b75 100644 --- a/lib/bundler/source/git/git_proxy.rb +++ b/lib/bundler/source/git/git_proxy.rb @@ -118,7 +118,8 @@ def copy_to(destination, submodules = false) end end - git "fetch", "--force", "--quiet", *extra_fetch_args, :dir => destination if @commit_ref + ref = @commit_ref || (locked_to_full_sha? && @revision) + git "fetch", "--force", "--quiet", *extra_fetch_args(ref), :dir => destination if ref git "reset", "--hard", @revision, :dir => destination @@ -235,7 +236,15 @@ def not_pinned? end def pinned_to_full_sha? - ref =~ /\A\h{40}\z/ + 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/) end def git_null(*command, dir: nil) @@ -399,9 +408,9 @@ def depth_args ["--depth", depth.to_s] end - def extra_fetch_args + def extra_fetch_args(ref) extra_args = [path.to_s, *depth_args] - extra_args.push(@commit_ref) + extra_args.push(ref) extra_args end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 44102c47c829a5..3d4d2eeec131f8 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -88,6 +88,7 @@ def options end def self.from_lock(options) + options["remotes"] = Array(options.delete("remote")).reverse new(options) end diff --git a/lib/bundler/stub_specification.rb b/lib/bundler/stub_specification.rb index 88a4257fa4521b..6f4264e56143d4 100644 --- a/lib/bundler/stub_specification.rb +++ b/lib/bundler/stub_specification.rb @@ -16,7 +16,8 @@ def source=(source) # 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) - path = File.join(stub.extensions_dir, source.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) stub.extension_dir = File.expand_path(path) end @@ -56,7 +57,7 @@ def extensions end def gem_build_complete_path - File.join(extension_dir, "gem.build_complete") + stub.gem_build_complete_path end def default_gem? @@ -108,6 +109,7 @@ def _remote_specification end rs.source = source + rs.base_dir = stub.base_dir rs end diff --git a/lib/bundler/templates/newgem/github/workflows/main.yml.tt b/lib/bundler/templates/newgem/github/workflows/main.yml.tt index be58dd81566dfb..32b39558d879fc 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@v3 + - uses: actions/checkout@v4 <%- if config[:ext] == 'rust' -%> - name: Set up Ruby & Rust uses: oxidize-rb/actions/setup-ruby-and-rust@v1 diff --git a/lib/bundler/yaml_serializer.rb b/lib/bundler/yaml_serializer.rb index d5ecbd4aef7188..6e4b44848fe0ba 100644 --- a/lib/bundler/yaml_serializer.rb +++ b/lib/bundler/yaml_serializer.rb @@ -54,8 +54,8 @@ def load(str) str.split(/\r?\n/).each do |line| if match = HASH_REGEX.match(line) indent, key, quote, val = match.captures - key = convert_to_backward_compatible_key(key) - depth = indent.scan(/ /).length + convert_to_backward_compatible_key!(key) + depth = indent.size / 2 if quote.empty? && val.empty? new_hash = {} stack[depth][key] = new_hash @@ -76,14 +76,13 @@ def load(str) end # for settings' keys - def convert_to_backward_compatible_key(key) - key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z} - key = key.gsub(".", "__") if key.include?(".") - key + 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 + private :dump_hash, :convert_to_backward_compatible_key! end end end diff --git a/lib/ipaddr.rb b/lib/ipaddr.rb index b7877970e4a7dc..75922baa90af9f 100644 --- a/lib/ipaddr.rb +++ b/lib/ipaddr.rb @@ -176,9 +176,7 @@ def mask(prefixlen) def include?(other) other = coerce_other(other) return false unless other.family == family - range = to_range - other = other.to_range - range.begin <= other.begin && range.end >= other.end + begin_addr <= other.begin_addr && end_addr >= other.end_addr end alias === include? @@ -406,17 +404,6 @@ def hash # 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 @@ -497,6 +484,21 @@ def zone_id=(zid) 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/cmd/show_source.rb b/lib/irb/cmd/show_source.rb index 10463ebf08ba6e..49cab43fab3d9f 100644 --- a/lib/irb/cmd/show_source.rb +++ b/lib/irb/cmd/show_source.rb @@ -2,6 +2,7 @@ require_relative "nop" require_relative "../source_finder" +require_relative "../pager" require_relative "../color" module IRB @@ -40,12 +41,16 @@ def execute(str = nil) private 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 + file_content = IRB::Color.colorize_code(File.read(source.file)) + code = file_content.lines[(source.first_line - 1)...source.last_line].join + content = <<~CONTENT + + #{bold("From")}: #{source.file}:#{source.first_line} + + #{code} + CONTENT + + Pager.page_content(content) end def bold(str) diff --git a/lib/irb/history.rb b/lib/irb/history.rb index ae924d152b096e..84d69e19cdafc0 100644 --- a/lib/irb/history.rb +++ b/lib/irb/history.rb @@ -10,6 +10,7 @@ def reset_history_counter def load_history history = self.class::HISTORY + if history_file = IRB.conf[:HISTORY_FILE] history_file = File.expand_path(history_file) end @@ -32,7 +33,8 @@ def load_history end def save_history - history = self.class::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) diff --git a/lib/net/http.rb b/lib/net/http.rb index ff780b45bd3c2a..82ab6ab574297e 100644 --- a/lib/net/http.rb +++ b/lib/net/http.rb @@ -1798,7 +1798,7 @@ def proxy_from_env? def proxy_uri # :nodoc: return if @proxy_uri == false @proxy_uri ||= URI::HTTP.new( - "http".freeze, nil, address, port, nil, nil, nil, nil, nil + "http", nil, address, port, nil, nil, nil, nil, nil ).find_proxy || false @proxy_uri || nil end diff --git a/lib/net/http/generic_request.rb b/lib/net/http/generic_request.rb index 9421535ceb2e45..44e329a0c84990 100644 --- a/lib/net/http/generic_request.rb +++ b/lib/net/http/generic_request.rb @@ -23,7 +23,7 @@ def initialize(m, reqbody, resbody, uri_or_path, initheader = nil) # :nodoc: raise ArgumentError, "no host component for URI" unless (hostname && hostname.length > 0) @uri = uri_or_path.dup host = @uri.hostname.dup - host << ":".freeze << @uri.port.to_s if @uri.port != @uri.default_port + 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 @@ -212,15 +212,15 @@ def update_uri(addr, port, ssl) # :nodoc: internal use only return unless @uri if ssl - scheme = 'https'.freeze + scheme = 'https' klass = URI::HTTPS else - scheme = 'http'.freeze + scheme = 'http' klass = URI::HTTP end if host = self['host'] - host.sub!(/:.*/m, ''.freeze) + host.sub!(/:.*/m, '') elsif host = @uri.host else host = addr diff --git a/lib/open3.rb b/lib/open3.rb index 9652b2719468eb..63f0a90fa9dd4a 100644 --- a/lib/open3.rb +++ b/lib/open3.rb @@ -33,55 +33,133 @@ module Open3 - # 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. + # :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 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 + # [stdin, stdout, stderr, wait_thread]. + # The caller should close each of the three returned streams. + # + # stdin, stdout, stderr, wait_thread = Open3.popen3('echo') + # # => [#, #, #, #] + # stdin.close + # stdout.close + # stderr.close + # wait_thread.pid # => 2210481 + # wait_thread.value # => # + # + # 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 # - # Block form: + # Output: # - # 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. - # } + # # + # # + # # + # # + # 2211047 + # # # - # Non-block form: + # Like Process.spawn, this method has potential security vulnerabilities + # if called with untrusted input; + # see {Command Injection}[rdoc-ref:command_injection.rdoc]. # - # 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. + # Unlike Process.spawn, this method waits for the child process to exit + # before returning, so the caller need not do so. # - # 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: + # Argument +options+ is a hash of options for the new process; + # see {Execution Options}[rdoc-ref:Process@Execution+Options]. # - # 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| ... } + # The single required argument is one of the following: # - # If the last parameter, opts, is a Hash, it is recognized as an option for Process.spawn. + # - +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. # - # Open3.popen3("pwd", :chdir=>"/") {|i,o,e,t| - # p o.read.chomp #=> "/" - # } + # Argument +command_line+ + # + # \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): + # + # [#, #, #, #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.popen3('echo "Foo"') { |i, o, e, t| o.gets } + # "Foo\n" + # + # Argument +exe_path+ + # + # 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" # - # wait_thr.value waits for the termination of the process. - # The block form also waits for the process when it returns. + # Ruby invokes the executable directly, with no shell and no shell expansion: # - # Closing stdin, stdout and stderr does not wait for the process to complete. + # Open3.popen3('doesnt_exist') { |i, o, e, t| o.gets } # Raises Errno::ENOENT # - # 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. + # If one or more +args+ is given, each is an argument or option + # to be passed to the executable: + # + # 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" + # + # 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). + # + # 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.popen2e: Makes the standard input and the merge + # of the standard output and standard error streams + # of the child process available as separate streams. # def popen3(*cmd, &block) if Hash === cmd.last @@ -104,45 +182,124 @@ def popen3(*cmd, &block) end module_function :popen3 - # Open3.popen2 is similar to Open3.popen3 except that it doesn't create a pipe for - # the standard error stream. + # :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 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 + # [stdin, stdout, wait_thread]. + # The caller should close each of the two returned streams. + # + # stdin, stdout, wait_thread = Open3.popen2('echo') + # # => [#, #, #] + # stdin.close + # stdout.close + # wait_thread.pid # => 2263572 + # wait_thread.value # => # + # + # 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 # - # Block form: + # Output: # - # 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. - # } + # # + # # + # # + # 2263636 + # # # - # Non-block form: + # Like Process.spawn, this method has potential security vulnerabilities + # if called with untrusted input; + # see {Command Injection}[rdoc-ref:command_injection.rdoc]. # - # stdin, stdout, wait_thr = Open3.popen2([env,] cmd... [, opts]) - # ... - # stdin.close # stdin and stdout should be closed explicitly in this form. - # stdout.close + # Unlike Process.spawn, this method waits for the child process to exit + # before returning, so the caller need not do so. + # + # Argument +options+ is a hash of options for the new process; + # 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. + # + # Argument +command_line+ + # + # \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): + # + # # => [#, #, #] + # + # The command line may also contain arguments and options for the command: + # + # Open3.popen2('echo "Foo"') { |i, o, t| o.gets } + # "Foo\n" # - # See Process.spawn for the optional hash arguments _env_ and _opts_. + # Argument +exe_path+ + # + # 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.popen2("wc -c") {|i,o,t| - # i.print "answer to life the universe and everything" - # i.close - # p o.gets #=> "42\n" - # } + # Open3.popen2('/usr/bin/date') { |i, o, t| o.gets } + # # => "Thu Sep 28 09:41:06 AM CDT 2023\n" # - # Open3.popen2("bc -q") {|i,o,t| - # i.puts "obase=13" - # i.puts "6 * 9" - # p o.gets #=> "42\n" - # } + # Ruby invokes the executable directly, with no shell and no shell expansion: # - # Open3.popen2("dc") {|i,o,t| - # i.print "42P" - # i.close - # p o.read #=> "*" - # } + # 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" + # + # + # 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. # def popen2(*cmd, &block) if Hash === cmd.last @@ -162,36 +319,123 @@ def popen2(*cmd, &block) end module_function :popen2 - # Open3.popen2e is similar to Open3.popen3 except that it merges - # the standard output stream and the standard error stream. + # :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 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 + # [stdin, stdout_and_stderr, wait_thread]. + # The caller should close each of the two returned streams. + # + # stdin, stdout_and_stderr, wait_thread = Open3.popen2e('echo') + # # => [#, #, #] + # stdin.close + # stdout_and_stderr.close + # wait_thread.pid # => 2274600 + # wait_thread.value # => # + # + # 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 # - # Block form: + # Output: # - # 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. - # } + # # + # # + # # + # 2274763 + # # # - # Non-block form: + # Like Process.spawn, this method has potential security vulnerabilities + # if called with untrusted input; + # see {Command Injection}[rdoc-ref:command_injection.rdoc]. # - # 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 + # Unlike Process.spawn, this method waits for the child process to exit + # before returning, so the caller need not do so. + # + # Argument +options+ is a hash of options for the new process; + # see {Execution Options}[rdoc-ref:Process@Execution+Options]. # - # See Process.spawn for the optional hash arguments _env_ and _opts_. + # 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. + # + # Argument +command_line+ + # + # \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('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. + # + # Output (similar for each call above): + # + # # => [#, #, #] + # + # 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" + # + # Argument +exe_path+ + # + # 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: - # # check gcc warnings - # source = "foo.c" - # Open3.popen2e("gcc", "-Wall", source) {|i,oe,t| - # oe.each {|line| - # if /warning/ =~ line - # ... - # end - # } - # } + # + # 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. # def popen2e(*cmd, &block) if Hash === cmd.last diff --git a/lib/ostruct.gemspec b/lib/ostruct.gemspec index 21cce182260a65..61bf6e7deed2f1 100644 --- a/lib/ostruct.gemspec +++ b/lib/ostruct.gemspec @@ -24,4 +24,5 @@ Gem::Specification.new do |spec| spec.add_development_dependency "bundler" spec.add_development_dependency "rake" + spec.add_development_dependency "test-unit" end diff --git a/lib/ostruct.rb b/lib/ostruct.rb index a08561d6c96aca..7311138fbf5ceb 100644 --- a/lib/ostruct.rb +++ b/lib/ostruct.rb @@ -109,6 +109,14 @@ class OpenStruct VERSION = "0.5.5" + HAS_PERFORMANCE_WARNINGS = begin + Warning[:performance] + true + rescue NoMethodError, ArgumentError + false + end + private_constant :HAS_PERFORMANCE_WARNINGS + # # Creates a new OpenStruct object. By default, the resulting OpenStruct # object will have no attributes. @@ -124,6 +132,10 @@ class OpenStruct # data # => # # 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/prettyprint.rb b/lib/prettyprint.rb index 540b12fb706373..156d7102840d2e 100644 --- a/lib/prettyprint.rb +++ b/lib/prettyprint.rb @@ -23,10 +23,10 @@ # # == References # Christian Lindig, Strictly Pretty, March 2000, -# http://www.st.cs.uni-sb.de/~lindig/papers/#pretty +# https://lindig.github.io/papers/strictly-pretty-2000.pdf # # Philip Wadler, A prettier printer, March 1998, -# http://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier +# https://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier # # == Author # Tanaka Akira diff --git a/lib/prism.rb b/lib/prism.rb new file mode 100644 index 00000000000000..b45098480a5f6f --- /dev/null +++ b/lib/prism.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +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 :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 + + # Returns an array of tokens that closely resembles that of the Ripper lexer. + # The only difference is that since we don't keep track of lexer state in the + # same way, it's going to always return the NONE state. + def self.lex_compat(source, filepath = "") + LexCompat.new(source, filepath).result + end + + # 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 + + # Load the serialized AST using the source as a reference into a tree. + def self.load(source, serialized) + Serialize.load(source, serialized) + 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 new file mode 100644 index 00000000000000..9c6756ff35cd52 --- /dev/null +++ b/lib/prism/debug.rb @@ -0,0 +1,157 @@ +# 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 + class ISeq + attr_reader :parts + + def initialize(parts) + @parts = parts + end + + def type + parts[0] + end + + def local_table + parts[10] + end + + def instructions + parts[13] + end + + def each_child + instructions.each do |instruction| + # Only look at arrays. Other instructions are line numbers or + # tracepoint events. + next unless instruction.is_a?(Array) + + instruction.each do |opnd| + # Only look at arrays. Other operands are literals. + next unless opnd.is_a?(Array) + + # Only look at instruction sequences. Other operands are literals. + next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat" + + yield ISeq.new(opnd) + end + end + end + end + + # 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) + if iseq.type != :once + names = iseq.local_table + + # CRuby will push on a special local variable when there are keyword + # arguments. We get rid of that here. + names = names.grep_v(Integer) + + # For some reason, CRuby occasionally pushes this special local + # variable when there are splat arguments. We get rid of that here. + names = names.grep_v(:"#arg_rest") + + # Now push them onto the list of locals. + locals << names + end + + iseq.each_child { |child| stack << child } + end + + locals + ensure + $VERBOSE = verbose + end + end + + # For the given source, parses with prism and returns a list of all of the + # sets of local variables that were encountered. + def self.prism_locals(source) + locals = [] + stack = [Prism.parse(source).value] + + while (node = stack.pop) + case node + when BlockNode, DefNode, LambdaNode + names = node.locals + + params = node.parameters + params = params&.parameters unless node.is_a?(DefNode) + + # 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.grep(RequiredParameterNode).map(&:name), + *params.optionals.map(&:name), + *((params.rest.name || :*) if params.rest && params.rest.operator != ","), + *params.posts.grep(RequiredParameterNode).map(&:name), + *params.keywords.reject(&:value).map(&:name), + *params.keywords.select(&:value).map(&:name) + ] + + # TODO: When we get a ... parameter, we should be pushing * and & + # onto the local list. We don't do that yet, so we need to add them + # in here. + if params.keyword_rest.is_a?(ForwardingParameterNode) + sorted.push(:*, :&, :"...") + end + + # Recurse down the parameter tree to find any destructured + # parameters and add them after the other parameters. + param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse + while (param = param_stack.pop) + case param + when RequiredDestructuredParameterNode + param_stack.concat(param.parameters.reverse) + when RequiredParameterNode + sorted << param.name + when SplatNode + sorted << param.expression.name if param.expression + end + end + + names = sorted.concat(names - sorted) + end + + locals << names + when ClassNode, ModuleNode, ProgramNode, SingletonClassNode + locals << node.locals + when ForNode + locals << [] + when PostExecutionNode + locals.push([], []) + when InterpolatedRegularExpressionNode + locals << [] if node.once? + end + + stack.concat(node.compact_child_nodes) + end + + locals + end + + def self.newlines(source) + Prism.parse(source).source.offsets + end + + def self.parse_serialize_file(filepath) + parse_serialize_file_metadata(filepath, [filepath.bytesize, filepath.b, 0].pack("LA*L")) + end + end +end diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb new file mode 100644 index 00000000000000..232c6ecb3773b6 --- /dev/null +++ b/lib/prism/desugar_compiler.rb @@ -0,0 +1,206 @@ +# 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( + read_class.new(*arguments, node.name_loc), + nil, + node.operator_loc.copy(length: node.operator_loc.length - 1), + nil, + ArgumentsNode.new([node.value], node.value.location), + nil, + nil, + 0, + node.operator_loc.slice.chomp("="), + 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), + 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 new file mode 100644 index 00000000000000..3ff1875611bce3 --- /dev/null +++ b/lib/prism/ffi.rb @@ -0,0 +1,251 @@ +# 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 + 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/librubyparser.#{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.delete_prefix("const ") + type.end_with?("*") ? :pointer : type.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 (?.+) (?\w+)\((?.+)\);$/ =~ 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_parse_serialize", + "pm_lex_serialize", + "pm_parse_lex_serialize" + ) + + 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 + 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 + 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 + + def self.dump_internal(source, source_size, filepath) + PrismBuffer.with do |buffer| + metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath + pm_parse_serialize(source, source_size, buffer.pointer, metadata) + buffer.read + 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 + + # Mirror the Prism.dump API by using the serialization API. + def self.dump(code, filepath = nil) + LibRubyParser.dump_internal(code, code.bytesize, filepath) + end + + # Mirror the Prism.dump_file API by using the serialization API. + def self.dump_file(filepath) + LibRubyParser::PrismString.with(filepath) do |string| + LibRubyParser.dump_internal(string.source, string.length, filepath) + end + end + + # Mirror the Prism.lex API by using the serialization API. + def self.lex(code, filepath = nil) + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_lex_serialize(code, code.bytesize, filepath, buffer.pointer) + Serialize.load_tokens(Source.new(code), buffer.read) + end + end + + # Mirror the Prism.lex_file API by using the serialization API. + def self.lex_file(filepath) + LibRubyParser::PrismString.with(filepath) do |string| + lex(string.read, filepath) + end + end + + # Mirror the Prism.parse API by using the serialization API. + def self.parse(code, filepath = nil) + Prism.load(code, dump(code, filepath)) + 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 self.parse_file(filepath) + LibRubyParser::PrismString.with(filepath) do |string| + parse(string.read, filepath) + end + end + + # Mirror the Prism.parse_lex API by using the serialization API. + def self.parse_lex(code, filepath = nil) + LibRubyParser::PrismBuffer.with do |buffer| + metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath + LibRubyParser.pm_parse_lex_serialize(code, code.bytesize, buffer.pointer, metadata) + + source = Source.new(code) + loader = Serialize::Loader.new(source, buffer.read) + + tokens = loader.load_tokens + node, comments, errors, warnings = loader.load_nodes + + tokens.each { |token,| token.value.force_encoding(loader.encoding) } + + ParseResult.new([node, tokens], comments, errors, warnings, source) + end + end + + # Mirror the Prism.parse_lex_file API by using the serialization API. + def self.parse_lex_file(filepath) + LibRubyParser::PrismString.with(filepath) do |string| + parse_lex(string.read, filepath) + end + end +end diff --git a/lib/yarp/lex_compat.rb b/lib/prism/lex_compat.rb similarity index 94% rename from lib/yarp/lex_compat.rb rename to lib/prism/lex_compat.rb index 37bfecd0bca934..afc0f3b605d368 100644 --- a/lib/yarp/lex_compat.rb +++ b/lib/prism/lex_compat.rb @@ -2,14 +2,14 @@ require "delegate" -module YARP - # This class is responsible for lexing the source using YARP and then +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 - # This is a mapping of YARP token types to Ripper token types. This is a + # 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 = { @@ -128,6 +128,7 @@ class LexCompat 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, @@ -338,8 +339,8 @@ def to_a # 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. YARP only modifies the node itself and keeps - # the token the same. This simplifies YARP, but makes comparing against + # 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 @@ -562,7 +563,7 @@ def result state = :default heredoc_stack = [[]] - result = YARP.lex(source, @filepath) + result = Prism.lex(source, @filepath) result_value = result.value previous_state = nil @@ -649,7 +650,7 @@ def result 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. YARP sets lex state + # 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 @@ -705,7 +706,7 @@ def result # 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 YARP, we skip forward and lex the rest of the content of + # 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. # @@ -794,48 +795,44 @@ def result end end - # The constant that wraps the behavior of the lexer to match Ripper's output - # is an implementation detail, so we don't want it to be public. - private_constant :LexCompat + # This is a class that wraps the Ripper lexer to produce almost exactly the + # same tokens. + class LexRipper + attr_reader :source - # Returns an array of tokens that closely resembles that of the Ripper lexer. - # The only difference is that since we don't keep track of lexer state in the - # same way, it's going to always return the NONE state. - def self.lex_compat(source, filepath = "") - LexCompat.new(source, filepath).result - end + def initialize(source) + @source = source + end - # 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) - 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] + 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 - else - results << token - previous = token end - end - results + results + end end end diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb new file mode 100644 index 00000000000000..08d9e9f36af398 --- /dev/null +++ b/lib/prism/node_ext.rb @@ -0,0 +1,55 @@ +# 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 + 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 InterpolatedRegularExpressionNode < Node + # 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 RationalNode < Node + # Returns the value of the node as a Ruby Rational. + def value + Rational(slice.chomp("r")) + end + end + + class RegularExpressionNode < Node + # 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 +end diff --git a/lib/prism/node_inspector.rb b/lib/prism/node_inspector.rb new file mode 100644 index 00000000000000..be5b3532db791b --- /dev/null +++ b/lib/prism/node_inspector.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Prism + # This object is responsible for generating the output for the inspect method + # implementations of child nodes. + class NodeInspector + 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/yarp/pack.rb b/lib/prism/pack.rb similarity index 99% rename from lib/yarp/pack.rb rename to lib/prism/pack.rb index 83f5569923eecf..5c5f0a34fef904 100644 --- a/lib/yarp/pack.rb +++ b/lib/prism/pack.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module YARP +module Prism module Pack %i[ SPACE diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb new file mode 100644 index 00000000000000..fafa1ae15f5045 --- /dev/null +++ b/lib/prism/parse_result.rb @@ -0,0 +1,266 @@ +# 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 + attr_reader :source, :offsets + + def initialize(source, offsets = compute_offsets(source)) + @source = source + @offsets = offsets + end + + def slice(offset, length) + source.byteslice(offset, length) + end + + def line(value) + offsets.bsearch_index { |offset| offset > value } || offsets.length + end + + def line_offset(value) + offsets[line(value) - 1] + end + + def column(value) + value - offsets[line(value) - 1] + end + + private + + 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 + + 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 + "#" + end + + # The source code that this location represents. + def slice + source.slice(start_offset, length) + end + + # The byte offset from the beginning of the source where this location ends. + def end_offset + start_offset + length + 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_offset(start_offset) + source.slice(offset, start_offset - offset) + end + + # The line number where this location ends. + def end_line + source.line(end_offset - 1) + 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 bytes where this location ends from the start of the + # line. + def end_column + source.column(end_offset) + end + + def deconstruct_keys(keys) + { start_offset: start_offset, end_offset: end_offset } + end + + def pretty_print(q) + q.text("(#{start_line},#{start_column})-(#{end_line},#{end_column}))") + end + + 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 + + def self.null + new(0, 0) + end + end + + # This represents a comment that was encountered during parsing. + class Comment + TYPES = [:inline, :embdoc, :__END__] + + attr_reader :type, :location + + def initialize(type, location) + @type = type + @location = location + end + + def deconstruct_keys(keys) + { type: type, location: location } + end + + # Returns true if the comment happens on the same line as other code and false if the comment is by itself + def trailing? + type == :inline && !location.start_line_slice.strip.empty? + end + + def inspect + "#" + end + end + + # This represents an error that was encountered during parsing. + class ParseError + attr_reader :message, :location + + def initialize(message, location) + @message = message + @location = location + end + + def deconstruct_keys(keys) + { message: message, location: location } + end + + def inspect + "#" + end + end + + # This represents a warning that was encountered during parsing. + class ParseWarning + attr_reader :message, :location + + def initialize(message, location) + @message = message + @location = location + end + + def deconstruct_keys(keys) + { message: message, location: location } + end + + def 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 + attr_reader :value, :comments, :errors, :warnings, :source + + def initialize(value, comments, errors, warnings, source) + @value = value + @comments = comments + @errors = errors + @warnings = warnings + @source = source + end + + def deconstruct_keys(keys) + { value: value, comments: comments, errors: errors, warnings: warnings } + end + + def success? + errors.empty? + end + + def failure? + !success? + end + end + + # This represents a token from the Ruby source. + class Token + attr_reader :type, :value, :location + + def initialize(type, value, location) + @type = type + @value = value + @location = location + end + + def deconstruct_keys(keys) + { type: type, value: value, location: location } + end + + 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 + + def ==(other) + other.is_a?(Token) && + other.type == type && + other.value == value + end + end +end diff --git a/lib/yarp/parse_result/comments.rb b/lib/prism/parse_result/comments.rb similarity index 99% rename from lib/yarp/parse_result/comments.rb rename to lib/prism/parse_result/comments.rb index 88240609b16c4d..fba0b1a5aa5bf8 100644 --- a/lib/yarp/parse_result/comments.rb +++ b/lib/prism/parse_result/comments.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module YARP +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 diff --git a/lib/yarp/parse_result/newlines.rb b/lib/prism/parse_result/newlines.rb similarity index 99% rename from lib/yarp/parse_result/newlines.rb rename to lib/prism/parse_result/newlines.rb index d16600afd0d4fb..334f3f2a69bc0f 100644 --- a/lib/yarp/parse_result/newlines.rb +++ b/lib/prism/parse_result/newlines.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -module YARP +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 diff --git a/lib/yarp/pattern.rb b/lib/prism/pattern.rb similarity index 88% rename from lib/yarp/pattern.rb rename to lib/prism/pattern.rb index 339f1506c35cb1..3d7d5bea70a08e 100644 --- a/lib/yarp/pattern.rb +++ b/lib/prism/pattern.rb @@ -1,24 +1,24 @@ # frozen_string_literal: true -module YARP +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: :YARP], ConstantReadNode[name: :Pattern]] + # in ConstantPathNode[ConstantReadNode[name: :Prism], ConstantReadNode[name: :Pattern]] # end # # the pattern is the `ConstantPathNode[...]` expression. # # The pattern gets compiled into an object that responds to #call by running - # the #compile method. This method itself will run back through YARP to + # 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 = YARP::Pattern.new("ConstantPathNode[ConstantReadNode[name: :YARP], ConstantReadNode[name: :Pattern]]").compile + # 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 @@ -32,7 +32,7 @@ module YARP # # 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 YARP::Pattern::CompilationError will be + # 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 @@ -40,15 +40,15 @@ class Pattern class CompilationError < StandardError def initialize(repr) super(<<~ERROR) - YARP was unable to compile the pattern you provided into a usable + 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 YARP's patterns. If you're using some 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/yarp/issues/new. + GitHub at https://github.com/ruby/prism/issues/new. ERROR end end @@ -61,7 +61,7 @@ def initialize(query) end def compile - result = YARP.parse("case nil\nin #{query}\nend") + result = Prism.parse("case nil\nin #{query}\nend") compile_node(result.value.statements.body.last.conditions.last.pattern) end @@ -73,7 +73,7 @@ def scan(root) while (node = queue.shift) yield node if @compiled.call(node) - queue.concat(node.child_nodes.compact) + queue.concat(node.compact_child_nodes) end end @@ -126,11 +126,11 @@ def compile_alternation_pattern_node(node) combine_or(compile_node(node.left), compile_node(node.right)) end - # in YARP::ConstantReadNode + # in Prism::ConstantReadNode def compile_constant_path_node(node) parent = node.parent - if parent.is_a?(ConstantReadNode) && parent.slice == "YARP" + if parent.is_a?(ConstantReadNode) && parent.slice == "Prism" compile_node(node.child) else compile_error(node) @@ -142,8 +142,8 @@ def compile_constant_path_node(node) def compile_constant_read_node(node) value = node.slice - if YARP.const_defined?(value, false) - clazz = YARP.const_get(value) + if Prism.const_defined?(value, false) + clazz = Prism.const_get(value) ->(other) { clazz === other } elsif Object.const_defined?(value, false) diff --git a/lib/prism/prism.gemspec b/lib/prism/prism.gemspec new file mode 100644 index 00000000000000..0204ecc75f92fc --- /dev/null +++ b/lib/prism/prism.gemspec @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "prism" + spec.version = "0.13.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/mapping.md", + "docs/prism.png", + "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/enc/pm_encoding.h", + "include/prism/node.h", + "include/prism/pack.h", + "include/prism/parser.h", + "include/prism/regexp.h", + "include/prism/unescape.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_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/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/enc/pm_big5.c", + "src/enc/pm_euc_jp.c", + "src/enc/pm_gbk.c", + "src/enc/pm_shift_jis.c", + "src/enc/pm_tables.c", + "src/enc/pm_unicode.c", + "src/enc/pm_windows_31j.c", + "src/node.c", + "src/pack.c", + "src/prettyprint.c", + "src/regexp.c", + "src/serialize.c", + "src/token_type.c", + "src/unescape.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/prism.c", + "prism.gemspec", + ] + + spec.extensions = ["ext/prism/extconf.rb"] + spec.metadata["allowed_push_host"] = "https://rubygems.org" +end diff --git a/lib/yarp/ripper_compat.rb b/lib/prism/ripper_compat.rb similarity index 96% rename from lib/yarp/ripper_compat.rb rename to lib/prism/ripper_compat.rb index c76f3fd07ad153..e0064196ea3855 100644 --- a/lib/yarp/ripper_compat.rb +++ b/lib/prism/ripper_compat.rb @@ -2,14 +2,14 @@ require "ripper" -module YARP - # This class is meant to provide a compatibility layer between YARP and +module Prism + # 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 YARP. It is also - # meant as a test harness for the YARP parser. + # is meant as a stopgap until developers migrate to using prism. It is also + # meant as a test harness for the prism parser. class RipperCompat # This class mirrors the ::Ripper::SexpBuilder subclass of ::Ripper that # returns the arrays of [type, *children]. @@ -156,7 +156,7 @@ def bounds(location) end def result - @result ||= YARP.parse(source) + @result ||= Prism.parse(source) end def _dispatch0; end diff --git a/lib/pstore.rb b/lib/pstore.rb index 97df3c1509b86b..2d162f3d1ab03e 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -517,8 +517,8 @@ def path end # Exits the current transaction block, committing any changes - # specified in the transaction block. - # See {Committing or Aborting}[rdoc-ref:PStore@Committing+or+Aborting]. + # specified in the + # {transaction block}[rdoc-ref:PStore@The+Transaction+Block]. # # Raises an exception if called outside a transaction block. def commit @@ -528,8 +528,8 @@ def commit end # Exits the current transaction block, discarding any changes - # specified in the transaction block. - # See {Committing or Aborting}[rdoc-ref:PStore@Committing+or+Aborting]. + # specified in the + # {transaction block}[rdoc-ref:PStore@The+Transaction+Block]. # # Raises an exception if called outside a transaction block. def abort diff --git a/lib/random/formatter.rb b/lib/random/formatter.rb index 45b53a7b6e620e..7fe7785e1ab534 100644 --- a/lib/random/formatter.rb +++ b/lib/random/formatter.rb @@ -174,6 +174,125 @@ def uuid "%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 with Kernel#srand, which + # can only affect the random bits. The sorted bits will still be based on + # Process.clock_gettime. + # + # 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 extra_timestamp_bits: 12 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 + private def gen_random(n) self.bytes(n) end diff --git a/lib/reline/config.rb b/lib/reline/config.rb index 87726393a6622a..4c07a737017c09 100644 --- a/lib/reline/config.rb +++ b/lib/reline/config.rb @@ -252,7 +252,7 @@ def handle_directive(directive, file, no) end @skip_section = @if_stack.pop when 'include' - read(args) + read(File.expand_path(args)) end end diff --git a/lib/reline/general_io.rb b/lib/reline/general_io.rb index dd2e87eaf0a441..eaae63f925daf4 100644 --- a/lib/reline/general_io.rb +++ b/lib/reline/general_io.rb @@ -3,7 +3,11 @@ class Reline::GeneralIO def self.reset(encoding: nil) @@pasting = false - @@encoding = encoding + if encoding + @@encoding = encoding + elsif defined?(@@encoding) + remove_class_variable(:@@encoding) + end end def self.encoding diff --git a/lib/reline/unicode/east_asian_width.rb b/lib/reline/unicode/east_asian_width.rb index c1c941f7993cc9..fa16a1bb560e74 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.0.0' + # UNICODE_VERSION = '15.1.0' # 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{2FFB} + \u{2FF0}-\u{2FFF} \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{31F0}-\u{321E} + \u{31EF}-\u{321E} \u{3220}-\u{3247} \u{3250}-\u{4DBF} \u{4E00}-\u{A48C} diff --git a/lib/rubygems.rb b/lib/rubygems.rb index cb716570187433..557d7aa8eb3f4a 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -604,6 +604,16 @@ def self.load_yaml @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. # diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index 4aa74fd29c693a..6246737847d9ee 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -133,9 +133,9 @@ def full_gem_path def full_name if platform == Gem::Platform::RUBY || platform.nil? - "#{name}-#{version}".dup.tap(&Gem::UNTAINT) + (+"#{name}-#{version}").tap(&Gem::UNTAINT) else - "#{name}-#{version}-#{platform}".dup.tap(&Gem::UNTAINT) + (+"#{name}-#{version}-#{platform}").tap(&Gem::UNTAINT) end end diff --git a/lib/rubygems/commands/open_command.rb b/lib/rubygems/commands/open_command.rb index 5a13074a1d02b1..f342fa6c6b4290 100644 --- a/lib/rubygems/commands/open_command.rb +++ b/lib/rubygems/commands/open_command.rb @@ -70,9 +70,7 @@ def open_gem(name) end def open_editor(path) - Dir.chdir(path) do - system(*@editor.split(/\s+/) + [path]) - end + system(*@editor.split(/\s+/) + [path], { :chdir => path }) end def spec_for(name) diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb index c6691517b38dab..f4c981b9efc640 100644 --- a/lib/rubygems/indexer.rb +++ b/lib/rubygems/indexer.rb @@ -411,7 +411,8 @@ def update_index # +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) + Gem.load_safe_marshal + specs_index = Gem::SafeMarshal.safe_load Gem.read_binary(source) index.each do |spec| platform = spec.original_platform diff --git a/lib/rubygems/package.rb b/lib/rubygems/package.rb index ba05fadbaf679b..5dcc3ce858de39 100644 --- a/lib/rubygems/package.rb +++ b/lib/rubygems/package.rb @@ -413,6 +413,8 @@ def extract_files(destination_dir, pattern = "*") # extracted. def extract_tar_gz(io, destination_dir, pattern = "*") # :nodoc: + destination_dir = File.realpath(destination_dir) + directories = [] symlinks = [] diff --git a/lib/rubygems/safe_marshal.rb b/lib/rubygems/safe_marshal.rb new file mode 100644 index 00000000000000..b81d1a0a475a00 --- /dev/null +++ b/lib/rubygems/safe_marshal.rb @@ -0,0 +1,74 @@ +# 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 new file mode 100644 index 00000000000000..067ab59d19d6e4 --- /dev/null +++ b/lib/rubygems/safe_marshal/elements.rb @@ -0,0 +1,138 @@ +# 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 + end + end +end diff --git a/lib/rubygems/safe_marshal/reader.rb b/lib/rubygems/safe_marshal/reader.rb new file mode 100644 index 00000000000000..c2c2295086124a --- /dev/null +++ b/lib/rubygems/safe_marshal/reader.rb @@ -0,0 +1,299 @@ +# 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 + + 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 + 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 + 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 + raise NotImplementedError, "Reading Marshal objects of type user_class is not implemented" + end + end + end +end diff --git a/lib/rubygems/safe_marshal/visitors/stream_printer.rb b/lib/rubygems/safe_marshal/visitors/stream_printer.rb new file mode 100644 index 00000000000000..162b36ad0541e9 --- /dev/null +++ b/lib/rubygems/safe_marshal/visitors/stream_printer.rb @@ -0,0 +1,31 @@ +# 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 new file mode 100644 index 00000000000000..58c44fa8bf2789 --- /dev/null +++ b/lib/rubygems/safe_marshal/visitors/to_ruby.rb @@ -0,0 +1,385 @@ +# 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 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 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 new file mode 100644 index 00000000000000..c9a079dc0ea593 --- /dev/null +++ b/lib/rubygems/safe_marshal/visitors/visitor.rb @@ -0,0 +1,74 @@ +# 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/source.rb b/lib/rubygems/source.rb index 8b3a8828d140db..7c5b746a439fa8 100644 --- a/lib/rubygems/source.rb +++ b/lib/rubygems/source.rb @@ -135,8 +135,9 @@ def fetch_spec(name_tuple) if File.exist? local_spec spec = Gem.read_binary local_spec + Gem.load_safe_marshal spec = begin - Marshal.load(spec) + Gem::SafeMarshal.safe_load(spec) rescue StandardError nil end @@ -157,8 +158,9 @@ def fetch_spec(name_tuple) end end + Gem.load_safe_marshal # TODO: Investigate setting Gem::Specification#loaded_from to a URI - Marshal.load spec + Gem::SafeMarshal.safe_load spec end ## @@ -188,8 +190,9 @@ def load_specs(type) spec_dump = fetcher.cache_update_path spec_path, local_file, update_cache? + Gem.load_safe_marshal begin - Gem::NameTuple.from_list Marshal.load(spec_dump) + Gem::NameTuple.from_list Gem::SafeMarshal.safe_load(spec_dump) rescue ArgumentError if update_cache? && !retried FileUtils.rm local_file diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index 0b9bf143dfb698..c8b561e04a55ab 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -1300,12 +1300,13 @@ def self.unresolved_deps def self._load(str) Gem.load_yaml + Gem.load_safe_marshal yaml_set = false retry_count = 0 array = begin - Marshal.load str + Gem::SafeMarshal.safe_load str rescue ArgumentError => e # Avoid an infinite retry loop when the argument error has nothing to do # with the classes not being defined. @@ -2362,12 +2363,12 @@ def ruby_code(obj) when Hash then seg = obj.keys.sort.map {|k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" } "{ #{seg.join(", ")} }" - when Gem::Version then obj.to_s.dump + when Gem::Version then ruby_code(obj.to_s) 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(#{obj.to_a.inspect})" + when Gem::Platform then "Gem::Platform.new(#{ruby_code obj.to_a})" when Gem::Requirement then list = obj.as_list "Gem::Requirement.new(#{ruby_code(list.size == 1 ? obj.to_s : list)})" @@ -2532,12 +2533,12 @@ def to_ruby end if String === signing_key - result << " s.signing_key = #{signing_key.dump}.freeze" + result << " s.signing_key = #{ruby_code signing_key}" end if @installed_by_version result << nil - result << " s.installed_by_version = \"#{Gem::VERSION}\" if s.respond_to? :installed_by_version" + result << " s.installed_by_version = #{ruby_code Gem::VERSION} if s.respond_to? :installed_by_version" end unless dependencies.empty? @@ -2546,9 +2547,8 @@ def to_ruby 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, #{req})" + result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{ruby_code dep.requirements_list})" end end diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb index a3793eaa205452..5953db0d64fe9b 100644 --- a/lib/rubygems/stub_specification.rb +++ b/lib/rubygems/stub_specification.rb @@ -35,7 +35,7 @@ class StubLine # :nodoc: all def initialize(data, extensions) parts = data[PREFIX.length..-1].split(" ", 4) - @name = parts[0].freeze + @name = -parts[0] @version = if Gem::Version.correct?(parts[1]) Gem::Version.new(parts[1]) else @@ -113,14 +113,19 @@ def data Gem.open_file loaded_from, OPEN_MODE do |file| file.readline # discard encoding line - stubline = file.readline.chomp + stubline = file.readline if stubline.start_with?(PREFIX) - extensions = if /\A#{PREFIX}/ =~ file.readline.chomp - $'.split "\0" - else - StubLine::NO_EXTENSIONS - end + extline = file.readline + extensions = + if extline.delete_prefix!(PREFIX) + extline.chomp! + extline.split "\0" + else + StubLine::NO_EXTENSIONS + end + + stubline.chomp! # readline(chomp: true) allocates 3x as much as .readline.chomp! @data = StubLine.new stubline, extensions end rescue EOFError diff --git a/lib/rubygems/yaml_serializer.rb b/lib/rubygems/yaml_serializer.rb index a447709c745d24..584762851493a4 100644 --- a/lib/rubygems/yaml_serializer.rb +++ b/lib/rubygems/yaml_serializer.rb @@ -54,8 +54,8 @@ def load(str) str.split(/\r?\n/).each do |line| if match = HASH_REGEX.match(line) indent, key, quote, val = match.captures - key = convert_to_backward_compatible_key(key) - depth = indent.scan(/ /).length + convert_to_backward_compatible_key!(key) + depth = indent.size / 2 if quote.empty? && val.empty? new_hash = {} stack[depth][key] = new_hash @@ -76,14 +76,13 @@ def load(str) end # for settings' keys - def convert_to_backward_compatible_key(key) - key = "#{key}/" if key =~ /https?:/i && key !~ %r{/\Z} - key = key.gsub(".", "__") if key.include?(".") - key + 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 + private :dump_hash, :convert_to_backward_compatible_key! end end end diff --git a/lib/yarp.rb b/lib/yarp.rb deleted file mode 100644 index f878e719cc32af..00000000000000 --- a/lib/yarp.rb +++ /dev/null @@ -1,601 +0,0 @@ -# frozen_string_literal: true - -module YARP - # 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 - attr_reader :source, :offsets - - def initialize(source, offsets = compute_offsets(source)) - @source = source - @offsets = offsets - end - - def slice(offset, length) - source.byteslice(offset, length) - end - - def line(value) - offsets.bsearch_index { |offset| offset > value } || offsets.length - end - - def line_offset(value) - offsets[line(value) - 1] - end - - def column(value) - value - offsets[line(value) - 1] - end - - private - - 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 - - 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 - "#" - end - - # The source code that this location represents. - def slice - source.slice(start_offset, length) - end - - # The byte offset from the beginning of the source where this location ends. - def end_offset - start_offset + length - 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_offset(start_offset) - source.slice(offset, start_offset - offset) - end - - # The line number where this location ends. - def end_line - source.line(end_offset - 1) - 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 bytes where this location ends from the start of the - # line. - def end_column - source.column(end_offset) - end - - def deconstruct_keys(keys) - { start_offset: start_offset, end_offset: end_offset } - end - - def pretty_print(q) - q.text("(#{start_offset}...#{end_offset})") - end - - 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 - - def self.null - new(0, 0) - end - end - - # This represents a comment that was encountered during parsing. - class Comment - TYPES = [:inline, :embdoc, :__END__] - - attr_reader :type, :location - - def initialize(type, location) - @type = type - @location = location - end - - def deconstruct_keys(keys) - { type: type, location: location } - end - - # Returns true if the comment happens on the same line as other code and false if the comment is by itself - def trailing? - type == :inline && !location.start_line_slice.strip.empty? - end - - def inspect - "#" - end - end - - # This represents an error that was encountered during parsing. - class ParseError - attr_reader :message, :location - - def initialize(message, location) - @message = message - @location = location - end - - def deconstruct_keys(keys) - { message: message, location: location } - end - - def inspect - "#" - end - end - - # This represents a warning that was encountered during parsing. - class ParseWarning - attr_reader :message, :location - - def initialize(message, location) - @message = message - @location = location - end - - def deconstruct_keys(keys) - { message: message, location: location } - end - - def inspect - "#" - end - end - - # 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 - def visit(node) - node&.accept(self) - end - - def visit_all(nodes) - nodes.map { |node| visit(node) } - end - - def visit_child_nodes(node) - visit_all(node.child_nodes) - end - end - - class Visitor < BasicVisitor - 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 - attr_reader :value, :comments, :errors, :warnings, :source - - def initialize(value, comments, errors, warnings, source) - @value = value - @comments = comments - @errors = errors - @warnings = warnings - @source = source - end - - def deconstruct_keys(keys) - { value: value, comments: comments, errors: errors, warnings: warnings } - end - - def success? - errors.empty? - end - - def failure? - !success? - end - end - - # This represents a token from the Ruby source. - class Token - attr_reader :type, :value, :location - - def initialize(type, value, location) - @type = type - @value = value - @location = location - end - - def deconstruct_keys(keys) - { type: type, value: value, location: location } - end - - 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 - - def ==(other) - other.is_a?(Token) && - other.type == type && - other.value == value - end - end - - # This represents a node in the tree. - class Node - attr_reader :location - - def newline? - @newline ? true : false - end - - def set_newline_flag(newline_marked) - 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 - - def pretty_print(q) - q.group do - q.text(self.class.name.split("::").last) - location.pretty_print(q) - q.text("[Li:#{location.start_line}]") if newline? - q.text("(") - q.nest(2) do - deconstructed = deconstruct_keys([]) - deconstructed.delete(:location) - q.breakable("") - q.seplist(deconstructed, lambda { q.comma_breakable }, :each_value) { |value| q.pp(value) } - end - q.breakable("") - q.text(")") - end - end - end - - # This object is responsible for generating the output for the inspect method - # implementations of child nodes. - class NodeInspector - 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_offset}...#{node.location.end_offset})" - 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_offset}...#{value.end_offset}) = #{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 - - class FloatNode < Node - def value - Float(slice) - end - end - - class ImaginaryNode < Node - def value - Complex(0, numeric.value) - end - end - - class IntegerNode < Node - def value - Integer(slice) - end - end - - class RationalNode < Node - def value - Rational(slice.chomp("r")) - end - end - - # Load the serialized AST using the source as a reference into a tree. - def self.load(source, serialized) - Serialize.load(source, serialized) - end - - # This module is used for testing and debugging and is not meant to be used by - # consumers of this library. - module Debug - class ISeq - attr_reader :parts - - def initialize(parts) - @parts = parts - end - - def type - parts[0] - end - - def local_table - parts[10] - end - - def instructions - parts[13] - end - - def each_child - instructions.each do |instruction| - # Only look at arrays. Other instructions are line numbers or - # tracepoint events. - next unless instruction.is_a?(Array) - - instruction.each do |opnd| - # Only look at arrays. Other operands are literals. - next unless opnd.is_a?(Array) - - # Only look at instruction sequences. Other operands are literals. - next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat" - - yield ISeq.new(opnd) - end - end - end - end - - # 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) - if iseq.type != :once - names = iseq.local_table - - # CRuby will push on a special local variable when there are keyword - # arguments. We get rid of that here. - names = names.grep_v(Integer) - - # TODO: We don't support numbered local variables yet, so we get rid - # of those here. - names = names.grep_v(/^_\d$/) - - # For some reason, CRuby occasionally pushes this special local - # variable when there are splat arguments. We get rid of that here. - names = names.grep_v(:"#arg_rest") - - # Now push them onto the list of locals. - locals << names - end - - iseq.each_child { |child| stack << child } - end - - locals - ensure - $VERBOSE = verbose - end - end - - # For the given source, parses with YARP and returns a list of all of the - # sets of local variables that were encountered. - def self.yarp_locals(source) - locals = [] - stack = [YARP.parse(source).value] - - while (node = stack.pop) - case node - when BlockNode, DefNode, LambdaNode - names = node.locals - - params = node.parameters - params = params&.parameters unless node.is_a?(DefNode) - - # YARP 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.grep(RequiredParameterNode).map(&:name), - *params.optionals.map(&:name), - *((params.rest.name || :*) if params.rest && params.rest.operator != ","), - *params.posts.grep(RequiredParameterNode).map(&:name), - *params.keywords.reject(&:value).map(&:name), - *params.keywords.select(&:value).map(&:name) - ] - - # TODO: When we get a ... parameter, we should be pushing * and & - # onto the local list. We don't do that yet, so we need to add them - # in here. - if params.keyword_rest.is_a?(ForwardingParameterNode) - sorted.push(:*, :&, :"...") - end - - # Recurse down the parameter tree to find any destructured - # parameters and add them after the other parameters. - param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse - while (param = param_stack.pop) - case param - when RequiredDestructuredParameterNode - param_stack.concat(param.parameters.reverse) - when RequiredParameterNode - sorted << param.name - when SplatNode - sorted << param.expression.name if param.expression - end - end - - names = sorted.concat(names - sorted) - end - - locals << names - when ClassNode, ModuleNode, ProgramNode, SingletonClassNode - locals << node.locals - when ForNode - locals << [] - when PostExecutionNode - locals.push([], []) - when InterpolatedRegularExpressionNode - locals << [] if node.once? - end - - stack.concat(node.child_nodes.compact) - end - - locals - end - - def self.newlines(source) - YARP.parse(source).source.offsets - end - - def self.parse_serialize_file(filepath) - parse_serialize_file_metadata(filepath, [filepath.bytesize, filepath.b, 0].pack("LA*L")) - end - end - - # Marking this as private so that consumers don't see it. It makes it a little - # annoying for testing since you have to const_get it to access the methods, - # but at least this way it's clear it's not meant for consumers. - private_constant :Debug -end - -require_relative "yarp/lex_compat" -require_relative "yarp/mutation_visitor" -require_relative "yarp/desugar_visitor" -require_relative "yarp/node" -require_relative "yarp/ripper_compat" -require_relative "yarp/serialize" -require_relative "yarp/pack" -require_relative "yarp/pattern" - -require_relative "yarp/parse_result/comments" -require_relative "yarp/parse_result/newlines" - -if RUBY_ENGINE == "ruby" and !ENV["YARP_FFI_BACKEND"] - require "yarp/yarp" -else - require_relative "yarp/ffi" -end diff --git a/lib/yarp/desugar_visitor.rb b/lib/yarp/desugar_visitor.rb deleted file mode 100644 index 6ee5861ac8b390..00000000000000 --- a/lib/yarp/desugar_visitor.rb +++ /dev/null @@ -1,204 +0,0 @@ -# frozen_string_literal: true - -module YARP - class DesugarVisitor < MutationVisitor - # @@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( - read_class.new(*arguments, node.name_loc), - nil, - node.operator_loc.copy(length: node.operator_loc.length - 1), - nil, - ArgumentsNode.new([node.value], node.value.location), - nil, - nil, - 0, - node.operator_loc.slice.chomp("="), - 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), - 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/yarp/ffi.rb b/lib/yarp/ffi.rb deleted file mode 100644 index 26b6019b27f894..00000000000000 --- a/lib/yarp/ffi.rb +++ /dev/null @@ -1,252 +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 YARP - BACKEND = :FFI - - module LibRubyParser - 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/librubyparser.#{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.delete_prefix("const ") - type.end_with?("*") ? :pointer : type.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?("YP_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 /^YP_EXPORTED_FUNCTION (?.+) (?\w+)\((?.+)\);$/ =~ 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( - "yarp.h", - "yp_version", - "yp_parse_serialize", - "yp_lex_serialize", - "yp_parse_lex_serialize" - ) - - load_exported_functions_from( - "yarp/util/yp_buffer.h", - "yp_buffer_sizeof", - "yp_buffer_init", - "yp_buffer_value", - "yp_buffer_length", - "yp_buffer_free" - ) - - load_exported_functions_from( - "yarp/util/yp_string.h", - "yp_string_mapped_init", - "yp_string_free", - "yp_string_source", - "yp_string_length", - "yp_string_sizeof" - ) - - # This object represents a yp_buffer_t. We only use it as an opaque pointer, - # so it doesn't need to know the fields of yp_buffer_t. - class YPBuffer - SIZEOF = LibRubyParser.yp_buffer_sizeof - - attr_reader :pointer - - def initialize(pointer) - @pointer = pointer - end - - def value - LibRubyParser.yp_buffer_value(pointer) - end - - def length - LibRubyParser.yp_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.yp_buffer_init(pointer) - yield new(pointer) - ensure - LibRubyParser.yp_buffer_free(pointer) - pointer.free - end - end - end - - # This object represents a yp_string_t. We only use it as an opaque pointer, - # so it doesn't have to be an FFI::Struct. - class YPString - SIZEOF = LibRubyParser.yp_string_sizeof - - attr_reader :pointer - - def initialize(pointer) - @pointer = pointer - end - - def source - LibRubyParser.yp_string_source(pointer) - end - - def length - LibRubyParser.yp_string_length(pointer) - end - - def read - source.read_string(length) - end - - # Yields a yp_string_t pointer to the given block. - def self.with(filepath, &block) - pointer = FFI::MemoryPointer.new(SIZEOF) - - begin - raise unless LibRubyParser.yp_string_mapped_init(pointer, filepath) - yield new(pointer) - ensure - LibRubyParser.yp_string_free(pointer) - pointer.free - end - end - end - end - - # Mark the LibRubyParser module as private as it should only be called through - # the YARP module. - private_constant :LibRubyParser - - # The version constant is set by reading the result of calling yp_version. - VERSION = LibRubyParser.yp_version.read_string - - def self.dump_internal(source, source_size, filepath) - LibRubyParser::YPBuffer.with do |buffer| - metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath - LibRubyParser.yp_parse_serialize(source, source_size, buffer.pointer, metadata) - buffer.read - end - end - private_class_method :dump_internal - - # Mirror the YARP.dump API by using the serialization API. - def self.dump(code, filepath = nil) - dump_internal(code, code.bytesize, filepath) - end - - # Mirror the YARP.dump_file API by using the serialization API. - def self.dump_file(filepath) - LibRubyParser::YPString.with(filepath) do |string| - dump_internal(string.source, string.length, filepath) - end - end - - # Mirror the YARP.lex API by using the serialization API. - def self.lex(code, filepath = nil) - LibRubyParser::YPBuffer.with do |buffer| - LibRubyParser.yp_lex_serialize(code, code.bytesize, filepath, buffer.pointer) - Serialize.load_tokens(Source.new(code), buffer.read) - end - end - - # Mirror the YARP.lex_file API by using the serialization API. - def self.lex_file(filepath) - LibRubyParser::YPString.with(filepath) do |string| - lex(string.read, filepath) - end - end - - # Mirror the YARP.parse API by using the serialization API. - def self.parse(code, filepath = nil) - YARP.load(code, dump(code, filepath)) - end - - # Mirror the YARP.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 self.parse_file(filepath) - LibRubyParser::YPString.with(filepath) do |string| - parse(string.read, filepath) - end - end - - # Mirror the YARP.parse_lex API by using the serialization API. - def self.parse_lex(code, filepath = nil) - LibRubyParser::YPBuffer.with do |buffer| - metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath - LibRubyParser.yp_parse_lex_serialize(code, code.bytesize, buffer.pointer, metadata) - - source = Source.new(code) - loader = Serialize::Loader.new(source, buffer.read) - - tokens = loader.load_tokens - node, comments, errors, warnings = loader.load_nodes - - tokens.each { |token,| token.value.force_encoding(loader.encoding) } - - ParseResult.new([node, tokens], comments, errors, warnings, source) - end - end - - # Mirror the YARP.parse_lex_file API by using the serialization API. - def self.parse_lex_file(filepath) - LibRubyParser::YPString.with(filepath) do |string| - parse_lex(string.read, filepath) - end - end -end diff --git a/lib/yarp/language_server.rb b/lib/yarp/language_server.rb deleted file mode 100644 index 5a10d484a17381..00000000000000 --- a/lib/yarp/language_server.rb +++ /dev/null @@ -1,166 +0,0 @@ -# frozen_string_literal: true - -require "cgi" -require "json" -require "uri" - -module YARP - # YARP additionally ships with a language server conforming to the - # language server protocol. It can be invoked by running the yarp-lsp - # bin script (bin/yarp-lsp) - class LanguageServer - GITHUB_TEMPLATE = <<~TEMPLATE - Reporting issue with error `%{error}`. - - ## Expected behavior - - - ## Actual behavior - - - ## Steps to reproduce the problem - - - ## Additional information - - - TEMPLATE - - attr_reader :input, :output - - def initialize( - input: $stdin, - output: $stdout - ) - @input = input.binmode - @output = output.binmode - end - - # rubocop:disable Layout/LineLength - def run - store = - Hash.new do |hash, uri| - filepath = CGI.unescape(URI.parse(uri).path) - File.exist?(filepath) ? (hash[uri] = File.read(filepath)) : nil - end - - while (headers = input.gets("\r\n\r\n")) - source = input.read(headers[/Content-Length: (\d+)/i, 1].to_i) - request = JSON.parse(source, symbolize_names: true) - - # stree-ignore - case request - in { method: "initialize", id: } - store.clear - write(id: id, result: { capabilities: capabilities }) - in { method: "initialized" } - # ignored - in { method: "shutdown" } # tolerate missing ID to be a good citizen - store.clear - write(id: request[:id], result: {}) - in { method: "exit"} - return - in { method: "textDocument/didChange", params: { textDocument: { uri: }, contentChanges: [{ text: }, *] } } - store[uri] = text - in { method: "textDocument/didOpen", params: { textDocument: { uri:, text: } } } - store[uri] = text - in { method: "textDocument/didClose", params: { textDocument: { uri: } } } - store.delete(uri) - in { method: "textDocument/diagnostic", id:, params: { textDocument: { uri: } } } - contents = store[uri] - write(id: id, result: contents ? diagnostics(contents) : nil) - in { method: "textDocument/codeAction", id:, params: { textDocument: { uri: }, context: { diagnostics: }}} - contents = store[uri] - write(id: id, result: contents ? code_actions(contents, diagnostics) : nil) - in { method: %r{\$/.+} } - # ignored - end - end - end - # rubocop:enable Layout/LineLength - - private - - def capabilities - { - codeActionProvider: { - codeActionKinds: [ - 'quickfix', - ], - }, - diagnosticProvider: { - interFileDependencies: false, - workspaceDiagnostics: false, - }, - textDocumentSync: { - change: 1, - openClose: true - }, - } - end - - def code_actions(source, diagnostics) - diagnostics.map do |diagnostic| - message = diagnostic[:message] - issue_content = URI.encode_www_form_component(GITHUB_TEMPLATE % {error: message}) - issue_link = "https://github.com/ruby/yarp/issues/new?&labels=Bug&body=#{issue_content}" - - { - title: "Report incorrect error: `#{diagnostic[:message]}`", - kind: "quickfix", - diagnostics: [diagnostic], - command: { - title: "Report incorrect error", - command: "vscode.open", - arguments: [issue_link] - } - } - end - end - - def diagnostics(source) - offsets = Hash.new do |hash, key| - slice = source.byteslice(...key) - lineno = slice.count("\n") - - char = slice.length - newline = source.rindex("\n", [char - 1, 0].max) || -1 - hash[key] = { line: lineno, character: char - newline - 1 } - end - - parse_output = YARP.parse(source) - - { - kind: "full", - items: [ - *parse_output.errors.map do |error| - { - range: { - start: offsets[error.location.start_offset], - end: offsets[error.location.end_offset], - }, - message: error.message, - severity: 1, - } - end, - *parse_output.warnings.map do |warning| - { - range: { - start: offsets[warning.location.start_offset], - end: offsets[warning.location.end_offset], - }, - message: warning.message, - severity: 2, - } - end, - ] - } - end - - def write(value) - response = value.merge(jsonrpc: "2.0").to_json - output.print("Content-Length: #{response.bytesize}\r\n\r\n#{response}") - output.flush - end - end -end diff --git a/lib/yarp/version.rb b/lib/yarp/version.rb deleted file mode 100644 index e450bfb526f866..00000000000000 --- a/lib/yarp/version.rb +++ /dev/null @@ -1,5 +0,0 @@ -# frozen_string_literal: true - -module YARP - VERSION = "0.8.0" -end diff --git a/lib/yarp/yarp.gemspec b/lib/yarp/yarp.gemspec deleted file mode 100644 index e96cb8d40346b6..00000000000000 --- a/lib/yarp/yarp.gemspec +++ /dev/null @@ -1,105 +0,0 @@ -# frozen_string_literal: true - -Gem::Specification.new do |spec| - spec.name = "yarp" - spec.version = "0.11.0" - spec.authors = ["Shopify"] - spec.email = ["ruby@shopify.com"] - - spec.summary = "Yet Another Ruby Parser" - spec.homepage = "https://github.com/ruby/yarp" - 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/mapping.md", - "docs/ripper.md", - "docs/ruby_api.md", - "docs/serialization.md", - "docs/testing.md", - "ext/yarp/api_node.c", - "ext/yarp/api_pack.c", - "ext/yarp/extension.c", - "ext/yarp/extension.h", - "include/yarp.h", - "include/yarp/ast.h", - "include/yarp/defines.h", - "include/yarp/diagnostic.h", - "include/yarp/enc/yp_encoding.h", - "include/yarp/node.h", - "include/yarp/pack.h", - "include/yarp/parser.h", - "include/yarp/regexp.h", - "include/yarp/unescape.h", - "include/yarp/util/yp_buffer.h", - "include/yarp/util/yp_char.h", - "include/yarp/util/yp_constant_pool.h", - "include/yarp/util/yp_list.h", - "include/yarp/util/yp_memchr.h", - "include/yarp/util/yp_newline_list.h", - "include/yarp/util/yp_state_stack.h", - "include/yarp/util/yp_string.h", - "include/yarp/util/yp_string_list.h", - "include/yarp/util/yp_strpbrk.h", - "include/yarp/version.h", - "lib/yarp.rb", - "lib/yarp/desugar_visitor.rb", - "lib/yarp/ffi.rb", - "lib/yarp/lex_compat.rb", - "lib/yarp/mutation_visitor.rb", - "lib/yarp/node.rb", - "lib/yarp/pack.rb", - "lib/yarp/pattern.rb", - "lib/yarp/ripper_compat.rb", - "lib/yarp/serialize.rb", - "lib/yarp/parse_result/comments.rb", - "lib/yarp/parse_result/newlines.rb", - "src/diagnostic.c", - "src/enc/yp_big5.c", - "src/enc/yp_euc_jp.c", - "src/enc/yp_gbk.c", - "src/enc/yp_shift_jis.c", - "src/enc/yp_tables.c", - "src/enc/yp_unicode.c", - "src/enc/yp_windows_31j.c", - "src/node.c", - "src/pack.c", - "src/prettyprint.c", - "src/regexp.c", - "src/serialize.c", - "src/token_type.c", - "src/unescape.c", - "src/util/yp_buffer.c", - "src/util/yp_char.c", - "src/util/yp_constant_pool.c", - "src/util/yp_list.c", - "src/util/yp_memchr.c", - "src/util/yp_newline_list.c", - "src/util/yp_state_stack.c", - "src/util/yp_string.c", - "src/util/yp_string_list.c", - "src/util/yp_strncasecmp.c", - "src/util/yp_strpbrk.c", - "src/yarp.c", - "yarp.gemspec", - ] - - spec.extensions = ["ext/yarp/extconf.rb"] - spec.metadata["allowed_push_host"] = "https://rubygems.org" -end diff --git a/man/ruby.1 b/man/ruby.1 index e62decbf56d752..a2b69c3cd65e1e 100644 --- a/man/ruby.1 +++ b/man/ruby.1 @@ -25,6 +25,7 @@ .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 ... @@ -469,6 +470,12 @@ 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 @@ -645,6 +652,61 @@ 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/ diff --git a/math.c b/math.c index 6f0ddf9ec55882..2394fe9f588a4a 100644 --- a/math.c +++ b/math.c @@ -538,6 +538,7 @@ math_log_split(VALUE x, size_t *numbits) # define log_intermediate log2 #else # define log_intermediate log10 +double log2(double x); #endif VALUE @@ -561,14 +562,14 @@ rb_math_log(int argc, const VALUE *argv) return DBL2NUM(-0.0); } d = log_intermediate(d) / log_intermediate(b); - numbits -= numbits_2; + 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; } - d += numbits * M_LN2; return DBL2NUM(d); } @@ -730,7 +731,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 6b60a49a3aac4d..fece2e54c346ce 100644 --- a/method.h +++ b/method.h @@ -101,8 +101,9 @@ static inline void METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src) { dst->flags = - (dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) | - (src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)); + (dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2 + |IMEMO_FL_USER3)) | + (src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER3)); } typedef enum { @@ -178,9 +179,9 @@ typedef struct rb_method_optimized { struct rb_method_definition_struct { BITFIELD(rb_method_type_t, type, VM_METHOD_TYPE_MINIMUM_BITS); unsigned int iseq_overload: 1; - int alias_count : 27; - int complemented_count : 28; unsigned int no_redef_warning: 1; + unsigned int aliased : 1; + int reference_count : 28; union { rb_method_iseq_t iseq; @@ -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) \ @@ -213,7 +214,7 @@ void rb_add_method_optimized(VALUE klass, ID mid, enum method_optimized_type, un void rb_add_refined_method_entry(VALUE refined_class, ID mid); rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex); -rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def); +rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, rb_method_definition_t *def); const rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id); diff --git a/missing/procstat_vm.c b/missing/procstat_vm.c index 76fd8f61ba2b50..155ee355d1a3aa 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) +procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout) { struct kinfo_vmentry *freep, *kve; int ptrwidth; @@ -17,7 +17,7 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) #else ptrwidth = 2*sizeof(void *) + 2; #endif - fprintf(stderr, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n", + fprintf(errout, "%*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) return; for (i = 0; i < cnt; i++) { kve = &freep[i]; - 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, "%#*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, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-"); - fprintf(stderr, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" : + fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-"); + fprintf(errout, "%-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) str = "??"; break; } - fprintf(stderr, "%-2s ", str); - fprintf(stderr, "%-s\n", kve->kve_path); + fprintf(errout, "%-2s ", str); + fprintf(errout, "%-s\n", kve->kve_path); } free(freep); } diff --git a/node.c b/node.c index bd03454befc799..1f0e457f52156b 100644 --- a/node.c +++ b/node.c @@ -17,6 +17,68 @@ #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_SIZE (sizeof(struct RNode) * 16) + +static void +init_node_buffer_elem(node_buffer_elem_t *nbe, size_t allocated, void *xmalloc(size_t)) +{ + 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 */ +} + +static void +init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head, void *xmalloc(size_t)) +{ + init_node_buffer_elem(head, NODE_BUF_DEFAULT_SIZE, xmalloc); + nb->head = nb->last = head; + nb->head->next = NULL; +} + +#ifdef UNIVERSAL_PARSER +#define ruby_xmalloc config->malloc +#define Qnil config->qnil +#endif + +#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 +{ + 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; +} + +#ifdef UNIVERSAL_PARSER +#undef ruby_xmalloc #define ruby_xmalloc ast->node_buffer->config->malloc #undef xfree #define xfree ast->node_buffer->config->free @@ -26,23 +88,16 @@ #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_OBJ_WRITE(old, slot, young) ast->node_buffer->config->obj_write((VALUE)(old), (VALUE *)(slot), (VALUE)(young)) - -#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 +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); /* Setup NODE structure. * NODE is not an object managed by GC, but it imitates an object @@ -51,18 +106,15 @@ * objects. */ void -rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2) +rb_node_init(NODE *n, enum node_type type) { - 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; + 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; } const char * @@ -92,62 +144,13 @@ ruby_node_name(int node) } #endif -static void -init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head) -{ - nb->idx = 0; - nb->len = NODE_BUF_DEFAULT_LEN; - nb->head = nb->last = head; - nb->head->len = nb->len; - nb->head->next = NULL; -} - -#ifdef UNIVERSAL_PARSER -static node_buffer_t * -rb_node_buffer_new(rb_parser_config_t *config) -{ - 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 = config->malloc(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 = config->qnil; - nb->tokens = config->qnil; - nb->config = config; - return nb; -} -#else -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_elem_t *nbe = nb->head; - while (nbe != nb->last) { void *buf = nbe; + xfree(nbe->nodes); nbe = nbe->next; xfree(buf); } @@ -161,9 +164,26 @@ struct rb_ast_local_table_link { // } }; +static void +free_ast_value(rb_ast_t *ast, void *ctx, NODE *node) +{ + switch (nd_type(node)) { + case NODE_ARGS: + xfree(RNODE_ARGS(node)->nd_ainfo); + break; + case NODE_ARYPTN: + xfree(RNODE_ARYPTN(node)->nd_apinfo); + break; + case NODE_FNDPTN: + xfree(RNODE_FNDPTN(node)->nd_fpinfo); + break; + } +} + static void rb_node_buffer_free(rb_ast_t *ast, 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); struct rb_ast_local_table_link *local_table = nb->local_tables; @@ -175,20 +195,31 @@ 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) +ast_newnode_in_bucket(rb_ast_t *ast, node_buffer_list_t *nb, size_t size, size_t alignment) { - if (nb->idx >= nb->len) { - long n = nb->len * 2; + 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; node_buffer_elem_t *nbe; - nbe = rb_xmalloc_mul_add(n, sizeof(NODE), offsetof(node_buffer_elem_t, buf)); - nbe->len = n; - nb->idx = 0; - nb->len = n; + nbe = rb_xmalloc_mul_add(n, sizeof(char *), offsetof(node_buffer_elem_t, buf)); + init_node_buffer_elem(nbe, n, ruby_xmalloc); nbe->next = nb->head; nb->head = nbe; + padding = 0; /* malloc returns aligned address then no need to add padding */ } - return &nb->head->buf[nb->idx++]; + + 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; } RBIMPL_ATTR_PURE() @@ -204,9 +235,6 @@ 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; @@ -214,12 +242,12 @@ nodetype_markable_p(enum node_type type) } NODE * -rb_ast_newnode(rb_ast_t *ast, enum node_type type) +rb_ast_newnode(rb_ast_t *ast, enum node_type type, size_t size, size_t alignment) { 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); + return ast_newnode_in_bucket(ast, bucket, size, alignment); } #if RUBY_DEBUG @@ -284,14 +312,12 @@ rb_ast_new(void) } #endif -typedef void node_itr_t(rb_ast_t *ast, 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) { long cursor; for (cursor = 0; cursor < len; cursor++) { - func(ast, ctx, &nbe->buf[cursor]); + func(ast, ctx, nbe->nodes[cursor]); } } @@ -300,10 +326,6 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo { node_buffer_elem_t *nbe = nb->head; - /* iterate over the head first because it's not full */ - iterate_buffer_elements(ast, nbe, nb->idx, func, ctx); - - nbe = nbe->next; while (nbe) { iterate_buffer_elements(ast, nbe, nbe->len, func, ctx); nbe = nbe->next; @@ -311,19 +333,13 @@ iterate_node_values(rb_ast_t *ast, node_buffer_list_t *nb, node_itr_t * func, vo } static void -mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node) +mark_ast_value(rb_ast_t *ast, 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: @@ -332,11 +348,7 @@ mark_ast_value(rb_ast_t *ast, void *ctx, NODE * node) case NODE_DXSTR: case NODE_DREGX: case NODE_DSYM: - rb_gc_mark_movable(node->nd_lit); - break; - case NODE_ARYPTN: - case NODE_FNDPTN: - rb_gc_mark_movable(node->nd_rval); + rb_gc_mark_movable(RNODE_LIT(node)->nd_lit); break; default: rb_bug("unreachable node %s", ruby_node_name(nd_type(node))); @@ -344,19 +356,13 @@ 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(rb_ast_t *ast, 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: @@ -365,11 +371,7 @@ update_ast_value(rb_ast_t *ast, void *ctx, NODE * node) case NODE_DXSTR: case NODE_DREGX: case NODE_DSYM: - 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); + RNODE_LIT(node)->nd_lit = rb_gc_location(RNODE_LIT(node)->nd_lit); break; default: rb_bug("unreachable"); @@ -423,8 +425,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 +438,7 @@ rb_ast_memsize(const rb_ast_t *ast) node_buffer_t *nb = ast->node_buffer; if (nb) { - size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE); + size += sizeof(node_buffer_t); size += buffer_list_size(&nb->unmarkable); size += buffer_list_size(&nb->markable); } diff --git a/node.h b/node.h index 1f365960fcbcc2..79c0c67860c99a 100644 --- a/node.h +++ b/node.h @@ -19,12 +19,14 @@ typedef void (*bug_report_func)(const char *fmt, ...); typedef struct node_buffer_elem_struct { struct node_buffer_elem_struct *next; - long len; - NODE buf[FLEX_ARY_LEN]; + 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 { - long idx, len; node_buffer_elem_t *head; node_buffer_elem_t *last; } node_buffer_list_t; @@ -50,7 +52,7 @@ RUBY_SYMBOL_EXPORT_BEGIN #ifdef UNIVERSAL_PARSER rb_ast_t *rb_ast_new(rb_parser_config_t *config); #else -rb_ast_t *rb_ast_new(); +rb_ast_t *rb_ast_new(void); #endif size_t rb_ast_memsize(const rb_ast_t*); void rb_ast_dispose(rb_ast_t*); @@ -59,14 +61,14 @@ VALUE rb_ast_tokens(rb_ast_t *ast); 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, VALUE a0, VALUE a1, VALUE a2); +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_free(rb_ast_t*); void rb_ast_add_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); +NODE *rb_ast_newnode(rb_ast_t*, enum node_type type, size_t size, size_t alignment); 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); @@ -100,21 +102,21 @@ RUBY_SYMBOL_EXPORT_END #define NODE_SPECIAL_EXCESSIVE_COMMA ((ID)1) #define NODE_SPECIAL_NO_REST_KEYWORD ((NODE *)-1) -#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_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)((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_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) ((n)->node_id) -#define nd_set_node_id(n,id) ((n)->node_id = (id)) +#define nd_node_id(n) (RNODE(n)->node_id) +#define nd_set_node_id(n,id) (RNODE(n)->node_id = (id)) static inline bool nd_type_p(const NODE *n, enum node_type t) diff --git a/node_dump.c b/node_dump.c index c13403d77ffa25..889fd521d8b500 100644 --- a/node_dump.c +++ b/node_dump.c @@ -60,14 +60,17 @@ #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_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_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, ann) \ - COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);} +#define F_NODE(name, type, ann) \ + COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, type(node)->name);} + +#define F_NODE2(name, n, ann) \ + COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, n);} #define ANN(ann) \ if (comment) { \ @@ -131,14 +134,14 @@ dump_array(VALUE buf, VALUE indent, int comment, const NODE *node) { 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"); + 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, "next element"); + F_NODE(nd_next, RNODE_LIST, "next element"); } static void @@ -167,16 +170,16 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) A_INDENT; rb_str_catf(buf, "+- nd_head (%s%d):\n", comment ? "statement #" : "", ++i); - if (!node->nd_next) LAST_NODE; + if (!RNODE_BLOCK(node)->nd_next) LAST_NODE; D_INDENT; - dump_node(buf, indent, comment, node->nd_head); + dump_node(buf, indent, comment, RNODE_BLOCK(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) { + } 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, "next block"); + F_NODE(nd_next, RNODE_BLOCK, "next block"); } return; @@ -184,65 +187,65 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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"); + F_NODE(nd_cond, RNODE_IF, "condition expr"); + F_NODE(nd_body, RNODE_IF, "then clause"); LAST_NODE; - F_NODE(nd_else, "else clause"); + 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, "condition expr"); - F_NODE(nd_body, "then clause"); + F_NODE(nd_cond, RNODE_UNLESS, "condition expr"); + F_NODE(nd_body, RNODE_UNLESS, "then clause"); LAST_NODE; - F_NODE(nd_else, "else clause"); + 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, "case expr"); + F_NODE(nd_head, RNODE_CASE, "case expr"); LAST_NODE; - F_NODE(nd_body, "when clauses"); + 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, "case expr"); + F_NODE(nd_head, RNODE_CASE2, "case expr"); LAST_NODE; - F_NODE(nd_body, "when clauses"); + 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, "case expr"); + F_NODE(nd_head, RNODE_CASE3, "case expr"); LAST_NODE; - F_NODE(nd_body, "in clauses"); + 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, "when value"); - F_NODE(nd_body, "when body"); + F_NODE(nd_head, RNODE_WHEN, "when value"); + F_NODE(nd_body, RNODE_WHEN, "when body"); LAST_NODE; - F_NODE(nd_next, "next when clause"); + 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, "in pattern"); - F_NODE(nd_body, "in body"); + F_NODE(nd_head, RNODE_IN, "in pattern"); + F_NODE(nd_body, RNODE_IN, "in body"); LAST_NODE; - F_NODE(nd_next, "next in clause"); + F_NODE(nd_next, RNODE_IN, "next in clause"); return; case NODE_WHILE: @@ -256,12 +259,12 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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)"); + A_INT((int)RNODE_WHILE(node)->nd_state); + A((RNODE_WHILE(node)->nd_state == 1) ? " (while-end)" : " (begin-end-while)"); } - F_NODE(nd_cond, "condition"); + F_NODE(nd_cond, RNODE_WHILE, "condition"); LAST_NODE; - F_NODE(nd_body, "body"); + F_NODE(nd_body, RNODE_WHILE, "body"); return; case NODE_ITER: @@ -274,9 +277,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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"); + F_NODE(nd_iter, RNODE_ITER, "iteration receiver"); LAST_NODE; - F_NODE(nd_body, "body"); + F_NODE(nd_body, RNODE_ITER, "body"); return; case NODE_FOR_MASGN: @@ -284,7 +287,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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"); + F_NODE(nd_var, RNODE_FOR_MASGN, "var"); return; case NODE_BREAK: @@ -303,7 +306,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("example: return 1"); jump: LAST_NODE; - F_NODE(nd_stts, "value"); + F_NODE(nd_stts, RNODE_BREAK, "value"); return; case NODE_REDO: @@ -323,36 +326,36 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: begin; [nd_body]; end"); ANN("example: begin; 1; end"); LAST_NODE; - F_NODE(nd_body, "body"); + 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, "body"); - F_NODE(nd_resq, "rescue clause list"); + F_NODE(nd_head, RNODE_RESCUE, "body"); + F_NODE(nd_resq, RNODE_RESCUE, "rescue clause list"); LAST_NODE; - F_NODE(nd_else, "rescue else clause"); + 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, "rescue exceptions"); - F_NODE(nd_body, "rescue clause"); + F_NODE(nd_args, RNODE_RESBODY, "rescue exceptions"); + F_NODE(nd_body, RNODE_RESBODY, "rescue clause"); LAST_NODE; - F_NODE(nd_head, "next rescue clause"); + 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, "body"); + F_NODE(nd_head, RNODE_ENSURE, "body"); LAST_NODE; - F_NODE(nd_ensr, "ensure clause"); + F_NODE(nd_ensr, RNODE_ENSURE, "ensure clause"); return; case NODE_AND: @@ -366,24 +369,24 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("example: foo || bar"); andor: while (1) { - F_NODE(nd_1st, "left expr"); - if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type)) + 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 = node->nd_2nd; + node = RNODE_AND(node)->nd_2nd; } LAST_NODE; - F_NODE(nd_2nd, "right expr"); + 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, "rhsn"); - F_NODE(nd_head, "lhsn"); - if (NODE_NAMED_REST_P(node->nd_args)) { + 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, "splatn"); + F_NODE(nd_args, RNODE_MASGN, "splatn"); } else { F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)"); @@ -394,13 +397,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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_ID(nd_vid, RNODE_LASGN, "local variable"); + if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node))) { F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)"); } else { LAST_NODE; - F_NODE(nd_value, "rvalue"); + F_NODE(nd_value, RNODE_LASGN, "rvalue"); } return; case NODE_DASGN: @@ -408,65 +411,65 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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_ID(nd_vid, RNODE_DASGN, "local variable"); + if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node))) { F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)"); } else { LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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, "instance variable"); + F_ID(nd_vid, RNODE_IASGN, "instance variable"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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, "class variable"); + F_ID(nd_vid, RNODE_CVASGN, "class variable"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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, "global variable"); + F_ID(nd_vid, RNODE_GASGN, "global variable"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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 (node->nd_vid) { - F_ID(nd_vid, "constant"); + 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, "extension"); + F_NODE(nd_else, RNODE_CDECL, "extension"); } LAST_NODE; - F_NODE(nd_value, "rvalue"); + F_NODE(nd_value, RNODE_CDECL, "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"); + F_NODE(nd_recv, RNODE_OP_ASGN1, "receiver"); + F_ID(nd_mid, RNODE_OP_ASGN1, "operator"); + F_NODE(nd_args->nd_head, RNODE_OP_ASGN1, "index"); LAST_NODE; - F_NODE(nd_args->nd_body, "rvalue"); + F_NODE(nd_args->nd_body, RNODE_OP_ASGN1, "rvalue"); return; case NODE_OP_ASGN2: @@ -474,14 +477,14 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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_NODE(nd_recv, RNODE_OP_ASGN2, "receiver"); F_CUSTOM1(nd_next->nd_vid, "attr") { - if (node->nd_next->nd_aid) A("? "); - A_ID(node->nd_next->nd_vid); + if (RNODE_OP_ASGN2(node)->nd_aid) A("? "); + A_ID(RNODE_OP_ASGN2(node)->nd_vid); } - F_ID(nd_next->nd_mid, "operator"); + F_ID(nd_mid, RNODE_OP_ASGN2, "operator"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + F_NODE(nd_value, RNODE_OP_ASGN2, "rvalue"); return; case NODE_OP_ASGN_AND: @@ -494,65 +497,65 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: [nd_head] ||= [nd_value]"); ANN("example: foo ||= bar"); asgn_andor: - F_NODE(nd_head, "variable"); + F_NODE(nd_head, RNODE_OP_ASGN_AND, "variable"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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, "constant"); - F_ID(nd_aid, "operator"); + F_NODE(nd_head, RNODE_OP_CDECL, "constant"); + F_ID(nd_aid, RNODE_OP_CDECL, "operator"); LAST_NODE; - F_NODE(nd_value, "rvalue"); + 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, "method id"); - F_NODE(nd_recv, "receiver"); + F_ID(nd_mid, RNODE_CALL, "method id"); + F_NODE(nd_recv, RNODE_CALL, "receiver"); LAST_NODE; - F_NODE(nd_args, "arguments"); + 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, "method id"); - F_NODE(nd_recv, "receiver"); + F_ID(nd_mid, RNODE_OPCALL, "method id"); + F_NODE(nd_recv, RNODE_OPCALL, "receiver"); LAST_NODE; - F_NODE(nd_args, "arguments"); + 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, "method id"); + F_ID(nd_mid, RNODE_FCALL, "method id"); LAST_NODE; - F_NODE(nd_args, "arguments"); + 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, "method id"); + 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, "method id"); - F_NODE(nd_recv, "receiver"); + F_ID(nd_mid, RNODE_QCALL, "method id"); + F_NODE(nd_recv, RNODE_QCALL, "receiver"); LAST_NODE; - F_NODE(nd_args, "arguments"); + F_NODE(nd_args, RNODE_QCALL, "arguments"); return; case NODE_SUPER: @@ -560,7 +563,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: super [nd_args]"); ANN("example: super 1"); LAST_NODE; - F_NODE(nd_args, "arguments"); + F_NODE(nd_args, RNODE_SUPER, "arguments"); return; case NODE_ZSUPER: @@ -589,7 +592,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) return; case NODE_HASH: - if (!node->nd_brace) { + if (!RNODE_HASH(node)->nd_brace) { ANN("keyword arguments"); ANN("format: [nd_head]"); ANN("example: a: 1, b: 2"); @@ -600,13 +603,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("example: { 1 => 2, 3 => 4 }"); } F_CUSTOM1(nd_brace, "keyword arguments or hash literal") { - switch (node->nd_brace) { + 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, "contents"); + F_NODE(nd_head, RNODE_HASH, "contents"); return; case NODE_YIELD: @@ -614,52 +617,52 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: yield [nd_head]"); ANN("example: yield 1"); LAST_NODE; - F_NODE(nd_head, "arguments"); + 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, "local variable"); + 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, "local variable"); + 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, "instance variable"); + 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, "constant"); + 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, "class variable"); + 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, "global variable"); + 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(node->nd_nth); } + F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(RNODE_NTH_REF(node)->nd_nth); } return; case NODE_BACK_REF: @@ -668,7 +671,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("example: $&, $`, $', $+"); F_CUSTOM1(nd_nth, "variable") { char name[3] = "$ "; - name[1] = (char)node->nd_nth; + name[1] = (char)RNODE_BACK_REF(node)->nd_nth; A(name); } return; @@ -677,19 +680,19 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("match expression (against $_ implicitly)"); ANN("format: [nd_lit] (in condition)"); ANN("example: if /foo/; foo; end"); - F_LIT(nd_lit, "regexp"); + 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, "regexp (receiver)"); - if (!node->nd_args) LAST_NODE; - F_NODE(nd_value, "string (argument)"); - if (node->nd_args) { + 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, "named captures"); + F_NODE(nd_args, RNODE_MATCH2, "named captures"); } return; @@ -697,9 +700,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("match expression (regexp second)"); ANN("format: [nd_recv] =~ [nd_value]"); ANN("example: 'foo' =~ /foo/"); - F_NODE(nd_recv, "string (receiver)"); + F_NODE(nd_recv, RNODE_MATCH3, "string (receiver)"); LAST_NODE; - F_NODE(nd_value, "regexp (argument)"); + F_NODE(nd_value, RNODE_MATCH3, "regexp (argument)"); return; case NODE_LIT: @@ -717,7 +720,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: [nd_lit]"); ANN("example: `foo`"); lit: - F_LIT(nd_lit, "literal"); + F_LIT(nd_lit, RNODE_LIT, "literal"); return; case NODE_ONCE: @@ -725,8 +728,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: [nd_body]"); ANN("example: /foo#{ bar }baz/o"); LAST_NODE; - F_NODE(nd_body, "body"); + F_NODE(nd_body, RNODE_ONCE, "body"); return; + case NODE_DSTR: ANN("string literal with interpolation"); ANN("format: [nd_lit]"); @@ -747,11 +751,11 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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"); + 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, "tailing strings"); + F_NODE(nd_next->nd_next, RNODE_DSTR, "tailing strings"); return; case NODE_EVSTR: @@ -759,25 +763,25 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: \"..#{ [nd_body] }..\""); ANN("example: \"foo#{ bar }baz\""); LAST_NODE; - F_NODE(nd_body, "body"); + 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, "preceding array"); + F_NODE(nd_head, RNODE_ARGSCAT, "preceding array"); LAST_NODE; - F_NODE(nd_body, "following array"); + 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, "preceding array"); + F_NODE(nd_head, RNODE_ARGSPUSH, "preceding array"); LAST_NODE; - F_NODE(nd_body, "following element"); + F_NODE(nd_body, RNODE_ARGSPUSH, "following element"); return; case NODE_SPLAT: @@ -785,52 +789,52 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: *[nd_head]"); ANN("example: foo(*ary)"); LAST_NODE; - F_NODE(nd_head, "splat'ed array"); + 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, "other arguments"); + F_NODE(nd_head, RNODE_BLOCK_PASS, "other arguments"); LAST_NODE; - F_NODE(nd_body, "block argument"); + 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, "method name"); + F_ID(nd_mid, RNODE_DEFN, "method name"); LAST_NODE; - F_NODE(nd_defn, "method definition"); + 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, "receiver"); - F_ID(nd_mid, "method name"); + F_NODE(nd_recv, RNODE_DEFS, "receiver"); + F_ID(nd_mid, RNODE_DEFS, "method name"); LAST_NODE; - F_NODE(nd_defn, "method definition"); + 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, "new name"); + F_NODE(nd_1st, RNODE_ALIAS, "new name"); LAST_NODE; - F_NODE(nd_2nd, "old name"); + 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, "new name"); - F_ID(nd_orig, "old name"); + F_ID(nd_alias, RNODE_VALIAS, "new name"); + F_ID(nd_orig, RNODE_VALIAS, "old name"); return; case NODE_UNDEF: @@ -838,51 +842,51 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: undef [nd_undef]"); ANN("example: undef foo"); LAST_NODE; - F_NODE(nd_undef, "old name"); + 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, "class path"); - F_NODE(nd_super, "superclass"); + F_NODE(nd_cpath, RNODE_CLASS, "class path"); + F_NODE(nd_super, RNODE_CLASS, "superclass"); LAST_NODE; - F_NODE(nd_body, "class definition"); + 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, "module path"); + F_NODE(nd_cpath, RNODE_MODULE, "module path"); LAST_NODE; - F_NODE(nd_body, "module definition"); + 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, "receiver"); + F_NODE(nd_recv, RNODE_SCLASS, "receiver"); LAST_NODE; - F_NODE(nd_body, "singleton class definition"); + 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, "constant name"); + F_ID(nd_mid, RNODE_COLON2, "constant name"); LAST_NODE; - F_NODE(nd_head, "receiver"); + 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, "constant name"); + F_ID(nd_mid, RNODE_COLON3, "constant name"); return; case NODE_DOT2: @@ -905,9 +909,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: [nd_beg]...[nd_end]"); ANN("example: if (x==1)...(x==5); foo; end"); dot: - F_NODE(nd_beg, "begin"); + F_NODE(nd_beg, RNODE_DOT2, "begin"); LAST_NODE; - F_NODE(nd_end, "end"); + F_NODE(nd_end, RNODE_DOT2, "end"); return; case NODE_SELF: @@ -944,7 +948,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("defined? expression"); ANN("format: defined?([nd_head])"); ANN("example: defined?(foo)"); - F_NODE(nd_head, "expr"); + F_NODE(nd_head, RNODE_DEFINED, "expr"); return; case NODE_POSTEXE: @@ -952,17 +956,17 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: END { [nd_body] }"); ANN("example: END { foo }"); LAST_NODE; - F_NODE(nd_body, "END clause"); + 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, "receiver"); - F_ID(nd_mid, "method name"); + F_NODE(nd_recv, RNODE_ATTRASGN, "receiver"); + F_ID(nd_mid, RNODE_ATTRASGN, "method name"); LAST_NODE; - F_NODE(nd_args, "arguments"); + F_NODE(nd_args, RNODE_ATTRASGN, "arguments"); return; case NODE_LAMBDA: @@ -970,70 +974,70 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) ANN("format: -> [nd_body]"); ANN("example: -> { foo }"); LAST_NODE; - F_NODE(nd_body, "lambda clause"); + 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, "body"); + F_NODE(nd_body, RNODE_OPT_ARG, "body"); LAST_NODE; - F_NODE(nd_next, "next"); + 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, "body"); + F_NODE(nd_body, RNODE_KW_ARG, "body"); LAST_NODE; - F_NODE(nd_next, "next"); + 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(node->nd_1st)) { - F_NODE(nd_1st, "rest argument"); + 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, "post arguments"); + 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, "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_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 (node->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) { + if (RNODE_ARGS(node)->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) { A("1 (excessed comma)"); } else { - A_ID(node->nd_ainfo->rest_arg); + A_ID(RNODE_ARGS(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"); + 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, "keyword rest argument"); + 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 = node->nd_tbl; + rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl; int i; int size = tbl ? tbl->size : 0; if (size == 0) A("(empty)"); @@ -1041,41 +1045,41 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) A_ID(tbl->ids[i]); if (i < size - 1) A(","); } } - F_NODE(nd_args, "arguments"); + F_NODE(nd_args, RNODE_SCOPE, "arguments"); LAST_NODE; - F_NODE(nd_body, "body"); + 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, "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"); + F_NODE(nd_pconst, RNODE_ARYPTN, "constant"); + F_NODE(nd_apinfo->pre_args, RNODE_ARYPTN, "pre arguments"); + if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->nd_apinfo->rest_arg)) { + F_NODE(nd_apinfo->rest_arg, RNODE_ARYPTN, "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"); + F_NODE(nd_apinfo->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, "constant"); - if (NODE_NAMED_REST_P(node->nd_fpinfo->pre_rest_arg)) { - F_NODE(nd_fpinfo->pre_rest_arg, "pre rest argument"); + F_NODE(nd_pconst, RNODE_FNDPTN, "constant"); + if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->nd_fpinfo->pre_rest_arg)) { + F_NODE(nd_fpinfo->pre_rest_arg, RNODE_FNDPTN, "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"); + F_NODE(nd_fpinfo->args, RNODE_FNDPTN, "arguments"); LAST_NODE; - if (NODE_NAMED_REST_P(node->nd_fpinfo->post_rest_arg)) { - F_NODE(nd_fpinfo->post_rest_arg, "post rest argument"); + if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->nd_fpinfo->post_rest_arg)) { + F_NODE(nd_fpinfo->post_rest_arg, RNODE_FNDPTN, "post rest argument"); } else { F_MSG(nd_fpinfo->post_rest_arg, "post rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)"); @@ -1085,14 +1089,14 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) 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"); + F_NODE(nd_pconst, RNODE_HSHPTN, "constant"); + F_NODE(nd_pkwargs, RNODE_HSHPTN, "keyword arguments"); LAST_NODE; - if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) { + 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, "keyword rest argument"); + F_NODE(nd_pkwrestarg, RNODE_HSHPTN, "keyword rest argument"); } return; case NODE_ERROR: @@ -1100,6 +1104,9 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node) return; case NODE_ARGS_AUX: + case NODE_DEF_TEMP: + case NODE_RIPPER: + case NODE_RIPPER_VALUES: case NODE_LAST: break; } diff --git a/numeric.c b/numeric.c index 82fac8320fea45..82967502e6c358 100644 --- a/numeric.c +++ b/numeric.c @@ -999,7 +999,7 @@ 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. @@ -1683,12 +1683,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. * diff --git a/parse.y b/parse.y index 277d313592ce9d..19e29d5d5d6e31 100644 --- a/parse.y +++ b/parse.y @@ -51,8 +51,6 @@ #include #include -struct lex_context; - #include "internal.h" #include "internal/compile.h" #include "internal/compilers.h" @@ -277,6 +275,13 @@ 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; @@ -284,6 +289,7 @@ 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); }; #if defined(__GNUC__) && !defined(__clang__) @@ -483,6 +489,7 @@ struct parser_params { rb_encoding *enc; token_info *token_info; VALUE case_labels; + NODE *exits; VALUE debug_buffer; VALUE debug_output; @@ -573,6 +580,7 @@ static void numparam_name(struct parser_params *p, ID id); #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 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 st_table * push_pvtbl(struct parser_params *p) @@ -842,8 +850,7 @@ 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 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 NEW_QCALL(q,r,m,a,loc) (CALL_Q_P(q) ? NEW_QCALL0(r,m,a,loc) : NEW_CALL(r,m,a,loc)) #define lambda_beginning_p() (p->lex.lpar_beg == p->lex.paren_nest) @@ -868,17 +875,244 @@ add_mark_object(struct parser_params *p, VALUE 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 NODE* node_newnode_with_locals(struct parser_params *, enum node_type, VALUE, VALUE, const rb_code_location_t*); +static rb_node_scope_t *rb_node_scope_new(struct parser_params *p, NODE *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, NODE *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, NODE *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, rb_node_argscat_t *nd_args, 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, struct rb_args_info *nd_ainfo, 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, NODE *nd_args, NODE *nd_body, const YYLTYPE *loc); +static rb_node_aryptn_t *rb_node_aryptn_new(struct parser_params *p, 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, 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) (NODE *)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,a,loc) (NODE *)rb_node_op_asgn1_new(p,r,id,a,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) (NODE *)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(a,loc) (NODE *)rb_node_args_new(p,a,loc) +#define NEW_ARGS_AUX(r,b,loc) (NODE *)rb_node_args_aux_new(p,r,b,loc) +#define NEW_OPT_ARG(v,loc) (NODE *)rb_node_opt_arg_new(p,v,loc) +#define NEW_KW_ARG(v,loc) (NODE *)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) (NODE *)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(loc) (NODE *)rb_node_aryptn_new(p,loc) +#define NEW_HSHPTN(c,kw,kwrest,loc) (NODE *)rb_node_hshptn_new(p,c,kw,kwrest,loc) +#define NEW_FNDPTN(loc) (NODE *)rb_node_fndptn_new(p,loc) +#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc) + #endif -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)) +/* This node is parse.y internal */ +typedef struct RNode_DEF_TEMP { + NODE node; + + ID nd_vid; + ID nd_mid; + struct RNode *nd_head; + long nd_nth; + struct lex_context ctxt; +} rb_node_def_temp_t; + +#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, ID nd_vid, ID nd_mid, NODE *nd_head, long nd_nth, struct lex_context ctxt, const YYLTYPE *loc); -/* Make a new temporal node, which should not be appeared in the +#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(v,m,h,n,c,loc) (NODE *)rb_node_def_temp_new(p,v,m,h,n,c,loc) + +/* Make a new internal node, which should not be appeared in the * result AST and does not have node_id and location. */ -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* node_new_internal(struct parser_params *p, enum node_type type, size_t size, size_t alignment); +#define NODE_NEW_INTERNAL(node_type, type) (type *)node_new_internal(p, node_type, sizeof(type), RUBY_ALIGNOF(type)) static NODE *nd_set_loc(NODE *nd, const YYLTYPE *loc); @@ -913,10 +1147,19 @@ set_line_body(NODE *body, int line) static void set_embraced_location(NODE *node, const rb_code_location_t *beg, const rb_code_location_t *end) { - node->nd_body->nd_loc = code_loc_gen(beg, 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) +{ + if (nd_type_p(expr, NODE_BLOCK)) { + expr = RNODE_BLOCK(RNODE_BLOCK(expr)->nd_end)->nd_head; + } + return expr; +} + #define yyparse ruby_yyparse static NODE* cond(struct parser_params *p, NODE *node, const YYLTYPE *loc); @@ -956,7 +1199,7 @@ 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) {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) {RNODE_ITER(b)->nd_iter = m; b->nd_loc = *loc; return b;} static bool args_info_empty_p(struct rb_args_info *args); static NODE *new_args(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*); @@ -1027,17 +1270,13 @@ 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) -#define NODE_RIPPER2 NODE_OP_CDECL -#define NEW_RIPPER2(a,b,c,loc) (VALUE)NEW_OP_CDECL(a,c,b,loc) static inline int ripper_is_node_yylval(struct parser_params *p, 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(c)->nd_cval; + if (ripper_is_node_yylval(p, c)) c = RNODE_RIPPER(c)->nd_cval; add_mark_object(p, b); add_mark_object(p, c); return NEW_RIPPER(a, b, c, &NULL_LOC); @@ -1049,7 +1288,7 @@ 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_RIPPER2(a, b, c, &NULL_LOC); + return NEW_RIPPER_VALUES(a, b, c, &NULL_LOC); } static inline int @@ -1214,24 +1453,18 @@ 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) { - 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)); + 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); } static inline VALUE new_args_tail(struct parser_params *p, VALUE kw_args, VALUE kw_rest_arg, VALUE block, YYLTYPE *loc) { - 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; + return ripper_new_yylval2(p, kw_args, kw_rest_arg, block); } static inline VALUE @@ -1243,8 +1476,8 @@ 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) { - NODE *t = (NODE *)aryptn; - VALUE pre_args = t->u1.value, rest_arg = t->u2.value, post_args = t->u3.value; + 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; if (!NIL_P(pre_arg)) { if (!NIL_P(pre_args)) { @@ -1266,8 +1499,8 @@ new_array_pattern_tail(struct parser_params *p, VALUE pre_args, VALUE has_rest, static VALUE new_find_pattern(struct parser_params *p, VALUE constant, VALUE fndptn, const YYLTYPE *loc) { - NODE *t = (NODE *)fndptn; - VALUE pre_rest_arg = t->u1.value, args = t->u2.value, post_rest_arg = t->u3.value; + 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; return dispatch4(fndptn, constant, pre_rest_arg, args, post_rest_arg); } @@ -1289,8 +1522,8 @@ 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) { - NODE *t = (NODE *)hshptn; - VALUE kw_args = t->u1.value, kw_rest_arg = t->u2.value; + struct RNode_RIPPER_VALUES *t = RNODE_RIPPER_VALUES(hshptn); + VALUE kw_args = t->nd_val1, kw_rest_arg = t->nd_val2; return dispatch3(hshptn, constant, kw_args, kw_rest_arg); } @@ -1320,9 +1553,9 @@ set_defun_body(struct parser_params *p, NODE *n, NODE *args, NODE *body, const Y { body = remove_begin(body); reduce_nodes(p, &body); - n->nd_defn = NEW_SCOPE(args, body, loc); + RNODE_DEFN(n)->nd_defn = NEW_SCOPE(args, body, loc); n->nd_loc = *loc; - nd_set_line(n->nd_defn, loc->end_pos.lineno); + nd_set_line(RNODE_DEFN(n)->nd_defn, loc->end_pos.lineno); set_line_body(body, loc->beg_pos.lineno); return n; } @@ -1339,25 +1572,40 @@ rescued_expr(struct parser_params *p, NODE *arg, NODE *rescue, #endif /* RIPPER */ +static NODE *add_block_exit(struct parser_params *p, NODE *node); +static NODE *init_block_exit(struct parser_params *p); +static NODE *allow_block_exit(struct parser_params *p); +static void restore_block_exit(struct parser_params *p, NODE *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, NODE *name) { - 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); + /* See: def_name action */ + rb_node_def_temp_t *temp = RNODE_DEF_TEMP(name); + struct lex_context ctxt = temp->ctxt; + p->cur_arg = temp->nd_vid; + 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 = (int)temp->nd_nth; + numparam_pop(p, temp->nd_head); + clear_block_exit(p, true); } static void endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc) { #ifdef RIPPER - defn = defn->nd_defn; + defn = RNODE_DEFN(defn)->nd_defn; #endif - ID mid = defn->nd_mid; + ID mid = RNODE_DEFN(defn)->nd_mid; if (is_attrset_id(mid)) { yyerror1(loc, "setter method cannot be defined in an endless method definition"); } @@ -1374,6 +1622,18 @@ endless_method_name(struct parser_params *p, NODE *defn, const YYLTYPE *loc) } \ } 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) + #ifndef RIPPER # define Qnone 0 # define Qnull 0 @@ -1443,10 +1703,87 @@ 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 char *fmt, ...), 2, 3); -# define compile_error parser_compile_error +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__) #endif +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", ruby_node_name(nd_type(node))); + break; + } + if (!p->ctxt.in_defined) { + NODE *exits = p->exits; + if (exits) { + /* Assume NODE_BREAK, NODE_NEXT, NODE_REDO has empty u3 (nd_next) */ + RNODE_LIST(RNODE_LIST(exits)->as.nd_end)->nd_next = node; + RNODE_LIST(exits)->as.nd_end = node; + } + } + return node; +} + +static NODE * +init_block_exit(struct parser_params *p) +{ + NODE *old = p->exits; + rb_node_zlist_t *exits = NODE_NEW_INTERNAL(NODE_ZLIST, rb_node_zlist_t); /* This has element */ + exits->not_used = 0; + exits->not_used2 = 0; + exits->not_used3 = 0; + p->exits = RNODE_LIST(exits)->as.nd_end = (NODE *)exits; + return old; +} + +static NODE * +allow_block_exit(struct parser_params *p) +{ + NODE *exits = p->exits; + p->exits = 0; + return exits; +} + +static void +restore_block_exit(struct parser_params *p, NODE *exits) +{ + p->exits = exits; +} + +static void +clear_block_exit(struct parser_params *p, bool error) +{ + NODE *exits = p->exits; + if (!exits) return; + if (error && !compile_for_eval) { + for (NODE *e = exits; (e = RNODE_LIST(e)->nd_next) != 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"); + break; + } + } + } + RNODE_LIST(exits)->as.nd_end = exits; + RNODE_LIST(exits)->nd_next = 0; +} + #define WARN_EOL(tok) \ (looking_at_eol_p(p) ? \ (void)rb_warning0("`" tok "' at the end of line without an expression") : \ @@ -1472,26 +1809,26 @@ static int looking_at_eol_p(struct parser_params *p); #ifndef RIPPER rb_parser_printf(p, "%"PRIsVALUE, rb_id2str($$)); #else - rb_parser_printf(p, "%"PRIsVALUE, RNODE($$)->nd_rval); + rb_parser_printf(p, "%"PRIsVALUE, RNODE_RIPPER($$)->nd_rval); #endif } tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL tOP_ASGN %printer { #ifndef RIPPER - rb_parser_printf(p, "%+"PRIsVALUE, $$->nd_lit); + rb_parser_printf(p, "%+"PRIsVALUE, RNODE_LIT($$)->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", $$->nd_nth); + rb_parser_printf(p, "$%ld", RNODE_NTH_REF($$)->nd_nth); #else rb_parser_printf(p, "%"PRIsVALUE, $$); #endif } tNTH_REF %printer { #ifndef RIPPER - rb_parser_printf(p, "$%c", (int)$$->nd_nth); + rb_parser_printf(p, "$%c", (int)RNODE_BACK_REF($$)->nd_nth); #else rb_parser_printf(p, "%"PRIsVALUE, $$); #endif @@ -1617,7 +1954,8 @@ static int looking_at_eol_p(struct parser_params *p); %type f_kwrest f_label f_arg_asgn call_op call_op2 reswords relop dot_or_colon %type p_kwrest p_kwnorest p_any_kwrest p_kw_label %type f_no_kwarg f_any_kwrest args_forward excessed_comma nonlocal_var - %type lex_ctxt /* keep in ripper */ +%type lex_ctxt begin_defined k_class k_module k_END k_rescue k_ensure after_rescue +%type p_lparen p_lbracket %token END_OF_INPUT 0 "end-of-input" %token '.' /* escaped chars, should be ignored otherwise */ @@ -1712,6 +2050,8 @@ static int looking_at_eol_p(struct parser_params *p); 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 { @@ -1720,10 +2060,10 @@ program : { NODE *node = $2; /* last expression should not be void */ if (nd_type_p(node, NODE_BLOCK)) { - while (node->nd_next) { - node = node->nd_next; + while (RNODE_BLOCK(node)->nd_next) { + node = RNODE_BLOCK(node)->nd_next; } - node = node->nd_head; + node = RNODE_BLOCK(node)->nd_head; } node = remove_begin(node); void_expr(p, node); @@ -1765,14 +2105,21 @@ top_stmts : none ; top_stmt : stmt + { + clear_block_exit(p, true); + $$ = $1; + } | keyword_BEGIN begin_block { $$ = $2; } ; -begin_block : '{' top_compstmt '}' +block_open : '{' {$$ = init_block_exit(p);}; + +begin_block : block_open top_compstmt '}' { + restore_block_exit(p, $1); /*%%%*/ p->eval_tree_begin = block_append(p, p->eval_tree_begin, NEW_BEGIN($2, &@$)); @@ -1782,25 +2129,37 @@ begin_block : '{' top_compstmt '}' } ; -bodystmt : compstmt +bodystmt : compstmt[body] + lex_ctxt[ctxt] opt_rescue - k_else {if (!$2) {yyerror1(&@3, "else without rescue is useless");}} - compstmt + 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, $1, $2, $5, $6, &@$); + $$ = new_bodystmt(p, $body, $opt_rescue, $elsebody, $opt_ensure, &@$); /*% %*/ - /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), escape_Qundef($5), escape_Qundef($6)) %*/ + /*% ripper: bodystmt!($body, $opt_rescue, $elsebody, $opt_ensure) %*/ } - | compstmt + | compstmt[body] + lex_ctxt[ctxt] opt_rescue + { + next_rescue_context(&p->ctxt, &$ctxt, after_ensure); + } opt_ensure { /*%%%*/ - $$ = new_bodystmt(p, $1, $2, 0, $3, &@$); + $$ = new_bodystmt(p, $body, $opt_rescue, 0, $opt_ensure, &@$); /*% %*/ - /*% ripper: bodystmt!(escape_Qundef($1), escape_Qundef($2), Qnil, escape_Qundef($3)) %*/ + /*% ripper: bodystmt!($body, $opt_rescue, Qnil, $opt_ensure) %*/ } ; @@ -1847,6 +2206,11 @@ stmt_or_begin : stmt } ; +k_END : keyword_END lex_ctxt + { + $$ = $2; + }; + stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem { /*%%%*/ @@ -1866,7 +2230,7 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem /*%%%*/ char buf[2]; buf[0] = '$'; - buf[1] = (char)$3->nd_nth; + buf[1] = (char)RNODE_BACK_REF($3)->nd_nth; $$ = NEW_VALIAS($2, rb_intern2(buf, 2), &@$); /*% %*/ /*% ripper: var_alias!($2, $3) %*/ @@ -1905,9 +2269,10 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem } | stmt modifier_while expr_value { + clear_block_exit(p, false); /*%%%*/ if ($1 && nd_type_p($1, NODE_BEGIN)) { - $$ = NEW_WHILE(cond(p, $3, &@3), $1->nd_body, 0, &@$); + $$ = NEW_WHILE(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$); } else { $$ = NEW_WHILE(cond(p, $3, &@3), $1, 1, &@$); @@ -1917,9 +2282,10 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem } | stmt modifier_until expr_value { + clear_block_exit(p, false); /*%%%*/ if ($1 && nd_type_p($1, NODE_BEGIN)) { - $$ = NEW_UNTIL(cond(p, $3, &@3), $1->nd_body, 0, &@$); + $$ = NEW_UNTIL(cond(p, $3, &@3), RNODE_BEGIN($1)->nd_body, 0, &@$); } else { $$ = NEW_UNTIL(cond(p, $3, &@3), $1, 1, &@$); @@ -1927,29 +2293,36 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem /*% %*/ /*% ripper: until_mod!($3, $1) %*/ } - | stmt modifier_rescue stmt + | stmt modifier_rescue after_rescue stmt { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ NODE *resq; - YYLTYPE loc = code_loc_gen(&@2, &@3); - resq = NEW_RESBODY(0, remove_begin($3), 0, &loc); + 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, $3) %*/ + /*% ripper: rescue_mod!($1, $4) %*/ } - | keyword_END '{' compstmt '}' + | k_END + { + $$ = allow_block_exit(p); + p->ctxt.in_rescue = before_rescue; + }[exits] + '{' compstmt '}' { if (p->ctxt.in_def) { rb_warn0("END in method; use at_exit"); } + restore_block_exit(p, $exits); + p->ctxt = $k_END; /*%%%*/ { - NODE *scope = NEW_NODE( - NODE_SCOPE, 0 /* tbl */, $3 /* body */, 0 /* args */, &@$); + NODE *scope = NEW_SCOPE2(0 /* tbl */, 0 /* args */, $compstmt /* body */, &@$); $$ = NEW_POSTEXE(scope, &@$); } /*% %*/ - /*% ripper: END!($3) %*/ + /*% ripper: END!($compstmt) %*/ } | command_asgn | mlhs '=' lex_ctxt command_call @@ -1967,13 +2340,18 @@ stmt : keyword_alias fitem {SET_LEX_STATE(EXPR_FNAME|EXPR_FITEM);} fitem /*% %*/ /*% ripper: assign!($1, $4) %*/ } - | mlhs '=' lex_ctxt mrhs_arg modifier_rescue stmt + | mlhs '=' lex_ctxt mrhs_arg modifier_rescue + after_rescue stmt[resbody] { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ - YYLTYPE loc = code_loc_gen(&@5, &@6); - $$ = node_assign(p, $1, NEW_RESCUE($4, NEW_RESBODY(0, remove_begin($6), 0, &loc), 0, &@$), $3, &@$); + 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, $mlhs, $mrhs_arg, $lex_ctxt, &@$); /*% %*/ - /*% ripper: massign!($1, rescue_mod!($4, $6)) %*/ + /*% ripper: massign!($1, rescue_mod!($4, $7)) %*/ } | mlhs '=' lex_ctxt mrhs_arg { @@ -2011,7 +2389,7 @@ command_asgn : lhs '=' lex_ctxt command_rhs /*%%%*/ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$); /*% %*/ - /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/ + /*% ripper: opassign!(aref_field!($1, $3), $5, $7) %*/ } | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt command_rhs @@ -2043,26 +2421,28 @@ command_asgn : lhs '=' lex_ctxt command_rhs /*% %*/ /*% ripper: opassign!(field!($1, $2, $3), $4, $6) %*/ } - | defn_head f_opt_paren_args '=' endless_command + | defn_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt] { - endless_method_name(p, $1, &@1); - restore_defun(p, $1->nd_defn); + endless_method_name(p, $head, &@head); + restore_defun(p, RNODE_DEFN($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $args, $bodystmt, &@$); /*% %*/ - /*% ripper: def!(get_value($1), $2, bodystmt!($4, Qnil, Qnil, Qnil)) %*/ + /*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ + /*% ripper: def!($head, $args, $$) %*/ local_pop(p); } - | defs_head f_opt_paren_args '=' endless_command + | defs_head[head] f_opt_paren_args[args] '=' endless_command[bodystmt] { - endless_method_name(p, $1, &@1); - restore_defun(p, $1->nd_defn); + endless_method_name(p, $head, &@head); + restore_defun(p, RNODE_DEFS($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $args, $bodystmt, &@$); /*% - $1 = get_value($1); + $head = get_value($head); %*/ - /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, bodystmt!($4, Qnil, Qnil, Qnil)) %*/ + /*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ + /*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $$) %*/ local_pop(p); } | backref tOP_ASGN lex_ctxt command_rhs @@ -2076,12 +2456,13 @@ command_asgn : lhs '=' lex_ctxt command_rhs ; endless_command : command - | endless_command modifier_rescue arg + | endless_command modifier_rescue after_rescue arg { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ - $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3); + $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4); /*% %*/ - /*% ripper: rescue_mod!($1, $3) %*/ + /*% ripper: rescue_mod!($1, $4) %*/ } | keyword_not opt_nl endless_command { @@ -2094,14 +2475,15 @@ command_rhs : command_call %prec tOP_ASGN value_expr($1); $$ = $1; } - | command_call modifier_rescue stmt + | command_call modifier_rescue after_rescue stmt { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ - YYLTYPE loc = code_loc_gen(&@2, &@3); + YYLTYPE loc = code_loc_gen(&@2, &@4); value_expr($1); - $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($3), 0, &loc), 0, &@$); + $$ = NEW_RESCUE($1, NEW_RESBODY(0, remove_begin($4), 0, &loc), 0, &@$); /*% %*/ - /*% ripper: rescue_mod!($1, $3) %*/ + /*% ripper: rescue_mod!($1, $4) %*/ } | command_asgn ; @@ -2123,49 +2505,49 @@ expr : command_call { $$ = call_uni_op(p, method_cond(p, $2, &@2), '!', &@1, &@$); } - | arg tASSOC + | arg tASSOC[ctxt] { - value_expr($1); + value_expr($arg); SET_LEX_STATE(EXPR_BEG|EXPR_LABEL); p->command_start = FALSE; - $2 = p->ctxt; + $ctxt = p->ctxt; p->ctxt.in_kwarg = 1; $$ = push_pvtbl(p); - } + }[pvtbl] { $$ = push_pktbl(p); - } - p_top_expr_body + }[pktbl] + p_top_expr_body[body] { - pop_pktbl(p, $4); - pop_pvtbl(p, $3); - p->ctxt.in_kwarg = $2.in_kwarg; + pop_pktbl(p, $pktbl); + pop_pvtbl(p, $pvtbl); + p->ctxt.in_kwarg = $ctxt.in_kwarg; /*%%%*/ - $$ = NEW_CASE3($1, NEW_IN($5, 0, 0, &@5), &@$); + $$ = NEW_CASE3($arg, NEW_IN($body, 0, 0, &@body), &@$); /*% %*/ - /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/ + /*% ripper: case!($arg, in!($body, Qnil, Qnil)) %*/ } - | arg keyword_in + | arg keyword_in[ctxt] { - value_expr($1); + value_expr($arg); SET_LEX_STATE(EXPR_BEG|EXPR_LABEL); p->command_start = FALSE; - $2 = p->ctxt; + $ctxt = p->ctxt; p->ctxt.in_kwarg = 1; $$ = push_pvtbl(p); - } + }[pvtbl] { $$ = push_pktbl(p); - } - p_top_expr_body + }[pktbl] + p_top_expr_body[body] { - pop_pktbl(p, $4); - pop_pvtbl(p, $3); - p->ctxt.in_kwarg = $2.in_kwarg; + pop_pktbl(p, $pktbl); + pop_pvtbl(p, $pvtbl); + p->ctxt.in_kwarg = $ctxt.in_kwarg; /*%%%*/ - $$ = NEW_CASE3($1, NEW_IN($5, NEW_TRUE(&@5), NEW_FALSE(&@5), &@5), &@$); + $$ = NEW_CASE3($arg, NEW_IN($body, NEW_TRUE(&@body), NEW_FALSE(&@body), &@body), &@$); /*% %*/ - /*% ripper: case!($1, in!($5, Qnil, Qnil)) %*/ + /*% ripper: case!($arg, in!($body, Qnil, Qnil)) %*/ } | arg %prec tLBRACE_ARG ; @@ -2174,17 +2556,14 @@ def_name : fname { ID fname = get_id($1); ID cur_arg = p->cur_arg; - YYSTYPE c = {.ctxt = p->ctxt}; + struct lex_context 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); + NODE *save = numparam_push(p); local_push(p, 0); p->cur_arg = 0; p->ctxt.in_def = 1; - $$ = NEW_NODE(NODE_SELF, /*vid*/cur_arg, /*mid*/fname, /*args*/save, &@$); + p->ctxt.in_rescue = before_rescue; + $$ = NEW_DEF_TEMP(cur_arg, fname, save, p->max_numparam, ctxt, &@$); /*%%%*/ /*% $$ = NEW_RIPPER(fname, get_value($1), $$, &NULL_LOC); @@ -2196,7 +2575,7 @@ defn_head : k_def def_name { $$ = $2; /*%%%*/ - $$ = NEW_NODE(NODE_DEFN, 0, $$->nd_mid, $$, &@$); + $$ = NEW_DEFN(RNODE_DEF_TEMP($$)->nd_mid, $$, &@$); /*% %*/ } ; @@ -2209,13 +2588,13 @@ defs_head : k_def singleton dot_or_colon def_name { SET_LEX_STATE(EXPR_ENDFN|EXPR_LABEL); /* force for args */ - $$ = $5; + $$ = $def_name; /*%%%*/ - $$ = NEW_NODE(NODE_DEFS, $2, $$->nd_mid, $$, &@$); + $$ = NEW_DEFS($singleton, RNODE_DEF_TEMP($$)->nd_mid, $$, &@$); /*% - VALUE ary = rb_ary_new_from_args(3, $2, $3, get_value($$)); + VALUE ary = rb_ary_new_from_args(3, $singleton, $dot_or_colon, get_value($$)); add_mark_object(p, ary); - $$->nd_rval = ary; + RNODE_RIPPER($$)->nd_rval = ary; %*/ } ; @@ -2275,7 +2654,7 @@ fcall : operation command : fcall command_args %prec tLOWEST { /*%%%*/ - $1->nd_args = $2; + RNODE_FCALL($1)->nd_args = $2; nd_set_last_loc($1, @2.end_pos); $$ = $1; /*% %*/ @@ -2285,7 +2664,7 @@ command : fcall command_args %prec tLOWEST { /*%%%*/ block_dup_check(p, $2, $3); - $1->nd_args = $2; + RNODE_FCALL($1)->nd_args = $2; $$ = method_add_block(p, $1, $3, &@$); fixpos($$, $1); nd_set_last_loc($1, @2.end_pos); @@ -2336,7 +2715,7 @@ command : fcall command_args %prec tLOWEST /*% %*/ /*% ripper: super!($2) %*/ } - | keyword_yield command_args + | k_yield command_args { /*%%%*/ $$ = new_yield(p, $2, &@$); @@ -2353,16 +2732,20 @@ command : fcall command_args %prec tLOWEST } | keyword_break call_args { + NODE *args = 0; /*%%%*/ - $$ = NEW_BREAK(ret_args(p, $2), &@$); + args = ret_args(p, $2); /*% %*/ + $$ = add_block_exit(p, NEW_BREAK(args, &@$)); /*% ripper: break!($2) %*/ } | keyword_next call_args { + NODE *args = 0; /*%%%*/ - $$ = NEW_NEXT(ret_args(p, $2), &@$); + args = ret_args(p, $2); /*% %*/ + $$ = add_block_exit(p, NEW_NEXT(args, &@$)); /*% ripper: next!($2) %*/ } ; @@ -2397,7 +2780,7 @@ mlhs_basic : mlhs_head | mlhs_head mlhs_item { /*%%%*/ - $$ = NEW_MASGN(list_append(p, $1,$2), 0, &@$); + $$ = NEW_MASGN(list_append(p, $1, $2), 0, &@$); /*% %*/ /*% ripper: mlhs_add!($1, $2) %*/ } @@ -2520,7 +2903,7 @@ mlhs_node : user_variable /*%%%*/ $$ = aryset(p, $1, $3, &@$); /*% %*/ - /*% ripper: aref_field!($1, escape_Qundef($3)) %*/ + /*% ripper: aref_field!($1, $3) %*/ } | primary_value call_op tIDENTIFIER { @@ -2588,7 +2971,7 @@ lhs : user_variable /*%%%*/ $$ = aryset(p, $1, $3, &@$); /*% %*/ - /*% ripper: aref_field!($1, escape_Qundef($3)) %*/ + /*% ripper: aref_field!($1, $3) %*/ } | primary_value call_op tIDENTIFIER { @@ -2656,7 +3039,7 @@ cpath : tCOLON3 cname | cname { /*%%%*/ - $$ = NEW_COLON2(0, $$, &@$); + $$ = NEW_COLON2(0, $1, &@$); /*% %*/ /*% ripper: const_ref!($1) %*/ } @@ -2772,7 +3155,7 @@ arg : lhs '=' lex_ctxt arg_rhs /*%%%*/ $$ = new_ary_op_assign(p, $1, $3, $5, $7, &@3, &@$); /*% %*/ - /*% ripper: opassign!(aref_field!($1, escape_Qundef($3)), $5, $7) %*/ + /*% ripper: opassign!(aref_field!($1, $3), $5, $7) %*/ } | primary_value call_op tIDENTIFIER tOP_ASGN lex_ctxt arg_rhs { @@ -2966,9 +3349,9 @@ arg : lhs '=' lex_ctxt arg_rhs { $$ = logop(p, idOROP, $1, $3, &@2, &@$); } - | keyword_defined opt_nl {p->ctxt.in_defined = 1;} arg + | keyword_defined opt_nl begin_defined arg { - p->ctxt.in_defined = 0; + p->ctxt.in_defined = $3.in_defined; $$ = new_defined(p, $4, &@$); } | arg '?' arg opt_nl ':' arg @@ -2980,26 +3363,28 @@ arg : lhs '=' lex_ctxt arg_rhs /*% %*/ /*% ripper: ifop!($1, $3, $6) %*/ } - | defn_head f_opt_paren_args '=' endless_arg + | defn_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt] { - endless_method_name(p, $1, &@1); - restore_defun(p, $1->nd_defn); + endless_method_name(p, $head, &@head); + restore_defun(p, RNODE_DEFN($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $2, $bodystmt, &@$); /*% %*/ - /*% ripper: def!(get_value($1), $2, bodystmt!($4, Qnil, Qnil, Qnil)) %*/ + /*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ + /*% ripper: def!($head, $2, $$) %*/ local_pop(p); } - | defs_head f_opt_paren_args '=' endless_arg + | defs_head[head] f_opt_paren_args[args] '=' endless_arg[bodystmt] { - endless_method_name(p, $1, &@1); - restore_defun(p, $1->nd_defn); + endless_method_name(p, $head, &@head); + restore_defun(p, RNODE_DEFS($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $args, $bodystmt, &@$); /*% - $1 = get_value($1); + $head = get_value($head); %*/ - /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, bodystmt!($4, Qnil, Qnil, Qnil)) %*/ + /*% ripper: bodystmt!($bodystmt, Qnil, Qnil, Qnil) %*/ + /*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $$) %*/ local_pop(p); } | primary @@ -3009,12 +3394,13 @@ arg : lhs '=' lex_ctxt arg_rhs ; endless_arg : arg %prec modifier_rescue - | endless_arg modifier_rescue arg + | endless_arg modifier_rescue after_rescue arg { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ - $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3); + $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4); /*% %*/ - /*% ripper: rescue_mod!($1, $3) %*/ + /*% ripper: rescue_mod!($1, $4) %*/ } | keyword_not opt_nl endless_arg { @@ -3045,6 +3431,20 @@ lex_ctxt : none } ; +begin_defined : lex_ctxt + { + p->ctxt.in_defined = 1; + $$ = $1; + } + ; + +after_rescue : lex_ctxt + { + p->ctxt.in_rescue = after_rescue; + $$ = $1; + } + ; + arg_value : arg { value_expr($1); @@ -3078,13 +3478,14 @@ arg_rhs : arg %prec tOP_ASGN value_expr($1); $$ = $1; } - | arg modifier_rescue arg + | arg modifier_rescue after_rescue arg { + p->ctxt.in_rescue = $3.in_rescue; /*%%%*/ value_expr($1); - $$ = rescued_expr(p, $1, $3, &@1, &@2, &@3); + $$ = rescued_expr(p, $1, $4, &@1, &@2, &@4); /*% %*/ - /*% ripper: rescue_mod!($1, $3) %*/ + /*% ripper: rescue_mod!($1, $4) %*/ } ; @@ -3093,7 +3494,7 @@ paren_args : '(' opt_call_args rparen /*%%%*/ $$ = $2; /*% %*/ - /*% ripper: arg_paren!(escape_Qundef($2)) %*/ + /*% ripper: arg_paren!($2) %*/ } | '(' args ',' args_forward rparen { @@ -3365,7 +3766,7 @@ primary : literal | tLPAREN_ARG compstmt {SET_LEX_STATE(EXPR_ENDARG);} ')' { /*%%%*/ - if (nd_type_p($2, NODE_SELF)) $2->nd_state = 0; + if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0; $$ = $2; /*% %*/ /*% ripper: paren!($2) %*/ @@ -3373,7 +3774,7 @@ primary : literal | tLPAREN compstmt ')' { /*%%%*/ - if (nd_type_p($2, NODE_SELF)) $2->nd_state = 0; + if (nd_type_p($2, NODE_SELF)) RNODE_SELF($2)->nd_state = 0; $$ = $2; /*% %*/ /*% ripper: paren!($2) %*/ @@ -3397,15 +3798,15 @@ primary : literal /*%%%*/ $$ = make_list($2, &@$); /*% %*/ - /*% ripper: array!(escape_Qundef($2)) %*/ + /*% ripper: array!($2) %*/ } | tLBRACE assoc_list '}' { /*%%%*/ $$ = new_hash(p, $2, &@$); - $$->nd_brace = TRUE; + RNODE_HASH($$)->nd_brace = TRUE; /*% %*/ - /*% ripper: hash!(escape_Qundef($2)) %*/ + /*% ripper: hash!($2) %*/ } | k_return { @@ -3414,30 +3815,30 @@ primary : literal /*% %*/ /*% ripper: return0! %*/ } - | keyword_yield '(' call_args rparen + | k_yield '(' call_args rparen { /*%%%*/ $$ = new_yield(p, $3, &@$); /*% %*/ /*% ripper: yield!(paren!($3)) %*/ } - | keyword_yield '(' rparen + | k_yield '(' rparen { /*%%%*/ $$ = NEW_YIELD(0, &@$); /*% %*/ /*% ripper: yield!(paren!(args_new!)) %*/ } - | keyword_yield + | k_yield { /*%%%*/ $$ = NEW_YIELD(0, &@$); /*% %*/ /*% ripper: yield0! %*/ } - | keyword_defined opt_nl '(' {p->ctxt.in_defined = 1;} expr rparen + | keyword_defined opt_nl '(' begin_defined expr rparen { - p->ctxt.in_defined = 0; + p->ctxt.in_defined = $4.in_defined; $$ = new_defined(p, $5, &@$); } | keyword_not '(' expr rparen @@ -3459,7 +3860,7 @@ primary : literal | method_call brace_block { /*%%%*/ - block_dup_check(p, $1->nd_args, $2); + block_dup_check(p, RNODE_FCALL($1)->nd_args, $2); $$ = method_add_block(p, $1, $2, &@$); /*% %*/ /*% ripper: method_add_block!($1, $2) %*/ @@ -3474,7 +3875,7 @@ primary : literal $$ = new_if(p, $2, $4, $5, &@$); fixpos($$, $2); /*% %*/ - /*% ripper: if!($2, $4, escape_Qundef($5)) %*/ + /*% ripper: if!($2, $4, $5) %*/ } | k_unless expr_value then compstmt @@ -3485,12 +3886,13 @@ primary : literal $$ = new_unless(p, $2, $4, $5, &@$); fixpos($$, $2); /*% %*/ - /*% ripper: unless!($2, $4, escape_Qundef($5)) %*/ + /*% 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); @@ -3501,6 +3903,7 @@ primary : literal compstmt k_end { + restore_block_exit(p, $1); /*%%%*/ $$ = NEW_UNTIL(cond(p, $2, &@2), $3, 1, &@$); fixpos($$, $2); @@ -3551,6 +3954,7 @@ primary : literal compstmt k_end { + restore_block_exit(p, $1); /*%%%*/ /* * for a, b, c in e @@ -3562,7 +3966,7 @@ primary : literal * e.each{|x| a, = x} */ ID id = internal_id(p); - NODE *m = NEW_ARGS_AUX(0, 0, &NULL_LOC); + struct RNode_ARGS_AUX *m = RNODE_ARGS_AUX(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 */ @@ -3570,7 +3974,7 @@ primary : literal switch (nd_type($2)) { case NODE_LASGN: case NODE_DASGN: /* e.each {|internal_var| a = internal_var; ... } */ - $2->nd_value = internal_var; + RNODE_LASGN($2)->nd_value = internal_var; id = 0; m->nd_plen = 1; m->nd_next = $2; @@ -3582,8 +3986,8 @@ primary : literal m->nd_next = node_assign(p, NEW_MASGN(NEW_LIST($2, &@2), 0, &@2), internal_var, NO_LEX_CTXT, &@2); } /* {|*internal_id| = 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, &@$); + args = new_args(p, (NODE *)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); /*% %*/ @@ -3591,131 +3995,121 @@ primary : literal } | 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); + begin_definition("class", &@k_class, &@cpath); } 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); + $$ = 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!($2, $3, $5) %*/ + /*% ripper: class!($cpath, $superclass, $bodystmt) %*/ local_pop(p); - p->ctxt.in_class = $1.in_class; - p->ctxt.shareable_constant_value = $1.shareable_constant_value; + p->ctxt.in_class = $k_class.in_class; + p->ctxt.shareable_constant_value = $k_class.shareable_constant_value; } | k_class tLSHFT expr { - p->ctxt.in_def = 0; - p->ctxt.in_class = 0; - local_push(p, 0); + begin_definition("", &@k_class, &@tLSHFT); } 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); + $$ = NEW_SCLASS($expr, $bodystmt, &@$); + nd_set_line(RNODE_SCLASS($$)->nd_body, @k_end.end_pos.lineno); + set_line_body($bodystmt, nd_line($expr)); + fixpos($$, $expr); /*% %*/ - /*% ripper: sclass!($3, $6) %*/ + /*% ripper: sclass!($expr, $bodystmt) %*/ local_pop(p); - p->ctxt.in_def = $1.in_def; - p->ctxt.in_class = $1.in_class; - p->ctxt.shareable_constant_value = $1.shareable_constant_value; + 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 { - 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); + begin_definition("module", &@k_module, &@cpath); } 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); + $$ = 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!($2, $4) %*/ + /*% ripper: module!($cpath, $bodystmt) %*/ local_pop(p); - p->ctxt.in_class = $1.in_class; - p->ctxt.shareable_constant_value = $1.shareable_constant_value; + p->ctxt.in_class = $k_module.in_class; + p->ctxt.shareable_constant_value = $k_module.shareable_constant_value; } - | defn_head - f_arglist + | defn_head[head] + f_arglist[args] { /*%%%*/ - push_end_expect_token_locations(p, &@1.beg_pos); + push_end_expect_token_locations(p, &@head.beg_pos); /*% %*/ } bodystmt k_end { - restore_defun(p, $1->nd_defn); + restore_defun(p, RNODE_DEFN($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $args, $bodystmt, &@$); /*% %*/ - /*% ripper: def!(get_value($1), $2, $4) %*/ + /*% ripper: def!($head, $args, $bodystmt) %*/ local_pop(p); } - | defs_head - f_arglist + | defs_head[head] + f_arglist[args] { /*%%%*/ - push_end_expect_token_locations(p, &@1.beg_pos); + push_end_expect_token_locations(p, &@head.beg_pos); /*% %*/ } bodystmt k_end { - restore_defun(p, $1->nd_defn); + restore_defun(p, RNODE_DEFS($head)->nd_defn); /*%%%*/ - $$ = set_defun_body(p, $1, $2, $4, &@$); + $$ = set_defun_body(p, $head, $args, $bodystmt, &@$); /*% - $1 = get_value($1); + $head = get_value($head); %*/ - /*% ripper: defs!(AREF($1, 0), AREF($1, 1), AREF($1, 2), $2, $4) %*/ + /*% ripper: defs!(AREF($head, 0), AREF($head, 1), AREF($head, 2), $args, $bodystmt) %*/ local_pop(p); } | keyword_break { - /*%%%*/ - $$ = NEW_BREAK(0, &@$); - /*% %*/ + $$ = add_block_exit(p, NEW_BREAK(0, &@$)); /*% ripper: break!(args_new!) %*/ } | keyword_next { - /*%%%*/ - $$ = NEW_NEXT(0, &@$); - /*% %*/ + $$ = add_block_exit(p, NEW_NEXT(0, &@$)); /*% ripper: next!(args_new!) %*/ } | keyword_redo { - /*%%%*/ - $$ = NEW_REDO(&@$); - /*% %*/ + $$ = 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(&@$); /*% %*/ @@ -3770,6 +4164,7 @@ k_unless : keyword_unless k_while : keyword_while { + $$ = allow_block_exit(p); token_info_push(p, "while", &@$); /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); @@ -3779,6 +4174,7 @@ k_while : keyword_while k_until : keyword_until { + $$ = allow_block_exit(p); token_info_push(p, "until", &@$); /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); @@ -3797,6 +4193,7 @@ k_case : keyword_case k_for : keyword_for { + $$ = allow_block_exit(p); token_info_push(p, "for", &@$); /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); @@ -3807,7 +4204,8 @@ k_for : keyword_for k_class : keyword_class { token_info_push(p, "class", &@$); - $$ = p->ctxt; + $$ = p->ctxt; + p->ctxt.in_rescue = before_rescue; /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); /*% %*/ @@ -3817,7 +4215,8 @@ k_class : keyword_class k_module : keyword_module { token_info_push(p, "module", &@$); - $$ = p->ctxt; + $$ = p->ctxt; + p->ctxt.in_rescue = before_rescue; /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); /*% %*/ @@ -3837,7 +4236,6 @@ k_do : keyword_do /*%%%*/ push_end_expect_token_locations(p, &@1.beg_pos); /*% %*/ - } ; @@ -3853,12 +4251,15 @@ k_do_block : keyword_do_block k_rescue : keyword_rescue { token_info_warn(p, "rescue", p->token_info, 1, &@$); + $$ = p->ctxt; + p->ctxt.in_rescue = after_rescue; } ; k_ensure : keyword_ensure { token_info_warn(p, "ensure", p->token_info, 1, &@$); + $$ = p->ctxt; } ; @@ -3910,6 +4311,13 @@ k_return : keyword_return } ; +k_yield : keyword_yield + { + if (!p->ctxt.in_defined && !p->ctxt.in_def && !dyna_in_block(p)) + yyerror1(&@1, "Invalid yield"); + } + ; + then : term | keyword_then | term keyword_then @@ -3928,7 +4336,7 @@ if_tail : opt_else $$ = new_if(p, $2, $4, $5, &@$); fixpos($$, $2); /*% %*/ - /*% ripper: elsif!($2, $4, escape_Qundef($5)) %*/ + /*% ripper: elsif!($2, $4, $5) %*/ } ; @@ -4155,7 +4563,8 @@ block_param_def : '|' opt_bv_decl '|' /*%%%*/ $$ = 0; /*% %*/ - /*% ripper: block_var!(params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil), escape_Qundef($2)) %*/ + /*% ripper: params!(Qnil,Qnil,Qnil,Qnil,Qnil,Qnil,Qnil) %*/ + /*% ripper: block_var!($$, $2) %*/ } | '|' block_param opt_bv_decl '|' { @@ -4165,7 +4574,7 @@ block_param_def : '|' opt_bv_decl '|' /*%%%*/ $$ = $2; /*% %*/ - /*% ripper: block_var!(escape_Qundef($2), escape_Qundef($3)) %*/ + /*% ripper: block_var!($2, $3) %*/ } ; @@ -4200,43 +4609,47 @@ bvar : tIDENTIFIER } ; -lambda : tLAMBDA +lambda : tLAMBDA[dyna] { token_info_push(p, "->", &@1); $1 = dyna_push(p); $$ = p->lex.lpar_beg; p->lex.lpar_beg = p->lex.paren_nest; - } + }[lpar] { $$ = p->max_numparam; p->max_numparam = 0; - } + }[max_numparam] { $$ = numparam_push(p); - } - f_larglist + }[numparam] + { + $$ = allow_block_exit(p); + }[exits] + f_larglist[args] { CMDARG_PUSH(0); } - lambda_body + lambda_body[body] { int max_numparam = p->max_numparam; - p->lex.lpar_beg = $2; - p->max_numparam = $3; + p->lex.lpar_beg = $lpar; + p->max_numparam = $max_numparam; + restore_block_exit(p, $exits); CMDARG_POP(); - $5 = args_with_numbered(p, $5, max_numparam); + $args = args_with_numbered(p, $args, max_numparam); /*%%%*/ { - 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); + 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); } /*% %*/ - /*% ripper: lambda!($5, $7) %*/ - numparam_pop(p, $4); - dyna_pop(p, $1); + /*% ripper: lambda!($args, $body) %*/ + numparam_pop(p, $numparam); + dyna_pop(p, $dyna); } ; @@ -4253,7 +4666,7 @@ f_larglist : '(' f_args opt_bv_decl ')' { p->ctxt.in_argdef = 0; /*%%%*/ - if (!args_info_empty_p($1->nd_ainfo)) + if (!args_info_empty_p(RNODE_ARGS($1)->nd_ainfo)) p->max_numparam = ORDINAL_PARAM; /*% %*/ $$ = $1; @@ -4293,7 +4706,7 @@ block_call : command do_block compile_error(p, "block given to yield"); } else { - block_dup_check(p, $1->nd_args, $2); + block_dup_check(p, RNODE_FCALL($1)->nd_args, $2); } $$ = method_add_block(p, $1, $2, &@$); fixpos($$, $1); @@ -4327,7 +4740,7 @@ method_call : fcall paren_args { /*%%%*/ $$ = $1; - $$->nd_args = $2; + RNODE_FCALL($$)->nd_args = $2; nd_set_last_loc($1, @2.end_pos); /*% %*/ /*% ripper: method_add_arg!(fcall!($1), $2) %*/ @@ -4391,7 +4804,7 @@ method_call : fcall paren_args $$ = NEW_CALL($1, tAREF, $3, &@$); fixpos($$, $1); /*% %*/ - /*% ripper: aref!($1, escape_Qundef($3)) %*/ + /*% ripper: aref!($1, $3) %*/ } ; @@ -4411,49 +4824,57 @@ brace_block : '{' brace_body '}' } ; -brace_body : {$$ = dyna_push(p);} +brace_body : {$$ = dyna_push(p);}[dyna] { $$ = p->max_numparam; p->max_numparam = 0; - } + }[max_numparam] { $$ = numparam_push(p); - } - opt_block_param compstmt + }[numparam] + { + $$ = allow_block_exit(p); + }[exits] + opt_block_param[args] compstmt { int max_numparam = p->max_numparam; - p->max_numparam = $2; - $4 = args_with_numbered(p, $4, max_numparam); + p->max_numparam = $max_numparam; + $args = args_with_numbered(p, $args, max_numparam); /*%%%*/ - $$ = NEW_ITER($4, $5, &@$); + $$ = NEW_ITER($args, $compstmt, &@$); /*% %*/ - /*% ripper: brace_block!(escape_Qundef($4), $5) %*/ - numparam_pop(p, $3); - dyna_pop(p, $1); + /*% ripper: brace_block!($args, $compstmt) %*/ + restore_block_exit(p, $exits); + numparam_pop(p, $numparam); + dyna_pop(p, $dyna); } ; -do_body : {$$ = dyna_push(p);} +do_body : {$$ = dyna_push(p);}[dyna] { $$ = p->max_numparam; p->max_numparam = 0; - } + }[max_numparam] { $$ = numparam_push(p); CMDARG_PUSH(0); - } - opt_block_param bodystmt + }[numparam] + { + $$ = allow_block_exit(p); + }[exits] + opt_block_param[args] bodystmt { int max_numparam = p->max_numparam; - p->max_numparam = $2; - $4 = args_with_numbered(p, $4, max_numparam); + p->max_numparam = $max_numparam; + $args = args_with_numbered(p, $args, max_numparam); /*%%%*/ - $$ = NEW_ITER($4, $5, &@$); + $$ = NEW_ITER($args, $bodystmt, &@$); /*% %*/ - /*% ripper: do_block!(escape_Qundef($4), $5) %*/ + /*% ripper: do_block!($args, $bodystmt) %*/ CMDARG_POP(); - numparam_pop(p, $3); - dyna_pop(p, $1); + restore_block_exit(p, $exits); + numparam_pop(p, $numparam); + dyna_pop(p, $dyna); } ; @@ -4497,7 +4918,7 @@ case_body : k_when case_args then $$ = NEW_WHEN($2, $4, $5, &@$); fixpos($$, $2); /*% %*/ - /*% ripper: when!($2, $4, escape_Qundef($5)) %*/ + /*% ripper: when!($2, $4, $5) %*/ } ; @@ -4505,30 +4926,30 @@ cases : opt_else | case_body ; -p_case_body : keyword_in +p_case_body : keyword_in[ctxt] { SET_LEX_STATE(EXPR_BEG|EXPR_LABEL); p->command_start = FALSE; - $1 = p->ctxt; + $ctxt = p->ctxt; p->ctxt.in_kwarg = 1; $$ = push_pvtbl(p); - } + }[pvtbl] { $$ = push_pktbl(p); - } - p_top_expr then + }[pktbl] + p_top_expr[expr] then { - pop_pktbl(p, $3); - pop_pvtbl(p, $2); - p->ctxt.in_kwarg = $1.in_kwarg; + pop_pktbl(p, $pktbl); + pop_pvtbl(p, $pvtbl); + p->ctxt.in_kwarg = $ctxt.in_kwarg; } compstmt - p_cases + p_cases[cases] { /*%%%*/ - $$ = NEW_IN($4, $7, $8, &@$); + $$ = NEW_IN($expr, $compstmt, $cases, &@$); /*% %*/ - /*% ripper: in!($4, $7, escape_Qundef($8)) %*/ + /*% ripper: in!($expr, $compstmt, $cases) %*/ } ; @@ -4601,21 +5022,21 @@ p_as : p_expr tASSOC p_variable p_alt : p_alt '|' p_expr_basic { /*%%%*/ - $$ = NEW_NODE(NODE_OR, $1, $3, 0, &@$); + $$ = NEW_OR($1, $3, &@$); /*% %*/ /*% ripper: binary!($1, STATIC_ID2SYM(idOr), $3) %*/ } | p_expr_basic ; -p_lparen : '(' {$$ = push_pktbl(p);}; -p_lbracket : '[' {$$ = push_pktbl(p);}; +p_lparen : '(' {$$ = push_pktbl(p);}; +p_lbracket : '[' {$$ = push_pktbl(p);}; p_expr_basic : p_value | p_variable | p_const p_lparen p_args rparen { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_array_pattern(p, $1, Qnone, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4624,7 +5045,7 @@ p_expr_basic : p_value } | p_const p_lparen p_find rparen { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_find_pattern(p, $1, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4633,7 +5054,7 @@ p_expr_basic : p_value } | p_const p_lparen p_kwargs rparen { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_hash_pattern(p, $1, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4647,7 +5068,7 @@ p_expr_basic : p_value } | p_const p_lbracket p_args rbracket { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_array_pattern(p, $1, Qnone, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4656,7 +5077,7 @@ p_expr_basic : p_value } | p_const p_lbracket p_find rbracket { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_find_pattern(p, $1, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4665,7 +5086,7 @@ p_expr_basic : p_value } | p_const p_lbracket p_kwargs rbracket { - pop_pktbl(p, $2); + pop_pktbl(p, $2); $$ = new_hash_pattern(p, $1, $3, &@$); /*%%%*/ nd_set_first_loc($$, @1.beg_pos); @@ -4871,12 +5292,12 @@ p_kw_label : tLABEL /*%%%*/ if (!$2 || nd_type_p($2, NODE_STR)) { NODE *node = dsym_node(p, $2, &loc); - $$ = SYM2ID(node->nd_lit); + $$ = SYM2ID(RNODE_LIT(node)->nd_lit); } /*% - if (ripper_is_node_yylval(p, $2) && RNODE($2)->nd_cval) { - VALUE label = RNODE($2)->nd_cval; - VALUE rval = RNODE($2)->nd_rval; + 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; } @@ -5049,10 +5470,13 @@ opt_rescue : k_rescue exc_list exc_var then opt_rescue { /*%%%*/ - $$ = NEW_RESBODY($2, - $3 ? block_append(p, node_assign(p, $3, NEW_ERRINFO(&@3), NO_LEX_CTXT, &@3), $5) : $5, - $6, &@$); - + 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, &@$); if ($2) { fixpos($$, $2); } @@ -5063,7 +5487,7 @@ opt_rescue : k_rescue exc_list exc_var then fixpos($$, $5); } /*% %*/ - /*% ripper: rescue!(escape_Qundef($2), escape_Qundef($3), escape_Qundef($5), escape_Qundef($6)) %*/ + /*% ripper: rescue!($2, $3, $5, $6) %*/ } | none ; @@ -5094,6 +5518,7 @@ exc_var : tASSOC lhs opt_ensure : k_ensure compstmt { + p->ctxt.in_rescue = $1.in_rescue; /*%%%*/ $$ = $2; /*% %*/ @@ -5112,7 +5537,7 @@ strings : string NODE *node = $1; if (!node) { node = NEW_STR(STR_NEW0(), &@$); - RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(node)->nd_lit); } else { node = evstr2dstr(p, node); @@ -5294,9 +5719,9 @@ string_contents : /* none */ /*%%%*/ /*% if (ripper_is_node_yylval(p, $1) && ripper_is_node_yylval(p, $2) && - !RNODE($1)->nd_cval) { - RNODE($1)->nd_cval = RNODE($2)->nd_cval; - RNODE($1)->nd_rval = add_mark_object(p, $$); + !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; } %*/ @@ -5356,12 +5781,12 @@ regexp_contents: /* none */ /*% VALUE s1 = 1, s2 = 0, n1 = $1, n2 = $2; if (ripper_is_node_yylval(p, n1)) { - s1 = RNODE(n1)->nd_cval; - n1 = RNODE(n1)->nd_rval; + s1 = RNODE_RIPPER(n1)->nd_cval; + n1 = RNODE_RIPPER(n1)->nd_rval; } if (ripper_is_node_yylval(p, n2)) { - s2 = RNODE(n2)->nd_cval; - n2 = RNODE(n2)->nd_rval; + s2 = RNODE_RIPPER(n2)->nd_cval; + n2 = RNODE_RIPPER(n2)->nd_rval; } $$ = dispatch2(regexp_add, n1, n2); if (!s1 && s2) { @@ -5389,42 +5814,38 @@ string_content : tSTRING_CONTENT /*% %*/ /*% ripper: string_dvar!($3) %*/ } - | tSTRING_DBEG + | 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 */ - $$ = p->lex.strterm; + $term = p->lex.strterm; p->lex.strterm = 0; - } - { $$ = p->lex.state; SET_LEX_STATE(EXPR_BEG); - } + }[state] { $$ = p->lex.brace_nest; p->lex.brace_nest = 0; - } + }[brace] { $$ = p->heredoc_indent; p->heredoc_indent = 0; - } + }[indent] compstmt string_dend { COND_POP(); CMDARG_POP(); - p->lex.strterm = $3; - SET_LEX_STATE($4); - p->lex.brace_nest = $5; - p->heredoc_indent = $6; + p->lex.strterm = $term; + SET_LEX_STATE($state); + p->lex.brace_nest = $brace; + p->heredoc_indent = $indent; p->heredoc_line_indent = -1; /*%%%*/ - if ($7) $7->flags &= ~NODE_FL_NEWLINE; - $$ = new_evstr(p, $7, &@$); + if ($compstmt) $compstmt->flags &= ~NODE_FL_NEWLINE; + $$ = new_evstr(p, $compstmt, &@$); /*% %*/ - /*% ripper: string_embexpr!($7) %*/ + /*% ripper: string_embexpr!($compstmt) %*/ } ; @@ -5475,7 +5896,7 @@ numeric : simple_numeric { /*%%%*/ $$ = $2; - RB_OBJ_WRITE(p->ast, &$$->nd_lit, negate_lit(p, $$->nd_lit)); + RB_OBJ_WRITE(p->ast, &RNODE_LIT($$)->nd_lit, negate_lit(p, RNODE_LIT($$)->nd_lit)); /*% %*/ /*% ripper: unary!(ID2VAL(idUMinus), $2) %*/ } @@ -5625,7 +6046,7 @@ args_tail : f_kwarg ',' f_kwrest opt_f_block_arg add_forwarding_args(p); $$ = new_args_tail(p, Qnone, $1, arg_FWD_BLOCK, &@1); /*%%%*/ - ($$->nd_ainfo)->forwarding = 1; + (RNODE_ARGS($$)->nd_ainfo)->forwarding = 1; /*% %*/ } ; @@ -5789,13 +6210,13 @@ f_arg_item : f_arg_asgn loc.end_pos = @2.beg_pos; arg_var(p, tid); if (dyna_in_block(p)) { - $2->nd_value = NEW_DVAR(tid, &loc); + RNODE_MASGN($2)->nd_value = NEW_DVAR(tid, &loc); } else { - $2->nd_value = NEW_LVAR(tid, &loc); + RNODE_MASGN($2)->nd_value = NEW_LVAR(tid, &loc); } $$ = NEW_ARGS_AUX(tid, 1, &NULL_LOC); - $$->nd_next = $2; + RNODE_ARGS_AUX($$)->nd_next = $2; /*% %*/ /*% ripper: mlhs_paren!($2) %*/ } @@ -5807,8 +6228,8 @@ f_arg : f_arg_item { /*%%%*/ $$ = $1; - $$->nd_plen++; - $$->nd_next = block_append(p, $$->nd_next, $3->nd_next); + RNODE_ARGS_AUX($$)->nd_plen++; + RNODE_ARGS_AUX($$)->nd_next = block_append(p, RNODE_ARGS_AUX($$)->nd_next, RNODE_ARGS_AUX($3)->nd_next); rb_discard_node(p, $3); /*% %*/ /*% ripper: rb_ary_push($1, get_value($3)) %*/ @@ -5932,7 +6353,7 @@ f_opt : f_arg_asgn f_eq arg_value p->cur_arg = 0; p->ctxt.in_argdef = 1; /*%%%*/ - $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$); + $$ = NEW_OPT_ARG(assignable(p, $1, $3, &@$), &@$); /*% %*/ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/ } @@ -5943,7 +6364,7 @@ f_block_opt : f_arg_asgn f_eq primary_value p->cur_arg = 0; p->ctxt.in_argdef = 1; /*%%%*/ - $$ = NEW_OPT_ARG(0, assignable(p, $1, $3, &@$), &@$); + $$ = NEW_OPT_ARG(assignable(p, $1, $3, &@$), &@$); /*% %*/ /*% ripper: rb_assoc_new(get_value(assignable(p, $1)), get_value($3)) %*/ } @@ -6043,16 +6464,18 @@ singleton : var_ref | '(' {SET_LEX_STATE(EXPR_BEG);} expr rparen { /*%%%*/ - switch (nd_type($3)) { + 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(&@3, "can't define singleton method for literals"); + yyerror1(&expr->nd_loc, "can't define singleton method for literals"); break; default: value_expr($3); @@ -6085,11 +6508,11 @@ assocs : assoc 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)) { + 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)) { /* DSTAR */ - tail = tail->nd_next->nd_head->nd_head; + tail = RNODE_HASH(RNODE_LIST(RNODE_LIST(tail)->nd_next)->nd_head)->nd_head; } assocs = list_concat(assocs, tail); } @@ -6104,7 +6527,7 @@ assoc : arg_value tASSOC 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)); + RB_OBJ_WRITE(p->ast, &RNODE_LIT($1)->nd_lit, rb_fstring(RNODE_LIT($1)->nd_lit)); } $$ = list_append(p, NEW_LIST($1, &@$), $3); /*% %*/ @@ -6138,7 +6561,7 @@ assoc : arg_value tASSOC arg_value { /*%%%*/ if (nd_type_p($2, NODE_HASH) && - !($2->nd_head && $2->nd_head->nd_alen)) { + !(RNODE_HASH($2)->nd_head && RNODE_LIST(RNODE_HASH($2)->nd_head)->as.nd_alen)) { static VALUE empty_hash; if (!empty_hash) { empty_hash = rb_obj_freeze(rb_hash_new()); @@ -6371,7 +6794,7 @@ 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) ? &yylval.node->nd_rval : &yylval.val)) +#define yylval_rval (*(RB_TYPE_P(yylval.val, T_NODE) ? &RNODE_RIPPER(yylval.node)->nd_rval : &yylval.val)) static int ripper_has_scan_event(struct parser_params *p) @@ -6547,7 +6970,7 @@ parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc) } static int -parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg) +parser_yyerror(struct parser_params *p, const rb_code_location_t *yylloc, const char *msg) { #if 0 YYLTYPE current; @@ -6560,7 +6983,7 @@ parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg) yylloc = 0; } #endif - compile_error(p, "%s", msg); + parser_compile_error(p, yylloc, "%s", msg); parser_show_error_line(p, yylloc); return 0; } @@ -6879,9 +7302,9 @@ yycompile0(VALUE arg) else { VALUE tokens = p->tokens; NODE *prelude; - NODE *body = parser_append_options(p, tree->nd_body); + NODE *body = parser_append_options(p, RNODE_SCOPE(tree)->nd_body); prelude = block_append(p, p->eval_tree_begin, body); - tree->nd_body = prelude; + 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) { @@ -7890,11 +8313,11 @@ flush_string_content(struct parser_params *p, rb_encoding *enc) } dispatch_delayed_token(p, tSTRING_CONTENT); p->lex.ptok = p->lex.pcur; - RNODE(content)->nd_rval = yylval.val; + RNODE_RIPPER(content)->nd_rval = yylval.val; } dispatch_scan_event(p, tSTRING_CONTENT); if (yylval.val != content) - RNODE(content)->nd_rval = yylval.val; + RNODE_RIPPER(content)->nd_rval = yylval.val; yylval.val = content; } #else @@ -8227,10 +8650,10 @@ 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 = root->nd_head; + if (nd_type_p(root, NODE_LIST)) str_node = RNODE_LIST(root)->nd_head; while (str_node) { - VALUE lit = str_node->nd_lit; + VALUE lit = RNODE_LIT(str_node)->nd_lit; if (str_node->flags & NODE_FL_NEWLINE) { dedent_string(p, lit, indent); } @@ -8241,22 +8664,22 @@ heredoc_dedent(struct parser_params *p, NODE *root) return 0; } else { - NODE *end = node->nd_end; - node = prev_node->nd_next = node->nd_next; + 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; } - node->nd_end = end; + RNODE_LIST(node)->as.nd_end = end; goto next_str; } str_node = 0; - while ((node = (prev_node = node)->nd_next) != 0) { + while ((node = RNODE_LIST(prev_node = node)->nd_next) != 0) { next_str: if (!nd_type_p(node, NODE_LIST)) break; - if ((str_node = node->nd_head) != 0) { + 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; @@ -9538,22 +9961,22 @@ parse_gvar(struct parser_params *p, const enum lex_state_e last_state) 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 */ + 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; @@ -9574,10 +9997,10 @@ parse_gvar(struct parser_params *p, const enum lex_state_e last_state) 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. */ + 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); @@ -9622,7 +10045,13 @@ parse_gvar(struct parser_params *p, const enum lex_state_e last_state) if (tokadd_ident(p, c)) return 0; SET_LEX_STATE(EXPR_END); - tokenize_ident(p); + 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(); + } return tGVAR; } @@ -10578,124 +11007,1291 @@ yylex(YYSTYPE *lval, YYLTYPE *yylloc, struct parser_params *p) #define LVAR_USED ((ID)1 << (sizeof(ID) * CHAR_BIT - 1)) static NODE* -node_new_temporal(struct parser_params *p, enum node_type type, VALUE a0, VALUE a1, VALUE a2) +node_new_internal(struct parser_params *p, enum node_type type, size_t size, size_t alignment) { - NODE *n = rb_ast_newnode(p->ast, type); + NODE *n = rb_ast_newnode(p->ast, type, size, alignment); - rb_node_init(n, type, a0, a1, a2); + rb_node_init(n, type); 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, VALUE a0, VALUE a1, VALUE a2, const rb_code_location_t *loc) +node_newnode(struct parser_params *p, enum node_type type, size_t size, size_t alignment, const rb_code_location_t *loc) { - NODE *n = node_new_temporal(p, type, a0, a1, a2); + NODE *n = node_new_internal(p, type, size, alignment); nd_set_loc(n, loc); nd_set_node_id(n, parser_get_node_id(p)); 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; -} +#define NODE_NEWNODE(node_type, type, loc) (type *)(node_newnode(p, node_type, sizeof(type), RUBY_ALIGNOF(type), loc)) #ifndef RIPPER -static enum node_type -nodetype(NODE *node) /* for debug */ + +static rb_node_scope_t * +rb_node_scope_new(struct parser_params *p, NODE *nd_args, NODE *nd_body, const YYLTYPE *loc) { - return (enum node_type)nd_type(node); + 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 int -nodeline(NODE *node) +static rb_node_scope_t * +rb_node_scope_new2(struct parser_params *p, rb_ast_id_table_t *nd_tbl, NODE *nd_args, NODE *nd_body, const YYLTYPE *loc) { - return nd_line(node); + 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 NODE* -newline_node(NODE *node) +static rb_node_defn_t * +rb_node_defn_new(struct parser_params *p, ID nd_mid, NODE *nd_defn, const YYLTYPE *loc) { - if (node) { - node = remove_begin(node); - node->flags |= NODE_FL_NEWLINE; - } - return node; + rb_node_defn_t *n = NODE_NEWNODE(NODE_DEFN, rb_node_defn_t, loc); + n->not_used = 0; + n->nd_mid = nd_mid; + n->nd_defn = nd_defn; + + return n; } -static void -fixpos(NODE *node, NODE *orig) +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) { - if (!node) return; - if (!orig) return; - nd_set_line(node, nd_line(orig)); + 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 void -parser_warning(struct parser_params *p, NODE *node, const char *mesg) +static rb_node_block_t * +rb_node_block_new(struct parser_params *p, NODE *nd_head, const YYLTYPE *loc) { - rb_compile_warning(p->ruby_sourcefile, nd_line(node), "%s", mesg); + rb_node_block_t *n = NODE_NEWNODE(NODE_BLOCK, rb_node_block_t, loc); + n->nd_head = nd_head; + n->nd_end = 0; + n->nd_next = 0; + + return n; } -static void -parser_warn(struct parser_params *p, NODE *node, const char *mesg) +static rb_node_for_t * +rb_node_for_new(struct parser_params *p, NODE *nd_iter, NODE *nd_body, const YYLTYPE *loc) { - rb_compile_warn(p->ruby_sourcefile, nd_line(node), "%s", mesg); + rb_node_for_t *n = NODE_NEWNODE(NODE_FOR, rb_node_for_t, loc); + n->not_used = 0; + n->nd_body = nd_body; + n->nd_iter = nd_iter; + + return n; } -static NODE* -block_append(struct parser_params *p, NODE *head, NODE *tail) +static rb_node_for_masgn_t * +rb_node_for_masgn_new(struct parser_params *p, NODE *nd_var, const YYLTYPE *loc) { - NODE *end, *h = head, *nd; + rb_node_for_masgn_t *n = NODE_NEWNODE(NODE_FOR_MASGN, rb_node_for_masgn_t, loc); + n->nd_var = nd_var; + n->not_used = 0; + n->not_used2 = 0; - if (tail == 0) return head; + return n; +} - 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); - end->nd_end = end; - head = end; - break; - case NODE_BLOCK: - end = h->nd_end; - break; - } +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); + n->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; - 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; + return n; +} - default: - break; - } +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->not_used = 0; + n->nd_body = nd_body; + n->not_used2 = 0; - if (!nd_type_p(tail, NODE_BLOCK)) { - tail = NEW_BLOCK(tail, &tail->nd_loc); - tail->nd_end = tail; + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + return n; +} + +static rb_node_iter_t * +rb_node_iter_new(struct parser_params *p, NODE *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->not_used = 0; + n->nd_body = scope; + n->nd_iter = 0; + + return n; +} + +static rb_node_lambda_t * +rb_node_lambda_new(struct parser_params *p, NODE *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->not_used = 0; + n->nd_body = scope; + n->not_used2 = 0; + + 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; + n->not_used = 0; + + 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->not_used = 0; + n->nd_mid = nd_mid; + n->not_used2 = 0; + + 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->not_used = 0; + n->not_used2 = 0; + 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); + n->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; + + 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; + n->not_used = 0; + + 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); + n->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; + + 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; + n->not_used = 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + return n; +} + +static rb_node_op_asgn1_t * +rb_node_op_asgn1_new(struct parser_params *p, NODE *nd_recv, ID nd_mid, rb_node_argscat_t *nd_args, 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_args = nd_args; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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->not_used = 0; + n->nd_nth = nd_nth; + n->not_used2 = 0; + + 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->not_used = 0; + n->nd_nth = nd_nth; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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->not_used = 0; + n->nd_body = nd_body; + n->not_used2 = 0; + + 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->not_used = 0; + 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->not_used = 0; + n->nd_mid = nd_mid; + n->not_used2 = 0; + + 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->not_used = 0; + n->nd_body = nd_body; + n->not_used2 = 0; + + return n; +} + +static rb_node_args_t * +rb_node_args_new(struct parser_params *p, struct rb_args_info *nd_ainfo, const YYLTYPE *loc) +{ + rb_node_args_t *n = NODE_NEWNODE(NODE_ARGS, rb_node_args_t, loc); + n->not_used = 0; + n->not_used2 = 0; + n->nd_ainfo = nd_ainfo; + + 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->not_used = 0; + 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->not_used = 0; + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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; + n->not_used = 0; + + 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); + n->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; + + 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; + n->not_used = 0; + n->not_used2 = 0; + + 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->not_used = 0; + n->nd_body = nd_body; + n->not_used2 = 0; + + 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, const YYLTYPE *loc) +{ + rb_node_aryptn_t *n = NODE_NEWNODE(NODE_ARYPTN, rb_node_aryptn_t, loc); + n->nd_pconst = 0; + n->not_used = 0; + n->nd_apinfo = 0; + + 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, const YYLTYPE *loc) +{ + rb_node_fndptn_t *n = NODE_NEWNODE(NODE_FNDPTN, rb_node_fndptn_t, loc); + n->nd_pconst = 0; + n->not_used = 0; + n->nd_fpinfo = 0; + + 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); + n->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; + + 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->not_used = 0; + n->not_used2 = 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->not_used = 0; + n->not_used2 = 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->not_used = 0; + n->not_used2 = 0; + n->not_used3 = 0; + + return n; +} + +static rb_node_def_temp_t * +rb_node_def_temp_new(struct parser_params *p, ID nd_vid, ID nd_mid, NODE *nd_head, long nd_nth, struct lex_context ctxt, const YYLTYPE *loc) +{ + rb_node_def_temp_t *n = NODE_NEWNODE(NODE_DEF_TEMP, rb_node_def_temp_t, loc); + n->nd_vid = nd_vid; + n->nd_mid = nd_mid; + n->nd_head = nd_head; + n->nd_nth = nd_nth; + n->ctxt = ctxt; + + return n; +} + +#ifndef RIPPER +static enum node_type +nodetype(NODE *node) /* for debug */ +{ + return (enum node_type)nd_type(node); +} + +static int +nodeline(NODE *node) +{ + return nd_line(node); +} + +static NODE* +newline_node(NODE *node) +{ + if (node) { + node = remove_begin(node); + node->flags |= NODE_FL_NEWLINE; + } + return node; +} + +static void +fixpos(NODE *node, NODE *orig) +{ + if (!node) return; + if (!orig) return; + nd_set_line(node, nd_line(orig)); +} + +static void +parser_warning(struct parser_params *p, NODE *node, const char *mesg) +{ + rb_compile_warning(p->ruby_sourcefile, nd_line(node), "%s", mesg); +} + +static void +parser_warn(struct parser_params *p, NODE *node, const char *mesg) +{ + rb_compile_warn(p->ruby_sourcefile, nd_line(node), "%s", mesg); +} + +static NODE* +block_append(struct parser_params *p, NODE *head, NODE *tail) +{ + NODE *end, *h = head, *nd; + + if (tail == 0) return head; + + 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); + RNODE_BLOCK(end)->nd_end = end; + head = end; + break; + case NODE_BLOCK: + end = RNODE_BLOCK(h)->nd_end; + break; + } + + nd = RNODE_BLOCK(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; + + default: + break; + } + + if (!nd_type_p(tail, NODE_BLOCK)) { + tail = NEW_BLOCK(tail, &tail->nd_loc); + RNODE_BLOCK(tail)->nd_end = tail; } - end->nd_next = tail; - h->nd_end = tail->nd_end; + RNODE_BLOCK(end)->nd_next = tail; + RNODE_BLOCK(h)->nd_end = RNODE_BLOCK(tail)->nd_end; nd_set_last_loc(head, nd_last_loc(tail)); return head; } @@ -10707,16 +12303,16 @@ list_append(struct parser_params *p, NODE *list, NODE *item) NODE *last; if (list == 0) return NEW_LIST(item, &item->nd_loc); - if (list->nd_next) { - last = list->nd_next->nd_end; + if (RNODE_LIST(list)->nd_next) { + last = RNODE_LIST(RNODE_LIST(list)->nd_next)->as.nd_end; } else { last = list; } - list->nd_alen += 1; - last->nd_next = NEW_LIST(item, &item->nd_loc); - list->nd_next->nd_end = last->nd_next; + 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; nd_set_last_loc(list, nd_last_loc(item)); @@ -10729,20 +12325,20 @@ list_concat(NODE *head, NODE *tail) { NODE *last; - if (head->nd_next) { - last = head->nd_next->nd_end; + if (RNODE_LIST(head)->nd_next) { + last = RNODE_LIST(RNODE_LIST(head)->nd_next)->as.nd_end; } else { last = head; } - head->nd_alen += tail->nd_alen; - last->nd_next = tail; - if (tail->nd_next) { - head->nd_next->nd_end = tail->nd_next->nd_end; + 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; } else { - head->nd_next->nd_end = tail; + RNODE_LIST(RNODE_LIST(head)->nd_next)->as.nd_end = tail; } nd_set_last_loc(head, nd_last_loc(tail)); @@ -10770,11 +12366,11 @@ static VALUE string_literal_head(struct parser_params *p, enum node_type htype, NODE *head) { if (htype != NODE_DSTR) return Qfalse; - if (head->nd_next) { - head = head->nd_next->nd_end->nd_head; + 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; } - const VALUE lit = head->nd_lit; + const VALUE lit = RNODE_DSTR(head)->nd_lit; ASSUME(lit != Qfalse); return lit; } @@ -10810,10 +12406,10 @@ literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *l htype = NODE_STR; } else { - lit = head->nd_lit; + lit = RNODE_DSTR(head)->nd_lit; } if (htype == NODE_STR) { - if (!literal_concat0(p, lit, tail->nd_lit)) { + if (!literal_concat0(p, lit, RNODE_STR(tail)->nd_lit)) { error: rb_discard_node(p, head); rb_discard_node(p, tail); @@ -10828,39 +12424,39 @@ literal_concat(struct parser_params *p, NODE *head, NODE *tail, const YYLTYPE *l case NODE_DSTR: if (htype == NODE_STR) { - if (!literal_concat0(p, head->nd_lit, tail->nd_lit)) + if (!literal_concat0(p, RNODE_STR(head)->nd_lit, RNODE_DSTR(tail)->nd_lit)) goto error; - tail->nd_lit = head->nd_lit; + RNODE_DSTR(tail)->nd_lit = RNODE_STR(head)->nd_lit; rb_discard_node(p, head); head = tail; } - else if (NIL_P(tail->nd_lit)) { + else if (NIL_P(RNODE_DSTR(tail)->nd_lit)) { append: - head->nd_alen += tail->nd_alen - 1; - if (!head->nd_next) { - head->nd_next = tail->nd_next; + 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 (tail->nd_next) { - head->nd_next->nd_end->nd_next = tail->nd_next; - head->nd_next->nd_end = tail->nd_next->nd_end; + 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, tail->nd_lit)) + if (!literal_concat0(p, lit, RNODE_DSTR(tail)->nd_lit)) goto error; - tail->nd_lit = Qnil; + RNODE_DSTR(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)); + 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; case NODE_EVSTR: if (htype == NODE_STR) { nd_set_type(head, NODE_DSTR); - head->nd_alen = 1; + RNODE_DSTR(head)->as.nd_alen = 1; } list_append(p, head, tail); break; @@ -10946,7 +12542,17 @@ 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) ? (node)->nd_body : node) +#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; + node = last_expr_node(node); + if (!node) return 0; + return nd_once_body(node); +} + static NODE* match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_loc, const YYLTYPE *loc) { @@ -10955,7 +12561,8 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo value_expr(node1); value_expr(node2); - if (node1 && (n = nd_once_body(node1)) != 0) { + + if ((n = last_expr_once_body(node1)) != 0) { switch (nd_type(n)) { case NODE_DREGX: { @@ -10965,22 +12572,22 @@ match_op(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *op_lo } case NODE_LIT: - if (RB_TYPE_P(n->nd_lit, T_REGEXP)) { - const VALUE lit = n->nd_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); - match->nd_args = reg_named_capture_assign(p, lit, loc); + RNODE_MATCH2(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) { + if ((n = last_expr_once_body(node2)) != 0) { NODE *match3; switch (nd_type(n)) { case NODE_LIT: - if (!RB_TYPE_P(n->nd_lit, T_REGEXP)) break; + if (!RB_TYPE_P(RNODE_LIT(n)->nd_lit, T_REGEXP)) break; /* fallthru */ case NODE_DREGX: match3 = NEW_MATCH3(node2, node1, loc); @@ -11053,7 +12660,7 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *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, node->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit); return node; } @@ -11112,11 +12719,11 @@ opt_arg_append(NODE *opt_list, NODE *opt) NODE *opts = opt_list; opts->nd_loc.end_pos = opt->nd_loc.end_pos; - while (opts->nd_next) { - opts = opts->nd_next; + while (RNODE_OPT_ARG(opts)->nd_next) { + opts = RNODE_OPT_ARG(opts)->nd_next; opts->nd_loc.end_pos = opt->nd_loc.end_pos; } - opts->nd_next = opt; + RNODE_OPT_ARG(opts)->nd_next = opt; return opt_list; } @@ -11146,7 +12753,7 @@ symbol_append(struct parser_params *p, NODE *symbols, NODE *symbol) break; case NODE_STR: nd_set_type(symbol, NODE_LIT); - RB_OBJ_WRITTEN(p->ast, Qnil, symbol->nd_lit = rb_str_intern(symbol->nd_lit)); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(symbol)->nd_lit = rb_str_intern(RNODE_STR(symbol)->nd_lit)); break; default: compile_error(p, "unexpected node as symbol: %s", ruby_node_name(type)); @@ -11157,64 +12764,65 @@ 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) { - NODE *list, *prev; + struct RNode_LIST *list; + NODE *prev; VALUE lit; if (!node) { node = NEW_LIT(reg_compile(p, STR_NEW0(), options), loc); - RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(node)->nd_lit); return node; } switch (nd_type(node)) { case NODE_STR: { - VALUE src = node->nd_lit; + VALUE src = RNODE_STR(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)); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(node)->nd_lit = reg_compile(p, src, options)); } break; default: lit = STR_NEW0(); - node = NEW_NODE(NODE_DSTR, lit, 1, NEW_LIST(node, loc), loc); + node = NEW_DSTR0(lit, 1, NEW_LIST(node, loc), loc); RB_OBJ_WRITTEN(p->ast, Qnil, lit); /* fall through */ case NODE_DSTR: 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) { + 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 && !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 (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); - prev->nd_next = list->nd_next; + RNODE_LIST(prev)->nd_next = list->nd_next; rb_discard_node(p, list->nd_head); - rb_discard_node(p, list); - list = prev; + rb_discard_node(p, (NODE *)list); + list = RNODE_LIST(prev); } else { - prev = list; + prev = (NODE *)list; } } else { prev = 0; } } - if (!node->nd_next) { - VALUE src = node->nd_lit; + if (!RNODE_DREGX(node)->nd_next) { + VALUE src = RNODE_DREGX(node)->nd_lit; nd_set_type(node, NODE_LIT); - RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = reg_compile(p, src, options)); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_DREGX(node)->nd_lit = reg_compile(p, src, options)); } if (options & RE_OPTION_ONCE) { - node = NEW_NODE(NODE_ONCE, 0, node, 0, loc); + node = NEW_ONCE(node, loc); } break; } @@ -11247,7 +12855,7 @@ new_xstring(struct parser_params *p, NODE *node, const YYLTYPE *loc) nd_set_loc(node, loc); break; default: - node = NEW_NODE(NODE_DXSTR, Qnil, 1, NEW_LIST(node, loc), loc); + node = NEW_DXSTR(Qnil, 1, NEW_LIST(node, loc), loc); break; } return node; @@ -11263,7 +12871,7 @@ 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, arg->nd_lit = lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_STR(arg)->nd_lit = lit); } if (NIL_P(p->case_labels)) { @@ -11307,12 +12915,12 @@ new_regexp(struct parser_params *p, VALUE re, VALUE opt, const YYLTYPE *loc) VALUE src = 0, err = 0; int options = 0; if (ripper_is_node_yylval(p, re)) { - src = RNODE(re)->nd_cval; - re = RNODE(re)->nd_rval; + src = RNODE_RIPPER(re)->nd_cval; + re = RNODE_RIPPER(re)->nd_rval; } if (ripper_is_node_yylval(p, opt)) { - options = (int)RNODE(opt)->nd_tag; - opt = RNODE(opt)->nd_rval; + options = (int)RNODE_RIPPER(opt)->nd_vid; + opt = RNODE_RIPPER(opt)->nd_rval; } if (src && NIL_P(parser_reg_compile(p, src, options, &err))) { compile_error(p, "%"PRIsVALUE, err); @@ -11680,10 +13288,10 @@ 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", node->nd_nth); + compile_error(p, "Can't set variable $%ld", RNODE_NTH_REF(node)->nd_nth); break; case NODE_BACK_REF: - compile_error(p, "Can't set variable $%c", (int)node->nd_nth); + compile_error(p, "Can't set variable $%c", (int)RNODE_BACK_REF(node)->nd_nth); break; } } @@ -11692,7 +13300,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, ref->nd_cval); + rb_str_append(mesg, RNODE_RIPPER(ref)->nd_cval); return dispatch2(assign_error, mesg, expr); } #endif @@ -11706,18 +13314,18 @@ arg_append(struct parser_params *p, NODE *node1, NODE *node2, const YYLTYPE *loc case NODE_LIST: return list_append(p, node1, node2); case NODE_BLOCK_PASS: - node1->nd_head = arg_append(p, node1->nd_head, node2, loc); - node1->nd_loc.end_pos = node1->nd_head->nd_loc.end_pos; + 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; case NODE_ARGSPUSH: - 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; + 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; case NODE_ARGSCAT: - 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; + 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; return node1; } return NEW_ARGSPUSH(node1, node2, loc); @@ -11729,20 +13337,20 @@ 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 (node1->nd_head) - node1->nd_head = arg_concat(p, node1->nd_head, node2, loc); + 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 - node1->nd_head = NEW_LIST(node2, loc); + RNODE_LIST(node1)->nd_head = NEW_LIST(node2, loc); return node1; case NODE_ARGSPUSH: if (!nd_type_p(node2, NODE_LIST)) break; - node1->nd_body = list_concat(NEW_LIST(node1->nd_body, loc), node2); + RNODE_ARGSPUSH(node1)->nd_body = list_concat(NEW_LIST(RNODE_ARGSPUSH(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(node1->nd_body, NODE_LIST)) break; - node1->nd_body = list_concat(node1->nd_body, node2); + !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; } return NEW_ARGSCAT(node1, node2, loc); @@ -11771,7 +13379,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 = node->nd_head; + if (nd_type_p(node, NODE_SPLAT)) node = RNODE_SPLAT(node)->nd_head; if (nd_type_p(node, NODE_LIST)) return node; return 0; } @@ -11783,12 +13391,12 @@ mark_lvar_used(struct parser_params *p, NODE *rhs) if (!rhs) return; switch (nd_type(rhs)) { case NODE_LASGN: - if (local_id_ref(p, rhs->nd_vid, &vidp)) { + if (local_id_ref(p, RNODE_LASGN(rhs)->nd_vid, &vidp)) { if (vidp) *vidp |= LVAR_USED; } break; case NODE_DASGN: - if (dvar_defined_ref(p, rhs->nd_vid, &vidp)) { + if (dvar_defined_ref(p, RNODE_DASGN(rhs)->nd_vid, &vidp)) { if (vidp) *vidp |= LVAR_USED; } break; @@ -11809,18 +13417,18 @@ const_decl_path(struct parser_params *p, NODE **dest) if (!nd_type_p(n, NODE_CALL)) { const YYLTYPE *loc = &n->nd_loc; VALUE path; - if (n->nd_vid) { - path = rb_id2str(n->nd_vid); + if (RNODE_DASGN(n)->nd_vid) { + path = rb_id2str(RNODE_DASGN(n)->nd_vid); } else { - n = n->nd_else; + n = RNODE_CDECL(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)); + 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(n->nd_vid)); + rb_ary_push(path, rb_id2str(RNODE_CONST(n)->nd_vid)); } else if (n && nd_type_p(n, NODE_COLON3)) { // ::Const::Name @@ -11834,7 +13442,7 @@ const_decl_path(struct parser_params *p, NODE **dest) path = rb_fstring(path); } *dest = n = NEW_LIT(path, loc); - RB_OBJ_WRITTEN(p->ast, Qnil, n->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit); } return n; } @@ -11878,7 +13486,7 @@ shareable_literal_value(struct parser_params *p, NODE *node) case NODE_NIL: return Qnil; case NODE_LIT: - return node->nd_lit; + return RNODE_LIT(node)->nd_lit; default: return Qundef; } @@ -11912,26 +13520,26 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, return value; case NODE_STR: - lit = rb_fstring(value->nd_lit); + lit = rb_fstring(RNODE_STR(value)->nd_lit); nd_set_type(value, NODE_LIT); - RB_OBJ_WRITE(p->ast, &value->nd_lit, lit); + RB_OBJ_WRITE(p->ast, &RNODE_STR(value)->nd_lit, lit); return value; case NODE_ZLIST: lit = rb_ary_new(); OBJ_FREEZE_RAW(lit); NODE *n = NEW_LIT(lit, loc); - RB_OBJ_WRITTEN(p->ast, Qnil, n->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit); return n; case NODE_LIST: lit = rb_ary_new(); - for (NODE *n = value; n; n = n->nd_next) { - NODE *elt = n->nd_head; + 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) { - n->nd_head = elt; + RNODE_LIST(n)->nd_head = elt; } else if (RTEST(lit)) { rb_ary_clear(lit); @@ -11952,15 +13560,15 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, break; case NODE_HASH: - if (!value->nd_brace) return 0; + if (!RNODE_HASH(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; + 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) { - n->nd_head = key; + RNODE_LIST(n)->nd_head = key; } else if (RTEST(lit)) { rb_hash_clear(lit); @@ -11970,7 +13578,7 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, if (val) { val = shareable_literal_constant_next(val); if (val) { - n->nd_next->nd_head = val; + RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head = val; } else if (RTEST(lit)) { rb_hash_clear(lit); @@ -12008,7 +13616,7 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable, } else { value = NEW_LIT(rb_ractor_make_shareable(lit), loc); - RB_OBJ_WRITTEN(p->ast, Qnil, value->nd_lit); + RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit); } return value; @@ -12062,12 +13670,12 @@ node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ct case NODE_DASGN: case NODE_MASGN: case NODE_CVASGN: - lhs->nd_value = rhs; + RNODE_GASGN(lhs)->nd_value = rhs; nd_set_loc(lhs, loc); break; case NODE_ATTRASGN: - lhs->nd_args = arg_append(p, lhs->nd_args, rhs, loc); + RNODE_ATTRASGN(lhs)->nd_args = arg_append(p, RNODE_ATTRASGN(lhs)->nd_args, rhs, loc); nd_set_loc(lhs, loc); break; @@ -12097,44 +13705,44 @@ value_expr_check(struct parser_params *p, NODE *node) return void_node ? void_node : node; case NODE_CASE3: - if (!node->nd_body || !nd_type_p(node->nd_body, NODE_IN)) { + if (!RNODE_CASE3(node)->nd_body || !nd_type_p(RNODE_CASE3(node)->nd_body, NODE_IN)) { compile_error(p, "unexpected node"); return NULL; } - if (node->nd_body->nd_body) { + 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 (node->nd_next) { - node = node->nd_next; + while (RNODE_BLOCK(node)->nd_next) { + node = RNODE_BLOCK(node)->nd_next; } - node = node->nd_head; + node = RNODE_BLOCK(node)->nd_head; break; case NODE_BEGIN: - node = node->nd_body; + node = RNODE_BEGIN(node)->nd_body; break; case NODE_IF: case NODE_UNLESS: - if (!node->nd_body) { + if (!RNODE_IF(node)->nd_body) { return NULL; } - else if (!node->nd_else) { + else if (!RNODE_IF(node)->nd_else) { return NULL; } - vn = value_expr_check(p, node->nd_body); + vn = value_expr_check(p, RNODE_IF(node)->nd_body); if (!vn) return NULL; if (!void_node) void_node = vn; - node = node->nd_else; + node = RNODE_IF(node)->nd_else; break; case NODE_AND: case NODE_OR: - node = node->nd_1st; + node = RNODE_AND(node)->nd_1st; break; case NODE_LASGN: @@ -12162,6 +13770,7 @@ value_expr_gen(struct parser_params *p, NODE *node) } return TRUE; } + static void void_expr(struct parser_params *p, NODE *node) { @@ -12172,7 +13781,7 @@ void_expr(struct parser_params *p, NODE *node) if (!node || !(node = nd_once_body(node))) return; switch (nd_type(node)) { case NODE_OPCALL: - switch (node->nd_mid) { + switch (RNODE_OPCALL(node)->nd_mid) { case '+': case '-': case '*': @@ -12191,7 +13800,7 @@ void_expr(struct parser_params *p, NODE *node) case tLEQ: case tEQ: case tNEQ: - useless = rb_id2name(node->nd_mid); + useless = rb_id2name(RNODE_OPCALL(node)->nd_mid); break; } break; @@ -12254,9 +13863,9 @@ void_stmts(struct parser_params *p, NODE *node) if (!node) return n; if (!nd_type_p(node, NODE_BLOCK)) return n; - while (node->nd_next) { - void_expr(p, node->nd_head); - node = node->nd_next; + while (RNODE_BLOCK(node)->nd_next) { + void_expr(p, RNODE_BLOCK(node)->nd_head); + node = RNODE_BLOCK(node)->nd_next; } return n; } @@ -12265,8 +13874,8 @@ static NODE * remove_begin(NODE *node) { NODE **n = &node, *n1 = node; - while (n1 && nd_type_p(n1, NODE_BEGIN) && n1->nd_body) { - *n = n1 = n1->nd_body; + while (n1 && nd_type_p(n1, NODE_BEGIN) && RNODE_BEGIN(n1)->nd_body) { + *n = n1 = RNODE_BEGIN(n1)->nd_body; } return node; } @@ -12276,7 +13885,7 @@ remove_begin_all(NODE *node) { NODE **n = &node, *n1 = node; while (n1 && nd_type_p(n1, NODE_BEGIN)) { - *n = n1 = n1->nd_body; + *n = n1 = RNODE_BEGIN(n1)->nd_body; } return node; } @@ -12290,10 +13899,10 @@ reduce_nodes(struct parser_params *p, NODE **body) *body = NEW_NIL(&NULL_LOC); return; } -#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)) +#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)) while (node) { int newline = (int)(node->flags & NODE_FL_NEWLINE); @@ -12303,36 +13912,36 @@ reduce_nodes(struct parser_params *p, NODE **body) *body = 0; return; case NODE_RETURN: - *body = node = node->nd_stts; + *body = node = RNODE_RETURN(node)->nd_stts; if (newline && node) node->flags |= NODE_FL_NEWLINE; continue; case NODE_BEGIN: - *body = node = node->nd_body; + *body = node = RNODE_BEGIN(node)->nd_body; if (newline && node) node->flags |= NODE_FL_NEWLINE; continue; case NODE_BLOCK: - body = &node->nd_end->nd_head; + body = &RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head; break; case NODE_IF: case NODE_UNLESS: - if (subnodes(nd_body, nd_else)) break; + if (subnodes(RNODE_IF, nd_body, nd_else)) break; return; case NODE_CASE: - body = &node->nd_body; + body = &RNODE_CASE(node)->nd_body; break; case NODE_WHEN: - if (!subnodes(nd_body, nd_next)) goto end; + if (!subnodes(RNODE_WHEN, nd_body, nd_next)) goto end; break; case NODE_ENSURE: - if (!subnodes(nd_head, nd_resq)) goto end; + if (!subnodes(RNODE_ENSURE, nd_head, nd_resq)) goto end; break; case NODE_RESCUE: newline = 0; // RESBODY should not be a NEWLINE - if (node->nd_else) { - body = &node->nd_resq; + if (RNODE_RESCUE(node)->nd_else) { + body = &RNODE_RESCUE(node)->nd_resq; break; } - if (!subnodes(nd_head, nd_resq)) goto end; + if (!subnodes(RNODE_RESCUE, nd_head, nd_resq)) goto end; break; default: return; @@ -12350,11 +13959,11 @@ is_static_content(NODE *node) if (!node) return 1; switch (nd_type(node)) { case NODE_HASH: - if (!(node = node->nd_head)) break; + if (!(node = RNODE_HASH(node)->nd_head)) break; case NODE_LIST: do { - if (!is_static_content(node->nd_head)) return 0; - } while ((node = node->nd_next) != 0); + if (!is_static_content(RNODE_LIST(node)->nd_head)) return 0; + } while ((node = RNODE_LIST(node)->nd_next) != 0); case NODE_LIT: case NODE_STR: case NODE_NIL: @@ -12383,10 +13992,10 @@ assign_in_cond(struct parser_params *p, NODE *node) return 0; } - if (!node->nd_value) return 1; - if (is_static_content(node->nd_value)) { + if (!RNODE_MASGN(node)->nd_value) return 1; + if (is_static_content(RNODE_MASGN(node)->nd_value)) { /* reports always */ - parser_warn(p, node->nd_value, "found `= literal' in conditional, should be =="); + parser_warn(p, RNODE_MASGN(node)->nd_value, "found `= literal' in conditional, should be =="); } return 1; } @@ -12415,7 +14024,7 @@ range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc) type = nd_type(node); value_expr(node); - if (type == NODE_LIT && FIXNUM_P(node->nd_lit)) { + 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); @@ -12442,16 +14051,20 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l return NEW_MATCH2(node, NEW_GVAR(idLASTLINE, loc), loc); + case NODE_BLOCK: + RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head = cond0(p, RNODE_BLOCK(RNODE_BLOCK(node)->nd_end)->nd_head, type, loc); + break; + case NODE_AND: case NODE_OR: - node->nd_1st = cond0(p, node->nd_1st, COND_IN_COND, loc); - node->nd_2nd = cond0(p, node->nd_2nd, COND_IN_COND, loc); + RNODE_AND(node)->nd_1st = cond0(p, RNODE_AND(node)->nd_1st, COND_IN_COND, loc); + RNODE_AND(node)->nd_2nd = cond0(p, RNODE_AND(node)->nd_2nd, COND_IN_COND, loc); break; case NODE_DOT2: case NODE_DOT3: - node->nd_beg = range_op(p, node->nd_beg, loc); - node->nd_end = range_op(p, node->nd_end, loc); + 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; @@ -12462,15 +14075,15 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l break; case NODE_LIT: - if (RB_TYPE_P(node->nd_lit, T_REGEXP)) { + 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 (node->nd_lit == Qtrue || - node->nd_lit == Qfalse) { + 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(node->nd_lit)) { + else if (SYMBOL_P(RNODE_LIT(node)->nd_lit)) { goto warn_symbol; } else { @@ -12519,6 +14132,8 @@ new_unless(struct parser_params *p, NODE *cc, NODE *left, NODE *right, const YYL 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) @@ -12528,19 +14143,21 @@ logop(struct parser_params *p, ID id, NODE *left, NODE *right, value_expr(left); if (left && nd_type_p(left, type)) { NODE *node = left, *second; - while ((second = node->nd_2nd) != 0 && nd_type_p(second, type)) { + while ((second = RNODE_AND(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); + 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_NODE(type, left, right, 0, loc); + op = NEW_AND_OR(type, left, right, 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) { @@ -12555,8 +14172,8 @@ ret_args(struct parser_params *p, NODE *node) if (node) { no_blockarg(p, node); if (nd_type_p(node, NODE_LIST)) { - if (node->nd_next == 0) { - node = node->nd_head; + if (RNODE_LIST(node)->nd_next == 0) { + node = RNODE_LIST(node)->nd_head; } else { nd_set_type(node, NODE_VALUES); @@ -12617,7 +14234,7 @@ arg_blk_pass(NODE *node1, NODE *node2) { if (node2) { if (!node1) return node2; - node2->nd_head = node1; + RNODE_BLOCK_PASS(node2)->nd_head = node1; nd_set_first_lineno(node2, nd_first_lineno(node1)); nd_set_first_column(node2, nd_first_column(node1)); return node2; @@ -12642,7 +14259,7 @@ 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) { int saved_line = p->ruby_sourceline; - struct rb_args_info *args = tail->nd_ainfo; + struct rb_args_info *args = RNODE_ARGS(tail)->nd_ainfo; if (args->forwarding) { if (rest_arg) { @@ -12652,12 +14269,12 @@ new_args(struct parser_params *p, NODE *pre_args, NODE *opt_args, ID rest_arg, N rest_arg = idFWD_REST; } - args->pre_args_num = pre_args ? rb_long2int(pre_args->nd_plen) : 0; - args->pre_init = pre_args ? pre_args->nd_next : 0; + args->pre_args_num = pre_args ? rb_long2int(RNODE_ARGS_AUX(pre_args)->nd_plen) : 0; + args->pre_init = pre_args ? RNODE_ARGS_AUX(pre_args)->nd_next : 0; - args->post_args_num = post_args ? rb_long2int(post_args->nd_plen) : 0; - args->post_init = post_args ? post_args->nd_next : 0; - args->first_post_arg = post_args ? post_args->nd_pid : 0; + args->post_args_num = post_args ? rb_long2int(RNODE_ARGS_AUX(post_args)->nd_plen) : 0; + args->post_init = post_args ? RNODE_ARGS_AUX(post_args)->nd_next : 0; + args->first_post_arg = post_args ? RNODE_ARGS_AUX(post_args)->nd_pid : 0; args->rest_arg = rest_arg; @@ -12679,13 +14296,9 @@ static NODE* new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, const YYLTYPE *kw_rest_loc) { int saved_line = p->ruby_sourceline; - NODE *node; - VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(); + NODE *node = NEW_ARGS(0, &NULL_LOC); 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); + RNODE_ARGS(node)->nd_ainfo = args; if (p->error_p) return node; args->block_arg = block; @@ -12706,15 +14319,15 @@ new_args_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, ID block, 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)) + if (!NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(RNODE_KW_ARG(kwn)->nd_body))) --kw_vars; --required_kw_vars; - kwn = kwn->nd_next; + kwn = RNODE_KW_ARG(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)) { + for (kwn = kw_args; kwn; kwn = RNODE_KW_ARG(kwn)->nd_next) { + ID vid = RNODE_LASGN(RNODE_KW_ARG(kwn)->nd_body)->nd_vid; + if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(RNODE_KW_ARG(kwn)->nd_body))) { *required_kw_vars++ = vid; } else { @@ -12748,7 +14361,7 @@ args_with_numbered(struct parser_params *p, NODE *args, int max_numparam) args = new_args_tail(p, 0, 0, 0, 0); nd_set_loc(args, &loc); } - args->nd_ainfo->pre_args_num = max_numparam; + RNODE_ARGS(args)->nd_ainfo->pre_args_num = max_numparam; } return args; } @@ -12756,9 +14369,9 @@ args_with_numbered(struct parser_params *p, NODE *args, int max_numparam) static NODE* new_array_pattern(struct parser_params *p, NODE *constant, NODE *pre_arg, NODE *aryptn, const YYLTYPE *loc) { - struct rb_ary_pattern_info *apinfo = aryptn->nd_apinfo; + struct rb_ary_pattern_info *apinfo = RNODE_ARYPTN(aryptn)->nd_apinfo; - aryptn->nd_pconst = constant; + RNODE_ARYPTN(aryptn)->nd_pconst = constant; if (pre_arg) { NODE *pre_args = NEW_LIST(pre_arg, loc); @@ -12776,12 +14389,9 @@ 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) { int saved_line = p->ruby_sourceline; - NODE *node; - VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(); + NODE *node = NEW_ARYPTN(loc); 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); + RNODE_ARYPTN(node)->nd_apinfo = apinfo; apinfo->pre_args = pre_args; @@ -12801,7 +14411,7 @@ new_array_pattern_tail(struct parser_params *p, NODE *pre_args, int has_rest, NO static NODE* new_find_pattern(struct parser_params *p, NODE *constant, NODE *fndptn, const YYLTYPE *loc) { - fndptn->nd_pconst = constant; + RNODE_FNDPTN(fndptn)->nd_pconst = constant; return fndptn; } @@ -12810,12 +14420,9 @@ static NODE* new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc) { int saved_line = p->ruby_sourceline; - NODE *node; - VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer(); + NODE *node = NEW_FNDPTN(loc); 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); + RNODE_FNDPTN(node)->nd_fpinfo = fpinfo; fpinfo->pre_rest_arg = pre_rest_arg ? pre_rest_arg : NODE_SPECIAL_NO_NAME_REST; fpinfo->args = args; @@ -12828,7 +14435,7 @@ new_find_pattern_tail(struct parser_params *p, NODE *pre_rest_arg, NODE *args, N static NODE* new_hash_pattern(struct parser_params *p, NODE *constant, NODE *hshptn, const YYLTYPE *loc) { - hshptn->nd_pconst = constant; + RNODE_HSHPTN(hshptn)->nd_pconst = constant; return hshptn; } @@ -12848,7 +14455,7 @@ new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw_rest_arg, co kw_rest_arg_node = NULL; } - node = NEW_NODE(NODE_HSHPTN, 0, kw_args, kw_rest_arg_node, loc); + node = NEW_HSHPTN(0, kw_args, kw_rest_arg_node, loc); p->ruby_sourceline = saved_line; return node; @@ -12869,13 +14476,13 @@ dsym_node(struct parser_params *p, NODE *node, const YYLTYPE *loc) nd_set_loc(node, loc); break; case NODE_STR: - lit = node->nd_lit; - RB_OBJ_WRITTEN(p->ast, Qnil, node->nd_lit = ID2SYM(rb_intern_str(lit))); + lit = RNODE_STR(node)->nd_lit; + 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; default: - node = NEW_NODE(NODE_DSYM, Qnil, 1, NEW_LIST(node, loc), loc); + node = NEW_DSYM(Qnil, 1, NEW_LIST(node, loc), loc); break; } return node; @@ -12886,9 +14493,9 @@ append_literal_keys(st_data_t k, st_data_t v, st_data_t h) { NODE *node = (NODE *)v; NODE **result = (NODE **)h; - node->nd_alen = 2; - node->nd_next->nd_end = node->nd_next; - node->nd_next->nd_next = 0; + 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; if (*result) list_concat(*result, node); else @@ -12904,28 +14511,28 @@ remove_duplicate_keys(struct parser_params *p, NODE *hash) literal_hash, }; - st_table *literal_keys = st_init_table_with_size(&literal_type, hash->nd_alen / 2); + st_table *literal_keys = st_init_table_with_size(&literal_type, RNODE_LIST(hash)->as.nd_alen / 2); NODE *result = 0; NODE *last_expr = 0; rb_code_location_t loc = hash->nd_loc; - while (hash && hash->nd_head && hash->nd_next) { - NODE *head = hash->nd_head; - NODE *value = hash->nd_next; - NODE *next = value->nd_next; + while (hash && RNODE_LIST(hash)->nd_head && 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; - value->nd_next = 0; + RNODE_LIST(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; + 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", - head->nd_lit, nd_line(head)); + RNODE_LIT(head)->nd_lit, nd_line(head)); if (dup_value == last_expr) { - value->nd_head = block_append(p, dup_value->nd_head, value->nd_head); + RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head); } else { - last_expr->nd_head = block_append(p, dup_value->nd_head, last_expr->nd_head); + 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); @@ -12992,7 +14599,7 @@ new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_c NODE *asgn; if (lhs) { - ID vid = lhs->nd_vid; + ID vid = RNODE_LASGN(lhs)->nd_vid; YYLTYPE lhs_loc = lhs->nd_loc; int shareable = ctxt.shareable_constant_value; if (shareable) { @@ -13008,23 +14615,15 @@ new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_c } if (op == tOROP) { rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc); - lhs->nd_value = rhs; + RNODE_LASGN(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; + RNODE_LASGN(lhs)->nd_value = rhs; nd_set_loc(lhs, loc); asgn = NEW_OP_ASGN_AND(gettable(p, vid, &lhs_loc), lhs, loc); } @@ -13034,7 +14633,7 @@ new_op_assign(struct parser_params *p, NODE *lhs, ID op, NODE *rhs, struct lex_c if (shareable) { rhs = shareable_constant_value(p, shareable, lhs, rhs, &rhs->nd_loc); } - asgn->nd_value = rhs; + RNODE_LASGN(asgn)->nd_value = rhs; nd_set_loc(asgn, loc); } } @@ -13057,7 +14656,7 @@ new_ary_op_assign(struct parser_params *p, NODE *ary, else { args = arg_concat(p, args, rhs, loc); } - asgn = NEW_OP_ASGN1(ary, op, args, loc); + asgn = NEW_OP_ASGN1(ary, op, (rb_node_argscat_t *)args, loc); fixpos(asgn, ary); return asgn; } @@ -13261,17 +14860,6 @@ 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 @@ -13599,23 +15187,8 @@ 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; - - if (!len) return ST_CONTINUE; - if (rb_enc_symname_type(s, len, enc, (1U<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; + return rb_reg_named_capture_assign_iter_impl(p, s, len, enc, &arg->succ_block, arg->loc); } static NODE * @@ -13630,7 +15203,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 arg.succ_block->nd_next; + return RNODE_BLOCK(arg.succ_block)->nd_next; } #endif @@ -13642,7 +15215,7 @@ rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, lo NODE *node, *succ; if (!len) return ST_CONTINUE; - if (rb_enc_symname_type(s, len, enc, (1U<nd_cval : str; + str = ripper_is_node_yylval(p, str) ? RNODE_RIPPER(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); @@ -13789,6 +15362,7 @@ 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 @@ -14361,9 +15935,19 @@ rb_parser_printf(struct parser_params *p, const char *fmt, ...) } static void -parser_compile_error(struct parser_params *p, const char *fmt, ...) +parser_compile_error(struct parser_params *p, const rb_code_location_t *loc, 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; @@ -14371,8 +15955,7 @@ parser_compile_error(struct parser_params *p, const char *fmt, ...) p->error_buffer = rb_syntax_error_append(p->error_buffer, p->ruby_sourcefile_string, - p->ruby_sourceline, - rb_long2int(p->lex.pcur - p->lex.pbeg), + lineno, column, p->enc, fmt, ap); va_end(ap); } diff --git a/parser_node.h b/parser_node.h index 886f9af7d28051..29557206762811 100644 --- a/parser_node.h +++ b/parser_node.h @@ -22,107 +22,6 @@ code_loc_gen(const rb_code_location_t *loc1, const rb_code_location_t *loc2) return loc; } -#define RNODE(obj) ((struct RNode *)(obj)) - - -#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,0,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,0,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(v,loc) NEW_NODE(NODE_KW_ARG,0,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) - #if defined(__cplusplus) #if 0 { /* satisfy cc-mode */ diff --git a/prism/api_pack.c b/prism/api_pack.c new file mode 100644 index 00000000000000..bb2f4ea2153e1b --- /dev/null +++ b/prism/api_pack.c @@ -0,0 +1,256 @@ +#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)); +} + +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); +} + +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/yarp/config.yml b/prism/config.yml similarity index 94% rename from yarp/config.yml rename to prism/config.yml index e63c2bb80216e3..3e05706f50038b 100644 --- a/yarp/config.yml +++ b/prism/config.yml @@ -232,6 +232,8 @@ tokens: comment: "<<" - name: LESS_LESS_EQUAL comment: "<<=" + - name: METHOD_NAME + comment: "a method name" - name: MINUS comment: "-" - name: MINUS_EQUAL @@ -333,6 +335,16 @@ flags: comment: "&. operator" - name: VARIABLE_CALL comment: "a call that could have been a local variable" + - name: IntegerBaseFlags + values: + - name: BINARY + comment: "0b prefix" + - name: OCTAL + comment: "0o or 0 prefix" + - name: DECIMAL + comment: "0d or no prefix" + - name: HEXADECIMAL + comment: "0x prefix" - name: LoopFlags values: - name: BEGIN_MODIFIER @@ -345,10 +357,10 @@ flags: values: - name: IGNORE_CASE comment: "i - ignores the case of characters when matching" - - name: MULTI_LINE - comment: "m - allows $ to match the end of lines within strings" - 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: EUC_JP comment: "e - forces the EUC-JP encoding" - name: ASCII_8BIT @@ -359,8 +371,12 @@ flags: comment: "u - forces the UTF-8 encoding" - name: ONCE comment: "o - only interpolates values into the regular expression once" + - name: StringFlags + values: + - name: FROZEN + comment: "frozen by virtue of a frozen_string_literal comment" nodes: - - name: AliasNode + - name: AliasGlobalVariableNode fields: - name: new_name type: node @@ -369,7 +385,20 @@ nodes: - name: keyword_loc type: location comment: | - Represents the use of the `alias` keyword. + 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 ^^^^^^^^^^^^^ @@ -641,7 +670,6 @@ nodes: type: location? - name: block type: node? - kind: BlockNode - name: flags type: flags kind: CallNodeFlags @@ -1386,6 +1414,19 @@ nodes: 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: InNode fields: - name: pattern @@ -1483,11 +1524,34 @@ nodes: @foo = 1 ^^^^^^^^ - name: IntegerNode + fields: + - name: flags + type: flags + kind: IntegerBaseFlags comment: | Represents an integer number literal. 1 ^ + - name: InterpolatedMatchLastLineNode + fields: + - name: opening_loc + type: location + - name: parts + type: node[] + - name: closing_loc + type: location + - name: flags + type: flags + kind: RegularExpressionFlags + 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: opening_loc @@ -1702,6 +1766,27 @@ nodes: foo = 1 ^^^^^^^ + - name: MatchLastLineNode + fields: + - name: opening_loc + type: location + - name: content_loc + type: location + semantic_field: true # https://github.com/ruby/prism/issues/1452 + - name: closing_loc + type: location + - name: unescaped + type: string + - name: flags + type: flags + kind: RegularExpressionFlags + 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 @@ -1728,6 +1813,19 @@ nodes: foo => bar ^^^^^^^^^^ + - name: MatchWriteNode + fields: + - name: call + type: node + kind: CallNode + - name: locals + type: constant[] + comment: | + Represents writing local variables using a regular expression match with + named capture groups. + + /(?bar)/ =~ baz + ^^^^^^^^^^^^^^^^^^^^ - name: MissingNode comment: | Represents a node that is missing from the source and results in a syntax @@ -1855,11 +1953,11 @@ nodes: type: node[] - name: optionals type: node[] - - name: posts - type: node[] - name: rest type: node? kind: RestParameterNode + - name: posts + type: node[] - name: keywords type: node[] - name: keyword_rest @@ -1995,6 +2093,7 @@ nodes: type: location - name: content_loc type: location + semantic_field: true # https://github.com/ruby/prism/issues/1452 - name: closing_loc type: location - name: unescaped @@ -2183,10 +2282,15 @@ nodes: ^^^^^^^^^^^ - name: StringNode fields: + - name: flags + type: flags + kind: StringFlags - name: opening_loc type: location? + semantic_field: true # https://github.com/ruby/prism/issues/1452 - name: content_loc type: location + semantic_field: true # https://github.com/ruby/prism/issues/1452 - name: closing_loc type: location? - name: unescaped @@ -2216,7 +2320,6 @@ nodes: type: location? - name: block type: node? - kind: BlockNode comment: | Represents the use of the `super` keyword with parentheses or arguments. diff --git a/prism/defines.h b/prism/defines.h new file mode 100644 index 00000000000000..6037ae7e26b62b --- /dev/null +++ b/prism/defines.h @@ -0,0 +1,45 @@ +#ifndef PRISM_DEFINES_H +#define PRISM_DEFINES_H + +// This file should be included first by any *.h or *.c in prism + +#include +#include +#include +#include +#include +#include + +// PRISM_EXPORTED_FUNCTION +#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 + +// PRISM_ATTRIBUTE_UNUSED +#if defined(__GNUC__) +# define PRISM_ATTRIBUTE_UNUSED __attribute__((unused)) +#else +# define PRISM_ATTRIBUTE_UNUSED +#endif + +// inline +#if defined(_MSC_VER) && !defined(inline) +# define inline __inline +#endif + +// Windows versions before 2015 use _snprintf +#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900) +# define snprintf _snprintf +#endif + +int pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length); + +#endif diff --git a/prism/diagnostic.c b/prism/diagnostic.c new file mode 100644 index 00000000000000..7eafd8b088ef63 --- /dev/null +++ b/prism/diagnostic.c @@ -0,0 +1,287 @@ +#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" + - 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_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_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_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 body", + [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_MODULE_IN_METHOD] = "Unexpected module definition in a method body", + [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 alongside explicit parameters", + [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_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_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] = "Token reserved for a numbered parameter", + [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_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_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_WHILE_TERM] = "Expected an `end` to close the `while` statement", + [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", +}; + +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 *) malloc(sizeof(pm_diagnostic_t)); + if (diagnostic == NULL) return false; + + *diagnostic = (pm_diagnostic_t) { .start = start, .end = end, .message = pm_diagnostic_message(diag_id) }; + 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; + free(diagnostic); + } +} diff --git a/prism/diagnostic.h b/prism/diagnostic.h new file mode 100644 index 00000000000000..062ba07d4287f5 --- /dev/null +++ b/prism/diagnostic.h @@ -0,0 +1,231 @@ +#ifndef PRISM_DIAGNOSTIC_H +#define PRISM_DIAGNOSTIC_H + +#include "prism/defines.h" +#include "prism/util/pm_list.h" + +#include +#include +#include + +// This struct represents a diagnostic found during parsing. +typedef struct { + pm_list_node_t node; + const uint8_t *start; + const uint8_t *end; + const char *message; +} pm_diagnostic_t; + +typedef enum { + PM_ERR_ALIAS_ARGUMENT, + PM_ERR_AMPAMPEQ_MULTI_ASSIGN, + PM_ERR_ARGUMENT_AFTER_BLOCK, + 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_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_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_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_BLOCK, + PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI, + PM_ERR_PARAMETER_BLOCK_MULTI, + 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_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_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_WHILE_TERM, + 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, + /* This must be the last member. */ + PM_DIAGNOSTIC_ID_LEN, +} pm_diagnostic_id_t; + +// Append a diagnostic to the given list of diagnostics. +bool pm_diagnostic_list_append(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. +void pm_diagnostic_list_free(pm_list_t *list); + +#endif diff --git a/prism/enc/pm_big5.c b/prism/enc/pm_big5.c new file mode 100644 index 00000000000000..deaa3afb3fb0fd --- /dev/null +++ b/prism/enc/pm_big5.c @@ -0,0 +1,52 @@ +#include "prism/enc/pm_encoding.h" + +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] <= 0xFE)) { + return 2; + } + + return 0; +} + +static size_t +pm_encoding_big5_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_big5_char_width(b, n) == 1) { + return pm_encoding_ascii_alpha_char(b, n); + } else { + return 0; + } +} + +static size_t +pm_encoding_big5_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_big5_char_width(b, n) == 1) { + return pm_encoding_ascii_alnum_char(b, n); + } else { + return 0; + } +} + +static bool +pm_encoding_big5_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_big5_char_width(b, n) == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else { + return false; + } +} + +pm_encoding_t pm_encoding_big5 = { + .name = "big5", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_big5_alnum_char, + .alpha_char = pm_encoding_big5_alpha_char, + .isupper_char = pm_encoding_big5_isupper_char, + .multibyte = true +}; diff --git a/prism/enc/pm_encoding.h b/prism/enc/pm_encoding.h new file mode 100644 index 00000000000000..5236a0b3c4ec5a --- /dev/null +++ b/prism/enc/pm_encoding.h @@ -0,0 +1,95 @@ +#ifndef PRISM_ENCODING_H +#define PRISM_ENCODING_H + +#include "prism/defines.h" + +#include +#include +#include +#include + +// 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; + +// These bits define the location of each bit of metadata within the various +// lookup tables that are used to determine the properties of a character. +#define PRISM_ENCODING_ALPHABETIC_BIT 1 << 0 +#define PRISM_ENCODING_ALPHANUMERIC_BIT 1 << 1 +#define PRISM_ENCODING_UPPERCASE_BIT 1 << 2 + +// These functions are reused by some other encodings, so they are defined here +// so they can be shared. +size_t pm_encoding_ascii_alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n); +size_t pm_encoding_ascii_alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n); +bool pm_encoding_ascii_isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n); + +// These functions are shared between the actual encoding and the fast path in +// the parser so they need to be internally visible. +size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n); +size_t pm_encoding_utf_8_alnum_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. +extern const uint8_t pm_encoding_unicode_table[256]; + +// These are the encodings that are supported by the parser. They are defined in +// their own files in the src/enc directory. +extern pm_encoding_t pm_encoding_ascii; +extern pm_encoding_t pm_encoding_ascii_8bit; +extern pm_encoding_t pm_encoding_big5; +extern pm_encoding_t pm_encoding_euc_jp; +extern pm_encoding_t pm_encoding_gbk; +extern pm_encoding_t pm_encoding_iso_8859_1; +extern pm_encoding_t pm_encoding_iso_8859_2; +extern pm_encoding_t pm_encoding_iso_8859_3; +extern pm_encoding_t pm_encoding_iso_8859_4; +extern pm_encoding_t pm_encoding_iso_8859_5; +extern pm_encoding_t pm_encoding_iso_8859_6; +extern pm_encoding_t pm_encoding_iso_8859_7; +extern pm_encoding_t pm_encoding_iso_8859_8; +extern pm_encoding_t pm_encoding_iso_8859_9; +extern pm_encoding_t pm_encoding_iso_8859_10; +extern pm_encoding_t pm_encoding_iso_8859_11; +extern pm_encoding_t pm_encoding_iso_8859_13; +extern pm_encoding_t pm_encoding_iso_8859_14; +extern pm_encoding_t pm_encoding_iso_8859_15; +extern pm_encoding_t pm_encoding_iso_8859_16; +extern pm_encoding_t pm_encoding_koi8_r; +extern pm_encoding_t pm_encoding_shift_jis; +extern pm_encoding_t pm_encoding_utf_8; +extern pm_encoding_t pm_encoding_utf8_mac; +extern pm_encoding_t pm_encoding_windows_31j; +extern pm_encoding_t pm_encoding_windows_1251; +extern pm_encoding_t pm_encoding_windows_1252; + +#endif diff --git a/prism/enc/pm_euc_jp.c b/prism/enc/pm_euc_jp.c new file mode 100644 index 00000000000000..13d36624559fe7 --- /dev/null +++ b/prism/enc/pm_euc_jp.c @@ -0,0 +1,58 @@ +#include "prism/enc/pm_encoding.h" + +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[1] >= 0xA1 && b[1] <= 0xFE)) || + ((b[0] >= 0xA1 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) + ) + ) { + return 2; + } + + return 0; +} + +static size_t +pm_encoding_euc_jp_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_euc_jp_char_width(b, n) == 1) { + return pm_encoding_ascii_alpha_char(b, n); + } else { + return 0; + } +} + +static size_t +pm_encoding_euc_jp_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_euc_jp_char_width(b, n) == 1) { + return pm_encoding_ascii_alnum_char(b, n); + } else { + return 0; + } +} + +static bool +pm_encoding_euc_jp_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_euc_jp_char_width(b, n) == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else { + return 0; + } +} + +pm_encoding_t pm_encoding_euc_jp = { + .name = "euc-jp", + .char_width = pm_encoding_euc_jp_char_width, + .alnum_char = pm_encoding_euc_jp_alnum_char, + .alpha_char = pm_encoding_euc_jp_alpha_char, + .isupper_char = pm_encoding_euc_jp_isupper_char, + .multibyte = true +}; diff --git a/prism/enc/pm_gbk.c b/prism/enc/pm_gbk.c new file mode 100644 index 00000000000000..2fc67b47a4d988 --- /dev/null +++ b/prism/enc/pm_gbk.c @@ -0,0 +1,61 @@ +#include "prism/enc/pm_encoding.h" + +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 + ) + ) { + return 2; + } + + return 0; +} + +static size_t +pm_encoding_gbk_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_gbk_char_width(b, n) == 1) { + return pm_encoding_ascii_alpha_char(b, n); + } else { + return 0; + } +} + +static size_t +pm_encoding_gbk_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_gbk_char_width(b, n) == 1) { + return pm_encoding_ascii_alnum_char(b, n); + } else { + return 0; + } +} + +static bool +pm_encoding_gbk_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_gbk_char_width(b, n) == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else { + return false; + } +} + +pm_encoding_t pm_encoding_gbk = { + .name = "gbk", + .char_width = pm_encoding_gbk_char_width, + .alnum_char = pm_encoding_gbk_alnum_char, + .alpha_char = pm_encoding_gbk_alpha_char, + .isupper_char = pm_encoding_gbk_isupper_char, + .multibyte = true +}; diff --git a/prism/enc/pm_shift_jis.c b/prism/enc/pm_shift_jis.c new file mode 100644 index 00000000000000..3c93937efc3ca1 --- /dev/null +++ b/prism/enc/pm_shift_jis.c @@ -0,0 +1,56 @@ +#include "prism/enc/pm_encoding.h" + +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; +} + +static size_t +pm_encoding_shift_jis_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_shift_jis_char_width(b, n) == 1) { + return pm_encoding_ascii_alpha_char(b, n); + } else { + return 0; + } +} + +static size_t +pm_encoding_shift_jis_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_shift_jis_char_width(b, n) == 1) { + return pm_encoding_ascii_alnum_char(b, n); + } else { + return 0; + } +} + +static bool +pm_encoding_shift_jis_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_shift_jis_char_width(b, n) == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else { + return 0; + } +} + +pm_encoding_t pm_encoding_shift_jis = { + .name = "shift_jis", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true +}; diff --git a/prism/enc/pm_tables.c b/prism/enc/pm_tables.c new file mode 100644 index 00000000000000..c6bb4dce651d08 --- /dev/null +++ b/prism/enc/pm_tables.c @@ -0,0 +1,507 @@ +#include "prism/enc/pm_encoding.h" + +// Each element of the following table contains a bitfield that indicates a +// piece of information about the corresponding ASCII character. +static 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 ISO-8859-1 character. +static 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 windows-1251 character. +static 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 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 +}; + +static size_t +pm_encoding_ascii_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return *b < 0x80 ? 1 : 0; +} + +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); +} + +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; +} + +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); +} + +static size_t +pm_encoding_koi8_r_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return ((*b >= 0x20 && *b <= 0x7E) || (*b >= 0x80)) ? 1 : 0; +} + +static size_t +pm_encoding_single_char_width(PRISM_ATTRIBUTE_UNUSED const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return 1; +} + +pm_encoding_t pm_encoding_ascii = { + .name = "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_t 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 +}; + +#define PRISM_ENCODING_TABLE(s, i, w) \ + static size_t pm_encoding_ ##i ## _alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##i ## _table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); \ + } \ + static size_t pm_encoding_ ##i ## _alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##i ## _table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; \ + } \ + static bool pm_encoding_ ##i ## _isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##i ## _table[*b] & PRISM_ENCODING_UPPERCASE_BIT); \ + } \ + pm_encoding_t pm_encoding_ ##i = { \ + .name = s, \ + .char_width = w, \ + .alnum_char = pm_encoding_ ##i ## _alnum_char, \ + .alpha_char = pm_encoding_ ##i ## _alpha_char, \ + .isupper_char = pm_encoding_ ##i ## _isupper_char, \ + .multibyte = false, \ + }; + +PRISM_ENCODING_TABLE("iso-8859-1", iso_8859_1, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-2", iso_8859_2, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-3", iso_8859_3, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-4", iso_8859_4, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-5", iso_8859_5, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-6", iso_8859_6, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-7", iso_8859_7, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-8", iso_8859_8, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-9", iso_8859_9, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-10", iso_8859_10, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-11", iso_8859_11, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-13", iso_8859_13, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-14", iso_8859_14, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-15", iso_8859_15, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("iso-8859-16", iso_8859_16, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("koi8-r", koi8_r, pm_encoding_koi8_r_char_width) +PRISM_ENCODING_TABLE("windows-1251", windows_1251, pm_encoding_single_char_width) +PRISM_ENCODING_TABLE("windows-1252", windows_1252, pm_encoding_single_char_width) + +#undef PRISM_ENCODING_TABLE diff --git a/prism/enc/pm_unicode.c b/prism/enc/pm_unicode.c new file mode 100644 index 00000000000000..ab10044424b9c5 --- /dev/null +++ b/prism/enc/pm_unicode.c @@ -0,0 +1,2324 @@ +// Note that the UTF-8 decoding code is based on Bjoern Hoehrmann's UTF-8 DFA +// decoder. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + +#include "prism/enc/pm_encoding.h" + +typedef uint32_t pm_unicode_codepoint_t; + +// 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 +}; + +#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, +}; + +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; +} + +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 +}; + +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; +} + +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; + } +} + +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; + } +} + +static 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; + } +} + +#undef UNICODE_ALPHA_CODEPOINTS_LENGTH +#undef UNICODE_ALNUM_CODEPOINTS_LENGTH +#undef UNICODE_ISUPPER_CODEPOINTS_LENGTH + +pm_encoding_t 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_t 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 +}; diff --git a/prism/enc/pm_windows_31j.c b/prism/enc/pm_windows_31j.c new file mode 100644 index 00000000000000..cf7eb46864d972 --- /dev/null +++ b/prism/enc/pm_windows_31j.c @@ -0,0 +1,56 @@ +#include "prism/enc/pm_encoding.h" + +static size_t +pm_encoding_windows_31j_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; +} + +static size_t +pm_encoding_windows_31j_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_windows_31j_char_width(b, n) == 1) { + return pm_encoding_ascii_alpha_char(b, n); + } else { + return 0; + } +} + +static size_t +pm_encoding_windows_31j_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_windows_31j_char_width(b, n) == 1) { + return pm_encoding_ascii_alnum_char(b, n); + } else { + return 0; + } +} + +static bool +pm_encoding_windows_31j_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (pm_encoding_windows_31j_char_width(b, n) == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else { + return false; + } +} + +pm_encoding_t pm_encoding_windows_31j = { + .name = "windows-31j", + .char_width = pm_encoding_windows_31j_char_width, + .alnum_char = pm_encoding_windows_31j_alnum_char, + .alpha_char = pm_encoding_windows_31j_alpha_char, + .isupper_char = pm_encoding_windows_31j_isupper_char, + .multibyte = true +}; diff --git a/prism/extension.c b/prism/extension.c new file mode 100644 index 00000000000000..97eab6c6133f5a --- /dev/null +++ b/prism/extension.c @@ -0,0 +1,626 @@ +#include "prism/extension.h" + +// NOTE: this file should contain only bindings. +// All non-trivial logic should be in librubyparser 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_cPrismParseError; +VALUE rb_cPrismParseWarning; +VALUE rb_cPrismParseResult; + +/******************************************************************************/ +/* 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)); +} + +/******************************************************************************/ +/* Serializing the AST */ +/******************************************************************************/ + +// Dump the AST corresponding to the given input to a string. +static VALUE +dump_input(pm_string_t *input, const char *filepath) { + 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), filepath); + + 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; +} + +// Dump the AST corresponding to the given string to a string. +static VALUE +dump(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + pm_string_t input; + input_load_string(&input, string); + +#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, check_string(filepath)); + +#ifdef PRISM_DEBUG_MODE_BUILD + free(dup); +#endif + + return value; +} + +// Dump the AST corresponding to the given file to a string. +static VALUE +dump_file(VALUE self, VALUE filepath) { + pm_string_t input; + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + VALUE value = dump_input(&input, checked); + pm_string_free(&input); + + 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->start - parser->start), + LONG2FIX(comment->end - comment->start) + }; + + VALUE type; + switch (comment->type) { + case PM_COMMENT_INLINE: + type = ID2SYM(rb_intern("inline")); + break; + case PM_COMMENT_EMBDOC: + type = ID2SYM(rb_intern("embdoc")); + break; + case PM_COMMENT___END__: + type = ID2SYM(rb_intern("__END__")); + break; + default: + type = ID2SYM(rb_intern("inline")); + break; + } + + VALUE comment_argv[] = { type, rb_class_new_instance(3, location_argv, rb_cPrismLocation) }; + rb_ary_push(comments, rb_class_new_instance(2, comment_argv, rb_cPrismComment)); + } + + return comments; +} + +// 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->start - parser->start), + LONG2FIX(error->end - error->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->start - parser->start), + LONG2FIX(warning->end - warning->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 char *filepath, bool return_nodes) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), filepath); + 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)), offsets }; + VALUE source = rb_class_new_instance(2, 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_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(5, result_argv, rb_cPrismParseResult); +} + +// Return an array of tokens corresponding to the given string. +static VALUE +lex(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + pm_string_t input; + input_load_string(&input, string); + + return parse_lex_input(&input, check_string(filepath), false); +} + +// Return an array of tokens corresponding to the given file. +static VALUE +lex_file(VALUE self, VALUE filepath) { + pm_string_t input; + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + VALUE value = parse_lex_input(&input, checked, false); + pm_string_free(&input); + + return value; +} + +/******************************************************************************/ +/* Parsing Ruby code */ +/******************************************************************************/ + +// Parse the given input and return a ParseResult instance. +static VALUE +parse_input(pm_string_t *input, const char *filepath) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), filepath); + + 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_errors(&parser, encoding, source), + parser_warnings(&parser, encoding, source), + source + }; + + VALUE result = rb_class_new_instance(5, result_argv, rb_cPrismParseResult); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + return result; +} + +// Parse the given string and return a ParseResult instance. +static VALUE +parse(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + pm_string_t input; + input_load_string(&input, string); + +#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, check_string(filepath)); + +#ifdef PRISM_DEBUG_MODE_BUILD + free(dup); +#endif + + return value; +} + +// Parse the given file and return a ParseResult instance. +static VALUE +parse_file(VALUE self, VALUE filepath) { + pm_string_t input; + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + VALUE value = parse_input(&input, checked); + pm_string_free(&input); + + return value; +} + +// Parse the given string and return a ParseResult instance. +static VALUE +parse_lex(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + pm_string_t input; + input_load_string(&input, string); + + VALUE value = parse_lex_input(&input, check_string(filepath), true); + pm_string_free(&input); + + return value; +} + +// Parse and lex the given file and return a ParseResult instance. +static VALUE +parse_lex_file(VALUE self, VALUE filepath) { + pm_string_t input; + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + VALUE value = parse_lex_input(&input, checked, true); + pm_string_free(&input); + + return value; +} + +/******************************************************************************/ +/* Utility functions exposed to make testing easier */ +/******************************************************************************/ + +// 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; + pm_string_list_init(&string_list); + + if (!pm_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, &pm_encoding_utf_8)) { + 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; +} + +// Accepts a source string and a type of unescaping and returns the unescaped +// version. +static VALUE +unescape(VALUE source, pm_unescape_type_t unescape_type) { + pm_string_t result; + + if (pm_unescape_string((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), unescape_type, &result)) { + VALUE str = rb_str_new((const char *) pm_string_source(&result), pm_string_length(&result)); + pm_string_free(&result); + return str; + } else { + pm_string_free(&result); + return Qnil; + } +} + +// Do not unescape anything in the given string. This is here to provide a +// consistent API. +static VALUE +unescape_none(VALUE self, VALUE source) { + return unescape(source, PM_UNESCAPE_NONE); +} + +// Minimally unescape the given string. This means effectively unescaping just +// the quotes of a string. Returns the unescaped string. +static VALUE +unescape_minimal(VALUE self, VALUE source) { + return unescape(source, PM_UNESCAPE_MINIMAL); +} + +// Escape the given string minimally plus whitespace. Returns the unescaped string. +static VALUE +unescape_whitespace(VALUE self, VALUE source) { + return unescape(source, PM_UNESCAPE_WHITESPACE); +} + +// Unescape everything in the given string. Return the unescaped string. +static VALUE +unescape_all(VALUE self, VALUE source) { + return unescape(source, PM_UNESCAPE_ALL); +} + +// 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; +} + +// 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_parser_t parser; + pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), checked); + + pm_node_t *node = pm_parse(&parser); + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + pm_string_free(&input); + + return Qnil; +} + +// Parse the file and serialize the result. This is mostly used to test this +// path since it is used by client libraries. +static VALUE +parse_serialize_file_metadata(VALUE self, VALUE filepath, VALUE metadata) { + pm_string_t input; + pm_buffer_t buffer; + pm_buffer_init(&buffer); + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + pm_parse_serialize(pm_string_source(&input), pm_string_length(&input), &buffer, check_string(metadata)); + VALUE result = rb_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer)); + + pm_string_free(&input); + pm_buffer_free(&buffer); + return result; +} + +/******************************************************************************/ +/* Initialization of the 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_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); + + // Define the version string here so that we can use the constants defined + // in prism.h. + rb_define_const(rb_cPrism, "VERSION", rb_str_new2(EXPECTED_PRISM_VERSION)); + rb_define_const(rb_cPrism, "BACKEND", ID2SYM(rb_intern("CExtension"))); + + // 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_lex", parse_lex, -1); + rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, 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, "unescape_none", unescape_none, 1); + rb_define_singleton_method(rb_cPrismDebug, "unescape_minimal", unescape_minimal, 1); + rb_define_singleton_method(rb_cPrismDebug, "unescape_whitespace", unescape_whitespace, 1); + rb_define_singleton_method(rb_cPrismDebug, "unescape_all", unescape_all, 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, "parse_serialize_file_metadata", parse_serialize_file_metadata, 2); + + // Next, initialize the other APIs. + Init_prism_api_node(); + Init_prism_pack(); +} diff --git a/prism/extension.h b/prism/extension.h new file mode 100644 index 00000000000000..13753f16bbcaad --- /dev/null +++ b/prism/extension.h @@ -0,0 +1,18 @@ +#ifndef PRISM_EXT_NODE_H +#define PRISM_EXT_NODE_H + +#define EXPECTED_PRISM_VERSION "0.13.0" + +#include +#include +#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 new file mode 100644 index 00000000000000..a532badef8490d --- /dev/null +++ b/prism/node.h @@ -0,0 +1,41 @@ +#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. +void pm_node_list_append(pm_node_list_t *list, pm_node_t *node); + +// Clear the node but preserves the location. +void pm_node_clear(pm_node_t *node); + +// Deallocate a node and all of its children. +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 { + size_t memsize; + size_t node_count; +} pm_memsize_t; + +// Calculates the memory footprint of a given node. +PRISM_EXPORTED_FUNCTION void pm_node_memsize(pm_node_t *node, pm_memsize_t *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); + +#define PM_EMPTY_NODE_LIST ((pm_node_list_t) { .nodes = NULL, .size = 0, .capacity = 0 }) + +// 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_parameters_node *parameters; + pm_node_t *body; + pm_constant_id_list_t locals; +} pm_scope_node_t; + +#endif // PRISM_NODE_H diff --git a/prism/pack.c b/prism/pack.c new file mode 100644 index 00000000000000..d5bfc4d6fdf97d --- /dev/null +++ b/prism/pack.c @@ -0,0 +1,493 @@ +#include "prism/pack.h" + +#include +#include + +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 new file mode 100644 index 00000000000000..be52a7b4de823e --- /dev/null +++ b/prism/pack.h @@ -0,0 +1,141 @@ +#ifndef PRISM_PACK_H +#define PRISM_PACK_H + +#include "prism/defines.h" + +#include +#include + +typedef enum pm_pack_version { + PM_PACK_VERSION_3_2_0 +} pm_pack_version; + +typedef enum pm_pack_variant { + PM_PACK_VARIANT_PACK, + PM_PACK_VARIANT_UNPACK +} pm_pack_variant; + +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; + +typedef enum pm_pack_signed { + PM_PACK_UNSIGNED, + PM_PACK_SIGNED, + PM_PACK_SIGNED_NA +} pm_pack_signed; + +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; + +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; + +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; + +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; + +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. +// +// Parameters: +// - [in] pm_pack_version version the version of Ruby +// - [in] pm_pack_variant variant pack or unpack +// - [in out] const char **format 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 +// - [in] const char *format_end the end of the format string +// - [out] pm_pack_type *type the type of the directive +// - [out] pm_pack_signed *signed_type +// whether the value is signed +// - [out] pm_pack_endian *endian the endianness of the value +// - [out] pm_pack_size *size the size of the value +// - [out] pm_pack_length_type *length_type +// what kind of length is specified +// - [out] size_t *length the length of the directive +// - [in out] pm_pack_encoding *encoding +// 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 +// - PM_PACK_ERROR_* on error +// +// Notes: +// Consult Ruby documentation for the meaning of directives. +PRISM_EXPORTED_FUNCTION pm_pack_result +pm_pack_parse( + pm_pack_variant variant_arg, + 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. +PRISM_EXPORTED_FUNCTION size_t pm_size_to_native(pm_pack_size size); + +#endif diff --git a/prism/parser.h b/prism/parser.h new file mode 100644 index 00000000000000..0a5ba80819fe0e --- /dev/null +++ b/prism/parser.h @@ -0,0 +1,418 @@ +#ifndef PRISM_PARSER_H +#define PRISM_PARSER_H + +#include "prism/ast.h" +#include "prism/defines.h" +#include "prism/enc/pm_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 + +// 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; + +typedef enum { + PM_HEREDOC_QUOTE_NONE, + PM_HEREDOC_QUOTE_SINGLE = '\'', + PM_HEREDOC_QUOTE_DOUBLE = '"', + PM_HEREDOC_QUOTE_BACKTICK = '`', +} pm_heredoc_quote_t; + +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 { + 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; + + 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 { + // These pointers point to the beginning and end of the heredoc + // identifier. + const uint8_t *ident_start; + size_t ident_length; + + pm_heredoc_quote_t quote; + 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; + } 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 + +// A forward declaration since our error handler struct accepts a parser for +// each of its function calls. +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 { + PM_CONTEXT_BEGIN, // a begin statement + PM_CONTEXT_BLOCK_BRACES, // expressions in block arguments using braces + PM_CONTEXT_BLOCK_KEYWORDS, // expressions in block arguments using do..end + PM_CONTEXT_CASE_WHEN, // a case when statements + PM_CONTEXT_CASE_IN, // a case in statements + PM_CONTEXT_CLASS, // a class declaration + PM_CONTEXT_DEF, // a method definition + PM_CONTEXT_DEF_PARAMS, // a method definition's parameters + PM_CONTEXT_DEFAULT_PARAMS, // a method definition's default parameter + PM_CONTEXT_ELSE, // an else clause + PM_CONTEXT_ELSIF, // an elsif clause + PM_CONTEXT_EMBEXPR, // an interpolated expression + PM_CONTEXT_ENSURE, // an ensure statement + PM_CONTEXT_FOR, // a for loop + PM_CONTEXT_IF, // an if statement + PM_CONTEXT_LAMBDA_BRACES, // a lambda expression with braces + PM_CONTEXT_LAMBDA_DO_END, // a lambda expression with do..end + PM_CONTEXT_MAIN, // the top level context + PM_CONTEXT_MODULE, // a module declaration + PM_CONTEXT_PARENS, // a parenthesized expression + PM_CONTEXT_POSTEXE, // an END block + PM_CONTEXT_PREDICATE, // a predicate inside an if/elsif/unless statement + PM_CONTEXT_PREEXE, // a BEGIN block + PM_CONTEXT_RESCUE_ELSE, // a rescue else statement + PM_CONTEXT_RESCUE, // a rescue statement + PM_CONTEXT_SCLASS, // a singleton class definition + PM_CONTEXT_UNLESS, // an unless statement + PM_CONTEXT_UNTIL, // an until statement + PM_CONTEXT_WHILE, // a while statement +} pm_context_t; + +// This is a node in a linked list of contexts. +typedef struct pm_context_node { + pm_context_t context; + 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___END__ +} pm_comment_type_t; + +// This is a node in the linked list of comments that we've found while parsing. +typedef struct pm_comment { + pm_list_node_t node; + const uint8_t *start; + const uint8_t *end; + pm_comment_type_t type; +} pm_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 an encoding is encountered that isn't understood by prism, we provide +// the ability here to call out to a user-defined function to get an encoding +// struct. If the function returns something that isn't NULL, we set that to +// our encoding and use it to parse identifiers. +typedef pm_encoding_t *(*pm_encoding_decode_callback_t)(pm_parser_t *parser, const uint8_t *name, size_t width); + +// 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; + + // A boolean indicating whether or not this scope has numbered parameters. + // This is necessary to determine if child blocks are allowed to use + // numbered parameters. + bool numbered_params; +} 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 { + pm_lex_state_t lex_state; // the current state of the lexer + int enclosure_nesting; // tracks the current nesting of (), [], and {} + + // 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; + + struct { + pm_lex_mode_t *current; // the current mode of the lexer + pm_lex_mode_t stack[PM_LEX_STACK_SIZE]; // the stack of lexer modes + size_t index; // the current index into the lexer mode stack + } lex_modes; + + const uint8_t *start; // the pointer to the start of the source + const uint8_t *end; // the pointer to the end of the source + pm_token_t previous; // the previous token we were considering + pm_token_t current; // the current token we're considering + + // 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; + + pm_list_t comment_list; // the list of comments that have been found while parsing + pm_list_t warning_list; // the list of warnings that have been found while parsing + pm_list_t error_list; // the list of errors that have been found while parsing + pm_scope_t *current_scope; // the current local scope + + pm_context_node_t *current_context; // the current parsing 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. + 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; + + // When an encoding is encountered that isn't understood by prism, we + // provide the ability here to call out to a user-defined function to get an + // encoding struct. If the function returns something that isn't NULL, we + // set that to our encoding and use it to parse identifiers. + pm_encoding_decode_callback_t encoding_decode_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; + + // 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; + + // 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; +}; + +#endif // PRISM_PARSER_H diff --git a/prism/prism.c b/prism/prism.c new file mode 100644 index 00000000000000..f8c0beb327c35f --- /dev/null +++ b/prism/prism.c @@ -0,0 +1,14597 @@ +#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 + +// Debugging logging will provide you will additional debugging functions as +// well as automatically replace some functions with their debugging +// counterparts. +#ifndef PM_DEBUG_LOGGING +#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_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_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_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 char *message, pm_parser_t *parser, pm_node_t *node) { + pm_buffer_t buffer; + if (!pm_buffer_init(&buffer)) return; + + pm_prettyprint(parser, node, &buffer); + + fprintf(stderr, "%s\n%.*s\n", message, (int) buffer.length, buffer.value); + pm_buffer_free(&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; + } + + return lex_mode_push(parser, lex_mode); +} + +// 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; + } + + return lex_mode_push(parser, lex_mode); +} + +// 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)); +} + +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 + +/******************************************************************************/ +/* 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 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); +} + +// 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(&token, parser->previous.end); +// +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 { + pm_location_t opening_loc; + pm_arguments_node_t *arguments; + pm_location_t closing_loc; + pm_node_t *block; +} pm_arguments_t; + +#define PM_EMPTY_ARGUMENTS ((pm_arguments_t) { \ + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, \ + .arguments = NULL, \ + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, \ + .block = NULL, \ +}) + +// 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_diagnostic_list_append( + &parser->error_list, + block->base.location.start, + block->base.location.end, + PM_ERR_ARGUMENT_UNEXPECTED_BLOCK + ); +} + +/******************************************************************************/ +/* Scope node functions */ +/******************************************************************************/ + +// Generate a scope node from the given node. +void +pm_scope_node_init(pm_node_t *node, pm_scope_node_t *scope) { + scope->base.type = PM_SCOPE_NODE; + scope->base.location.start = node->location.start; + scope->base.location.end = node->location.end; + + scope->parameters = NULL; + scope->body = 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; + if (cast->parameters) scope->parameters = cast->parameters->parameters; + scope->body = cast->body; + scope->locals = cast->locals; + 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 = cast->parameters; + scope->body = cast->body; + scope->locals = cast->locals; + break; + } + case PM_LAMBDA_NODE: { + pm_lambda_node_t *cast = (pm_lambda_node_t *) node; + if (cast->parameters) scope->parameters = cast->parameters->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_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_SINGLETON_CLASS_NODE: { + pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node; + scope->body = cast->body; + scope->locals = cast->locals; + break; + } + default: + assert(false && "unreachable"); + break; + } +} + +/******************************************************************************/ +/* 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_diagnostic_list_append(&parser->error_list, start, end, PM_ERR_INVALID_NUMBER_DECIMAL); + value = UINT32_MAX; + } + + free(digits); + + if (value > UINT32_MAX) { + pm_diagnostic_list_append(&parser->error_list, start, end, PM_ERR_INVALID_NUMBER_DECIMAL); + value = UINT32_MAX; + } + + return (uint32_t) value; +} + +// 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 'e': flags |= PM_REGULAR_EXPRESSION_FLAGS_EUC_JP; break; + case 'n': flags |= PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break; + case 's': flags |= PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break; + case 'u': flags |= PM_REGULAR_EXPRESSION_FLAGS_UTF_8; break; + case 'o': flags |= PM_REGULAR_EXPRESSION_FLAGS_ONCE; break; + default: assert(false && "unreachable"); + } + } + } + + return flags; +} + +// Allocate and initialize a new StatementsNode node. +static pm_statements_node_t * +pm_statements_node_create(pm_parser_t *parser); + +// 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); + +// Get the length of the given StatementsNode node's body. +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_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 = PM_EMPTY_NODE_LIST + }; + + 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 = PM_EMPTY_NODE_LIST + }; + + 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) || (element->flags & PM_NODE_FLAG_STATIC_LITERAL) == 0) { + node->base.flags &= (pm_node_flags_t) ~PM_NODE_FLAG_STATIC_LITERAL; + } +} + +// 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 = PM_EMPTY_NODE_LIST, + .posts = PM_EMPTY_NODE_LIST, + .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)) { + 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 = PM_EMPTY_NODE_LIST, + .posts = PM_EMPTY_NODE_LIST, + .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 = PM_EMPTY_NODE_LIST, + .posts = PM_EMPTY_NODE_LIST + }; + + 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 = PM_EMPTY_NODE_LIST, + .posts = PM_EMPTY_NODE_LIST + }; + + 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), + } + }; + + 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, const pm_token_t *opening, pm_block_parameters_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, + .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 = PM_EMPTY_NODE_LIST + }; + + 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 + }; + + 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_call_node_t *node = pm_call_node_create(parser); + + node->base.location.start = receiver->location.start; + if (arguments->block != NULL) { + node->base.location.end = arguments->block->location.end; + } else { + node->base.location.end = arguments->closing_loc.end; + } + + 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; + + pm_string_constant_init(&node->name, "[]", 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_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; + + pm_string_shared_init(&node->name, operator->start, operator->end); + 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_call_node_t *node = pm_call_node_create(parser); + + node->base.location.start = receiver->location.start; + if (arguments->block != NULL) { + node->base.location.end = arguments->block->location.end; + } else if (arguments->closing_loc.start != NULL) { + node->base.location.end = arguments->closing_loc.end; + } else if (arguments->arguments != NULL) { + node->base.location.end = arguments->arguments->base.location.end; + } else { + node->base.location.end = message->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) { + node->base.flags |= PM_CALL_NODE_FLAGS_SAFE_NAVIGATION; + } + + pm_string_shared_init(&node->name, message->start, message->end); + 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; + if (arguments->block != NULL) { + node->base.location.end = arguments->block->location.end; + } else if (arguments->closing_loc.start != NULL) { + node->base.location.end = arguments->closing_loc.end; + } else if (arguments->arguments != NULL) { + node->base.location.end = arguments->arguments->base.location.end; + } else { + node->base.location.end = arguments->closing_loc.end; + } + + 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; + + pm_string_shared_init(&node->name, message->start, message->end); + 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_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; + + pm_string_constant_init(&node->name, "!", 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_call_node_t *node = pm_call_node_create(parser); + + node->base.location.start = receiver->location.start; + if (arguments->block != NULL) { + node->base.location.end = arguments->block->location.end; + } else { + node->base.location.end = arguments->closing_loc.end; + } + + 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) { + node->base.flags |= PM_CALL_NODE_FLAGS_SAFE_NAVIGATION; + } + + pm_string_constant_init(&node->name, "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_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); + + pm_string_constant_init(&node->name, 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); + + pm_string_shared_init(&node->name, message->start, message->end); + 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 node->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL; +} + +// Initialize the read name by reading the write name and chopping off the '='. +static void +pm_call_write_read_name_init(pm_string_t *read_name, pm_string_t *write_name) { + if (write_name->length >= 1) { + size_t length = write_name->length - 1; + + void *memory = malloc(length); + memcpy(memory, write_name->source, length); + + pm_string_owned_init(read_name, (uint8_t *) memory, length); + } else { + // We can get here if the message was missing because of a syntax error. + pm_string_constant_init(read_name, "", 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, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .read_name = PM_EMPTY_STRING, + .write_name = target->name, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + pm_call_write_read_name_init(&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 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, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .read_name = PM_EMPTY_STRING, + .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(&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 CallOperatorOrWriteNode 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, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .read_name = PM_EMPTY_STRING, + .write_name = target->name, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + pm_call_write_read_name_init(&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 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, pm_else_node_t *consequent, 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 = consequent, + .case_keyword_loc = PM_LOCATION_TOKEN_VALUE(case_keyword), + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword), + .conditions = PM_EMPTY_NODE_LIST + }; + + 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_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 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 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_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, + 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, + .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 = PM_EMPTY_NODE_LIST, + .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, + .kwrest = NULL, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .assocs = PM_EMPTY_NODE_LIST + }; + + 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 *assocs) { + 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 = assocs->nodes[0]->location.start, + .end = assocs->nodes[assocs->size - 1]->location.end + }, + }, + .constant = NULL, + .kwrest = NULL, + .assocs = PM_EMPTY_NODE_LIST, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + for (size_t index = 0; index < assocs->size; index++) { + pm_node_t *assoc = assocs->nodes[index]; + pm_node_list_append(&node->assocs, assoc); + } + + 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, pm_node_t *target) { + if (PM_NODE_TYPE_P(target, PM_GLOBAL_VARIABLE_READ_NODE)) { + return ((pm_global_variable_read_node_t *) target)->name; + } + + assert(PM_NODE_TYPE_P(target, PM_BACK_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(target, 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); +} + +// 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 = PM_EMPTY_NODE_LIST + }; + + 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); + + // If the element is not a static literal, then the hash is not a static + // literal. Turn that flag off. + if ((element->flags & PM_NODE_FLAG_STATIC_LITERAL) == 0) { + hash->base.flags &= (pm_node_flags_t) ~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, + 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, + .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, + .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, pm_node_t *true_expression, const pm_token_t *colon, pm_node_t *false_expression) { + 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, + .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 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 = PM_EMPTY_NODE_LIST + }; + + 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; + node->base.flags |= 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 = parts == NULL ? PM_EMPTY_NODE_LIST : *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 = parts == NULL ? PM_EMPTY_NODE_LIST : *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 = PM_EMPTY_NODE_LIST + }; + + 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 + }, + .elements = PM_EMPTY_NODE_LIST + }; + + 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) { + 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 a new KeywordParameterNode node. +static pm_keyword_parameter_node_t * +pm_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, pm_node_t *value) { + pm_keyword_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_keyword_parameter_node_t); + + *node = (pm_keyword_parameter_node_t) { + { + .type = PM_KEYWORD_PARAMETER_NODE, + .location = { + .start = name->start, + .end = value == NULL ? name->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, + const pm_token_t *operator, + const pm_token_t *opening, + const pm_token_t *closing, + pm_block_parameters_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, + .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_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 = pm_parser_constant_id_token(parser, name), + .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; +} + +// 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_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 = PM_LOCATION_TOKEN_VALUE(name) + }, + .name = pm_parser_constant_id_token(parser, name), + .depth = 0 + }; + + return node; +} + +// 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_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_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 + }; + + pm_constant_id_list_init(&node->locals); + 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 } + }, + .targets = PM_EMPTY_NODE_LIST, + .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_multi_target_node_t *node, pm_node_t *target) { + pm_node_list_append(&node->targets, 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; + } +} + +// 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 + } + }, + .targets = target->targets, + .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 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_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 = PM_EMPTY_NODE_LIST, + .optionals = PM_EMPTY_NODE_LIST, + .posts = PM_EMPTY_NODE_LIST, + .keywords = PM_EMPTY_NODE_LIST + }; + + 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(¶ms->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(¶ms->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(¶ms->posts, param); +} + +// Set the rest parameter on a ParametersNode node. +static void +pm_parameters_node_rest_set(pm_parameters_node_t *params, pm_rest_parameter_node_t *param) { + assert(params->rest == NULL); + pm_parameters_node_location_set(params, (pm_node_t *) 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(¶ms->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_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 RegularExpressionNode node. +static 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) { + 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 = PM_EMPTY_STRING + }; + + return node; +} + +// Allocate a new RequiredDestructuredParameterNode node. +static pm_required_destructured_parameter_node_t * +pm_required_destructured_parameter_node_create(pm_parser_t *parser, const pm_token_t *opening) { + pm_required_destructured_parameter_node_t *node = PM_ALLOC_NODE(parser, pm_required_destructured_parameter_node_t); + + *node = (pm_required_destructured_parameter_node_t) { + { + .type = PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE, + .location = PM_LOCATION_TOKEN_VALUE(opening) + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .parameters = PM_EMPTY_NODE_LIST + }; + + return node; +} + +// Append a new parameter to the given RequiredDestructuredParameterNode node. +static void +pm_required_destructured_parameter_node_append_parameter(pm_required_destructured_parameter_node_t *node, pm_node_t *parameter) { + pm_node_list_append(&node->parameters, parameter); +} + +// Set the closing token of the given RequiredDestructuredParameterNode node. +static void +pm_required_destructured_parameter_node_closing_set(pm_required_destructured_parameter_node_t *node, const pm_token_t *closing) { + node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing); + node->base.location.end = closing->end; +} + +// 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 = PM_EMPTY_NODE_LIST + }; + + 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 = PM_EMPTY_NODE_LIST + }; + + 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. + statement->flags |= PM_NODE_FLAG_NEWLINE; +} + +// Allocate a new StringConcatNode node. +static pm_string_concat_node_t * +pm_string_concat_node_create(pm_parser_t *parser, pm_node_t *left, pm_node_t *right) { + pm_string_concat_node_t *node = PM_ALLOC_NODE(parser, pm_string_concat_node_t); + + *node = (pm_string_concat_node_t) { + { + .type = PM_STRING_CONCAT_NODE, + .location = { + .start = left->location.start, + .end = right->location.end + } + }, + .left = left, + .right = right + }; + + 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) { + 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 = PM_EMPTY_STRING + }; + + 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; + if (arguments->block != NULL) { + end = arguments->block->location.end; + } else if (arguments->closing_loc.start != NULL) { + end = arguments->closing_loc.end; + } else if (arguments->arguments != NULL) { + end = arguments->arguments->base.location.end; + } else { + assert(false && "unreachable"); + end = NULL; + } + + *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 a new SymbolNode node. +static 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) { + 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 = PM_EMPTY_STRING + }; + + 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); + + pm_unescape_manipulate_string(parser, &node->unescaped, PM_UNESCAPE_ALL); + 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 = PM_EMPTY_NODE_LIST + }; + + 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, 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, + .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, + .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 = PM_EMPTY_NODE_LIST + }; + + 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. +static 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) { + 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, + .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 = PM_EMPTY_STRING + }; + + return node; +} + +// 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_EMPTY_STRING +#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_params = false + }; + + pm_constant_id_list_init(&scope->locals); + parser->current_scope = scope; + + return true; +} + +// Check if the current scope has a given local variables. +static int +pm_parser_local_depth(pm_parser_t *parser, pm_token_t *token) { + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, token); + 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; +} + +// 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); + } +} + +// 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 inline void +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); +} + +static inline bool +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])); +} + +// 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, pm_token_t *name) { + // We want to check whether the parameter name is a numbered parameter or not. + if (token_is_numbered_parameter(name->start, name->end)) { + pm_diagnostic_list_append(&parser->error_list, name->start, name->end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + // We want to ignore any parameter name that starts with an underscore. + if ((*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_diagnostic_list_append(&parser->error_list, name->start, name->end, 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) { + return parser->encoding.alpha_char(b, parser->end - b) || (*b == '_') || (*b >= 0x80); + } 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); + } +} + +// 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) { + return parser->encoding.alnum_char(b, parser->end - b) || (*b == '_') || (*b >= 0x80); + } else if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT ? 1 : 0) || (*b == '_'); + } else { + return (size_t) (pm_encoding_utf_8_alnum_char(b, parser->end - b) || 1u); + } +} + +// 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); +} + +// Get the next string of length len in the source starting from parser->current.end. +// If the string extends beyond the end of the source, return the empty string "" +static inline const uint8_t * +peek_string(pm_parser_t *parser, size_t len) { + if (parser->current.end + len <= parser->end) { + return parser->current.end; + } else { + return (const uint8_t *) ""; + } +} + +// 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); +} + +// Find the start of the encoding comment. This is effectively an inlined +// version of strnstr with some modifications. +static inline const uint8_t * +parser_lex_encoding_comment_start(pm_parser_t *parser, const uint8_t *cursor, ptrdiff_t remaining) { + assert(remaining >= 0); + size_t length = (size_t) remaining; + + size_t key_length = strlen("coding:"); + if (key_length > length) return NULL; + + const uint8_t *cursor_limit = cursor + length - key_length + 1; + while ((cursor = pm_memchr(cursor, 'c', (size_t) (cursor_limit - cursor), parser->encoding_changed, &parser->encoding)) != NULL) { + if (memcmp(cursor, "coding", key_length - 1) == 0) { + size_t whitespace_after_coding = pm_strspn_inline_whitespace(cursor + key_length - 1, parser->end - (cursor + key_length - 1)); + size_t cur_pos = key_length + whitespace_after_coding; + + if (cursor[cur_pos - 1] == ':' || cursor[cur_pos - 1] == '=') { + return cursor + cur_pos; + } + } + + cursor++; + } + + return NULL; +} + +// Here we're going to check if this is a "magic" comment, and perform whatever +// actions are necessary for it here. +static void +parser_lex_encoding_comment(pm_parser_t *parser) { + const uint8_t *start = parser->current.start + 1; + const uint8_t *end = parser->current.end; + + // These are the patterns we're going to match to find the encoding comment. + // This is definitely not complete or even really correct. + const uint8_t *encoding_start = parser_lex_encoding_comment_start(parser, start, end - start); + + // If we didn't find anything that matched our patterns, then return. Note + // that this does a _very_ poor job of actually finding the encoding, and + // there is a lot of work to do here to better reflect actual magic comment + // parsing from CRuby, but this at least gets us part of the way there. + if (encoding_start == NULL) return; + + // Skip any non-newline whitespace after the "coding:" or "coding=". + encoding_start += pm_strspn_inline_whitespace(encoding_start, end - encoding_start); + + // Now determine the end of the encoding string. This is either the end of + // the line, the first whitespace character, or a punctuation mark. + const uint8_t *encoding_end = pm_strpbrk(parser, encoding_start, (const uint8_t *) " \t\f\r\v\n;,", end - encoding_start); + encoding_end = encoding_end == NULL ? end : encoding_end; + + // Finally, we can determine the width of the encoding string. + size_t width = (size_t) (encoding_end - encoding_start); + + // First, we're going to call out to a user-defined callback if one was + // provided. If they return an encoding struct that we can use, then we'll + // use that here. + if (parser->encoding_decode_callback != NULL) { + pm_encoding_t *encoding = parser->encoding_decode_callback(parser, encoding_start, width); + + if (encoding != NULL) { + parser->encoding = *encoding; + return; + } + } + + // Next, we're going to check for UTF-8. This is the most common encoding. + // Extensions like utf-8 can contain extra encoding details like, + // utf-8-dos, utf-8-linux, utf-8-mac. We treat these all as utf-8 should + // treat any encoding starting utf-8 as utf-8. + if ((encoding_start + 5 <= parser->end) && (pm_strncasecmp(encoding_start, (const uint8_t *) "utf-8", 5) == 0)) { + // We don't need to do anything here because the default encoding is + // already UTF-8. We'll just return. + return; + } + + // 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 ENCODING(value, prebuilt) \ + if (width == sizeof(value) - 1 && encoding_start + width <= parser->end && pm_strncasecmp(encoding_start, (const uint8_t *) value, width) == 0) { \ + parser->encoding = prebuilt; \ + parser->encoding_changed |= true; \ + if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); \ + return; \ + } + + // Check most common first. (This is pretty arbitrary.) + ENCODING("ascii", pm_encoding_ascii); + ENCODING("ascii-8bit", pm_encoding_ascii_8bit); + ENCODING("us-ascii", pm_encoding_ascii); + ENCODING("binary", pm_encoding_ascii_8bit); + ENCODING("shift_jis", pm_encoding_shift_jis); + ENCODING("euc-jp", pm_encoding_euc_jp); + + // Then check all the others. + ENCODING("big5", pm_encoding_big5); + ENCODING("gbk", pm_encoding_gbk); + ENCODING("iso-8859-1", pm_encoding_iso_8859_1); + ENCODING("iso-8859-2", pm_encoding_iso_8859_2); + ENCODING("iso-8859-3", pm_encoding_iso_8859_3); + ENCODING("iso-8859-4", pm_encoding_iso_8859_4); + ENCODING("iso-8859-5", pm_encoding_iso_8859_5); + ENCODING("iso-8859-6", pm_encoding_iso_8859_6); + ENCODING("iso-8859-7", pm_encoding_iso_8859_7); + ENCODING("iso-8859-8", pm_encoding_iso_8859_8); + ENCODING("iso-8859-9", pm_encoding_iso_8859_9); + ENCODING("iso-8859-10", pm_encoding_iso_8859_10); + ENCODING("iso-8859-11", pm_encoding_iso_8859_11); + ENCODING("iso-8859-13", pm_encoding_iso_8859_13); + ENCODING("iso-8859-14", pm_encoding_iso_8859_14); + ENCODING("iso-8859-15", pm_encoding_iso_8859_15); + ENCODING("iso-8859-16", pm_encoding_iso_8859_16); + ENCODING("koi8-r", pm_encoding_koi8_r); + ENCODING("windows-31j", pm_encoding_windows_31j); + ENCODING("windows-1251", pm_encoding_windows_1251); + ENCODING("windows-1252", pm_encoding_windows_1252); + ENCODING("cp1251", pm_encoding_windows_1251); + ENCODING("cp1252", pm_encoding_windows_1252); + ENCODING("cp932", pm_encoding_windows_31j); + ENCODING("sjis", pm_encoding_windows_31j); + ENCODING("utf8-mac", pm_encoding_utf8_mac); + +#undef ENCODING + + // If nothing was returned by this point, 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_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, 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_frozen_string_literal_comment(pm_parser_t *parser) { + const uint8_t *cursor = parser->current.start + 1; + const uint8_t *end = parser->current.end; + + size_t key_length = strlen("frozen_string_literal"); + if (key_length > (size_t) (end - cursor)) return; + + const uint8_t *cursor_limit = cursor + (end - cursor) - key_length + 1; + + while ((cursor = pm_memchr(cursor, 'f', (size_t) (cursor_limit - cursor), parser->encoding_changed, &parser->encoding)) != NULL) { + if (memcmp(cursor, "frozen_string_literal", key_length) == 0) { + cursor += key_length; + cursor += pm_strspn_inline_whitespace(cursor, end - cursor); + + if (*cursor == ':' || *cursor == '=') { + cursor++; + cursor += pm_strspn_inline_whitespace(cursor, end - cursor); + + if (cursor + 4 <= end && pm_strncasecmp(cursor, (const uint8_t *) "true", 4) == 0) { + parser->frozen_string_literal = true; + } + + return; + } + } + + cursor++; + } +} + +/******************************************************************************/ +/* 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: + return token->type == PM_TOKEN_KEYWORD_END; + 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: + 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: + 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: + 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_diagnostic_list_append(&parser->error_list, 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) { + 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, '-')); + + if (pm_char_is_decimal_digit(*parser->current.end)) { + parser->current.end++; + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + type = PM_TOKEN_FLOAT; + } else { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_INVALID_FLOAT_EXPONENT); + type = PM_TOKEN_FLOAT; + } + } + + return type; +} + +static pm_token_type_t +lex_numeric_prefix(pm_parser_t *parser) { + pm_token_type_t type = PM_TOKEN_INTEGER; + + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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); + break; + } + + // 0exxx is a float + case 'e': + case 'E': { + type = lex_optional_float_suffix(parser); + 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); + } + + 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) { + type = lex_numeric_prefix(parser); + + 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 (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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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 true. Otherwise, it returns false. The arguments are as follows: +// +// * `value` - the literal string that we're checking for +// * `width` - the length of the token +// * `state` - the state that we should transition to if the token matches +// +static inline pm_token_type_t +lex_keyword(pm_parser_t *parser, const char *value, size_t vlen, pm_lex_state_t state, pm_token_type_t type, pm_token_type_t modifier_type) { + pm_lex_state_t last_state = parser->lex_state; + + if (parser->current.start + vlen <= parser->end && memcmp(parser->current.start, value, vlen) == 0) { + 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; + while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0) { + parser->current.end += width; + } + + // Now cache the length of the identifier so that we can quickly compare it + // against known keywords. + width = (size_t) (parser->current.end - parser->current.start); + + if (parser->current.end < parser->end) { + if (((parser->current.end + 1 >= parser->end) || (parser->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, "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, "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, "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, "in", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_IN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "and", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_AND, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "def", width, PM_LEX_STATE_FNAME, PM_TOKEN_KEYWORD_DEF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "end", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "END", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "for", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_FOR, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "nil", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_NIL, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "case", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_CASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "else", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "next", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_NEXT, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "redo", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_REDO, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "self", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_SELF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "then", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "true", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_TRUE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "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, "begin", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_BEGIN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "BEGIN", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_BEGIN_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "break", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_BREAK, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "class", width, PM_LEX_STATE_CLASS, PM_TOKEN_KEYWORD_CLASS, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "elsif", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "false", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_FALSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "retry", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_RETRY, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "super", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_SUPER, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "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, "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, "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, "ensure", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "module", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_MODULE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "return", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_RETURN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "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, "__LINE__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___LINE__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, "__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, "__ENCODING__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___ENCODING__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + } + } + + return parser->encoding.isupper_char(parser->current.start, parser->end - parser->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; + } +} + +// 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_INCOMPLETE_QUESTION_MARK); + 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 (parser->current.start[1] == '\\') { + lex_state_set(parser, PM_LEX_STATE_END); + parser->current.end += pm_unescape_calculate_difference(parser, parser->current.start + 1, PM_UNESCAPE_ALL, true); + 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 + 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; + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_INCOMPLETE_VARIABLE_CLASS); + } else { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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 *) malloc(sizeof(pm_comment_t)); + if (comment == NULL) return NULL; + + *comment = (pm_comment_t) { + .type = type, + .start = parser->current.start, + .end = 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->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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_EMBDOC_TERM); + + comment->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; +} + +// 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); + + if (parser->current.start == parser->encoding_comment_start) { + parser_lex_encoding_comment(parser); + } + + if (!semantic_token_seen) { + parser_lex_frozen_string_literal_comment(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_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, 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) && memcmp(peek_string(parser, 5), "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 + } + + 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 + } + }); + + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append( + &parser->warning_list, + parser->current.start, + parser->current.end, + 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_diagnostic_list_append( + &parser->warning_list, + parser->current.start, + parser->current.end, + 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_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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)) { + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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++); + } + + 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++); + } + + 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++; + } + + 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++; + } + + 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++; + } + + 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++; + } + + 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++); + } + + 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++); + } + + 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++; + } + + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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); + + pm_comment_t *comment = parser_comment(parser, PM_COMMENT___END__); + pm_list_append(&parser->comment_list, (pm_list_node_t *) comment); + + 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) || + 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); + + 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; + 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) { + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + 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; + 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 == '\\') { + pm_unescape_type_t unescape_type = lex_mode->as.list.interpolation ? PM_UNESCAPE_ALL : PM_UNESCAPE_MINIMAL; + size_t difference = pm_unescape_calculate_difference(parser, breakpoint, unescape_type, false); + if (difference == 0) { + // we're at the end of the file + breakpoint = NULL; + continue; + } + + // If the result is an escaped newline ... + if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; + parser_flush_heredoc_end(parser); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, breakpoint + difference - 1); + } + } + + breakpoint = pm_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + 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) { + LEX(type); + } + + // 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 we've hit the incrementor, then we need to skip past it + // and find the next breakpoint. + assert(*breakpoint == lex_mode->as.list.incrementor); + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + lex_mode->as.list.nesting++; + continue; + } + + // If we were unable to find a breakpoint, then this token hits the end of + // the file. + LEX(PM_TOKEN_EOF); + + 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); + + 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'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. + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + 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) { + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + 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; + 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 == '\\') { + size_t difference = pm_unescape_calculate_difference(parser, breakpoint, PM_UNESCAPE_ALL, false); + if (difference == 0) { + // we're at the end of the file + breakpoint = NULL; + continue; + } + + // If the result is an escaped newline ... + if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; + parser_flush_heredoc_end(parser); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, breakpoint + difference - 1); + } + } + + breakpoint = pm_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + 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) { + LEX(type); + } + + // 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 we've hit the incrementor, then we need to skip past it + // and find the next breakpoint. + assert(*breakpoint == lex_mode->as.regexp.incrementor); + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + lex_mode->as.regexp.nesting++; + continue; + } + + // At this point, the breakpoint is NULL which means we were unable to + // find anything before the end of the file. + LEX(PM_TOKEN_EOF); + } + 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. + const uint8_t *breakpoints = parser->lex_modes.current->as.string.breakpoints; + const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); + + while (breakpoint != NULL) { + // If we hit the incrementor, then we'll increment then nesting and + // continue lexing. + if ( + parser->lex_modes.current->as.string.incrementor != '\0' && + *breakpoint == parser->lex_modes.current->as.string.incrementor + ) { + parser->lex_modes.current->as.string.nesting++; + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + 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 == parser->lex_modes.current->as.string.terminator) { + // If this terminator doesn't actually close the string, then we need + // to continue on past it. + if (parser->lex_modes.current->as.string.nesting > 0) { + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + parser->lex_modes.current->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; + 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 ( + parser->lex_modes.current->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); + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + continue; + } else { + parser->current.end = breakpoint + 1; + parser_flush_heredoc_end(parser); + LEX(PM_TOKEN_STRING_CONTENT); + } + } + + switch (*breakpoint) { + case '\0': + // Skip directly past the null character. + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + break; + case '\\': { + // 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. + pm_unescape_type_t unescape_type = parser->lex_modes.current->as.string.interpolation ? PM_UNESCAPE_ALL : PM_UNESCAPE_MINIMAL; + size_t difference = pm_unescape_calculate_difference(parser, breakpoint, unescape_type, false); + if (difference == 0) { + // we're at the end of the file + breakpoint = NULL; + break; + } + + // If the result is an escaped newline ... + if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; + parser_flush_heredoc_end(parser); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, breakpoint + difference - 1); + } + } + + breakpoint = pm_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + break; + } + case '#': { + pm_token_type_t type = lex_interpolation(parser, breakpoint); + if (type != PM_TOKEN_NOT_PROVIDED) { + LEX(type); + } + + // 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; + } + default: + assert(false && "unreachable"); + } + } + + // If we've hit the end of the string, then this is an unterminated + // string. In that case we'll return the EOF token. + parser->current.end = parser->end; + LEX(PM_TOKEN_EOF); + } + 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. + const uint8_t *ident_start = parser->lex_modes.current->as.heredoc.ident_start; + size_t ident_length = parser->lex_modes.current->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 (parser->lex_modes.current->as.heredoc.indent != PM_HEREDOC_INDENT_NONE) { + start += pm_strspn_inline_whitespace(start, parser->end - start); + } + + if ((start + ident_length <= parser->end) && (memcmp(start, ident_start, ident_length) == 0)) { + bool matched = true; + bool at_end = false; + + size_t eol_length = match_eol_at(parser, start + ident_length); + if (eol_length) { + parser->current.end = start + ident_length + eol_length; + pm_newline_list_append(&parser->newline_list, parser->current.end - 1); + } else if (parser->end == (start + ident_length)) { + parser->current.end = start + ident_length; + at_end = true; + } else { + matched = false; + } + + if (matched) { + if (*parser->lex_modes.current->as.heredoc.next_start == '\\') { + parser->next_start = NULL; + } else { + parser->next_start = parser->lex_modes.current->as.heredoc.next_start; + parser->heredoc_end = parser->current.end; + } + + lex_mode_pop(parser); + if (!at_end) { + lex_state_set(parser, PM_LEX_STATE_END); + } + LEX(PM_TOKEN_HEREDOC_END); + } + } + } + + // 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 = parser->lex_modes.current->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); + + while (breakpoint != NULL) { + switch (*breakpoint) { + case '\0': + // Skip directly past the null character. + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + break; + case '\n': { + if (parser->heredoc_end != NULL && (parser->heredoc_end > breakpoint)) { + parser_flush_heredoc_end(parser); + parser->current.end = breakpoint + 1; + LEX(PM_TOKEN_STRING_CONTENT); + } + + pm_newline_list_append(&parser->newline_list, breakpoint); + + const uint8_t *start = breakpoint + 1; + if (parser->lex_modes.current->as.heredoc.indent != PM_HEREDOC_INDENT_NONE) { + start += pm_strspn_inline_whitespace(start, parser->end - start); + } + + // 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 ( + (start + ident_length <= parser->end) && + (memcmp(start, ident_start, ident_length) == 0) + ) { + // Heredoc terminators must be followed by a newline, CRLF, or EOF to be valid. + if ( + start + ident_length == parser->end || + match_eol_at(parser, start + ident_length) + ) { + parser->current.end = breakpoint + 1; + LEX(PM_TOKEN_STRING_CONTENT); + } + } + + // Otherwise we hit a newline and it wasn't followed by a + // terminator, so we can continue parsing. + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + 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. + size_t eol_length = match_eol_at(parser, breakpoint + 1); + if (eol_length) { + breakpoint += eol_length; + } else { + pm_unescape_type_t unescape_type = (quote == PM_HEREDOC_QUOTE_SINGLE) ? PM_UNESCAPE_MINIMAL : PM_UNESCAPE_ALL; + size_t difference = pm_unescape_calculate_difference(parser, breakpoint, unescape_type, false); + if (difference == 0) { + // we're at the end of the file + breakpoint = NULL; + break; + } + + pm_newline_list_check_append(&parser->newline_list, breakpoint + difference - 1); + + breakpoint = pm_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + } + + break; + } + case '#': { + pm_token_type_t type = lex_interpolation(parser, breakpoint); + if (type != PM_TOKEN_NOT_PROVIDED) { + LEX(type); + } + + // 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; + } + default: + assert(false && "unreachable"); + } + } + + // If we've hit the end of the string, then this is an unterminated + // heredoc. In that case we'll return the EOF token. + parser->current.end = parser->end; + LEX(PM_TOKEN_EOF); + } + } + + assert(false && "unreachable"); +} + +#undef LEX + +/******************************************************************************/ +/* Parse functions */ +/******************************************************************************/ + +// When we are parsing certain content, we need to unescape the content to +// provide to the consumers of the parser. The following functions accept a range +// of characters from the source and unescapes into the provided type. +// +// We have functions for unescaping regular expression nodes, string nodes, +// symbol nodes, and xstring nodes +static pm_regular_expression_node_t * +pm_regular_expression_node_create_and_unescape(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, pm_unescape_type_t unescape_type) { + pm_regular_expression_node_t *node = pm_regular_expression_node_create(parser, opening, content, closing); + + assert((content->end - content->start) >= 0); + pm_string_shared_init(&node->unescaped, content->start, content->end); + + pm_unescape_manipulate_string(parser, &node->unescaped, unescape_type); + return node; +} + +static pm_symbol_node_t * +pm_symbol_node_create_and_unescape(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, pm_unescape_type_t unescape_type) { + pm_symbol_node_t *node = pm_symbol_node_create(parser, opening, content, closing); + + assert((content->end - content->start) >= 0); + pm_string_shared_init(&node->unescaped, content->start, content->end); + + pm_unescape_manipulate_string(parser, &node->unescaped, unescape_type); + return node; +} + +static pm_string_node_t * +pm_char_literal_node_create_and_unescape(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, pm_unescape_type_t unescape_type) { + pm_string_node_t *node = pm_string_node_create(parser, opening, content, closing); + + assert((content->end - content->start) >= 0); + pm_string_shared_init(&node->unescaped, content->start, content->end); + + pm_unescape_manipulate_char_literal(parser, &node->unescaped, unescape_type); + return node; +} + +static pm_string_node_t * +pm_string_node_create_and_unescape(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, pm_unescape_type_t unescape_type) { + pm_string_node_t *node = pm_string_node_create(parser, opening, content, closing); + + assert((content->end - content->start) >= 0); + pm_string_shared_init(&node->unescaped, content->start, content->end); + + pm_unescape_manipulate_string(parser, &node->unescaped, unescape_type); + return node; +} + +static pm_x_string_node_t * +pm_xstring_node_create_and_unescape(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) { + pm_x_string_node_t *node = pm_xstring_node_create(parser, opening, content, closing); + + assert((content->end - content->start) >= 0); + pm_string_shared_init(&node->unescaped, content->start, content->end); + + pm_unescape_manipulate_string(parser, &node->unescaped, PM_UNESCAPE_ALL); + return node; +} + +// 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 in + 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, // => + PM_BINDING_POWER_DEFINED = 14, // defined? + PM_BINDING_POWER_ASSIGNMENT = 16, // = += -= *= /= %= &= |= ^= &&= ||= <<= >>= **= + PM_BINDING_POWER_TERNARY = 18, // ?: + PM_BINDING_POWER_RANGE = 20, // .. ... + PM_BINDING_POWER_LOGICAL_OR = 22, // || + PM_BINDING_POWER_LOGICAL_AND = 24, // && + PM_BINDING_POWER_EQUALITY = 26, // <=> == === != =~ !~ + PM_BINDING_POWER_COMPARISON = 28, // > >= < <= + PM_BINDING_POWER_BITWISE_OR = 30, // | ^ + PM_BINDING_POWER_BITWISE_AND = 32, // & + PM_BINDING_POWER_SHIFT = 34, // << >> + PM_BINDING_POWER_TERM = 36, // + - + PM_BINDING_POWER_FACTOR = 38, // * / % + PM_BINDING_POWER_UMINUS = 40, // -@ + PM_BINDING_POWER_EXPONENT = 42, // ** + PM_BINDING_POWER_UNARY = 44, // ! ~ +@ + PM_BINDING_POWER_INDEX = 46, // [] []= + PM_BINDING_POWER_CALL = 48, // :: . + PM_BINDING_POWER_MAX = 50 +} 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 { + pm_binding_power_t left; + pm_binding_power_t right; + bool binary; +} pm_binding_powers_t; + +#define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true } +#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true } +#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true } +#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false } + +pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = { + // if unless until while in rescue + [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), + [PM_TOKEN_KEYWORD_IN] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER), + + // rescue modifier + [PM_TOKEN_KEYWORD_RESCUE_MODIFIER] = { + PM_BINDING_POWER_ASSIGNMENT, + PM_BINDING_POWER_MODIFIER_RESCUE + 1, + true + }, + + // and or + [PM_TOKEN_KEYWORD_AND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION), + [PM_TOKEN_KEYWORD_OR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION), + + // => + [PM_TOKEN_EQUAL_GREATER] = LEFT_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] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_RANGE), + [PM_TOKEN_DOT_DOT_DOT] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_RANGE), + + // || + [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] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_BANG_TILDE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_EQUAL_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_TILDE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_LESS_EQUAL_GREATER] = LEFT_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 }, + + // ** + [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 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_diagnostic_list_append(&parser->error_list, 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_diagnostic_list_append(&parser->error_list, 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_diagnostic_list_append(&parser->error_list, 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, pm_diagnostic_id_t diag_id); + +// 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, pm_diagnostic_id_t diag_id) { + if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t operator = parser->previous; + pm_node_t *expression = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR); + return (pm_node_t *) pm_splat_node_create(parser, &operator, expression); + } + + return parse_expression(parser, binding_power, diag_id); +} + +// Convert the name of a method into the corresponding write method name. For +// exmaple, foo would be turned into foo=. +static void +parse_write_name(pm_string_t *string) { + // 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 =. + size_t length = pm_string_length(string); + uint8_t *name = calloc(length + 1, sizeof(uint8_t)); + if (name == NULL) return; + + memcpy(name, pm_string_source(string), length); + name[length] = '='; + + // Now switch the name to the new string. + pm_string_free(string); + pm_string_owned_init(string, 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_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, 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 (token_is_numbered_parameter(target->location.start, target->location.end)) { + pm_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } 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); + } + + pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(multi_target, (pm_node_t *) splat); + + return (pm_node_t *) multi_target; + } + 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); + + 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, 0); + + assert(sizeof(pm_local_variable_target_node_t) == sizeof(pm_local_variable_read_node_t)); + target->type = PM_LOCAL_VARIABLE_TARGET_NODE; + + if (token_is_numbered_parameter(message.start, message.end)) { + pm_diagnostic_list_append(&parser->error_list, message.start, message.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + 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(&call->name); + 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 ( + (call->call_operator_loc.start == NULL) && + (call->message_loc.start != NULL) && + (call->message_loc.start[0] == '[') && + (call->message_loc.end[-1] == ']') && + (call->block == NULL) + ) { + // Free the previous name and replace it with "[]=". + pm_string_free(&call->name); + pm_string_constant_init(&call->name, "[]=", 3); + return target; + } + } + /* 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_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, PM_ERR_WRITE_TARGET_UNEXPECTED); + return target; + } +} + +// Parse a write targets 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 either an = or a ) after the targets. + if (!match3(parser, PM_TOKEN_EQUAL, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_KEYWORD_IN)) { + pm_diagnostic_list_append(&parser->error_list, result->location.start, result->location.end, 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: + 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); + pm_node_destroy(parser, target); + return (pm_node_t *) node; + } + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + pm_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, 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: { + if (token_is_numbered_parameter(target->location.start, target->location.end)) { + pm_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + 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(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); + + if (token_is_numbered_parameter(message.start, message.end)) { + pm_diagnostic_list_append(&parser->error_list, message.start, message.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + 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(&call->name); + 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 ( + (call->call_operator_loc.start == NULL) && + (call->message_loc.start[0] == '[') && + (call->message_loc.end[-1] == ']') && + (call->block == NULL) + ) { + 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; + + // Free the previous name and replace it with "[]=". + pm_string_free(&call->name); + pm_string_constant_init(&call->name, "[]=", 3); + 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_diagnostic_list_append(&parser->error_list, operator->start, operator->end, 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_splat = 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(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_splat) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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, 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(result, splat); + has_splat = true; + } else if (token_begins_expression_p(parser->current.type)) { + pm_node_t *target = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA); + target = parse_target(parser, target); + + pm_multi_target_node_targets_append(result, target); + } else { + // If we get here, then we have a trailing , in a multi target node. + // We need to indicate this somehow in the tree, so we'll add an + // anonymous splat. + pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &parser->previous, NULL); + pm_multi_target_node_targets_append(result, splat); + 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_diagnostic_list_append(&parser->error_list, result->location.start, result->location.end, 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, 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. +static void +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)); + + 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_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); + } else if (pm_parser_local_depth(parser, &operator) == -1) { + pm_diagnostic_list_append(&parser->error_list, operator.start, operator.end, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); + } + + element = (pm_node_t *) pm_assoc_splat_node_create(parser, value, &operator); + 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_expression(parser, PM_BINDING_POWER_DEFINED, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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)) return; + + // 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. + return; + } +} + +// 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_bare_hash = false; + bool parsed_block_argument = false; + + while (!match1(parser, PM_TOKEN_EOF)) { + if (parsed_block_argument) { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_ARGUMENT_AFTER_BLOCK); + } + + pm_node_t *argument = NULL; + + switch (parser->current.type) { + case PM_TOKEN_USTAR_STAR: + case PM_TOKEN_LABEL: { + if (parsed_bare_hash) { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_ARGUMENT_BARE_HASH); + } + + pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser); + argument = (pm_node_t *) hash; + + if (!match7(parser, terminator, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_KEYWORD_DO, PM_TOKEN_PARENTHESIS_RIGHT)) { + parse_assocs(parser, (pm_node_t *) hash); + } + + parsed_bare_hash = true; + parse_arguments_append(parser, arguments, argument); + 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_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT); + } else if (pm_parser_local_depth(parser, &operator) == -1) { + pm_diagnostic_list_append(&parser->error_list, operator.start, operator.end, 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 (match2(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_COMMA)) { + if (pm_parser_local_depth(parser, &parser->previous) == -1) { + pm_diagnostic_list_append(&parser->error_list, operator.start, operator.end, PM_ERR_ARGUMENT_NO_FORWARDING_STAR); + } + + argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL); + } else { + pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT); + + if (parsed_bare_hash) { + pm_diagnostic_list_append(&parser->error_list, 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, 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); + } + + argument = (pm_node_t *) pm_forwarding_arguments_node_create(parser, &parser->previous); + parse_arguments_append(parser, arguments, argument); + break; + } + } + } + /* fallthrough */ + default: { + if (argument == NULL) { + argument = parse_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_EXPECT_ARGUMENT); + } + + if (pm_symbol_node_label_p(argument) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + if (parsed_bare_hash) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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) + )) { + parse_assocs(parser, (pm_node_t *) bare_hash); + } + + parsed_bare_hash = true; + } + + parse_arguments_append(parser, arguments, argument); + break; + } + } + + // 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_required_destructured_parameter_node_t * +parse_required_destructured_parameter(pm_parser_t *parser) { + expect1(parser, PM_TOKEN_PARENTHESIS_LEFT, PM_ERR_EXPECT_LPAREN_REQ_PARAMETER); + + pm_token_t opening = parser->previous; + pm_required_destructured_parameter_node_t *node = pm_required_destructured_parameter_node_create(parser, &opening); + bool parsed_splat = false; + + do { + pm_node_t *param; + + if (node->parameters.size > 0 && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + if (parsed_splat) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); + } + + param = (pm_node_t *) pm_splat_node_create(parser, &parser->previous, NULL); + pm_required_destructured_parameter_node_append_parameter(node, param); + break; + } + + if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + param = (pm_node_t *) parse_required_destructured_parameter(parser); + } else if (accept1(parser, PM_TOKEN_USTAR)) { + if (parsed_splat) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); + } + + 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_local_add_token(parser, &name); + } + + param = (pm_node_t *) pm_splat_node_create(parser, &star, value); + parsed_splat = true; + } 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_local_add_token(parser, &name); + } + + pm_required_destructured_parameter_node_append_parameter(node, param); + } while (accept1(parser, PM_TOKEN_COMMA)); + + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN_REQ_PARAMETER); + pm_required_destructured_parameter_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_diagnostic_list_append(&parser->error_list, token->start, token->end, 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_diagnostic_list_append(&parser->error_list, token->start, token->end, 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_parameter +) { + 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); + 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_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, 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_parameter) { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); + } + if (order > PM_PARAMETERS_ORDER_NOTHING_AFTER) { + update_parameter_state(parser, &parser->current, &order); + parser_lex(parser); + + 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_FORMAL_CONSTANT); + break; + case PM_TOKEN_INSTANCE_VARIABLE: + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_FORMAL_IVAR); + break; + case PM_TOKEN_GLOBAL_VARIABLE: + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_FORMAL_GLOBAL); + break; + case PM_TOKEN_CLASS_VARIABLE: + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_ARGUMENT_FORMAL_CLASS); + break; + case PM_TOKEN_METHOD_NAME: + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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_node_t *value = parse_expression(parser, binding_power, 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); + 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_keyword_parameter_node_create(parser, &name, NULL); + 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_keyword_parameter_node_create(parser, &name, NULL); + pm_parameters_node_keywords_append(params, param); + break; + } + default: { + pm_node_t *value = NULL; + if (token_begins_expression_p(parser->current.type)) { + context_push(parser, PM_CONTEXT_DEFAULT_PARAMS); + value = parse_expression(parser, binding_power, PM_ERR_PARAMETER_NO_DEFAULT_KW); + context_pop(parser); + } + + pm_node_t *param = (pm_node_t *) pm_keyword_parameter_node_create(parser, &name, value); + 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); + pm_parser_local_add_token(parser, &operator); + } + + pm_rest_parameter_node_t *param = pm_rest_parameter_node_create(parser, &operator, &name); + if (params->rest == NULL) { + pm_parameters_node_rest_set(params, param); + } else { + pm_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, PM_ERR_PARAMETER_SPLAT_MULTI); + pm_parameters_node_posts_append(params, (pm_node_t *) 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); + 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_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, 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. We need to create an anonymous rest parameter to + // represent it. + pm_token_t name = not_provided(parser); + pm_rest_parameter_node_t *param = pm_rest_parameter_node_create(parser, &parser->previous, &name); + + if (params->rest == NULL) { + pm_parameters_node_rest_set(params, param); + } else { + pm_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, PM_ERR_PARAMETER_SPLAT_MULTI); + pm_parameters_node_posts_append(params, (pm_node_t *) param); + } + } else { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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) { + 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, 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, 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, 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, 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, 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, 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) { + 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); + + // 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 (accept1(parser, PM_TOKEN_SEMICOLON)) { + do { + expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE); + 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 *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)) { + parameters = pm_block_parameters_node_create(parser, NULL, &block_parameters_opening); + parser->command_start = true; + parser_lex(parser); + } else { + 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(parameters, &parser->previous); + } + + 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); + } + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END); + } + + 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, &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 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 ((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); + + 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_diagnostic_list_append(&parser->error_list, block->base.location.start, block->base.location.end, 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) { + 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_expression(parser, binding_power, 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); + predicate_closed |= accept1(parser, PM_TOKEN_KEYWORD_THEN); + if (!predicate_closed) { + pm_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, context); + 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, statements, NULL, &end_keyword); + break; + case PM_CONTEXT_UNLESS: + parent = (pm_node_t *) pm_unless_node_create(parser, &keyword, predicate, 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); + 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, 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 + +// 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_unescape_type_t unescape_type = PM_UNESCAPE_ALL; + + if (parser->lex_modes.current->mode == PM_LEX_HEREDOC) { + if (parser->lex_modes.current->as.heredoc.indent == PM_HEREDOC_INDENT_TILDE) { + // If we're in a tilde heredoc, we want to unescape it later + // because we don't want unescaped newlines to disappear + // before we handle them in the dedent. + unescape_type = PM_UNESCAPE_NONE; + } else if (parser->lex_modes.current->as.heredoc.quote == PM_HEREDOC_QUOTE_SINGLE) { + unescape_type = PM_UNESCAPE_MINIMAL; + } + } + + parser_lex(parser); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + return (pm_node_t *) pm_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, unescape_type); + } + // 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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); + pm_token_t symbol; + + 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); + symbol = parser->previous; + break; + case PM_CASE_OPERATOR: + lex_state_set(parser, next_state == PM_LEX_STATE_NONE ? PM_LEX_STATE_ENDFN : next_state); + parser_lex(parser); + symbol = parser->previous; + break; + default: + expect2(parser, PM_TOKEN_IDENTIFIER, PM_TOKEN_METHOD_NAME, PM_ERR_SYMBOL_INVALID); + symbol = parser->previous; + break; + } + + pm_token_t closing = not_provided(parser); + return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &symbol, &closing, PM_UNESCAPE_ALL); + } + + 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_and_unescape(parser, &opening, &content, &closing, PM_UNESCAPE_NONE); + } + + // 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 = PM_EMPTY_NODE_LIST; + 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); + 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; + if (accept1(parser, PM_TOKEN_STRING_CONTENT)) { + content = parser->previous; + } else { + content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end }; + } + + if (next_state != PM_LEX_STATE_NONE) { + lex_state_set(parser, next_state); + } + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC); + + return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); +} + +// 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); + + return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + } + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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); + + return (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + } + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_params_p(pm_parser_t *parser) { + for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) { + if (scope->numbered_params) 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 && token_is_numbered_parameter(parser->previous.start, parser->previous.end)) { + // Indicate that this scope is using numbered params so that child + // scopes cannot. + parser->current_scope->numbered_params = true; + + // 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED); + } else if (outer_scope_using_numbered_params_p(parser)) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE); + } else { + // 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 number = parser->previous.start[1]; + 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); + node->base.flags |= flags; + + return (pm_node_t *) node; +} + +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_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: + 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 int +parse_heredoc_common_whitespace_for_single_node(pm_parser_t *parser, pm_node_t *node, int common_whitespace) +{ + const pm_location_t *content_loc = &((pm_string_node_t *) node)->content_loc; + int cur_whitespace; + const uint8_t *cur_char = content_loc->start; + + while (cur_char && cur_char < content_loc->end) { + // Any empty newlines aren't included in the minimum whitespace + // calculation. + size_t eol_length; + while ((eol_length = match_eol_at(parser, cur_char))) { + cur_char += eol_length; + } + + if (cur_char == content_loc->end) break; + + cur_whitespace = 0; + + while (pm_char_is_inline_whitespace(*cur_char) && cur_char < content_loc->end) { + if (cur_char[0] == '\t') { + cur_whitespace = (cur_whitespace / PM_TAB_WHITESPACE_SIZE + 1) * PM_TAB_WHITESPACE_SIZE; + } else { + cur_whitespace++; + } + cur_char++; + } + + // If we hit a newline, then we have encountered a line that + // contains only whitespace, and it shouldn't be considered in + // the calculation of common leading whitespace. + eol_length = match_eol_at(parser, cur_char); + if (eol_length) { + cur_char += eol_length; + continue; + } + + if (cur_whitespace < common_whitespace || common_whitespace == -1) { + common_whitespace = cur_whitespace; + } + + cur_char = next_newline(cur_char + 1, parser->end - (cur_char + 1)); + if (cur_char) cur_char++; + } + return common_whitespace; +} + +// Calculate the common leading whitespace for each line in a heredoc. +static int +parse_heredoc_common_whitespace(pm_parser_t *parser, pm_node_list_t *nodes) { + int common_whitespace = -1; + + for (size_t index = 0; index < nodes->size; index++) { + pm_node_t *node = nodes->nodes[index]; + if (!PM_NODE_TYPE_P(node, PM_STRING_NODE)) continue; + + // If the previous node wasn't a string node, we don't want to trim + // whitespace. This could happen after an interpolated expression or + // variable. + if (index == 0 || PM_NODE_TYPE_P(nodes->nodes[index - 1], PM_STRING_NODE)) { + common_whitespace = parse_heredoc_common_whitespace_for_single_node(parser, node, common_whitespace); + } + } + + return common_whitespace; +} + +static pm_string_t * +parse_heredoc_dedent_single_node(pm_parser_t *parser, pm_string_t *string, bool dedent_node, int common_whitespace, pm_heredoc_quote_t quote) +{ + // 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); + uint8_t *source_start = (uint8_t *) string->source; + + const uint8_t *source_cursor = source_start; + 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. + uint8_t *dest_cursor = source_start; + + while (source_cursor < source_end) { + // If we need to dedent the next element within the heredoc or the next + // line within the string node, then we'll do it here. + if (dedent_node) { + int 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--; + } + } + + // At this point we have dedented all that we need to, so we need to find + // the next newline. + const uint8_t *breakpoint = next_newline(source_cursor, source_end - source_cursor); + + if (breakpoint == NULL) { + // If there isn't another newline, then we can just move the rest of the + // string and break from the loop. + memmove(dest_cursor, source_cursor, (size_t) (source_end - source_cursor)); + break; + } + + // Otherwise, we need to move everything including the newline, and + // then set the dedent_node flag to true. + if (breakpoint < source_end) breakpoint++; + memmove(dest_cursor, source_cursor, (size_t) (breakpoint - source_cursor)); + dest_cursor += (breakpoint - source_cursor); + source_cursor = breakpoint; + dedent_node = true; + } + + // We only want to write this node into the list if it has any content. + string->length = dest_length; + + if (dest_length != 0) { + pm_unescape_manipulate_string(parser, string, (quote == PM_HEREDOC_QUOTE_SINGLE) ? PM_UNESCAPE_MINIMAL : PM_UNESCAPE_ALL); + } + return string; +} + +// 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_t *heredoc_node, pm_heredoc_quote_t quote) +{ + pm_node_list_t *nodes; + + if (quote == PM_HEREDOC_QUOTE_BACKTICK) { + nodes = &((pm_interpolated_x_string_node_t *) heredoc_node)->parts; + } else { + nodes = &((pm_interpolated_string_node_t *) heredoc_node)->parts; + } + + // First, calculate how much common whitespace we need to trim. If there is + // none or it's 0, then we can return early. + int common_whitespace; + if ((common_whitespace = parse_heredoc_common_whitespace(parser, nodes)) <= 0) return; + + // 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); + parse_heredoc_dedent_single_node(parser, &string_node->unescaped, dedent_next, common_whitespace, quote); + 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->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->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->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) { + if (PM_NODE_TYPE_P(first_assoc, 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_t assocs = PM_EMPTY_NODE_LIST; + pm_node_list_append(&assocs, first_assoc); + + // 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; + } + + pm_node_t *assoc; + + if (match1(parser, PM_TOKEN_USTAR_STAR)) { + assoc = parse_pattern_keyword_rest(parser); + } 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); + assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value); + } + + pm_node_list_append(&assocs, assoc); + } + + pm_hash_pattern_node_t *node = pm_hash_pattern_node_node_list_create(parser, &assocs); + 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_parser_local_add_token(parser, &parser->previous); + return (pm_node_t *) pm_local_variable_target_node_create(parser, &parser->previous); + } + 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 *key; + + switch (parser->current.type) { + case PM_TOKEN_LABEL: + parser_lex(parser); + key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous); + break; + case PM_TOKEN_USTAR_STAR: + key = parse_pattern_keyword_rest(parser); + break; + case PM_TOKEN_STRING_BEGIN: + key = parse_expression(parser, PM_BINDING_POWER_MAX, PM_ERR_PATTERN_HASH_KEY); + if (!pm_symbol_node_label_p(key)) { + pm_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, PM_ERR_PATTERN_HASH_KEY_LABEL); + } + + break; + default: + parser_lex(parser); + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, PM_ERR_PATTERN_HASH_KEY); + key = (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + break; + } + + pm_token_t operator = not_provided(parser); + node = parse_pattern_hash(parser, (pm_node_t *) pm_assoc_node_create(parser, key, &operator, NULL)); + + 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, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE); + return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right); + } + default: { + pm_diagnostic_list_append(&parser->error_list, operator.start, operator.end, 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, 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, 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_expression(parser, PM_BINDING_POWER_STATEMENT, 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_diagnostic_list_append(&parser->error_list, operator.start, operator.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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; + pm_parser_local_add_token(parser, &identifier); + + pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create(parser, &identifier); + 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 = PM_EMPTY_NODE_LIST; + 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)) { + 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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) { + assert(parser->current.type == PM_TOKEN_STRING_BEGIN); + pm_node_t *result = NULL; + + 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. + assert(parser->lex_modes.current->mode == PM_LEX_STRING); + bool lex_interpolation = parser->lex_modes.current->as.string.interpolation; + + pm_token_t opening = parser->current; + parser_lex(parser); + + if (accept1(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 = parse_strings_empty_content(parser->previous.start); + node = (pm_node_t *) pm_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_NONE); + } 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); + node = (pm_node_t *) pm_symbol_node_create(parser, &opening, &content, &parser->previous); + } else if (!lex_interpolation) { + // If we don't accept interpolation then we expect the string to + // start with a single string content node. + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_EXPECT_STRING_CONTENT); + pm_token_t 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 = PM_EMPTY_NODE_LIST; + + pm_token_t delimiters = not_provided(parser); + pm_node_t *part = (pm_node_t *) pm_string_node_create_and_unescape(parser, &delimiters, &content, &delimiters, PM_UNESCAPE_MINIMAL); + pm_node_list_append(&parts, part); + + while (accept1(parser, PM_TOKEN_STRING_CONTENT)) { + part = (pm_node_t *) pm_string_node_create_and_unescape(parser, &delimiters, &parser->previous, &delimiters, PM_UNESCAPE_MINIMAL); + pm_node_list_append(&parts, part); + } + + 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)) { + node = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_TERM); + node = (pm_node_t *) pm_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_MINIMAL); + } + } 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; + parser_lex(parser); + + if (accept1(parser, PM_TOKEN_STRING_END)) { + node = (pm_node_t *) pm_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); + } else if (accept1(parser, PM_TOKEN_LABEL_END)) { + node = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); + } 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 = PM_EMPTY_NODE_LIST; + 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_and_unescape(parser, &string_opening, &parser->previous, &string_closing, PM_UNESCAPE_ALL); + 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)) { + node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); + } 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 = PM_EMPTY_NODE_LIST; + pm_node_t *part = NULL; + + 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 { + 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 (result == 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. + result = 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_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, PM_ERR_STRING_CONCATENATION); + } + + // Either way we will create a concat node to hold the strings + // together. + result = (pm_node_t *) pm_string_concat_node_create(parser, result, node); + } + } + + return result; +} + +// 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) { + 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 = parse_expression(parser, PM_BINDING_POWER_DEFINED, 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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_expression(parser, PM_BINDING_POWER_DEFINED, PM_ERR_ARRAY_EXPRESSION); + + if (pm_symbol_node_label_p(element) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + if (parsed_bare_hash) { + pm_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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); + pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, PM_ERR_CANNOT_PARSE_EXPRESSION); + + // 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 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. + if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE)) { + pm_multi_target_node_t *multi_target; + if (((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(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)) { + return parse_targets_validate(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX); + } else { + 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_diagnostic_list_append(&parser->error_list, 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, 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_diagnostic_list_append(&parser->error_list, 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_char_literal_node_create_and_unescape(parser, &opening, &content, &closing, PM_UNESCAPE_ALL); + + // Characters can be followed by strings in which case they are + // automatically concatenated. + if (match1(parser, PM_TOKEN_STRING_BEGIN)) { + pm_node_t *concat = parse_strings(parser); + return (pm_node_t *) pm_string_concat_node_create(parser, node, concat); + } + + 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) || + (binding_power <= PM_BINDING_POWER_ASSIGNMENT && (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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, true); + 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, binding_power, 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 = PM_EMPTY_ARGUMENTS; + + if (parse_arguments_list(parser, &arguments, true)) { + // Since we found arguments, we need to turn off the + // variable call bit in the flags. + call->base.flags &= (pm_node_flags_t) ~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 ( + (binding_power <= PM_BINDING_POWER_ASSIGNMENT && (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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, true); + + 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. + assert(parser->lex_modes.current->mode == PM_LEX_HEREDOC); + pm_heredoc_quote_t quote = parser->lex_modes.current->as.heredoc.quote; + pm_heredoc_indent_t indent = parser->lex_modes.current->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_state_set(parser, PM_LEX_STATE_END); + 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_and_unescape(parser, &opening, &content, &parser->previous); + } else { + node = (pm_node_t *) pm_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_NONE); + } + + 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_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; + } + + lex_state_set(parser, PM_LEX_STATE_END); + expect1(parser, PM_TOKEN_HEREDOC_END, PM_ERR_HEREDOC_TERM); + + node = (pm_node_t *) cast; + + if (indent == PM_HEREDOC_INDENT_TILDE) { + int common_whitespace = parse_heredoc_common_whitespace_for_single_node(parser, node, -1); + parse_heredoc_dedent_single_node(parser, &cast->unescaped, true, common_whitespace, quote); + } + } 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 = PM_EMPTY_NODE_LIST; + 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); + } + } + + // 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_state_set(parser, PM_LEX_STATE_END); + 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_state_set(parser, PM_LEX_STATE_END); + 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) { + parse_heredoc_dedent(parser, node, quote); + } + } + + if (match1(parser, PM_TOKEN_STRING_BEGIN)) { + pm_node_t *concat = parse_strings(parser); + return (pm_node_t *) pm_string_concat_node_create(parser, node, concat); + } + + 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: { + 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_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, PM_ERR_ALIAS_ARGUMENT); + } + } else { + pm_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, 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_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, 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_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CASE_EXPRESSION_AFTER_CASE); + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + } + + if (accept1(parser, PM_TOKEN_KEYWORD_END)) { + pm_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, PM_ERR_CASE_MISSING_CONDITIONS); + return (pm_node_t *) pm_case_node_create(parser, &case_keyword, predicate, NULL, &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_case_node_t *case_node = pm_case_node_create(parser, &case_keyword, predicate, NULL, &end_keyword); + + if (match1(parser, PM_TOKEN_KEYWORD_WHEN)) { + // 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_expression(parser, PM_BINDING_POWER_DEFINED, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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); + } + } else { + // 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_expression(parser, PM_BINDING_POWER_DEFINED, 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_expression(parser, PM_BINDING_POWER_DEFINED, 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_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_diagnostic_list_append(&parser->error_list, case_keyword.start, case_keyword.end, PM_ERR_CASE_MISSING_CONDITIONS); + } + + 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); + } + + pm_case_node_consequent_set(case_node, else_node); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM); + pm_case_node_end_keyword_loc_set(case_node, &parser->previous); + return (pm_node_t *) case_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); + + 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_diagnostic_list_append( + &parser->error_list, + begin_node->else_clause->base.location.start, + begin_node->else_clause->base.location.end, + PM_ERR_BEGIN_LONELY_ELSE + ); + } + + return (pm_node_t *) begin_node; + } + case PM_TOKEN_KEYWORD_BEGIN_UPCASE: { + 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_diagnostic_list_append(&parser->error_list, keyword.start, keyword.end, 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 = PM_EMPTY_ARGUMENTS; + + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, true); + + if (arguments.opening_loc.start == NULL && arguments.arguments == NULL) { + 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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, false); + + 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_expression(parser, PM_BINDING_POWER_NOT, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS); + + 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); + } + + 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); + 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, PM_ERR_CLASS_NAME); + pm_token_t name = parser->previous; + if (name.type != PM_TOKEN_CONSTANT) { + pm_diagnostic_list_append(&parser->error_list, name.start, name.end, 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_expression(parser, PM_BINDING_POWER_COMPOSITION, PM_ERR_CLASS_SUPERCLASS); + } else { + inheritance_operator = not_provided(parser); + superclass = NULL; + } + + 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); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM); + + if (context_def_p(parser)) { + pm_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, PM_ERR_CLASS_IN_METHOD); + } + + pm_constant_id_list_t locals = parser->current_scope->locals; + pm_parser_scope_pop(parser); + 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_diagnostic_list_append(&parser->error_list, constant_path->location.start, constant_path->location.end, 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 }; + + context_push(parser, PM_CONTEXT_DEF_PARAMS); + parser_lex(parser); + + switch (parser->current.type) { + case PM_CASE_OPERATOR: + pm_parser_scope_push(parser, true); + 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); + lex_state_set(parser, PM_LEX_STATE_FNAME); + parser_lex(parser); + + operator = parser->previous; + name = parse_method_definition_name(parser); + } else { + pm_parser_scope_push(parser, true); + 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_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: { + parser_lex(parser); + pm_token_t lparen = parser->previous; + pm_node_t *expression = parse_expression(parser, PM_BINDING_POWER_STATEMENT, 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); + name = parse_method_definition_name(parser); + break; + } + default: + pm_parser_scope_push(parser, true); + 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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; + } + } + + 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_diagnostic_list_append(&parser->error_list, name.start, name.end, PM_ERR_DEF_ENDLESS_SETTER); + } + equal = parser->previous; + + context_push(parser, PM_CONTEXT_DEF); + statements = (pm_node_t *) pm_statements_node_create(parser); + + pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, 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, 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); + 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); + } + + 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; + pm_parser_scope_pop(parser); + + return (pm_node_t *) pm_def_node_create( + parser, + &name, + receiver, + params, + statements, + &locals, + &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, PM_ERR_DEFINED_EXPRESSION); + + if (parser->recovering) { + rparen = not_provided(parser); + } else { + 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, 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: { + parser_lex(parser); + pm_token_t keyword = parser->previous; + + 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; + + // 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, 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, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA); + } else { + pm_diagnostic_list_append(&parser->error_list, for_keyword.start, for_keyword.end, 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); + } + + 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_expression(parser, PM_BINDING_POWER_COMPOSITION, 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: { + 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 = PM_EMPTY_ARGUMENTS; + 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, 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_DEFINED, 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, 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_diagnostic_list_append(&parser->error_list, name.start, name.end, PM_ERR_MODULE_NAME); + } + + 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); + } + + pm_constant_id_list_t locals = parser->current_scope->locals; + pm_parser_scope_pop(parser); + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM); + + if (context_def_p(parser)) { + pm_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, 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_expression(parser, PM_BINDING_POWER_COMPOSITION, 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_expression(parser, PM_BINDING_POWER_COMPOSITION, 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_array_node_t *array = pm_array_node_create(parser, &parser->previous); + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + accept1(parser, PM_TOKEN_WORDS_SEP); + if (match1(parser, PM_TOKEN_STRING_END)) break; + + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_LOWER_ELEMENT); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_node_t *symbol = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_MINIMAL); + pm_array_node_elements_append(array, symbol); + } + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_LOWER_TERM); + pm_array_node_close_set(array, &parser->previous); + + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_UPPER_I: { + parser_lex(parser); + pm_array_node_t *array = pm_array_node_create(parser, &parser->previous); + + // 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. + parser_lex(parser); + current = (pm_node_t *) pm_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + } 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 *part = parse_string_part(parser); + pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part); + } 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_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); + pm_interpolated_symbol_node_append(interpolated, current); + + pm_node_t *part = parse_string_part(parser); + pm_interpolated_symbol_node_append(interpolated, part); + 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); + } + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_UPPER_TERM); + pm_array_node_close_set(array, &parser->previous); + + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_LOWER_W: { + parser_lex(parser); + pm_array_node_t *array = pm_array_node_create(parser, &parser->previous); + + // 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; + + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_LOWER_ELEMENT); + + 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_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_WHITESPACE); + pm_array_node_elements_append(array, string); + } + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_LOWER_TERM); + pm_array_node_close_set(array, &parser->previous); + + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_UPPER_W: { + parser_lex(parser); + pm_array_node_t *array = pm_array_node_create(parser, &parser->previous); + + // 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: { + 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 = parse_string_part(parser); + } 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_node_t *part = parse_string_part(parser); + pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part); + } 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_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); + + pm_node_t *part = parse_string_part(parser); + pm_interpolated_string_node_append(interpolated, part); + 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); + } + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_UPPER_TERM); + pm_array_node_close_set(array, &parser->previous); + + 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_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); + } + + 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_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_and_unescape(parser, &opening, &content, &parser->previous, PM_UNESCAPE_ALL); + } + + // 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_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + 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. + while (!match2(parser, PM_TOKEN_REGEXP_END, PM_TOKEN_EOF)) { + pm_node_t *part = parse_string_part(parser); + if (part != NULL) { + pm_interpolated_regular_expression_node_append(node, part); + } + } + + expect1(parser, PM_TOKEN_REGEXP_END, PM_ERR_REGEXP_TERM); + pm_interpolated_regular_expression_node_closing_set(node, &parser->previous); + + 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_token_t content = parser->current; + parser_lex(parser); + + if (accept1(parser, PM_TOKEN_STRING_END)) { + return (pm_node_t *) pm_xstring_node_create_and_unescape(parser, &opening, &content, &parser->previous); + } + + // 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_and_unescape(parser, &opening, &parser->previous, &closing, PM_UNESCAPE_ALL); + 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); + } + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + pm_node_t *part = parse_string_part(parser); + if (part != NULL) { + pm_interpolated_xstring_node_append(node, part); + } + } + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_XSTRING_TERM); + pm_interpolated_xstring_node_closing_set(node, &parser->previous); + 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, 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, 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, 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, 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, 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, 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 *params; + + 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)) { + params = pm_block_parameters_node_create(parser, NULL, &opening); + } else { + params = 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(params, &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); + params = parse_block_parameters(parser, false, &opening, true); + pm_accepts_block_stack_pop(parser); + break; + } + default: { + params = NULL; + break; + } + } + + 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); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END); + } + + 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, &operator, &opening, &parser->previous, params, 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, 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); + 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, pm_diagnostic_id_t diag_id) { + pm_node_t *value = parse_starred_expression(parser, binding_power, diag_id); + + if (previous_binding_power == PM_BINDING_POWER_STATEMENT && (PM_NODE_TYPE_P(value, PM_SPLAT_NODE) || match1(parser, PM_TOKEN_COMMA))) { + 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, PM_ERR_ARRAY_ELEMENT); + pm_array_node_elements_append(array, element); + if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break; + } + } + + return value; +} + +// Ensures a call node that is about to become a call operator node does not +// have a block attached. If it does, then we'll need to add an error message +// and destroy the 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_block(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) { + if (call_node->block != NULL) { + pm_diagnostic_list_append(&parser->error_list, operator->start, operator->end, PM_ERR_OPERATOR_WRITE_BLOCK); + pm_node_destroy(parser, (pm_node_t *) call_node->block); + call_node->block = NULL; + } +} + +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) { + 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_value(parser, previous_binding_power, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); + return parse_write(parser, node, &token, value); + } + case PM_SPLAT_NODE: { + pm_splat_node_t *splat_node = (pm_splat_node_t *) node; + + switch (PM_NODE_TYPE(splat_node->expression)) { + case PM_CASE_WRITABLE: + parser_lex(parser); + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); + return parse_write(parser, (pm_node_t *) splat_node, &token, value); + default: + break; + } + } + /* fallthrough */ + 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_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, PM_ERR_WRITE_TARGET_READONLY); + /* fallthrough */ + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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: { + // 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((pm_call_node_t *) node)) { + pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc; + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end); + + if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { + pm_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + parser_lex(parser); + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); + pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, constant_id, 0); + + pm_node_destroy(parser, node); + return result; + } + + parser_lex(parser); + node = parse_target(parser, node); + + assert(PM_NODE_TYPE_P(node, PM_CALL_NODE)); + parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token); + + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); + return (pm_node_t *) pm_call_and_write_node_create(parser, (pm_call_node_t *) node, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, PM_ERR_WRITE_TARGET_READONLY); + /* fallthrough */ + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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: { + // 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((pm_call_node_t *) node)) { + pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc; + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end); + + if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { + pm_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + parser_lex(parser); + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); + pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, constant_id, 0); + + pm_node_destroy(parser, node); + return result; + } + + parser_lex(parser); + node = parse_target(parser, node); + + assert(PM_NODE_TYPE_P(node, PM_CALL_NODE)); + parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token); + + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); + return (pm_node_t *) pm_call_or_write_node_create(parser, (pm_call_node_t *) node, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, PM_ERR_WRITE_TARGET_READONLY); + /* fallthrough */ + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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: { + // 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((pm_call_node_t *) node)) { + pm_location_t message_loc = ((pm_call_node_t *) node)->message_loc; + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc.start, message_loc.end); + + if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { + pm_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, PM_ERR_PARAMETER_NUMBERED_RESERVED); + } + + parser_lex(parser); + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); + pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, constant_id, 0); + + pm_node_destroy(parser, node); + return result; + } + + parser_lex(parser); + node = parse_target(parser, node); + + assert(PM_NODE_TYPE_P(node, PM_CALL_NODE)); + parse_call_operator_write_block(parser, (pm_call_node_t *) node, &token); + + pm_node_t *value = parse_expression(parser, binding_power, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); + return (pm_node_t *) pm_call_operator_write_node_create(parser, (pm_call_node_t *) node, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_diagnostic_list_append(&parser->error_list, token.start, token.end, 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_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, 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, 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, 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, + // + // /(?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, 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_REGULAR_EXPRESSION_NODE)) { + pm_string_list_t named_captures; + pm_string_list_init(&named_captures); + + const pm_location_t *content_loc = &((pm_regular_expression_node_t *) node)->content_loc; + if (pm_regexp_named_capture_group_names(content_loc->start, (size_t) (content_loc->end - content_loc->start), &named_captures, parser->encoding_changed, &parser->encoding) && (named_captures.length > 0)) { + pm_match_write_node_t *match = pm_match_write_node_create(parser, call); + + for (size_t index = 0; index < named_captures.length; index++) { + pm_string_t *name = &named_captures.strings[index]; + assert(name->type == PM_STRING_SHARED); + + pm_constant_id_t local = pm_parser_local_add_location(parser, name->source, name->source + name->length); + pm_constant_id_list_append(&match->locals, local); + } + + result = (pm_node_t *) match; + } + + pm_string_list_free(&named_captures); + } + + 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, 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 = PM_EMPTY_ARGUMENTS; + + // This if statement handles the foo.() syntax. + if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + parse_arguments_list(parser, &arguments, true); + 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_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, 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); + 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, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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_expression(parser, binding_power, 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: { + parser_lex(parser); + pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, 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, 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, PM_ERR_TERNARY_EXPRESSION_FALSE); + + return (pm_node_t *) pm_if_node_ternary_create(parser, node, 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 = PM_EMPTY_ARGUMENTS; + + parse_arguments_list(parser, &arguments, true); + 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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, true); + 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 = PM_EMPTY_ARGUMENTS; + parse_arguments_list(parser, &arguments, true); + + return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &delimiter, &arguments); + } + default: { + pm_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, 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, 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 = PM_EMPTY_ARGUMENTS; + 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_diagnostic_list_append(&parser->error_list, block->base.location.start, block->base.location.end, 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, pm_diagnostic_id_t diag_id) { + pm_token_t recovery = parser->previous; + pm_node_t *node = parse_expression_prefix(parser, binding_power); + + // 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. + if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) { + pm_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, diag_id); + return node; + } + + // 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); + } + + 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); +} + +// Read a 32-bit unsigned integer from a pointer. This function is used to read +// the metadata that is passed into the parser from the Ruby implementation. It +// handles aligned and unaligned reads. +static uint32_t +pm_metadata_read_u32(const char *ptr) { + if (((uintptr_t) ptr) % sizeof(uint32_t) == 0) { + return *((uint32_t *) ptr); + } else { + uint32_t value; + memcpy(&value, ptr, sizeof(uint32_t)); + return value; + } +} + +// Process any additional metadata being passed into a call to the parser via +// the pm_parse_serialize function. Since the source of these calls will be from +// Ruby implementation internals we assume it is from a trusted source. +// +// Currently, this is only passing in variable scoping surrounding an eval, but +// eventually it will be extended to hold any additional metadata. This data +// is serialized to reduce the calling complexity for a foreign function call +// vs a foreign runtime making a bindable in-memory version of a C structure. +// +// metadata is assumed to be a valid pointer pointing to well-formed data. The +// format is described below: +// +// ```text +// [ +// filepath_size: uint32_t, +// filepath: char*, +// scopes_count: uint32_t, +// [ +// locals_count: uint32_t, +// [local_size: uint32_t, local: char*]* +// ]* +// ] +// ``` +void +pm_parser_metadata(pm_parser_t *parser, const char *metadata) { + uint32_t filepath_size = pm_metadata_read_u32(metadata); + metadata += 4; + + if (filepath_size) { + pm_string_t filepath_string; + pm_string_constant_init(&filepath_string, metadata, filepath_size); + + parser->filepath_string = filepath_string; + metadata += filepath_size; + } + + uint32_t scopes_count = pm_metadata_read_u32(metadata); + metadata += 4; + + for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) { + uint32_t locals_count = pm_metadata_read_u32(metadata); + metadata += 4; + + pm_parser_scope_push(parser, scope_index == 0); + + for (size_t local_index = 0; local_index < locals_count; local_index++) { + uint32_t local_size = pm_metadata_read_u32(metadata); + metadata += 4; + + uint8_t *constant = malloc(local_size); + memcpy(constant, metadata, local_size); + + pm_parser_local_add_owned(parser, constant, (size_t) local_size); + metadata += local_size; + } + } +} + +/******************************************************************************/ +/* 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 char *filepath) { + assert(source != NULL); + + // Set filepath to the file that was passed + if (!filepath) filepath = ""; + pm_string_t filepath_string; + pm_string_constant_init(&filepath_string, filepath, strlen(filepath)); + + *parser = (pm_parser_t) { + .lex_state = PM_LEX_STATE_BEG, + .enclosure_nesting = 0, + .lambda_enclosure_nesting = -1, + .brace_nesting = 0, + .do_loop_stack = PM_STATE_STACK_EMPTY, + .accepts_block_stack = PM_STATE_STACK_EMPTY, + .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 = PM_LIST_EMPTY, + .warning_list = PM_LIST_EMPTY, + .error_list = PM_LIST_EMPTY, + .current_scope = NULL, + .current_context = NULL, + .encoding = pm_encoding_utf_8, + .encoding_changed_callback = NULL, + .encoding_decode_callback = NULL, + .encoding_comment_start = source, + .lex_callback = NULL, + .filepath_string = filepath_string, + .constant_pool = PM_CONSTANT_POOL_EMPTY, + .newline_list = PM_NEWLINE_LIST_EMPTY, + .integer_base = 0, + .command_start = true, + .recovering = false, + .encoding_changed = false, + .pattern_matching_newlines = false, + .in_keyword_arg = false, + .semantic_token_seen = false, + .frozen_string_literal = false + }; + + pm_accepts_block_stack_push(parser, true); + + // 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); + + // 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; +} + +// Register a callback that will be called when prism encounters a magic comment +// with an encoding referenced that it doesn't understand. The callback should +// return NULL if it also doesn't understand the encoding or it should return a +// pointer to a pm_encoding_t struct that contains the functions necessary to +// parse identifiers. +PRISM_EXPORTED_FUNCTION void +pm_parser_register_encoding_decode_callback(pm_parser_t *parser, pm_encoding_decode_callback_t callback) { + parser->encoding_decode_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 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_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); +} + +PRISM_EXPORTED_FUNCTION void +pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_buffer_append_str(buffer, "PRISM", 5); + pm_buffer_append_u8(buffer, PRISM_VERSION_MAJOR); + pm_buffer_append_u8(buffer, PRISM_VERSION_MINOR); + pm_buffer_append_u8(buffer, PRISM_VERSION_PATCH); + pm_buffer_append_u8(buffer, PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0); + + pm_serialize_content(parser, node, buffer); + pm_buffer_append_str(buffer, "\0", 1); +} + +// Parse and serialize the AST represented by the given source to the given +// buffer. +PRISM_EXPORTED_FUNCTION void +pm_parse_serialize(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata) { + pm_parser_t parser; + pm_parser_init(&parser, source, size, NULL); + if (metadata) pm_parser_metadata(&parser, metadata); + + pm_node_t *node = pm_parse(&parser); + pm_serialize(&parser, node, buffer); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); +} + +#undef PM_LOCATION_NULL_VALUE +#undef PM_LOCATION_TOKEN_VALUE +#undef PM_LOCATION_NODE_VALUE +#undef PM_LOCATION_NODE_BASE_VALUE +#undef PM_CASE_KEYWORD +#undef PM_CASE_OPERATOR +#undef PM_CASE_WRITABLE diff --git a/prism/prism.h b/prism/prism.h new file mode 100644 index 00000000000000..d73c71518f8aa3 --- /dev/null +++ b/prism/prism.h @@ -0,0 +1,82 @@ +#ifndef PRISM_H +#define PRISM_H + +#include "prism/defines.h" +#include "prism/ast.h" +#include "prism/diagnostic.h" +#include "prism/node.h" +#include "prism/pack.h" +#include "prism/parser.h" +#include "prism/regexp.h" +#include "prism/unescape.h" +#include "prism/util/pm_buffer.h" +#include "prism/util/pm_char.h" +#include "prism/util/pm_memchr.h" +#include "prism/util/pm_strpbrk.h" +#include "prism/version.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#endif + +void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer); + +void pm_print_node(pm_parser_t *parser, pm_node_t *node); + +void pm_parser_metadata(pm_parser_t *parser, const char *metadata); + +// Generate a scope node from the given node. +void pm_scope_node_init(pm_node_t *node, pm_scope_node_t *dest); + +// The prism version and the serialization format. +PRISM_EXPORTED_FUNCTION const char * pm_version(void); + +// 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 char *filepath); + +// 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); + +// Register a callback that will be called when prism encounters a magic comment +// with an encoding referenced that it doesn't understand. The callback should +// return NULL if it also doesn't understand the encoding or it should return a +// pointer to a pm_encoding_t struct that contains the functions necessary to +// parse identifiers. +PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_decode_callback(pm_parser_t *parser, pm_encoding_decode_callback_t callback); + +// Free any memory associated with the given parser. +PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *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); + +// Pretty-prints the AST represented by the given node to the given buffer. +PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer); + +// 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); + +// Parse the given source to the AST and serialize the AST to the given buffer. +PRISM_EXPORTED_FUNCTION void pm_parse_serialize(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata); + +// Lex the given source and serialize to the given buffer. +PRISM_EXPORTED_FUNCTION void pm_lex_serialize(const uint8_t *source, size_t size, const char *filepath, pm_buffer_t *buffer); + +// Parse and serialize both the AST and the tokens represented by the given +// source to the given buffer. +PRISM_EXPORTED_FUNCTION void pm_parse_lex_serialize(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata); + +// 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); + +#endif diff --git a/prism/regexp.c b/prism/regexp.c new file mode 100644 index 00000000000000..c227c7b4c14941 --- /dev/null +++ b/prism/regexp.c @@ -0,0 +1,580 @@ +#include "prism/regexp.h" + +// This is the parser that is going to handle parsing regular expressions. +typedef struct { + const uint8_t *start; + const uint8_t *cursor; + const uint8_t *end; + pm_string_list_t *named_captures; + bool encoding_changed; + 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, 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 +// | +// ; +static bool +pm_regexp_parse_quantifier(pm_regexp_parser_t *parser) { + 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 { + 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) - 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, 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 new file mode 100644 index 00000000000000..5745512dee7956 --- /dev/null +++ b/prism/regexp.h @@ -0,0 +1,19 @@ +#ifndef PRISM_REGEXP_H +#define PRISM_REGEXP_H + +#include "prism/defines.h" +#include "prism/parser.h" +#include "prism/enc/pm_encoding.h" +#include "prism/util/pm_memchr.h" +#include "prism/util/pm_string_list.h" +#include "prism/util/pm_string.h" + +#include +#include +#include + +// 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, 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 new file mode 100644 index 00000000000000..76eb50a7bd78b2 --- /dev/null +++ b/prism/templates/ext/prism/api_node.c.erb @@ -0,0 +1,208 @@ +#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, offsets }; + return rb_class_new_instance(2, 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]; + constants[index] = rb_intern3((const char *) constant->start, constant->length, encoding); + } + + 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::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 >> <%= Prism::COMMON_FLAGS %>); + <%- 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 new file mode 100644 index 00000000000000..92236f6b44b700 --- /dev/null +++ b/prism/templates/include/prism/ast.h.erb @@ -0,0 +1,116 @@ +#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 +#include +#include + +// This enum represents every type of token in the Ruby source. +typedef enum pm_token_type { +<%- tokens.each do |token| -%> + <%= token.declaration %> +<%- end -%> + PM_TOKEN_MAXIMUM, // the maximum token value +} 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 { + pm_token_type_t type; + const uint8_t *start; + 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 { + const uint8_t *start; + const uint8_t *end; +} pm_location_t; + +struct pm_node; + +typedef struct pm_node_list { + struct pm_node **nodes; + size_t size; + size_t capacity; +} pm_node_list_t; + +enum pm_node_type { +<%- nodes.each_with_index do |node, index| -%> + <%= node.type %> = <%= index + 1 %>, +<%- end -%> + PM_SCOPE_NODE +}; + +typedef uint16_t pm_node_type_t; +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. +static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = 0x1; +static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2; + +// For easy access, we define some macros to check node type +#define PM_NODE_TYPE(node) ((enum pm_node_type)node->type) +#define PM_NODE_TYPE_P(node, type) (PM_NODE_TYPE(node) == (type)) + +// This is the overall tagged union representing a node in the syntax tree. +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 + 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 -%> +typedef struct pm_<%= node.human %> { + pm_node_t base; +<%- node.fields.grep_v(Prism::FlagsField).each do |field| -%> + <%= 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::UInt32Field then "uint32_t #{field.name}" + else raise field.class.name + end + %>; +<%- end -%> +} pm_<%= node.human %>_t; +<%- end -%> +<%- flags.each do |flag| -%> + +// <%= flag.name %> +typedef enum { + <%- flag.values.each.with_index(Prism::COMMON_FLAGS) do |value, index| -%> + PM_<%= flag.human.upcase %>_<%= value.name %> = 1 << <%= index %>, + <%- end -%> +} pm_<%= flag.human %>_t; +<%- end -%> + +#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS <%= Prism::SERIALIZE_ONLY_SEMANTICS_FIELDS %> + +#endif // PRISM_AST_H diff --git a/prism/templates/lib/prism/compiler.rb.erb b/prism/templates/lib/prism/compiler.rb.erb new file mode 100644 index 00000000000000..03b8dfbb92ab95 --- /dev/null +++ b/prism/templates/lib/prism/compiler.rb.erb @@ -0,0 +1,41 @@ +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 new file mode 100644 index 00000000000000..3fe9d75bcc400a --- /dev/null +++ b/prism/templates/lib/prism/dispatcher.rb.erb @@ -0,0 +1,88 @@ +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 + + 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 + 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/dsl.rb.erb b/prism/templates/lib/prism/dsl.rb.erb new file mode 100644 index 00000000000000..be18ad45badc44 --- /dev/null +++ b/prism/templates/lib/prism/dsl.rb.erb @@ -0,0 +1,45 @@ +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 new file mode 100644 index 00000000000000..9a81b704ebcbf7 --- /dev/null +++ b/prism/templates/lib/prism/mutation_compiler.rb.erb @@ -0,0 +1,19 @@ +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 new file mode 100644 index 00000000000000..f7937dc3e5ee34 --- /dev/null +++ b/prism/templates/lib/prism/node.rb.erb @@ -0,0 +1,226 @@ +module Prism + # This represents a node in the tree. It is the parent class of all of the + # various node types. + class Node + attr_reader :location + + def newline? + @newline ? true : false + end + + def set_newline_flag(newline_marked) + 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 + end + <%- nodes.each do |node| -%> + + <%= "#{node.comment.split("\n").map { |line| line.empty? ? "#" : "# #{line}" }.join("\n ")}\n " if node.comment %>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) + # Never mark <%= node.name %> with a newline flag, mark children instead + end + <%- elsif node.newline.is_a?(String) -%> + + def set_newline_flag(newline_marked) + <%- field = node.fields.find { |f| f.name == node.newline } or raise node.newline -%> + <%- case field -%> + <%- when Prism::NodeField, Prism::OptionalNodeField -%> + <%= 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.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::OptionalConstantField, Prism::StringField, Prism::UInt32Field -%> + inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n" + <%- 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 + end + <%- end -%> + <%- flags.each_with_index do |flag, flag_index| -%> + + 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/yarp/templates/lib/yarp/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb similarity index 81% rename from yarp/templates/lib/yarp/serialize.rb.erb rename to prism/templates/lib/prism/serialize.rb.erb index 370453565c8ea8..52fe811a5a8139 100644 --- a/yarp/templates/lib/yarp/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -11,10 +11,10 @@ if String.instance_method(:unpack1).parameters.none? { |_, name| name == :offset ) end -module YARP +module Prism module Serialize MAJOR_VERSION = 0 - MINOR_VERSION = 11 + MINOR_VERSION = 13 PATCH_VERSION = 0 def self.load(input, serialized) @@ -67,7 +67,7 @@ module YARP length = load_varint lex_state = load_varint location = Location.new(@source, start, length) - tokens << [YARP::Token.new(type, location.slice, location), lex_state] + tokens << [Prism::Token.new(type, location.slice, location), lex_state] end tokens @@ -83,12 +83,16 @@ module YARP end raise "Expected to consume all bytes while deserializing" unless @io.eof? - YARP::ParseResult.new(tokens, comments, errors, warnings, @source) + Prism::ParseResult.new(tokens, comments, errors, warnings, @source) end def load_nodes - raise "Invalid serialization" if io.read(4) != "YARP" + 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 @encoding = load_encoding @input = input.force_encoding(@encoding).freeze @@ -103,7 +107,7 @@ module YARP def load_result node, comments, errors, warnings = load_nodes - YARP::ParseResult.new(node, comments, errors, warnings, @source) + Prism::ParseResult.new(node, comments, errors, warnings, @source) end private @@ -200,16 +204,16 @@ module YARP <%- end -%> <%= node.name %>.new(<%= (node.fields.map { |field| case field - when YARP::NodeField then "load_node" - when YARP::OptionalNodeField then "load_optional_node" - when YARP::StringField then "load_string" - when YARP::NodeListField then "Array.new(load_varint) { load_node }" - when YARP::ConstantField then "load_required_constant" - when YARP::OptionalConstantField then "load_optional_constant" - when YARP::ConstantListField then "Array.new(load_varint) { load_required_constant }" - when YARP::LocationField then "load_location" - when YARP::OptionalLocationField then "load_optional_location" - when YARP::UInt32Field, YARP::FlagsField then "load_varint" + 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_varint) { load_node }" + when Prism::ConstantField then "load_required_constant" + when Prism::OptionalConstantField then "load_optional_constant" + when Prism::ConstantListField then "Array.new(load_varint) { load_required_constant }" + when Prism::LocationField then "load_location" + when Prism::OptionalLocationField then "load_optional_location" + when Prism::UInt32Field, Prism::FlagsField then "load_varint" else raise end } + ["location"]).join(", ") -%>) diff --git a/prism/templates/lib/prism/visitor.rb.erb b/prism/templates/lib/prism/visitor.rb.erb new file mode 100644 index 00000000000000..1c33e7a0925d70 --- /dev/null +++ b/prism/templates/lib/prism/visitor.rb.erb @@ -0,0 +1,46 @@ +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 + def visit(node) + node&.accept(self) + end + + def visit_all(nodes) + nodes.each { |node| node&.accept(self) } + end + + 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 new file mode 100644 index 00000000000000..0126cc4361d297 --- /dev/null +++ b/prism/templates/src/node.c.erb @@ -0,0 +1,157 @@ +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" +#include "prism/node.h" + +// Clear the node but preserves the location. +void pm_node_clear(pm_node_t *node) { + pm_location_t location = node->location; + memset(node, 0, sizeof(pm_node_t)); + node->location = location; +} + +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::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::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::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 new file mode 100644 index 00000000000000..0dd8632616f4d2 --- /dev/null +++ b/prism/templates/src/prettyprint.c.erb @@ -0,0 +1,111 @@ +#include "prism/defines.h" + +#include + +#include "prism/ast.h" +#include "prism/parser.h" +#include "prism/util/pm_buffer.h" + +static void +prettyprint_location(pm_buffer_t *buffer, pm_parser_t *parser, pm_location_t *location) { + char printed[] = "[0000-0000]"; + snprintf(printed, sizeof(printed), "[%04ld-%04ld]", (long int)(location->start - parser->start), (long int)(location->end - parser->start)); + pm_buffer_append_str(buffer, printed, strlen(printed)); +} + +static void +prettyprint_node(pm_buffer_t *buffer, pm_parser_t *parser, pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + // We do not need to print a ScopeNode as it's not part + // of the AST + case PM_SCOPE_NODE: + return; + <%- nodes.each do |node| -%> + case <%= node.type %>: { + pm_buffer_append_str(buffer, "<%= node.name %>(", <%= node.name.length + 1 %>); + <%- node.fields.each_with_index do |field, index| -%> + <%= "pm_buffer_append_str(buffer, \", \", 2);" if index != 0 -%> + <%- case field -%> + <%- when Prism::NodeField -%> + prettyprint_node(buffer, parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>); + <%- when Prism::OptionalNodeField -%> + if (((pm_<%= node.human %>_t *)node)-><%= field.name %> == NULL) { + pm_buffer_append_str(buffer, "nil", 3); + } else { + prettyprint_node(buffer, parser, (pm_node_t *)((pm_<%= node.human %>_t *)node)-><%= field.name %>); + } + <%- when Prism::StringField -%> + pm_buffer_append_str(buffer, "\"", 1); + pm_buffer_append_bytes(buffer, pm_string_source(&((pm_<%= node.human %>_t *)node)-><%= field.name %>), pm_string_length(&((pm_<%= node.human %>_t *)node)-><%= field.name %>)); + pm_buffer_append_str(buffer, "\"", 1); + <%- when Prism::NodeListField -%> + pm_buffer_append_str(buffer, "[", 1); + for (uint32_t index = 0; index < ((pm_<%= node.human %>_t *)node)-><%= field.name %>.size; index++) { + if (index != 0) pm_buffer_append_str(buffer, ", ", 2); + prettyprint_node(buffer, parser, (pm_node_t *) ((pm_<%= node.human %>_t *) node)-><%= field.name %>.nodes[index]); + } + pm_buffer_append_str(buffer, "]", 1); + <%- when Prism::ConstantField -%> + char <%= field.name %>_buffer[12]; + snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((pm_<%= node.human %>_t *)node)-><%= field.name %>); + pm_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); + <%- when Prism::OptionalConstantField -%> + if (((pm_<%= node.human %>_t *)node)-><%= field.name %> == 0) { + pm_buffer_append_str(buffer, "nil", 3); + } else { + char <%= field.name %>_buffer[12]; + snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((pm_<%= node.human %>_t *)node)-><%= field.name %>); + pm_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); + } + <%- when Prism::ConstantListField -%> + pm_buffer_append_str(buffer, "[", 1); + for (uint32_t index = 0; index < ((pm_<%= node.human %>_t *)node)-><%= field.name %>.size; index++) { + if (index != 0) pm_buffer_append_str(buffer, ", ", 2); + char <%= field.name %>_buffer[12]; + snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((pm_<%= node.human %>_t *)node)-><%= field.name %>.ids[index]); + pm_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); + } + pm_buffer_append_str(buffer, "]", 1); + <%- when Prism::LocationField -%> + prettyprint_location(buffer, parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>); + <%- when Prism::OptionalLocationField -%> + if (((pm_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) { + pm_buffer_append_str(buffer, "nil", 3); + } else { + prettyprint_location(buffer, parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>); + } + <%- when Prism::UInt32Field -%> + char <%= field.name %>_buffer[12]; + snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "+%d", ((pm_<%= node.human %>_t *)node)-><%= field.name %>); + pm_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); + <%- when Prism::FlagsField -%> + char <%= field.name %>_buffer[12]; + snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "+%d", node->flags >> <%= Prism::COMMON_FLAGS %>); + pm_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); + <%- else -%> + <%- raise -%> + <%- end -%> + <%- end -%> + pm_buffer_append_str(buffer, ")", 1); + break; + } + <%- end -%> + } +} + +void +pm_print_node(pm_parser_t *parser, pm_node_t *node) { + pm_buffer_t buffer; + if (!pm_buffer_init(&buffer)) return; + + prettyprint_node(&buffer, parser, node); + printf("%.*s\n", (int) buffer.length, buffer.value); + + pm_buffer_free(&buffer); +} + +// Pretty-prints the AST represented by the given node to the given buffer. +PRISM_EXPORTED_FUNCTION void +pm_prettyprint(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + prettyprint_node(buffer, parser, node); +} diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb new file mode 100644 index 00000000000000..cc2d4db7a02db3 --- /dev/null +++ b/prism/templates/src/serialize.c.erb @@ -0,0 +1,299 @@ +#include "prism.h" + +#include + +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(pm_parser_t *parser, pm_location_t *location, pm_buffer_t *buffer) { + assert(location->start); + assert(location->end); + assert(location->start <= location->end); + + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(location->start - parser->start)); + pm_buffer_append_u32(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_u8(buffer, 1); + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(pm_string_source(string) - parser->start)); + pm_buffer_append_u32(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_u8(buffer, 2); + pm_buffer_append_u32(buffer, length); + pm_buffer_append_bytes(buffer, pm_string_source(string), length); + break; + } + case PM_STRING_MAPPED: + assert(false && "Cannot serialize mapped strings."); + break; + } +} + +void +pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_buffer_append_u8(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_str(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_u8(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_u32(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_u32(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_u32(buffer, <%= field.name %>_size); + for (uint32_t index = 0; index < <%= field.name %>_size; index++) { + pm_buffer_append_u32(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_u8(buffer, 0); + } else { + pm_buffer_append_u8(buffer, 1); + pm_serialize_location(parser, &((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer); + } + <%- end -%> + <%- when Prism::UInt32Field -%> + pm_buffer_append_u32(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>); + <%- when Prism::FlagsField -%> + pm_buffer_append_u32(buffer, node->flags >> <%= Prism::COMMON_FLAGS %>); + <%- 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_u8(buffer, (uint8_t) comment->type); + + // serialize location + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(comment->start - parser->start)); + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(comment->end - comment->start)); +} + +static void +pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) { + pm_buffer_append_u32(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_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_u32(buffer, pm_sizet_to_u32(message_length)); + pm_buffer_append_str(buffer, diagnostic->message, message_length); + + // serialize location + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(diagnostic->start - parser->start)); + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(diagnostic->end - diagnostic->start)); +} + +static void +pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) { + pm_buffer_append_u32(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); + } +} + +static void +pm_serialize_encoding(pm_encoding_t *encoding, pm_buffer_t *buffer) { + size_t encoding_length = strlen(encoding->name); + pm_buffer_append_u32(buffer, pm_sizet_to_u32(encoding_length)); + pm_buffer_append_str(buffer, encoding->name, encoding_length); +} + +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" +void +pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_serialize_encoding(&parser->encoding, buffer); + pm_serialize_comment_list(parser, &parser->comment_list, 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_u32(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->owned) { + // Since this is an owned 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_u32(buffer, token->type); + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(token->start - parser->start)); + pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(token->end - token->start)); + pm_buffer_append_u32(buffer, parser->lex_state); +} + +PRISM_EXPORTED_FUNCTION void +pm_lex_serialize(const uint8_t *source, size_t size, const char *filepath, pm_buffer_t *buffer) { + pm_parser_t parser; + pm_parser_init(&parser, source, size, filepath); + + 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_u8(buffer, 0); + + pm_serialize_encoding(&parser.encoding, buffer); + pm_serialize_comment_list(&parser, &parser.comment_list, 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); +} + +// Parse and serialize both the AST and the tokens represented by the given +// source to the given buffer. +PRISM_EXPORTED_FUNCTION void +pm_parse_lex_serialize(const uint8_t *source, size_t size, pm_buffer_t *buffer, const char *metadata) { + pm_parser_t parser; + pm_parser_init(&parser, source, size, NULL); + if (metadata) pm_parser_metadata(&parser, metadata); + + 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_u8(buffer, 0); + pm_serialize(&parser, node, buffer); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); +} diff --git a/prism/templates/src/token_type.c.erb b/prism/templates/src/token_type.c.erb new file mode 100644 index 00000000000000..98be08173222b8 --- /dev/null +++ b/prism/templates/src/token_type.c.erb @@ -0,0 +1,18 @@ +#include + +#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/yarp/templates/template.rb b/prism/templates/template.rb similarity index 86% rename from yarp/templates/template.rb rename to prism/templates/template.rb index 928ade61a6e601..b2f6525eec13b2 100755 --- a/yarp/templates/template.rb +++ b/prism/templates/template.rb @@ -4,8 +4,13 @@ require "fileutils" require "yaml" -module YARP - COMMON_FLAGS = 1 +module Prism + COMMON_FLAGS = 2 + + 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. @@ -15,6 +20,14 @@ class Field 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 @@ -22,9 +35,9 @@ def initialize(name:, type:, **options) class NodeKindField < Field def c_type if options[:kind] - "yp_#{options[:kind].gsub(/(?<=.)[A-Z]/, "_\\0").downcase}" + "pm_#{options[:kind].gsub(/(?<=.)[A-Z]/, "_\\0").downcase}" else - "yp_node" + "pm_node" end end @@ -81,7 +94,7 @@ def rbs_class end def java_type - "byte[]" + JAVA_STRING_TYPE end end @@ -93,7 +106,7 @@ def rbs_class end def java_type - "byte[]" + JAVA_STRING_TYPE end end @@ -105,7 +118,7 @@ def rbs_class end def java_type - "byte[][]" + "#{JAVA_STRING_TYPE}[]" end end @@ -122,6 +135,10 @@ def java_type # This represents a field on a node that is a location. class LocationField < Field + def semantic_field? + options[:semantic_field] || false + end + def rbs_class "Location" end @@ -133,6 +150,10 @@ def java_type # This represents a field on a node that is a location that is optional. class OptionalLocationField < Field + def semantic_field? + options[:semantic_field] || false + end + def rbs_class "Location?" end @@ -180,7 +201,7 @@ def initialize(config) @name = config.fetch("name") type = @name.gsub(/(?<=.)[A-Z]/, "_\\0") - @type = "YP_#{type.upcase}" + @type = "PM_#{type.upcase}" @human = type.downcase @fields = @@ -192,6 +213,10 @@ def initialize(config) @comment = config.fetch("comment") 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? @@ -230,7 +255,7 @@ def initialize(config) def declaration output = [] - output << "YP_TOKEN_#{name}" + output << "PM_TOKEN_#{name}" output << " = #{value}" if value output << ", // #{comment}" output.join @@ -336,14 +361,18 @@ def locals end TEMPLATES = [ - "ext/yarp/api_node.c", - "include/yarp/ast.h", - "java/org/yarp/Loader.java", - "java/org/yarp/Nodes.java", - "java/org/yarp/AbstractNodeVisitor.java", - "lib/yarp/mutation_visitor.rb", - "lib/yarp/node.rb", - "lib/yarp/serialize.rb", + "ext/prism/api_node.c", + "include/prism/ast.h", + "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/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", @@ -353,9 +382,9 @@ def locals if __FILE__ == $0 if ARGV.empty? - YARP::TEMPLATES.each { |filepath| YARP.template(filepath) } + Prism::TEMPLATES.each { |filepath| Prism.template(filepath) } else # ruby/ruby name, write_to = ARGV - YARP.template(name, write_to: write_to) + Prism.template(name, write_to: write_to) end end diff --git a/prism/unescape.c b/prism/unescape.c new file mode 100644 index 00000000000000..8634c411238bc1 --- /dev/null +++ b/prism/unescape.c @@ -0,0 +1,637 @@ +#include "prism.h" + +/******************************************************************************/ +/* Character checks */ +/******************************************************************************/ + +static inline bool +pm_char_is_hexadecimal_digits(const uint8_t *string, size_t length) { + for (size_t index = 0; index < length; index++) { + if (!pm_char_is_hexadecimal_digit(string[index])) { + return false; + } + } + return true; +} + +// We don't call the char_width function unless we have to because it's +// expensive to go through the indirection of the function pointer. Instead we +// provide a fast path that will check if we can just return 1. +static inline size_t +pm_char_width(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + if (parser->encoding_changed || (*start >= 0x80)) { + return parser->encoding.char_width(start, end - start); + } else { + return 1; + } +} + +/******************************************************************************/ +/* Lookup tables for characters */ +/******************************************************************************/ + +// This is a lookup table for unescapes that only take up a single character. +static const uint8_t unescape_chars[] = { + ['\''] = '\'', + ['\\'] = '\\', + ['a'] = '\a', + ['b'] = '\b', + ['e'] = '\033', + ['f'] = '\f', + ['n'] = '\n', + ['r'] = '\r', + ['s'] = ' ', + ['t'] = '\t', + ['v'] = '\v' +}; + +// 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]; +} + +/******************************************************************************/ +/* Unescaping for segments */ +/******************************************************************************/ + +// Scan the 1-3 digits of octal into the value. Returns the number of digits +// scanned. +static inline size_t +unescape_octal(const uint8_t *backslash, uint8_t *value, const uint8_t *end) { + *value = (uint8_t) (backslash[1] - '0'); + if (backslash + 2 >= end || !pm_char_is_octal_digit(backslash[2])) { + return 2; + } + *value = (uint8_t) ((*value << 3) | (backslash[2] - '0')); + if (backslash + 3 >= end || !pm_char_is_octal_digit(backslash[3])) { + return 3; + } + *value = (uint8_t) ((*value << 3) | (backslash[3] - '0')); + return 4; +} + +// Convert a hexadecimal digit into its equivalent value. +static inline uint8_t +unescape_hexadecimal_digit(const uint8_t value) { + return (uint8_t) ((value <= '9') ? (value - '0') : (value & 0x7) + 9); +} + +// Scan the 1-2 digits of hexadecimal into the value. Returns the number of +// digits scanned. +static inline size_t +unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end, pm_list_t *error_list) { + *value = 0; + if (backslash + 2 >= end || !pm_char_is_hexadecimal_digit(backslash[2])) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_HEXADECIMAL); + return 2; + } + *value = unescape_hexadecimal_digit(backslash[2]); + if (backslash + 3 >= end || !pm_char_is_hexadecimal_digit(backslash[3])) { + return 3; + } + *value = (uint8_t) ((*value << 4) | unescape_hexadecimal_digit(backslash[3])); + return 4; +} + +// 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 void +unescape_unicode(const uint8_t *string, size_t length, uint32_t *value) { + *value = 0; + for (size_t index = 0; index < length; index++) { + if (index != 0) *value <<= 4; + *value |= unescape_hexadecimal_digit(string[index]); + } +} + +// Accepts the pointer to the string to write the unicode value along with the +// 32-bit value to write. Writes the UTF-8 representation of the value to the +// string and returns the number of bytes written. +static inline size_t +unescape_unicode_write(uint8_t *dest, uint32_t value, const uint8_t *start, const uint8_t *end, pm_list_t *error_list) { + if (value <= 0x7F) { + // 0xxxxxxx + dest[0] = (uint8_t) value; + return 1; + } + + if (value <= 0x7FF) { + // 110xxxxx 10xxxxxx + dest[0] = (uint8_t) (0xC0 | (value >> 6)); + dest[1] = (uint8_t) (0x80 | (value & 0x3F)); + return 2; + } + + if (value <= 0xFFFF) { + // 1110xxxx 10xxxxxx 10xxxxxx + dest[0] = (uint8_t) (0xE0 | (value >> 12)); + dest[1] = (uint8_t) (0x80 | ((value >> 6) & 0x3F)); + dest[2] = (uint8_t) (0x80 | (value & 0x3F)); + return 3; + } + + // At this point it must be a 4 digit UTF-8 representation. If it's not, then + // the input is invalid. + if (value <= 0x10FFFF) { + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + dest[0] = (uint8_t) (0xF0 | (value >> 18)); + dest[1] = (uint8_t) (0x80 | ((value >> 12) & 0x3F)); + dest[2] = (uint8_t) (0x80 | ((value >> 6) & 0x3F)); + dest[3] = (uint8_t) (0x80 | (value & 0x3F)); + return 4; + } + + // If we get here, then the value is too big. This is an error, but we don't + // want to just crash, so instead we'll add an error to the error list and put + // in a replacement character instead. + if (error_list) pm_diagnostic_list_append(error_list, start, end, PM_ERR_ESCAPE_INVALID_UNICODE); + dest[0] = 0xEF; + dest[1] = 0xBF; + dest[2] = 0xBD; + return 3; +} + +typedef enum { + PM_UNESCAPE_FLAG_NONE = 0, + PM_UNESCAPE_FLAG_CONTROL = 1, + PM_UNESCAPE_FLAG_META = 2, + PM_UNESCAPE_FLAG_EXPECT_SINGLE = 4 +} pm_unescape_flag_t; + +// Unescape a single character value based on the given flags. +static inline uint8_t +unescape_char(uint8_t value, const uint8_t flags) { + if (flags & PM_UNESCAPE_FLAG_CONTROL) { + value &= 0x1f; + } + + if (flags & PM_UNESCAPE_FLAG_META) { + value |= 0x80; + } + + return value; +} + +// Read a specific escape sequence into the given destination. +static const uint8_t * +unescape( + pm_parser_t *parser, + uint8_t *dest, + size_t *dest_length, + const uint8_t *backslash, + const uint8_t *end, + const uint8_t flags, + pm_list_t *error_list +) { + switch (backslash[1]) { + case 'a': + case 'b': + case 'e': + case 'f': + case 'n': + case 'r': + case 's': + case 't': + case 'v': + if (dest) { + dest[(*dest_length)++] = unescape_char(unescape_chars[backslash[1]], flags); + } + return backslash + 2; + // \nnn octal bit pattern, where nnn is 1-3 octal digits ([0-7]) + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + uint8_t value; + const uint8_t *cursor = backslash + unescape_octal(backslash, &value, end); + + if (dest) { + dest[(*dest_length)++] = unescape_char(value, flags); + } + return cursor; + } + // \xnn hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F]) + case 'x': { + uint8_t value; + const uint8_t *cursor = backslash + unescape_hexadecimal(backslash, &value, end, error_list); + + if (dest) { + dest[(*dest_length)++] = unescape_char(value, flags); + } + return cursor; + } + // \u{nnnn ...} Unicode character(s), where each nnnn is 1-6 hexadecimal digits ([0-9a-fA-F]) + // \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F]) + case 'u': { + if ((flags & PM_UNESCAPE_FLAG_CONTROL) | (flags & PM_UNESCAPE_FLAG_META)) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS); + return backslash + 2; + } + + if ((backslash + 3) < end && backslash[2] == '{') { + const uint8_t *unicode_cursor = backslash + 3; + const uint8_t *extra_codepoints_start = NULL; + int codepoints_count = 0; + + unicode_cursor += pm_strspn_whitespace(unicode_cursor, end - unicode_cursor); + + while ((unicode_cursor < end) && (*unicode_cursor != '}')) { + const uint8_t *unicode_start = unicode_cursor; + size_t hexadecimal_length = pm_strspn_hexadecimal_digit(unicode_cursor, end - unicode_cursor); + + // \u{nnnn} character literal allows only 1-6 hexadecimal digits + if (hexadecimal_length > 6) { + if (error_list) pm_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, PM_ERR_ESCAPE_INVALID_UNICODE_LONG); + } + // there are not hexadecimal characters + else if (hexadecimal_length == 0) { + if (error_list) pm_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, PM_ERR_ESCAPE_INVALID_UNICODE); + return unicode_cursor; + } + + unicode_cursor += hexadecimal_length; + + codepoints_count++; + if (flags & PM_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count == 2) + extra_codepoints_start = unicode_start; + + uint32_t value; + unescape_unicode(unicode_start, (size_t) (unicode_cursor - unicode_start), &value); + if (dest) { + *dest_length += unescape_unicode_write(dest + *dest_length, value, unicode_start, unicode_cursor, error_list); + } + + unicode_cursor += pm_strspn_whitespace(unicode_cursor, end - unicode_cursor); + } + + // ?\u{nnnn} character literal should contain only one codepoint and cannot be like ?\u{nnnn mmmm} + if (flags & PM_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1) { + if (error_list) pm_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL); + } + + if (unicode_cursor < end && *unicode_cursor == '}') { + unicode_cursor++; + } else { + if (error_list) pm_diagnostic_list_append(error_list, backslash, unicode_cursor, PM_ERR_ESCAPE_INVALID_UNICODE_TERM); + } + + return unicode_cursor; + } + else if ((backslash + 5) < end && pm_char_is_hexadecimal_digits(backslash + 2, 4)) { + uint32_t value; + unescape_unicode(backslash + 2, 4, &value); + + if (dest) { + *dest_length += unescape_unicode_write(dest + *dest_length, value, backslash + 2, backslash + 6, error_list); + } + return backslash + 6; + } + + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_UNICODE); + return backslash + 2; + } + // \c\M-x meta control character, where x is an ASCII printable character + // \c? delete, ASCII 7Fh (DEL) + // \cx control character, where x is an ASCII printable character + case 'c': + if (backslash + 2 >= end) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL); + return end; + } + + if (flags & PM_UNESCAPE_FLAG_CONTROL) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT); + return backslash + 2; + } + + switch (backslash[2]) { + case '\\': + return unescape(parser, dest, dest_length, backslash + 2, end, flags | PM_UNESCAPE_FLAG_CONTROL, error_list); + case '?': + if (dest) { + dest[(*dest_length)++] = unescape_char(0x7f, flags); + } + return backslash + 3; + default: { + if (!char_is_ascii_printable(backslash[2])) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL); + return backslash + 2; + } + + if (dest) { + dest[(*dest_length)++] = unescape_char(backslash[2], flags | PM_UNESCAPE_FLAG_CONTROL); + } + return backslash + 3; + } + } + // \C-x control character, where x is an ASCII printable character + // \C-? delete, ASCII 7Fh (DEL) + case 'C': + if (backslash + 3 >= end) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL); + return end; + } + + if (flags & PM_UNESCAPE_FLAG_CONTROL) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT); + return backslash + 2; + } + + if (backslash[2] != '-') { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_CONTROL); + return backslash + 2; + } + + switch (backslash[3]) { + case '\\': + return unescape(parser, dest, dest_length, backslash + 3, end, flags | PM_UNESCAPE_FLAG_CONTROL, error_list); + case '?': + if (dest) { + dest[(*dest_length)++] = unescape_char(0x7f, flags); + } + return backslash + 4; + default: + if (!char_is_ascii_printable(backslash[3])) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_CONTROL); + return backslash + 2; + } + + if (dest) { + dest[(*dest_length)++] = unescape_char(backslash[3], flags | PM_UNESCAPE_FLAG_CONTROL); + } + return backslash + 4; + } + // \M-\C-x meta control character, where x is an ASCII printable character + // \M-\cx meta control character, where x is an ASCII printable character + // \M-x meta character, where x is an ASCII printable character + case 'M': { + if (backslash + 3 >= end) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 1, PM_ERR_ESCAPE_INVALID_META); + return end; + } + + if (flags & PM_UNESCAPE_FLAG_META) { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_META_REPEAT); + return backslash + 2; + } + + if (backslash[2] != '-') { + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_META); + return backslash + 2; + } + + if (backslash[3] == '\\') { + return unescape(parser, dest, dest_length, backslash + 3, end, flags | PM_UNESCAPE_FLAG_META, error_list); + } + + if (char_is_ascii_printable(backslash[3])) { + if (dest) { + dest[(*dest_length)++] = unescape_char(backslash[3], flags | PM_UNESCAPE_FLAG_META); + } + return backslash + 4; + } + + if (error_list) pm_diagnostic_list_append(error_list, backslash, backslash + 2, PM_ERR_ESCAPE_INVALID_META); + return backslash + 3; + } + // \n + case '\n': + return backslash + 2; + // \r + case '\r': + if (backslash + 2 < end && backslash[2] == '\n') { + return backslash + 3; + } + /* fallthrough */ + // In this case we're escaping something that doesn't need escaping. + default: { + size_t width = pm_char_width(parser, backslash + 1, end); + + if (dest) { + memcpy(dest + *dest_length, backslash + 1, width); + *dest_length += width; + } + + return backslash + 1 + width; + } + } +} + +/******************************************************************************/ +/* Public functions and entrypoints */ +/******************************************************************************/ + +// Unescape the contents of the given token into the given string using the +// given unescape mode. The supported escapes are: +// +// \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 void +pm_unescape_manipulate_string_or_char_literal(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type, bool expect_single_codepoint) { + if (unescape_type == PM_UNESCAPE_NONE) { + // If we're not unescaping then we can reference the source directly. + return; + } + + const uint8_t *backslash = pm_memchr(string->source, '\\', string->length, parser->encoding_changed, &parser->encoding); + + if (backslash == NULL) { + // Here there are no escapes, so we can reference the source directly. + return; + } + + // Here we have found an escape character, so we need to handle all escapes + // within the string. + uint8_t *allocated = malloc(string->length); + if (allocated == NULL) { + pm_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, PM_ERR_MALLOC_FAILED); + return; + } + + // This is the memory address where we're putting the unescaped string. + uint8_t *dest = allocated; + size_t dest_length = 0; + + // This is the current position in the source string that we're looking at. + // It's going to move along behind the backslash so that we can copy each + // segment of the string that doesn't contain an escape. + const uint8_t *cursor = string->source; + const uint8_t *end = string->source + string->length; + + // For each escape found in the source string, we will handle it and update + // the moving cursor->backslash window. + while (backslash != NULL && backslash + 1 < end) { + assert(dest_length < string->length); + + // This is the size of the segment of the string from the previous escape + // or the start of the string to the current escape. + size_t segment_size = (size_t) (backslash - cursor); + + // Here we're going to copy everything up until the escape into the + // destination buffer. + memcpy(dest + dest_length, cursor, segment_size); + dest_length += segment_size; + + switch (backslash[1]) { + case '\\': + case '\'': + dest[dest_length++] = unescape_chars[backslash[1]]; + cursor = backslash + 2; + break; + default: + if (unescape_type == PM_UNESCAPE_WHITESPACE) { + if (backslash[1] == '\r' && backslash[2] == '\n') { + cursor = backslash + 2; + break; + } + if (pm_strspn_whitespace(backslash + 1, 1)) { + cursor = backslash + 1; + break; + } + } + if (unescape_type == PM_UNESCAPE_WHITESPACE || unescape_type == PM_UNESCAPE_MINIMAL) { + // In this case we're escaping something that doesn't need escaping. + dest[dest_length++] = '\\'; + cursor = backslash + 1; + break; + } + + // This is the only type of unescaping left. In this case we need to + // handle all of the different unescapes. + assert(unescape_type == PM_UNESCAPE_ALL); + + uint8_t flags = PM_UNESCAPE_FLAG_NONE; + if (expect_single_codepoint) { + flags |= PM_UNESCAPE_FLAG_EXPECT_SINGLE; + } + + cursor = unescape(parser, dest, &dest_length, backslash, end, flags, &parser->error_list); + break; + } + + if (end > cursor) { + backslash = pm_memchr(cursor, '\\', (size_t) (end - cursor), parser->encoding_changed, &parser->encoding); + } else { + backslash = NULL; + } + } + + // We need to copy the final segment of the string after the last escape. + if (end > cursor) { + memcpy(dest + dest_length, cursor, (size_t) (end - cursor)); + } else { + cursor = end; + } + + // If the string was already allocated, then we need to free that memory + // here. That's because we're about to override it with the escaped string. + pm_string_free(string); + + // We also need to update the length at the end. This is because every escape + // reduces the length of the final string, and we don't want garbage at the + // end. + pm_string_owned_init(string, allocated, dest_length + ((size_t) (end - cursor))); +} + +PRISM_EXPORTED_FUNCTION void +pm_unescape_manipulate_string(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type) { + pm_unescape_manipulate_string_or_char_literal(parser, string, unescape_type, false); +} + +void +pm_unescape_manipulate_char_literal(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type) { + pm_unescape_manipulate_string_or_char_literal(parser, string, unescape_type, true); +} + +// This function is similar to pm_unescape_manipulate_string, except it doesn't +// actually perform any string manipulations. Instead, it calculates how long +// the unescaped character is, and returns that value +size_t +pm_unescape_calculate_difference(pm_parser_t *parser, const uint8_t *backslash, pm_unescape_type_t unescape_type, bool expect_single_codepoint) { + assert(unescape_type != PM_UNESCAPE_NONE); + + if (backslash + 1 >= parser->end) { + return 0; + } + + switch (backslash[1]) { + case '\\': + case '\'': + return 2; + default: { + if (unescape_type == PM_UNESCAPE_WHITESPACE) { + if (backslash[1] == '\r' && backslash[2] == '\n') { + return 2; + } + size_t whitespace = pm_strspn_whitespace(backslash + 1, 1); + if (whitespace > 0) { + return whitespace; + } + } + if (unescape_type == PM_UNESCAPE_WHITESPACE || unescape_type == PM_UNESCAPE_MINIMAL) { + return 1 + pm_char_width(parser, backslash + 1, parser->end); + } + + // This is the only type of unescaping left. In this case we need to + // handle all of the different unescapes. + assert(unescape_type == PM_UNESCAPE_ALL); + + uint8_t flags = PM_UNESCAPE_FLAG_NONE; + if (expect_single_codepoint) { + flags |= PM_UNESCAPE_FLAG_EXPECT_SINGLE; + } + + const uint8_t *cursor = unescape(parser, NULL, 0, backslash, parser->end, flags, NULL); + assert(cursor > backslash); + + return (size_t) (cursor - backslash); + } + } +} + +// This is one of the main entry points into the extension. It accepts a source +// string, a type of unescaping, and a pointer to a result string. It returns a +// boolean indicating whether or not the unescaping was successful. +PRISM_EXPORTED_FUNCTION bool +pm_unescape_string(const uint8_t *start, size_t length, pm_unescape_type_t unescape_type, pm_string_t *result) { + pm_parser_t parser; + pm_parser_init(&parser, start, length, NULL); + + pm_string_shared_init(result, start, start + length); + pm_unescape_manipulate_string(&parser, result, unescape_type); + + bool success = pm_list_empty_p(&parser.error_list); + pm_parser_free(&parser); + + return success; +} diff --git a/prism/unescape.h b/prism/unescape.h new file mode 100644 index 00000000000000..0684a72de0cbab --- /dev/null +++ b/prism/unescape.h @@ -0,0 +1,48 @@ +#ifndef PRISM_UNESCAPE_H +#define PRISM_UNESCAPE_H + +#include "prism/defines.h" +#include "prism/diagnostic.h" +#include "prism/parser.h" +#include "prism/util/pm_char.h" +#include "prism/util/pm_list.h" +#include "prism/util/pm_memchr.h" +#include "prism/util/pm_string.h" + +#include +#include +#include +#include + +// The type of unescape we are performing. +typedef enum { + // When we're creating a string inside of a list literal like %w, we + // shouldn't escape anything. + PM_UNESCAPE_NONE, + + // When we're unescaping a single-quoted string, we only need to unescape + // single quotes and backslashes. + PM_UNESCAPE_MINIMAL, + + // When we're unescaping a string list, in addition to MINIMAL, we need to + // unescape whitespace. + PM_UNESCAPE_WHITESPACE, + + // When we're unescaping a double-quoted string, we need to unescape all + // escapes. + PM_UNESCAPE_ALL, +} pm_unescape_type_t; + +// Unescape the contents of the given token into the given string using the given unescape mode. +PRISM_EXPORTED_FUNCTION void pm_unescape_manipulate_string(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type); +void pm_unescape_manipulate_char_literal(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type); + +// Accepts a source string and a type of unescaping and returns the unescaped version. +// The caller must pm_string_free(result); after calling this function. +PRISM_EXPORTED_FUNCTION bool pm_unescape_string(const uint8_t *start, size_t length, pm_unescape_type_t unescape_type, pm_string_t *result); + +// Returns the number of bytes that encompass the first escape sequence in the +// given string. +size_t pm_unescape_calculate_difference(pm_parser_t *parser, const uint8_t *value, pm_unescape_type_t unescape_type, bool expect_single_codepoint); + +#endif diff --git a/prism/util/pm_buffer.c b/prism/util/pm_buffer.c new file mode 100644 index 00000000000000..0d84375767251c --- /dev/null +++ b/prism/util/pm_buffer.c @@ -0,0 +1,103 @@ +#include "prism/util/pm_buffer.h" + +#define PRISM_BUFFER_INITIAL_SIZE 1024 + +// 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 its default values. +bool +pm_buffer_init(pm_buffer_t *buffer) { + buffer->length = 0; + buffer->capacity = PRISM_BUFFER_INITIAL_SIZE; + + buffer->value = (char *) malloc(PRISM_BUFFER_INITIAL_SIZE); + return buffer->value != NULL; +} + +#undef PRISM_BUFFER_INITIAL_SIZE + +// 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) { + do { + buffer->capacity *= 2; + } while (next_length > buffer->capacity); + + 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) { + pm_buffer_append_length(buffer, length); + memcpy(buffer->value + (buffer->length - length), 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) { + pm_buffer_append_length(buffer, length); + memset(buffer->value + (buffer->length - length), 0, length); +} + +// Append a string to the buffer. +void +pm_buffer_append_str(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_u8(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. +void +pm_buffer_append_u32(pm_buffer_t *buffer, uint32_t value) { + if (value < 128) { + pm_buffer_append_u8(buffer, (uint8_t) value); + } else { + uint32_t n = value; + while (n >= 128) { + pm_buffer_append_u8(buffer, (uint8_t) (n | 128)); + n >>= 7; + } + pm_buffer_append_u8(buffer, (uint8_t) n); + } +} + +// 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 new file mode 100644 index 00000000000000..160d60bc58fd10 --- /dev/null +++ b/prism/util/pm_buffer.h @@ -0,0 +1,51 @@ +#ifndef PRISM_BUFFER_H +#define PRISM_BUFFER_H + +#include "prism/defines.h" + +#include +#include +#include +#include +#include + +// A pm_buffer_t is a simple memory buffer that stores data in a contiguous +// block of memory. It is used to store the serialized representation of a +// prism tree. +typedef struct { + char *value; + size_t length; + size_t capacity; +} pm_buffer_t; + +// Return the size of the pm_buffer_t struct. +PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void); + +// Initialize a pm_buffer_t with its default values. +PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer); + +// Return the value of the buffer. +PRISM_EXPORTED_FUNCTION char * pm_buffer_value(pm_buffer_t *buffer); + +// Return 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. +void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length); + +// Append a string to the buffer. +void pm_buffer_append_str(pm_buffer_t *buffer, const char *value, size_t 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); + +// Append a single byte to the buffer. +void pm_buffer_append_u8(pm_buffer_t *buffer, uint8_t value); + +// Append a 32-bit unsigned integer to the buffer. +void pm_buffer_append_u32(pm_buffer_t *buffer, uint32_t value); + +// Free the memory associated with the buffer. +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 new file mode 100644 index 00000000000000..59a188ae0a44a0 --- /dev/null +++ b/prism/util/pm_char.c @@ -0,0 +1,272 @@ +#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 +}; + +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); +} + +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); +} + +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 new file mode 100644 index 00000000000000..f7f195eecc0b92 --- /dev/null +++ b/prism/util/pm_char.h @@ -0,0 +1,91 @@ +#ifndef PRISM_CHAR_H +#define PRISM_CHAR_H + +#include "prism/defines.h" +#include "prism/util/pm_newline_list.h" + +#include +#include + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// 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); + +// Returns 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. +bool pm_char_is_inline_whitespace(const uint8_t b); + +// Returns 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. +bool pm_char_is_octal_digit(const uint8_t b); + +// Returns 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. +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 new file mode 100644 index 00000000000000..d2c4f1e16c175f --- /dev/null +++ b/prism/util/pm_constant_pool.c @@ -0,0 +1,252 @@ +#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; +} + +// 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, bool owned) { + 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 (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->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->owned = false; + } + + 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 << 31))); + + *bucket = (pm_constant_pool_bucket_t) { + .id = (unsigned int) (id & 0x7FFFFFFF), + .owned = owned, + .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, false); +} + +// 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, true); +} + +// 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->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 new file mode 100644 index 00000000000000..c23628d99941b9 --- /dev/null +++ b/prism/util/pm_constant_pool.h @@ -0,0 +1,78 @@ +// The constant pool is 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 +#include +#include +#include +#include + +typedef uint32_t pm_constant_id_t; + +typedef struct { + pm_constant_id_t *ids; + size_t size; + size_t capacity; +} pm_constant_id_list_t; + +// Initialize a list of constant ids. +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. +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. +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. +size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list); + +// Free the memory associated with a list of constant ids. +void pm_constant_id_list_free(pm_constant_id_list_t *list); + +typedef struct { + unsigned int id: 31; + bool owned: 1; + uint32_t hash; +} pm_constant_pool_bucket_t; + +typedef struct { + const uint8_t *start; + size_t length; +} pm_constant_t; + +typedef struct { + pm_constant_pool_bucket_t *buckets; + pm_constant_t *constants; + uint32_t size; + uint32_t capacity; +} pm_constant_pool_t; + +// Define an empty constant pool. +#define PM_CONSTANT_POOL_EMPTY ((pm_constant_pool_t) { .buckets = NULL, .constants = NULL, .size = 0, .capacity = 0 }) + +// Initialize a new constant pool with a given capacity. +bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity); + +// 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. +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. +pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length); + +// Free the memory associated with a constant pool. +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 new file mode 100644 index 00000000000000..0c8feea9d8b738 --- /dev/null +++ b/prism/util/pm_list.c @@ -0,0 +1,41 @@ +#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 new file mode 100644 index 00000000000000..19fdec65e3c96a --- /dev/null +++ b/prism/util/pm_list.h @@ -0,0 +1,67 @@ +// 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: +// +// typedef struct { +// pm_list_node_t node; +// int value; +// } pm_int_node_t; +// +// pm_list_t list = PM_LIST_EMPTY; +// 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. + +#ifndef PRISM_LIST_H +#define PRISM_LIST_H + +#include "prism/defines.h" + +#include +#include +#include +#include + +// This represents a node in the linked list. +typedef struct pm_list_node { + 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 { + size_t size; + pm_list_node_t *head; + pm_list_node_t *tail; +} pm_list_t; + +// This represents an empty list. It's used to initialize a stack-allocated list +// as opposed to a method call. +#define PM_LIST_EMPTY ((pm_list_t) { .size = 0, .head = NULL, .tail = NULL }) + +// Returns true if the given list is empty. +PRISM_EXPORTED_FUNCTION bool pm_list_empty_p(pm_list_t *list); + +// Returns the size of the list. +PRISM_EXPORTED_FUNCTION size_t pm_list_size(pm_list_t *list); + +// Append a node to the given list. +void pm_list_append(pm_list_t *list, pm_list_node_t *node); + +// Deallocate the internal state of the given list. +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 new file mode 100644 index 00000000000000..c5dd2e86558518 --- /dev/null +++ b/prism/util/pm_memchr.c @@ -0,0 +1,33 @@ +#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, 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 new file mode 100644 index 00000000000000..fdc55a730b6914 --- /dev/null +++ b/prism/util/pm_memchr.h @@ -0,0 +1,14 @@ +#ifndef PRISM_MEMCHR_H +#define PRISM_MEMCHR_H + +#include "prism/defines.h" +#include "prism/enc/pm_encoding.h" + +#include + +// 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 *source, int character, size_t number, bool encoding_changed, pm_encoding_t *encoding); + +#endif diff --git a/prism/util/pm_newline_list.c b/prism/util/pm_newline_list.c new file mode 100644 index 00000000000000..779a0a8d5c4373 --- /dev/null +++ b/prism/util/pm_newline_list.c @@ -0,0 +1,134 @@ +#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; + + list->last_index = 0; + list->last_offset = 0; + + 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, assuming we don't have any +// information about the previous index that we found. +static pm_line_column_t +pm_newline_list_line_column_search(pm_newline_list_t *list, size_t offset) { + 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] }); +} + +// Returns the line and column of the given offset, assuming we know the last +// index that we found. +static pm_line_column_t +pm_newline_list_line_column_scan(pm_newline_list_t *list, size_t offset) { + if (offset > list->last_offset) { + size_t index = list->last_index; + while (index < list->size && list->offsets[index] < offset) { + index++; + } + + if (index == list->size) { + return ((pm_line_column_t) { index - 1, offset - list->offsets[index - 1] }); + } + + return ((pm_line_column_t) { index, 0 }); + } else { + size_t index = list->last_index; + while (index > 0 && list->offsets[index] > offset) { + index--; + } + + if (index == 0) { + return ((pm_line_column_t) { 0, offset }); + } + + return ((pm_line_column_t) { index, offset - list->offsets[index - 1] }); + } +} + +// 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(pm_newline_list_t *list, const uint8_t *cursor) { + assert(cursor >= list->start); + size_t offset = (size_t) (cursor - list->start); + pm_line_column_t result; + + if (list->last_offset == 0) { + result = pm_newline_list_line_column_search(list, offset); + } else { + result = pm_newline_list_line_column_scan(list, offset); + } + + list->last_index = result.line; + list->last_offset = offset; + + return result; +} + +// 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 new file mode 100644 index 00000000000000..38fb40196d587b --- /dev/null +++ b/prism/util/pm_newline_list.h @@ -0,0 +1,61 @@ +// 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 +#include +#include +#include + +// A list of offsets of newlines in a string. The offsets are assumed to be +// sorted/inserted in ascending order. +typedef struct { + const uint8_t *start; + + size_t *offsets; + size_t size; + size_t capacity; + + size_t last_offset; + size_t last_index; +} pm_newline_list_t; + +// A line and column in a string. +typedef struct { + size_t line; + size_t column; +} pm_line_column_t; + +#define PM_NEWLINE_LIST_EMPTY ((pm_newline_list_t) { \ + .start = NULL, .offsets = NULL, .size = 0, .capacity = 0, .last_offset = 0, .last_index = 0 \ +}) + +// 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); + +// 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); + +// 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); + +// 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(pm_newline_list_t *list, const uint8_t *cursor); + +// Free the internal memory allocated for the newline list. +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 new file mode 100644 index 00000000000000..f7f9c245dd3467 --- /dev/null +++ b/prism/util/pm_state_stack.c @@ -0,0 +1,19 @@ +#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 new file mode 100644 index 00000000000000..aef639074aaf1f --- /dev/null +++ b/prism/util/pm_state_stack.h @@ -0,0 +1,24 @@ +#ifndef PRISM_STATE_STACK_H +#define PRISM_STATE_STACK_H + +#include "prism/defines.h" + +#include +#include + +// A struct that represents a stack of bools. +typedef uint32_t pm_state_stack_t; + +// Initializes the state stack to an empty stack. +#define PM_STATE_STACK_EMPTY ((pm_state_stack_t) 0) + +// Pushes a value onto the stack. +void pm_state_stack_push(pm_state_stack_t *stack, bool value); + +// Pops a value off the stack. +void pm_state_stack_pop(pm_state_stack_t *stack); + +// Returns 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 new file mode 100644 index 00000000000000..bd1c93bacac168 --- /dev/null +++ b/prism/util/pm_string.c @@ -0,0 +1,200 @@ +#include "prism/util/pm_string.h" + +// The following headers are necessary to read files using demand paging. +#ifdef _WIN32 +#include +#else +#include +#include +#include +#include +#endif + +// 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 + }; +} + +static void +pm_string_mapped_init_internal(pm_string_t *string, uint8_t *source, size_t length) { + *string = (pm_string_t) { + .type = PM_STRING_MAPPED, + .source = source, + .length = length + }; +} + +// 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 + } +} + +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); + uint8_t empty[] = ""; + pm_string_mapped_init_internal(string, empty, 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; + } + + pm_string_mapped_init_internal(string, source, (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); + uint8_t empty[] = ""; + pm_string_mapped_init_internal(string, empty, 0); + return true; + } + + source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if (source == MAP_FAILED) { + perror("Map failed"); + return false; + } + + close(fd); + pm_string_mapped_init_internal(string, source, size); + return true; +#endif +} + +// 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); +} diff --git a/prism/util/pm_string.h b/prism/util/pm_string.h new file mode 100644 index 00000000000000..acc0fa5277fb20 --- /dev/null +++ b/prism/util/pm_string.h @@ -0,0 +1,61 @@ +#ifndef PRISM_STRING_H +#define PRISM_STRING_H + +#include "prism/defines.h" + +#include +#include +#include +#include +#include + +// This struct represents a string value. +typedef struct { + enum { PM_STRING_SHARED, PM_STRING_OWNED, PM_STRING_CONSTANT, PM_STRING_MAPPED } type; + const uint8_t *source; + size_t length; +} pm_string_t; + +#define PM_EMPTY_STRING ((pm_string_t) { .type = PM_STRING_CONSTANT, .source = NULL, .length = 0 }) + +// 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); + +// 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); + +// 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); + +// 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`. +PRISM_EXPORTED_FUNCTION bool pm_string_mapped_init(pm_string_t *string, const char *filepath); + +// Returns the memory size 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. +void pm_string_ensure_owned(pm_string_t *string); + +// Returns the length associated with the string. +PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string); + +// Returns the start pointer associated with the string. +PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string); + +// Free the associated memory of the given string. +PRISM_EXPORTED_FUNCTION void pm_string_free(pm_string_t *string); + +// 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); + +#endif // PRISM_STRING_H diff --git a/prism/util/pm_string_list.c b/prism/util/pm_string_list.c new file mode 100644 index 00000000000000..87e63a43eb0479 --- /dev/null +++ b/prism/util/pm_string_list.c @@ -0,0 +1,29 @@ +#include "prism/util/pm_string_list.h" + +// Initialize a pm_string_list_t with its default values. +void +pm_string_list_init(pm_string_list_t *string_list) { + string_list->strings = (pm_string_t *) malloc(sizeof(pm_string_t)); + string_list->length = 0; + string_list->capacity = 1; +} + +// 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) { + pm_string_t *original_string = string_list->strings; + string_list->capacity *= 2; + string_list->strings = (pm_string_t *) malloc(string_list->capacity * sizeof(pm_string_t)); + memcpy(string_list->strings, original_string, (string_list->length) * sizeof(pm_string_t)); + free(original_string); + } + + 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 new file mode 100644 index 00000000000000..1eec7a34da3ffd --- /dev/null +++ b/prism/util/pm_string_list.h @@ -0,0 +1,25 @@ +#ifndef PRISM_STRING_LIST_H +#define PRISM_STRING_LIST_H + +#include "prism/defines.h" +#include "prism/util/pm_string.h" + +#include +#include + +typedef struct { + pm_string_t *strings; + size_t length; + size_t capacity; +} pm_string_list_t; + +// Initialize a pm_string_list_t with its default values. +PRISM_EXPORTED_FUNCTION void pm_string_list_init(pm_string_list_t *string_list); + +// 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); + +// Free the memory associated with the string list. +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 new file mode 100644 index 00000000000000..fce11835e05837 --- /dev/null +++ b/prism/util/pm_strncasecmp.c @@ -0,0 +1,17 @@ +#include +#include +#include + +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_strpbrk.c b/prism/util/pm_strpbrk.c new file mode 100644 index 00000000000000..49bcd847b848ef --- /dev/null +++ b/prism/util/pm_strpbrk.c @@ -0,0 +1,66 @@ +#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(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(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 new file mode 100644 index 00000000000000..c9ea6c945ee8a2 --- /dev/null +++ b/prism/util/pm_strpbrk.h @@ -0,0 +1,29 @@ +#ifndef PRISM_STRPBRK_H +#define PRISM_STRPBRK_H + +#include "prism/defines.h" +#include "prism/parser.h" + +#include +#include + +// 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(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 new file mode 100644 index 00000000000000..ba63d0a5d24268 --- /dev/null +++ b/prism/version.h @@ -0,0 +1,4 @@ +#define PRISM_VERSION_MAJOR 0 +#define PRISM_VERSION_MINOR 13 +#define PRISM_VERSION_PATCH 0 +#define PRISM_VERSION "0.13.0" diff --git a/prism_compile.c b/prism_compile.c new file mode 100644 index 00000000000000..28710f848c13f4 --- /dev/null +++ b/prism_compile.c @@ -0,0 +1,2524 @@ +#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, compile_context) + +#define PM_COMPILE_POPPED(node) \ + pm_compile_node(iseq, (node), ret, src, true, compile_context) + +#define PM_COMPILE_NOT_POPPED(node) \ + pm_compile_node(iseq, (node), ret, src, false, compile_context) + +#define PM_POP_IF_POPPED \ + if (popped) ADD_INSN(ret, &dummy_line_node, pop); + +#define PM_POP_UNLESS_POPPED \ + if (!popped) ADD_INSN(ret, &dummy_line_node, pop); + +#define PM_DUP_UNLESS_POPPED \ + if (!popped) ADD_INSN(ret, &dummy_line_node, dup); + +#define PM_PUTNIL_UNLESS_POPPED \ + if (!popped) ADD_INSN(ret, &dummy_line_node, putnil); + +rb_iseq_t * +pm_iseq_new_with_opt(pm_scope_node_t *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) +{ + const char *start = (const char *) node->base.location.start; + const char *end = (const 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, NULL, 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) +{ + return rb_str_new((const char *) pm_string_source(string), pm_string_length(string)); +} + +static inline ID +parse_symbol(const uint8_t *start, const uint8_t *end) +{ + return rb_intern2((const char *) start, end - start); +} + +static inline ID +parse_string_symbol(pm_string_t *string) +{ + const uint8_t *start = pm_string_source(string); + return parse_symbol(start, start + pm_string_length(string)); +} + +static inline ID +parse_location_symbol(pm_location_t *location) +{ + return parse_symbol(location->start, location->end); +} + +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)); +} + +/** + * 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; + + 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; +} + +/** + * 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; +} + +/** + * 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_compile_context_t *compile_context) +{ + // 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], compile_context)); + } + + 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, compile_context), pm_static_literal_value(cast->value, compile_context) }; + 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; + + VALUE string = parse_string(&cast->unescaped); + return rb_reg_new(RSTRING_PTR(string), RSTRING_LEN(string), pm_reg_flags(node)); + } + case PM_SOURCE_ENCODING_NODE: { + rb_encoding *encoding = rb_find_encoding(rb_str_new_cstr(compile_context->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) : rb_fstring_lit(""); + } + case PM_SOURCE_LINE_NODE: + return INT2FIX((int) pm_newline_list_line_column(&compile_context->parser->newline_list, node->location.start).line); + case PM_STRING_NODE: + return parse_string(&((pm_string_node_t *) node)->unescaped); + case PM_SYMBOL_NODE: + return ID2SYM(parse_string_symbol(&((pm_symbol_node_t *) node)->unescaped)); + case PM_TRUE_NODE: + return Qtrue; + default: + rb_raise(rb_eArgError, "Don't have a literal value for this type"); + return Qfalse; + } +} + +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_compile_context_t *compile_context); + +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_compile_context_t *compile_context) +{ + pm_parser_t *parser = compile_context->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, compile_context); + + 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) { + ADD_INSN(seq, &dummy_line_node, 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_compile_context_t *context); + +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_compile_context_t *compile_context) +{ + pm_parser_t *parser = compile_context->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, compile_context); + 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, compile_context); + 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; + // TODO: Several more nodes in this case statement + default: { + DECL_ANCHOR(cond_seq); + INIT_ANCHOR(cond_seq); + + pm_compile_node(iseq, cond, cond_seq, src, false, compile_context); + 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_compile_context_t *compile_context) +{ + 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, popped, compile_context); + 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, compile_context); + PM_POP_IF_POPPED; + } else { + PM_PUTNIL_UNLESS_POPPED; + } + + if (else_label->refcnt) { + end_label = NEW_LABEL(line); + ADD_INSNL(then_seq, &dummy_line_node, jump, end_label); + PM_POP_UNLESS_POPPED; + } + 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 *)(((pm_else_node_t *)node_else)->statements), else_seq, src, popped, compile_context); + } + 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_compile_context_t *compile_context) +{ + 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); + ADD_INSN(ret, &dummy_line_node, putnil); + ADD_LABEL(ret, next_catch_label); + ADD_INSN(ret, &dummy_line_node, 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, compile_context); + } else if (type == PM_UNTIL_NODE) { + pm_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, compile_context); + } + + ADD_LABEL(ret, end_label); + ADD_ADJUST_RESTORE(ret, adjust_label); + + ADD_INSN(ret, &dummy_line_node, 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_compile_context_t *compile_context) +{ + 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)); + } + else { + PM_COMPILE_NOT_POPPED(part); + ADD_INSN(ret, &dummy_line_node, 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 { + ADD_INSN(ret, &dummy_line_node, putnil); + } +} +static int +pm_lookup_local_index(rb_iseq_t *iseq, pm_compile_context_t *compile_context, pm_constant_id_t constant_id) +{ + st_data_t local_index; + + int num_params = ISEQ_BODY(iseq)->param.size; + + if (!st_lookup(compile_context->index_lookup_table, constant_id, &local_index)) { + rb_bug("This local does not exist"); + } + + return num_params - (int)local_index; +} + +static int +pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_compile_context_t *compile_context, pm_constant_id_t constant_id, uint32_t depth) +{ + for(uint32_t i = 0; i < depth; i++) { + compile_context = compile_context->previous; + iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq; + } + + return pm_lookup_local_index(iseq, compile_context, 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 compile_context 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_compile_context_t *compile_context, pm_constant_id_t constant_id) +{ + return compile_context->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_compile_context_t *compile_context) +{ + 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; + } +} + +/** + * 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 pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context, uint8_t pushed, bool nested) +{ + switch (PM_NODE_TYPE(node)) { + case PM_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + for (size_t index = 0; index < cast->targets.size; index++) { + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->targets.nodes[index], ret, compile_context, 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) { + ADD_INSN(ret, &dummy_line_node, putnil); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->parent, ret, compile_context, 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, cast->parent, ret, compile_context, pushed, false); + } else { + ADD_INSN(ret, &dummy_line_node, pop); + ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject); + } + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->child, ret, compile_context, 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(compile_context, cast->name))); + pushed = pushed + 2; + break; + } + default: + break; + } + + return pushed; +} + +/** + * Compile a pattern matching expression. + */ +static int +pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, pm_compile_context_t *compile_context, LABEL *matched_label, LABEL *unmatched_label, bool in_alternation_pattern) +{ + int lineno = (int) pm_newline_list_line_column(&compile_context->parser->newline_list, node->location.start).line; + NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); + + switch (PM_NODE_TYPE(node)) { + case PM_ARRAY_PATTERN_NODE: + rb_bug("Array pattern matching not yet supported."); + break; + case PM_FIND_PATTERN_NODE: + rb_bug("Find pattern matching not yet supported."); + break; + case PM_HASH_PATTERN_NODE: + rb_bug("Hash pattern matching not yet supported."); + break; + case PM_CAPTURE_PATTERN_NODE: + rb_bug("Capture pattern matching not yet supported."); + break; + case PM_IF_NODE: { + // If guards can be placed on patterns to further limit matches based on + // a dynamic predicate. This looks like: + // + // case foo + // in bar if baz + // end + // + pm_if_node_t *cast = (pm_if_node_t *) node; + + pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, compile_context, matched_label, unmatched_label, in_alternation_pattern); + PM_COMPILE_NOT_POPPED(cast->predicate); + + ADD_INSNL(ret, &dummy_line_node, branchunless, unmatched_label); + ADD_INSNL(ret, &dummy_line_node, jump, matched_label); + break; + } + case PM_UNLESS_NODE: { + // Unless guards can be placed on patterns to further limit matches + // based on a dynamic predicate. This looks like: + // + // case foo + // in bar unless baz + // end + // + pm_unless_node_t *cast = (pm_unless_node_t *) node; + + pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, compile_context, matched_label, unmatched_label, in_alternation_pattern); + PM_COMPILE_NOT_POPPED(cast->predicate); + + ADD_INSNL(ret, &dummy_line_node, branchif, unmatched_label); + ADD_INSNL(ret, &dummy_line_node, jump, matched_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, compile_context, 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(compile_context, 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, &dummy_line_node, index, (int) cast->depth); + ADD_INSNL(ret, &dummy_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(lineno); + LABEL *unmatched_left_label = NEW_LABEL(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, &dummy_line_node, dup); + pm_compile_pattern(iseq, cast->left, ret, src, compile_context, matched_left_label, unmatched_left_label, true); + + // 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, &dummy_line_node, pop); + ADD_INSNL(ret, &dummy_line_node, jump, matched_label); + ADD_INSN(ret, &dummy_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); + pm_compile_pattern(iseq, cast->right, ret, src, compile_context, matched_label, unmatched_label, true); + 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); + ADD_INSN1(ret, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE)); + ADD_INSNL(ret, &dummy_line_node, branchif, matched_label); + ADD_INSNL(ret, &dummy_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; + pm_compile_pattern(iseq, cast->variable, ret, src, compile_context, matched_label, unmatched_label, false); + 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; + pm_compile_pattern(iseq, cast->expression, ret, src, compile_context, matched_label, unmatched_label, false); + 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; +} + +/* + * 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 instruction sequences to append instructions onto + * popped - True if compiling something with no side effects, so instructions don't + * need to be added + * compile_context - 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_compile_context_t *compile_context) +{ + pm_parser_t *parser = compile_context->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); + + switch (PM_NODE_TYPE(node)) { + 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: { + 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]); + } + 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) { + VALUE value = pm_static_literal_value(node, compile_context); + ADD_INSN1(ret, &dummy_line_node, duparray, value); + RB_OBJ_WRITTEN(iseq, Qundef, value); + } + } 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; + + 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); + + // TODO: Not sure this is accurate, look at FLUSH_CHUNK in the compiler + ADD_INSN1(ret, &dummy_line_node, newarraykwsplat, INT2FIX(0)); + + PM_POP_IF_POPPED; + return; + } + case PM_BACK_REFERENCE_READ_NODE: { + if (!popped) { + // Since a back reference is `$`, 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; + if (begin_node->statements) { + PM_COMPILE((pm_node_t *)begin_node->statements); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + return; + } + case PM_BLOCK_ARGUMENT_NODE: { + pm_block_argument_node_t *block_argument_node = (pm_block_argument_node_t *) node; + PM_COMPILE(block_argument_node->expression); + return; + } + case PM_BREAK_NODE: { + pm_break_node_t *break_node = (pm_break_node_t *) node; + if (break_node->arguments) { + PM_COMPILE_NOT_POPPED((pm_node_t *)break_node->arguments); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + + ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label); + + return; + } + case PM_CALL_NODE: { + pm_call_node_t *call_node = (pm_call_node_t *) node; + + ID method_id = parse_string_symbol(&call_node->name); + int flags = 0; + int orig_argc = 0; + + if (call_node->receiver == NULL) { + ADD_INSN(ret, &dummy_line_node, putself); + } else { + PM_COMPILE_NOT_POPPED(call_node->receiver); + } + + if (call_node->arguments == NULL) { + if (flags & VM_CALL_FCALL) { + flags |= VM_CALL_VCALL; + } + } else { + pm_arguments_node_t *arguments = call_node->arguments; + PM_COMPILE_NOT_POPPED((pm_node_t *) arguments); + orig_argc = (int)arguments->arguments.size; + } + + VALUE block_iseq = Qnil; + if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) { + // Scope associated with the block + pm_scope_node_t scope_node; + pm_scope_node_init(call_node->block, &scope_node); + + const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(&scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); + ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq; + ADD_SEND_WITH_BLOCK(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq); + } + else { + if (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 (block_iseq == Qnil && flags == 0) { + flags |= VM_CALL_ARGS_SIMPLE; + } + + if (call_node->receiver == NULL) { + flags |= VM_CALL_FCALL; + } + + ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(orig_argc), INT2FIX(flags)); + } + PM_POP_IF_POPPED; + return; + } + case PM_CLASS_NODE: { + pm_class_node_t *class_node = (pm_class_node_t *)node; + pm_scope_node_t scope_node; + pm_scope_node_init((pm_node_t *)class_node, &scope_node); + + ID class_id = pm_constant_id_lookup(compile_context, class_node->name); + + VALUE class_name = rb_str_freeze(rb_sprintf("", rb_id2str(class_id))); + + const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&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, compile_context); + + if (class_node->superclass) { + PM_COMPILE(class_node->superclass); + } + else { + ADD_INSN(ret, &dummy_line_node, 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(compile_context, 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(compile_context, 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(compile_context, 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); + + ID class_variable_name_id = pm_constant_id_lookup(compile_context, 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; + + 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(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, child->name))); + PM_POP_IF_POPPED; + return; + } + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)node; + + 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; + PM_COMPILE(constant_path_write_node->value); + PM_DUP_UNLESS_POPPED; + + ID constant_var_name = parse_location_symbol(&constant_path_write_node->target->base.location); + + ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); + ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_var_name)); + return; + } + case PM_CONSTANT_READ_NODE: { + pm_constant_read_node_t *constant_read_node = (pm_constant_read_node_t *) node; + ADD_INSN(ret, &dummy_line_node, putnil); + ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); + ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(compile_context, 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(compile_context, constant_and_write_node->name)); + + ADD_INSN(ret, &dummy_line_node, 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(compile_context, constant_operator_write_node->name); + ADD_INSN(ret, &dummy_line_node, 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(compile_context, 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); + + ADD_INSN(ret, &dummy_line_node, putnil); + VALUE constant_name = ID2SYM(pm_constant_id_lookup(compile_context, 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); + + ADD_INSN(ret, &dummy_line_node, 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(compile_context, 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(compile_context, 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(compile_context, def_node->name); + pm_scope_node_t scope_node; + pm_scope_node_init((pm_node_t *)def_node, &scope_node); + rb_iseq_t *method_iseq = NEW_ISEQ(&scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); + + 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: { + ADD_INSN(ret, &dummy_line_node, putself); + pm_defined_node_t *defined_node = (pm_defined_node_t *)node; + // TODO: Correct defined_type + enum defined_type dtype = DEFINED_CONST; + + VALUE sym = Qnil; + if (PM_NODE_TYPE_P(defined_node->value, PM_INTEGER_NODE)) { + sym = parse_integer((pm_integer_node_t *) defined_node->value); + } + + ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(dtype), sym, rb_iseq_defined_string(dtype)); + 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 { + ADD_INSN(ret, &dummy_line_node, 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_FLIP_FLOP_NODE: { + // TODO: The labels here are wrong, figure out why..... + pm_flip_flop_node_t *flip_flop_node = (pm_flip_flop_node_t *)node; + + LABEL *lend = NEW_LABEL(lineno); + LABEL *then_label = NEW_LABEL(lineno); + LABEL *else_label = NEW_LABEL(lineno); + //TODO: int again = type == NODE_FLIP2; + int again = 0; + + rb_num_t cnt = ISEQ_FLIP_CNT_INCREMENT(ISEQ_BODY(iseq)->local_iseq) + + VM_SVAR_FLIPFLOP_START; + VALUE key = INT2FIX(cnt); + + ADD_INSN2(ret, &dummy_line_node, getspecial, key, INT2FIX(0)); + ADD_INSNL(ret, &dummy_line_node, branchif, lend); + + PM_COMPILE(flip_flop_node->left); + /* *flip == 0 */ + 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); + } + + /* *flip == 1 */ + ADD_LABEL(ret, lend); + PM_COMPILE(flip_flop_node->right); + 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); + ADD_LABEL(ret, then_label); + ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); + ADD_INSNL(ret, &dummy_line_node, jump, lend); + ADD_LABEL(ret, else_label); + ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); + ADD_LABEL(ret, lend); + return; + } + case PM_FLOAT_NODE: { + if (!popped) { + ADD_INSN1(ret, &dummy_line_node, putobject, parse_float(node)); + } + 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(compile_context, 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(compile_context, 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(compile_context, 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); + + ADD_INSN(ret, &dummy_line_node, putnil); + VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, 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, compile_context); + 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; + pm_node_list_t *elements = &cast->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_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, compile_context); + 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_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(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, 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(compile_context, 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; + pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + + ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->parts.size))); + + ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(0), INT2FIX(0)); + ADD_SEND(ret, &dummy_line_node, idEqTilde, INT2NUM(1)); + PM_POP_IF_POPPED; + + return; + } + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; + pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + + ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->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, compile_context); + + 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, compile_context); + + 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 { + ADD_INSN(ret, &dummy_line_node, 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; + ADD_INSN(ret, &dummy_line_node, putself); + pm_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); + + 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]); + } + + ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements.size * 2)); + return; + } + case PM_LAMBDA_NODE: { + pm_scope_node_t scope_node; + pm_scope_node_init((pm_node_t *)node, &scope_node); + + const rb_iseq_t *block = NEW_CHILD_ISEQ(&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; + int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, 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; + int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, 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(compile_context, 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; + int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, 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(iseq, compile_context, local_read_node->name); + ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->depth); + } + 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(iseq, compile_context, constant_id); + + ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth); + 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(iseq, compile_context, constant_id); + + ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth); + 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); + 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. + ADD_INSN(ret, &dummy_line_node, putnil); + + // Next, compile the expression that we're going to match against. + PM_COMPILE_NOT_POPPED(cast->value); + ADD_INSN(ret, &dummy_line_node, 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, cast->pattern, ret, src, compile_context, matched_label, unmatched_label, false); + + // 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); + ADD_INSN(ret, &dummy_line_node, pop); + ADD_INSN(ret, &dummy_line_node, pop); + + if (!popped) ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); + ADD_INSNL(ret, &dummy_line_node, jump, done_label); + ADD_INSN(ret, &dummy_line_node, 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_WRITE_NODE: { + pm_match_write_node_t *cast = (pm_match_write_node_t *)node; + LABEL *fail_label = NEW_LABEL(lineno); + LABEL *end_label = NEW_LABEL(lineno); + size_t capture_count = cast->locals.size; + VALUE r; + + pm_constant_id_t *locals = ALLOCV_N(pm_constant_id_t, r, capture_count); + + for (size_t i = 0; i < capture_count; i++) { + locals[i] = cast->locals.ids[i]; + } + + PM_COMPILE((pm_node_t *)cast->call); + VALUE global_variable_name = rb_id2sym(idBACKREF); + + ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); + ADD_INSN(ret, &dummy_line_node, dup); + ADD_INSNL(ret, &dummy_line_node, branchunless, fail_label); + + if (capture_count == 1) { + int local_index = pm_lookup_local_index(iseq, compile_context, *locals); + + DECL_ANCHOR(nom); + INIT_ANCHOR(nom); + + ADD_INSNL(nom, &dummy_line_node, jump, end_label); + ADD_LABEL(nom, fail_label); + ADD_LABEL(nom, end_label); + ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(compile_context, *locals))); + ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); + ADD_SETLOCAL(nom, &dummy_line_node, local_index, 0); + + ADD_SEQ(ret, nom); + return; + } + + for (size_t index = 0; index < capture_count; index++) { + int local_index = pm_lookup_local_index(iseq, compile_context, locals[index]); + + if (index < (capture_count - 1)) { + ADD_INSN(ret, &dummy_line_node, dup); + } + ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(compile_context, locals[index]))); + ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); + ADD_SETLOCAL(ret, &dummy_line_node, local_index, 0); + } + + ADD_INSNL(ret, &dummy_line_node, jump, end_label); + ADD_LABEL(ret, fail_label); + ADD_INSN(ret, &dummy_line_node, pop); + + for (size_t index = 0; index < capture_count; index++) { + pm_constant_id_t constant = cast->locals.ids[index]; + int local_index = pm_lookup_local_index(iseq, compile_context, constant); + + ADD_INSN(ret, &dummy_line_node, putnil); + ADD_SETLOCAL(ret, &dummy_line_node, local_index, 0); + } + 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 scope_node; + pm_scope_node_init((pm_node_t *)module_node, &scope_node); + + ID module_id = pm_constant_id_lookup(compile_context, module_node->name); + VALUE module_name = rb_str_freeze(rb_sprintf("", rb_id2str(module_id))); + + const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&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, popped, compile_context); + + ADD_INSN(ret, &dummy_line_node, 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_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + for (size_t index = 0; index < cast->targets.size; index++) { + PM_COMPILE(cast->targets.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 node_list = multi_write_node->targets; + + // pre-process the left hand side of multi-assignments. + uint8_t pushed = 0; + for (size_t index = 0; index < node_list.size; index++) { + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, node_list.nodes[index], ret, compile_context, pushed, false); + } + + PM_COMPILE_NOT_POPPED(multi_write_node->value); + + // TODO: int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); + int flag = 0x00; + + if (!popped) { + ADD_INSN(ret, &dummy_line_node, dup); + } + ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(multi_write_node->targets.size), INT2FIX(flag)); + + for (size_t index = 0; index < node_list.size; index++) { + pm_node_t *considered_node = node_list.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(compile_context, ((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 { + PM_COMPILE(node_list.nodes[index]); + } + } + + if (pushed) { + ADD_INSN1(ret, &dummy_line_node, setn, INT2FIX(pushed)); + for (uint8_t index = 0; index < pushed; index++) { + ADD_INSN(ret, &dummy_line_node, pop); + } + } + + return; + } + case PM_NEXT_NODE: { + pm_next_node_t *next_node = (pm_next_node_t *) node; + if (next_node->arguments) { + PM_COMPILE_NOT_POPPED((pm_node_t *)next_node->arguments); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + + ADD_INSN(ret, &dummy_line_node, pop); + ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label); + + return; + } + case PM_NIL_NODE: + PM_PUTNIL_UNLESS_POPPED + 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, compile_context, optional_parameter_node->name); + + ADD_SETLOCAL(ret, &dummy_line_node, index, 0); + + 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_PROGRAM_NODE: { + pm_program_node_t *program_node = (pm_program_node_t *) node; + + pm_scope_node_t scope_node; + pm_scope_node_init((pm_node_t *)node, &scope_node); + if (program_node->statements->body.size == 0) { + ADD_INSN(ret, &dummy_line_node, putnil); + ADD_INSN(ret, &dummy_line_node, leave); + } else { + pm_scope_node_t *res_node = &scope_node; + PM_COMPILE((pm_node_t *) res_node); + } + + 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) { + ADD_INSN(ret, &dummy_line_node, putnil); + } else { + PM_COMPILE(range_node->left); + } + + if (range_node->right == NULL) { + ADD_INSN(ret, &dummy_line_node, 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: { + ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label); + return; + } + case PM_REGULAR_EXPRESSION_NODE: { + if (!popped) { + pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node; + + VALUE regex_str = parse_string(&cast->unescaped); + 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); + } + return; + } + case PM_RETURN_NODE: { + pm_arguments_node_t *arguments = ((pm_return_node_t *)node)->arguments; + + if (arguments) { + PM_COMPILE((pm_node_t *)arguments); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + + ADD_TRACE(ret, RUBY_EVENT_RETURN); + ADD_INSN(ret, &dummy_line_node, leave); + + if (!popped) { + ADD_INSN(ret, &dummy_line_node, putnil); + } + 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 = (pm_parameters_node_t *)scope_node->parameters; + pm_node_list_t requireds_list = PM_EMPTY_NODE_LIST; + pm_node_list_t optionals_list = PM_EMPTY_NODE_LIST; + + if (parameters_node) { + requireds_list = parameters_node->requireds; + optionals_list = parameters_node->optionals; + } + + size_t size = locals.size; + + // Index lookup table buffer size is only the number of the locals + st_table *index_lookup_table = st_init_numtable(); + + VALUE idtmp = 0; + rb_ast_id_table_t *tbl = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + size * sizeof(ID)); + tbl->size = (int)size; + + // First param gets 0, second param 1, param n... + // Calculate the local index for all locals + for (size_t i = 0; i < size; i++) { + pm_constant_id_t constant_id = locals.ids[i]; + ID local = pm_constant_id_lookup(compile_context, constant_id); + tbl->ids[i] = local; + st_insert(index_lookup_table, constant_id, i); + } + + pm_compile_context_t scope_compile_context = { + .parser = parser, + .previous = compile_context, + .constants = compile_context->constants, + .index_lookup_table = index_lookup_table + }; + + ISEQ_BODY(iseq)->param.lead_num = (int)requireds_list.size; + ISEQ_BODY(iseq)->param.opt_num = (int)optionals_list.size; + // TODO: Set all the other nums (good comment by lead_num illustrating what they are) + ISEQ_BODY(iseq)->param.size = (unsigned int)size; + + if (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++) { + label = NEW_LABEL(lineno); + opt_table[i] = label; + ADD_LABEL(ret, label); + pm_node_t *optional_node = optionals_list.nodes[i]; + pm_compile_node(iseq, optional_node, ret, src, false, &scope_compile_context); + } + + // Set the last label + label = NEW_LABEL(lineno); + opt_table[optionals_list.size] = label; + ADD_LABEL(ret, label); + + ISEQ_BODY(iseq)->param.flags.has_opt = TRUE; + ISEQ_BODY(iseq)->param.opt_table = (const VALUE *)opt_table; + } + + iseq_set_local_table(iseq, tbl); + + switch (ISEQ_BODY(iseq)->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(ISEQ_BODY(iseq)->location.first_lineno, -1); + ADD_INSN (ret, &dummy_line_node, nop); + ADD_LABEL(ret, start); + + if (scope_node->body) { + pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + + 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; + + /* 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; + } + default: + if (scope_node->body) { + pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + } + + free(index_lookup_table); + + ADD_INSN(ret, &dummy_line_node, leave); + return; + } + case PM_SELF_NODE: + if (!popped) { + ADD_INSN(ret, &dummy_line_node, 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 scope_node; + pm_scope_node_init((pm_node_t *)singleton_class_node, &scope_node); + + const rb_iseq_t *singleton_class = NEW_ISEQ(&scope_node, rb_fstring_lit("singleton class"), + ISEQ_TYPE_CLASS, lineno); + + PM_COMPILE(singleton_class_node->expression); + ADD_INSN(ret, &dummy_line_node, putnil); + ID singletonclass; + CONST_ID(singletonclass, "singletonclass"); + + ADD_INSN3(ret, &dummy_line_node, defineclass, + ID2SYM(singletonclass), singleton_class, + INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS)); + 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, compile_context); + 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, compile_context); + 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, compile_context); + 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; + PM_COMPILE(splat_node->expression); + + ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue); + + PM_POP_IF_POPPED; + 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; + for (size_t index = 0; index < node_list.size - 1; index++) { + PM_COMPILE_POPPED(node_list.nodes[index]); + } + if (node_list.size > 0) { + PM_COMPILE(node_list.nodes[node_list.size - 1]); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + return; + } + case PM_STRING_CONCAT_NODE: { + pm_string_concat_node_t *str_concat_node = (pm_string_concat_node_t *)node; + PM_COMPILE(str_concat_node->left); + PM_COMPILE(str_concat_node->right); + return; + } + case PM_STRING_NODE: { + if (!popped) { + pm_string_node_t *string_node = (pm_string_node_t *) node; + ADD_INSN1(ret, &dummy_line_node, putstring, parse_string(&string_node->unescaped)); + } + 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, compile_context); + 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(undef_node->names.nodes[index]); + + ADD_SEND(ret, &dummy_line_node, id_core_undef_method, INT2NUM(2)); + + if (index < undef_node->names.size - 1) + ADD_INSN(ret, &dummy_line_node, pop); + } + + 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_statements_node_t *node_body = unless_node->statements; + pm_node_t *node_else = (pm_node_t *)(unless_node->consequent); + pm_node_t *predicate = unless_node->predicate; + + pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context); + 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, compile_context); + 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, compile_context); + return; + } + case PM_X_STRING_NODE: { + pm_x_string_node_t *xstring_node = (pm_x_string_node_t *) node; + ADD_INSN(ret, &dummy_line_node, putself); + ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&xstring_node->unescaped)); + 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: { + unsigned int flag = 0; + struct rb_callinfo_kwarg *keywords = NULL; + + VALUE argc = INT2FIX(0); + + ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, 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(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context) +{ + RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); + RUBY_ASSERT(PM_NODE_TYPE_P(node, PM_PROGRAM_NODE) || PM_NODE_TYPE_P(node, PM_SCOPE_NODE)); + + pm_compile_node(iseq, node, ret, node->location.start, false, compile_context); + iseq_set_sequence(iseq, ret); + 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_init.c b/prism_init.c new file mode 100644 index 00000000000000..ddc87fad855b09 --- /dev/null +++ b/prism_init.c @@ -0,0 +1,9 @@ +#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/proc.c b/proc.c index 9fd24a8fd4e561..0f4735b589b8b0 100644 --- a/proc.c +++ b/proc.c @@ -793,16 +793,8 @@ proc_new(VALUE klass, int8_t is_lambda) break; case block_handler_type_ifunc: - 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); - } + return rb_vm_make_proc_lambda(ec, VM_BH_TO_CAPT_BLOCK(block_handler), klass, is_lambda); } VM_UNREACHABLE(proc_new); return Qnil; @@ -857,31 +849,34 @@ rb_block_lambda(void) } static void -f_lambda_warn(void) +f_lambda_filter_non_literal(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) { - 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: + 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; - 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_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; } - rb_warn_deprecated("lambda without a literal block", "the proc without lambda"); + rb_raise(rb_eArgError, "the lambda method requires a literal block"); } /* @@ -895,7 +890,7 @@ f_lambda_warn(void) static VALUE f_lambda(VALUE _) { - f_lambda_warn(); + f_lambda_filter_non_literal(); return rb_block_lambda(); } diff --git a/process.c b/process.c index 681535d92fd452..17c8ac4e5ffc4f 100644 --- a/process.c +++ b/process.c @@ -566,30 +566,21 @@ proc_get_ppid(VALUE _) * * Document-class: Process::Status * - * Process::Status encapsulates the information on the - * status of a running or terminated system process. The built-in - * variable $? 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. + * A Process::Status contains information about a system process. + * + * Thread-local variable $? 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 = $? # => # + * stat.class # => Process::Status + * stat.to_i # => 25344 + * stat >> 8 # => 99 + * stat.stopped? # => false + * stat.exited? # => true + * stat.exitstatus # => 99 + * */ static VALUE rb_cProcessStatus; @@ -716,14 +707,12 @@ pst_status(VALUE pst) /* * call-seq: - * stat.to_i -> integer + * to_i -> integer * - * Returns the bits in _stat_ as an Integer. Poking - * around in these bits is platform dependent. + * Returns the system-dependent integer status of +self+: * - * fork { exit 0xab } #=> 26566 - * Process.wait #=> 26566 - * sprintf('%04x', $?.to_i) #=> "ab00" + * `cat /nop` + * $?.to_i # => 256 */ static VALUE @@ -737,13 +726,13 @@ pst_to_i(VALUE self) /* * call-seq: - * stat.pid -> integer + * pid -> integer * - * Returns the process ID that this status object represents. + * Returns the process ID of the process: + * + * system("false") + * $?.pid # => 1247002 * - * fork { exit } #=> 26569 - * Process.wait #=> 26569 - * $?.pid #=> 26569 */ static VALUE @@ -799,12 +788,13 @@ pst_message_status(VALUE str, int status) /* * call-seq: - * stat.to_s -> string + * to_s -> string * - * Show pid and exit status as a string. + * Returns a string representation of +self+: + * + * `cat /nop` + * $?.to_s # => "pid 1262141 exit 1" * - * system("false") - * p $?.to_s #=> "pid 12766 exit 1" * */ @@ -826,12 +816,12 @@ pst_to_s(VALUE st) /* * call-seq: - * stat.inspect -> string + * inspect -> string * - * Override the inspection method. + * Returns a string representation of +self+: * * system("false") - * p $?.inspect #=> "#" + * $?.inspect # => "#" * */ @@ -880,6 +870,8 @@ pst_equal(VALUE st1, VALUE st2) * call-seq: * stat & mask -> integer * + * This method is deprecated; use other attribute methods. + * * Returns the logical AND of the value of #to_i with +mask+: * * `cat /nop` @@ -887,12 +879,40 @@ pst_equal(VALUE st1, VALUE st2) * sprintf('%x', stat.to_i) # => "100" * stat & 0x00 # => 0 * + * ArgumentError is raised if +mask+ is negative. */ static VALUE pst_bitand(VALUE st1, VALUE st2) { - int status = PST2INT(st1) & NUM2INT(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; return INT2NUM(status); } @@ -902,6 +922,8 @@ pst_bitand(VALUE st1, VALUE st2) * call-seq: * stat >> places -> integer * + * This method is deprecated; use other predicate methods. + * * Returns the value of #to_i, shifted +places+ to the right: * * `cat /nop` @@ -910,13 +932,34 @@ pst_bitand(VALUE st1, VALUE st2) * stat >> 1 # => 128 * stat >> 2 # => 64 * - * The behavior is unspecified if +places+ is negative. + * ArgumentError is raised if +places+ is negative. */ static VALUE pst_rshift(VALUE st1, VALUE st2) { - int status = PST2INT(st1) >> NUM2INT(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; return INT2NUM(status); } @@ -924,11 +967,11 @@ pst_rshift(VALUE st1, VALUE st2) /* * call-seq: - * stat.stopped? -> true or false + * stopped? -> true or false * - * Returns +true+ if this process is stopped. This is only returned - * if the corresponding #wait call had the Process::WUNTRACED flag - * set. + * Returns +true+ if this process is stopped, + * and if the corresponding #wait call had the Process::WUNTRACED flag set, + * +false+ otherwise. */ static VALUE @@ -942,10 +985,10 @@ pst_wifstopped(VALUE st) /* * call-seq: - * stat.stopsig -> integer or nil + * stopsig -> integer or nil * - * Returns the number of the signal that caused _stat_ to stop - * (or +nil+ if self is not stopped). + * Returns the number of the signal that caused the process to stop, + * or +nil+ if the process is not stopped. */ static VALUE @@ -961,10 +1004,10 @@ pst_wstopsig(VALUE st) /* * call-seq: - * stat.signaled? -> true or false + * signaled? -> true or false * - * Returns +true+ if _stat_ terminated because of - * an uncaught signal. + * Returns +true+ if the process terminated because of an uncaught signal, + * +false+ otherwise. */ static VALUE @@ -978,11 +1021,10 @@ pst_wifsignaled(VALUE st) /* * call-seq: - * stat.termsig -> integer or nil + * termsig -> integer or nil * - * Returns the number of the signal that caused _stat_ to - * terminate (or +nil+ if self was not terminated by an - * uncaught signal). + * Returns the number of the signal that caused the process to terminate + * or +nil+ if the process was not terminated by an uncaught signal. */ static VALUE @@ -998,11 +1040,11 @@ pst_wtermsig(VALUE st) /* * call-seq: - * stat.exited? -> true or false + * exited? -> true or false * - * Returns +true+ if _stat_ exited normally (for - * example using an exit() call or finishing the - * program). + * Returns +true+ if the process exited normally + * (for example using an exit() call or finishing the + * program), +false+ if not. */ static VALUE @@ -1016,20 +1058,15 @@ pst_wifexited(VALUE st) /* * call-seq: - * stat.exitstatus -> integer or nil + * exitstatus -> integer or nil * - * Returns the least significant eight bits of the return code of - * _stat_. Only available if #exited? is +true+. + * Returns the least significant eight bits of the return code + * of the process if it has exited; + * +nil+ otherwise: * - * fork { } #=> 26572 - * Process.wait #=> 26572 - * $?.exited? #=> true - * $?.exitstatus #=> 0 + * `exit 99` + * $?.exitstatus # => 99 * - * fork { exit 99 } #=> 26573 - * Process.wait #=> 26573 - * $?.exited? #=> true - * $?.exitstatus #=> 99 */ static VALUE @@ -1045,10 +1082,14 @@ pst_wexitstatus(VALUE st) /* * call-seq: - * stat.success? -> true, false or nil + * 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. * - * Returns +true+ if _stat_ is successful, +false+ if not. - * Returns +nil+ if #exited? is not +true+. */ static VALUE @@ -1064,10 +1105,12 @@ pst_success_p(VALUE st) /* * call-seq: - * stat.coredump? -> true or false + * coredump? -> true or false * - * Returns +true+ if _stat_ generated a coredump - * when it terminated. Not available on all platforms. + * Returns +true+ if the process generated a coredump + * when it terminated, +false+ if not. + * + * Not available on all platforms. */ static VALUE @@ -3026,7 +3069,7 @@ NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _)); * * - +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. + * or if it contains one or more meta characters. * - +exe_path+ otherwise. * * Argument +command_line+ @@ -3035,8 +3078,8 @@ NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _)); * it must begin with a shell reserved word, begin with a special built-in, * or contain meta characters: * - * exec('echo') # Built-in. * exec('if true; then echo "Foo"; fi') # Shell reserved word. + * exec('echo') # Built-in. * exec('date > date.tmp') # Contains meta character. * * The command line may also contain arguments and options for the command: @@ -3047,21 +3090,7 @@ NORETURN(static VALUE f_exec(int c, const VALUE *a, VALUE _)); * * Foo * - * On a Unix-like system, the shell is /bin/sh; - * otherwise the shell is determined by environment variable - * ENV['RUBYSHELL'], if defined, or ENV['COMSPEC'] 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: - * - * exec('echo C*') - * - * Output: - * - * CONTRIBUTING.md COPYING COPYING.ja + * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell. * * Raises an exception if the new process could not execute. * @@ -4712,7 +4741,7 @@ rb_spawn(int argc, const VALUE *argv) * * - +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. + * or if it contains one or more meta characters. * - +exe_path+ otherwise. * * Argument +command_line+ @@ -4721,8 +4750,8 @@ rb_spawn(int argc, const VALUE *argv) * it must begin with a shell reserved word, begin with a special built-in, * or contain meta characters: * - * system('echo') # => true # Built-in. * 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. @@ -4742,21 +4771,7 @@ rb_spawn(int argc, const VALUE *argv) * * Foo * - * On a Unix-like system, the shell is /bin/sh; - * otherwise the shell is determined by environment variable - * ENV['RUBYSHELL'], if defined, or ENV['COMSPEC'] 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: - * - * system('echo C*') # => true - * - * Output: - * - * CONTRIBUTING.md COPYING COPYING.ja + * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell. * * Raises an exception if the new process could not execute. * @@ -4902,7 +4917,7 @@ rb_f_system(int argc, VALUE *argv, VALUE _) * * - +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. + * or if it contains one or more meta characters. * - +exe_path+ otherwise. * * Argument +command_line+ @@ -4911,11 +4926,11 @@ rb_f_system(int argc, VALUE *argv, VALUE _) * it must begin with a shell reserved word, begin with a special built-in, * or contain meta characters: * - * spawn('echo') # => 798847 + * spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word. * Process.wait # => 798847 - * spawn('if true; then echo "Foo"; fi') # => 798848 + * spawn('echo') # => 798848 # Built-in. * Process.wait # => 798848 - * spawn('date > /tmp/date.tmp') # => 798879 + * spawn('date > /tmp/date.tmp') # => 798879 # Contains meta character. * Process.wait # => 798849 * spawn('date > /nop/date.tmp') # => 798882 # Issues error message. * Process.wait # => 798882 @@ -4929,22 +4944,7 @@ rb_f_system(int argc, VALUE *argv, VALUE _) * * Foo * - * On a Unix-like system, the shell is /bin/sh; - * otherwise the shell is determined by environment variable - * ENV['RUBYSHELL'], if defined, or ENV['COMSPEC'] 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 + * See {Execution Shell}[rdoc-ref:Process@Execution+Shell] for details about the shell. * * Raises an exception if the new process could not execute. * @@ -8746,6 +8746,7 @@ static VALUE rb_mProcID_Syscall; * * 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 @@ -8929,6 +8930,25 @@ proc_warmup(VALUE _) * Use execution option :close_others => true 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 /bin/sh; + * otherwise the shell invoked is determined by environment variable + * ENV['RUBYSHELL'], if defined, or ENV['COMSPEC'] 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 diff --git a/range.c b/range.c index 62e957e6224a96..d0e0c4c1afb13e 100644 --- a/range.c +++ b/range.c @@ -649,27 +649,30 @@ bsearch_integer_range(VALUE beg, VALUE end, int excl) VALUE low = rb_to_int(beg); VALUE high = rb_to_int(end); - VALUE mid, org_high; + VALUE mid; ID id_div; CONST_ID(id_div, "div"); - if (excl) high = rb_funcall(high, '-', 1, INT2FIX(1)); - org_high = high; + if (!excl) high = rb_funcall(high, '+', 1, INT2FIX(1)); + low = rb_funcall(low, '-', 1, INT2FIX(1)); - 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)); + /* + * 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) { BSEARCH_CHECK(mid); if (smaller) { high = mid; } else { - low = rb_funcall(mid, '+', 1, INT2FIX(1)); + low = mid; } } - if (rb_equal(low, org_high)) { - BSEARCH_CHECK(low); - if (!smaller) return Qnil; - } return satisfied; } @@ -696,52 +699,58 @@ 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) - * as well as the fact that -1/2 can be 0 or -1 in C89. + * 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. * * 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) \ +#define BSEARCH(conv, excl) \ do { \ RETURN_ENUMERATOR(range, 0, 0); \ - if (EXCL(range)) high--; \ - org_high = high; \ - while (low < high) { \ + if (!(excl)) high++; \ + low--; \ + while (low + 1 < high) { \ mid = ((high < 0) == (low < 0)) ? low + ((high - low) / 2) \ - : (low < -high) ? -((-1 - low - high)/2 + 1) : (low + high) / 2; \ + : (low + high) / 2; \ BSEARCH_CHECK(conv(mid)); \ if (smaller) { \ high = mid; \ } \ else { \ - low = mid + 1; \ + low = mid; \ } \ } \ - 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)) { - long low = FIX2LONG(beg); - long high = FIX2LONG(end); - long mid, org_high; - BSEARCH(INT2FIX); + BSEARCH_FIXNUM(beg, end, EXCL(range)); } #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, org_high; - BSEARCH(int64_as_double_to_num); + int64_t mid; + BSEARCH(int64_as_double_to_num, EXCL(range)); } #endif else if (is_integer_p(beg) && is_integer_p(end)) { @@ -755,9 +764,15 @@ range_bsearch(VALUE range) VALUE mid = rb_funcall(beg, '+', 1, diff); BSEARCH_CHECK(mid); if (smaller) { - return bsearch_integer_range(beg, mid, 0); + if (FIXNUM_P(beg) && FIXNUM_P(mid)) { + BSEARCH_FIXNUM(beg, mid, false); + } + else { + return bsearch_integer_range(beg, mid, false); + } } diff = rb_funcall(diff, '*', 1, LONG2FIX(2)); + beg = mid; } } else if (NIL_P(beg) && is_integer_p(end)) { @@ -767,9 +782,15 @@ range_bsearch(VALUE range) VALUE mid = rb_funcall(end, '+', 1, diff); BSEARCH_CHECK(mid); if (!smaller) { - return bsearch_integer_range(mid, end, 0); + if (FIXNUM_P(mid) && FIXNUM_P(end)) { + BSEARCH_FIXNUM(mid, end, false); + } + else { + return bsearch_integer_range(mid, end, false); + } } diff = rb_funcall(diff, '*', 1, LONG2FIX(2)); + end = mid; } } else { @@ -1818,6 +1839,7 @@ range_string_cover_internal(VALUE range, VALUE val) 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)) { @@ -1826,12 +1848,20 @@ range_string_cover_internal(VALUE range, VALUE val) 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); } @@ -1877,7 +1907,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 @@ -1898,7 +1928,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 @@ -1914,7 +1944,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 @@ -2149,6 +2179,101 @@ range_count(int argc, VALUE *argv, VALUE range) } } +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 <=> 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 + * + * 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 both begin values are equal, no more comparisons needed */ + if (rb_equal(self_beg, other_beg)) return Qtrue; + + 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 * that are between given begin and end values. * @@ -2363,7 +2488,7 @@ range_count(int argc, VALUE *argv, VALUE range) * - #%: 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 * @@ -2415,4 +2540,5 @@ 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/rjit_c.rb b/rjit_c.rb index 78d1a6cf747e62..b05980e11053c7 100644 --- a/rjit_c.rb +++ b/rjit_c.rb @@ -1269,9 +1269,9 @@ def C.rb_method_definition_struct "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], - alias_count: [CType::BitField.new(27, 5), 5], - complemented_count: [CType::BitField.new(28, 0), 32], - no_redef_warning: [CType::BitField.new(1, 4), 60], + 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, diff --git a/ruby.c b/ruby.c index be2ea2d0cde267..379f76c577443f 100644 --- a/ruby.c +++ b/ruby.c @@ -337,6 +337,7 @@ usage(const char *name, int help, int highlight, int columns) 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"), }; @@ -898,18 +899,20 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt) 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; - argstr = rb_str_tmp_new((len = strlen(s)) + (envopt!=0)); + const int hyphen = *s != '-'; + argstr = rb_str_tmp_new((len = strlen(s)) + hyphen); argary = rb_str_tmp_new(0); p = RSTRING_PTR(argstr); - if (envopt) *p++ = ' '; - memcpy(p, s, len + 1); + if (hyphen) *p = '-'; + memcpy(p + hyphen, s, len + 1); ap = 0; rb_str_cat(argary, (char *)&ap, sizeof(ap)); while (*p) { @@ -951,6 +954,9 @@ moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt) 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 */ @@ -1461,6 +1467,9 @@ proc_long_options(ruby_cmdline_options_t *opt, const char *s, long argc, char ** 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); @@ -2910,6 +2919,10 @@ ruby_process_options(int argc, char **argv) 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 index 6aaa867c16a55f..b239494886417b 100644 --- a/ruby_parser.c +++ b/ruby_parser.c @@ -356,7 +356,7 @@ reg_named_capture_assign(struct parser_params* p, VALUE regexp, const rb_code_lo onig_foreach_name(RREGEXP_PTR(regexp), reg_named_capture_assign_iter, &arg); if (!arg.succ_block) return 0; - return arg.succ_block->nd_next; + return RNODE_BLOCK(arg.succ_block)->nd_next; } static VALUE @@ -566,8 +566,6 @@ rb_parser_config_initialize(rb_parser_config_t *config) config->new_strterm = new_strterm; config->strterm_is_heredoc = strterm_is_heredoc; - config->tmpbuf_auto_free_pointer = rb_imemo_tmpbuf_auto_free_pointer; - config->tmpbuf_set_ptr = rb_imemo_tmpbuf_set_ptr; config->tmpbuf_parser_heap = tmpbuf_parser_heap; config->ast_new = ast_new; diff --git a/rubyparser.h b/rubyparser.h index e95b71f049f681..2c16b05e331738 100644 --- a/rubyparser.h +++ b/rubyparser.h @@ -5,6 +5,7 @@ */ #include /* for va_list */ +#include #ifdef UNIVERSAL_PARSER @@ -130,79 +131,12 @@ enum node_type { NODE_HSHPTN, NODE_FNDPTN, NODE_ERROR, + NODE_DEF_TEMP, + NODE_RIPPER, + NODE_RIPPER_VALUES, NODE_LAST }; - -#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_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 - #ifndef FLEX_ARY_LEN /* From internal/compilers.h */ /* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */ @@ -230,33 +164,988 @@ typedef struct rb_code_location_struct { rb_code_position_t end_pos; } rb_code_location_t; +/* Header part of AST Node */ 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; +typedef struct RNode_SCOPE { + NODE node; + + rb_ast_id_table_t *nd_tbl; + struct RNode *nd_body; + struct RNode *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; + + VALUE not_used; + struct RNode *nd_body; + struct RNode *nd_iter; +} rb_node_iter_t; + +typedef struct RNode_FOR { + NODE node; + + VALUE not_used; + struct RNode *nd_body; + struct RNode *nd_iter; +} rb_node_for_t; + +typedef struct RNode_FOR_MASGN { + NODE node; + + struct RNode *nd_var; + VALUE not_used; + VALUE not_used2; +} rb_node_for_masgn_t; + +/* RNode_BREAK, RNode_NEXT and RNode_RETURN should be same structure */ +typedef struct RNode_BREAK { + NODE node; + + struct RNode *nd_stts; + VALUE not_used; + VALUE not_used2; +} rb_node_break_t; + +typedef struct RNode_NEXT { + NODE node; + + struct RNode *nd_stts; + VALUE not_used; + VALUE not_used2; +} rb_node_next_t; + +typedef struct RNode_REDO { + NODE node; + + VALUE not_used; + VALUE not_used2; + VALUE not_used3; +} rb_node_redo_t; + +typedef struct RNode_RETRY { + NODE node; + + VALUE not_used; + VALUE not_used2; + VALUE not_used3; +} rb_node_retry_t; + +typedef struct RNode_BEGIN { + NODE node; + + VALUE not_used; + struct RNode *nd_body; + VALUE not_used2; +} 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; + VALUE not_used; +} rb_node_and_t; + +typedef struct RNode_OR { + NODE node; + + struct RNode *nd_1st; + struct RNode *nd_2nd; + VALUE not_used; +} 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; + +/* RNode_LASGN, RNode_DASGN, RNode_IASGN, RNode_CVASGN and RNode_GASGN should be same structure */ +typedef struct RNode_LASGN { + NODE node; + + ID nd_vid; + struct RNode *nd_value; + VALUE not_used; +} rb_node_lasgn_t; + +typedef struct RNode_DASGN { + NODE node; + + ID nd_vid; + struct RNode *nd_value; + VALUE not_used; +} rb_node_dasgn_t; + +typedef struct RNode_GASGN { + NODE node; + + ID nd_vid; + struct RNode *nd_value; + VALUE not_used; +} rb_node_gasgn_t; + +typedef struct RNode_IASGN { + NODE node; + + ID nd_vid; + struct RNode *nd_value; + VALUE not_used; +} 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; + VALUE not_used; +} rb_node_cvasgn_t; + +typedef struct RNode_OP_ASGN1 { + NODE node; + + struct RNode *nd_recv; + ID nd_mid; + struct RNode_ARGSCAT *nd_args; +} 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; + VALUE not_used; +} rb_node_op_asgn_and_t; + +typedef struct RNode_OP_ASGN_OR { + NODE node; + + struct RNode *nd_head; + struct RNode *nd_value; + VALUE not_used; +} 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; + +/* RNode_CALL, RNode_OPCALL and RNode_QCALL should be same structure */ +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; + + VALUE not_used; + ID nd_mid; + struct RNode *nd_args; +} rb_node_fcall_t; + +typedef struct RNode_VCALL { + NODE node; + + VALUE not_used; + ID nd_mid; + VALUE not_used2; +} 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; + + VALUE not_used; + VALUE not_used2; + struct RNode *nd_args; +} rb_node_super_t; + +typedef struct RNode_ZSUPER { + NODE node; + + VALUE not_used; + VALUE not_used2; + VALUE not_used3; +} 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; + + VALUE not_used; + VALUE not_used2; /* Used by p->exits */ + VALUE not_used3; /* Used by p->exits */ +} 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; + VALUE not_used; +} rb_node_hash_t; + +typedef struct RNode_RETURN { + NODE node; + + struct RNode *nd_stts; + VALUE not_used; + VALUE not_used2; +} rb_node_return_t; + +typedef struct RNode_YIELD { + NODE node; + + struct RNode *nd_head; + VALUE not_used; + VALUE not_used2; +} rb_node_yield_t; + +/* RNode_LVAR and RNode_DVAR should be same structure */ +typedef struct RNode_LVAR { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_lvar_t; + +typedef struct RNode_DVAR { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_dvar_t; + +/* RNode_GVAR, RNode_IVAR, RNode_CONST and RNode_CVAR should be same structure */ +typedef struct RNode_GVAR { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_gvar_t; + +typedef struct RNode_IVAR { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_ivar_t; + +typedef struct RNode_CONST { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_const_t; + +typedef struct RNode_CVAR { + NODE node; + + ID nd_vid; + VALUE not_used; + VALUE not_used2; +} rb_node_cvar_t; + +typedef struct RNode_NTH_REF { + NODE node; + + VALUE not_used; + long nd_nth; + VALUE not_used2; +} rb_node_nth_ref_t; + +typedef struct RNode_BACK_REF { + NODE node; + + VALUE not_used; + long nd_nth; + VALUE not_used2; +} 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; + VALUE not_used; + VALUE not_used2; +} 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; + VALUE not_used; +} rb_node_match3_t; + +typedef struct RNode_LIT { + NODE node; + + VALUE nd_lit; + VALUE not_used; + VALUE not_used2; +} rb_node_lit_t; + +typedef struct RNode_STR { + NODE node; + + VALUE nd_lit; + VALUE not_used; + VALUE not_used2; +} 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; + VALUE not_used; + VALUE not_used2; +} 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; + + VALUE not_used; + struct RNode *nd_body; + VALUE not_used2; +} 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; + + VALUE not_used; + struct RNode *nd_body; + VALUE not_used2; +} rb_node_once_t; + +typedef struct RNode_ARGS { + NODE node; + + VALUE not_used; + VALUE not_used2; + 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; + + VALUE not_used; + struct RNode *nd_body; + struct RNode *nd_next; +} rb_node_opt_arg_t; + +typedef struct RNode_KW_ARG { + NODE node; + + VALUE not_used; + struct RNode *nd_body; + struct RNode *nd_next; +} rb_node_kw_arg_t; + +typedef struct RNode_POSTARG { + NODE node; + + struct RNode *nd_1st; + struct RNode *nd_2nd; + VALUE not_used; +} rb_node_postarg_t; + +typedef struct RNode_ARGSCAT { + NODE node; + + struct RNode *nd_head; + struct RNode *nd_body; + VALUE not_used; +} rb_node_argscat_t; + +typedef struct RNode_ARGSPUSH { + NODE node; + + struct RNode *nd_head; + struct RNode *nd_body; + VALUE not_used; +} rb_node_argspush_t; + +typedef struct RNode_SPLAT { + NODE node; + + struct RNode *nd_head; + VALUE not_used; + VALUE not_used2; +} rb_node_splat_t; + +typedef struct RNode_BLOCK_PASS { + NODE node; + + struct RNode *nd_head; + struct RNode *nd_body; + VALUE not_used; +} rb_node_block_pass_t; + +typedef struct RNode_DEFN { + NODE node; + + VALUE not_used; + 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; + VALUE not_used; +} rb_node_module_t; + +typedef struct RNode_SCLASS { + NODE node; + + struct RNode *nd_recv; + struct RNode *nd_body; + VALUE not_used; +} rb_node_sclass_t; + +typedef struct RNode_COLON2 { + NODE node; + + struct RNode *nd_head; + ID nd_mid; + VALUE not_used; +} rb_node_colon2_t; + +typedef struct RNode_COLON3 { + NODE node; + + VALUE not_used; + ID nd_mid; + VALUE not_used2; +} 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; + + VALUE not_used; + VALUE not_used2; + VALUE not_used3; +} rb_node_errinfo_t; + +typedef struct RNode_DEFINED { + NODE node; + + struct RNode *nd_head; + VALUE not_used; + VALUE not_used2; +} rb_node_defined_t; + +typedef struct RNode_POSTEXE { + NODE node; + + VALUE not_used; + struct RNode *nd_body; + VALUE not_used2; +} 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; + + VALUE not_used; + struct RNode *nd_body; + VALUE not_used2; +} rb_node_lambda_t; + +typedef struct RNode_ARYPTN { + NODE node; + + struct RNode *nd_pconst; + VALUE not_used; + struct rb_ary_pattern_info *nd_apinfo; +} 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; + VALUE not_used; + struct rb_fnd_pattern_info *nd_fpinfo; +} rb_node_fndptn_t; + +typedef struct RNode_ERROR { + NODE node; + + VALUE not_used; + VALUE not_used2; + VALUE not_used3; +} 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_ASGN22(node) ((struct RNode_OP_ASGN22 *)(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_VALUES(node) ((struct RNode_VALUES *)(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, @@ -267,7 +1156,7 @@ typedef struct RNode { #define NODE_TYPESHIFT 8 #define NODE_TYPEMASK (((VALUE)0x7f)<flags & NODE_TYPEMASK)>>NODE_TYPESHIFT)) +#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) \ @@ -292,8 +1181,6 @@ struct rb_args_info { unsigned int no_kwarg: 1; unsigned int ruby2_keywords: 1; unsigned int forwarding: 1; - - VALUE imemo; }; struct rb_ary_pattern_info { @@ -364,8 +1251,6 @@ typedef struct rb_parser_config_struct { // TODO: Should it return `rb_strterm_t *'? VALUE (*new_strterm)(VALUE v1, VALUE v2, VALUE v3, VALUE v0, int heredoc); int (*strterm_is_heredoc)(VALUE strterm); - VALUE (*tmpbuf_auto_free_pointer)(void); - void *(*tmpbuf_set_ptr)(VALUE v, void *ptr); 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); diff --git a/scheduler.c b/scheduler.c index 866e53993fff1e..022e8401e0248f 100644 --- a/scheduler.c +++ b/scheduler.c @@ -458,7 +458,7 @@ 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) -> read length or -errno + * call-seq: io_read(io, buffer, length, offset) -> 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+. @@ -518,7 +518,7 @@ 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) -> written length or -errno + * call-seq: io_write(io, buffer, length, offset) -> 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+. diff --git a/spec/bundler/bundler/bundler_spec.rb b/spec/bundler/bundler/bundler_spec.rb index f4c1664620a05d..132ce5c8adf664 100644 --- a/spec/bundler/bundler/bundler_spec.rb +++ b/spec/bundler/bundler/bundler_spec.rb @@ -23,7 +23,7 @@ end it "loads simple structure" do - simple_structure = { "name" => [:abc] } + simple_structure = { "name" => [:development] } data = Marshal.dump(simple_structure) expect(Bundler.safe_load_marshal(data)).to eq(simple_structure) end diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb index d28479cf318d3c..1731a2085e41d7 100644 --- a/spec/bundler/bundler/plugin_spec.rb +++ b/spec/bundler/bundler/plugin_spec.rb @@ -225,7 +225,7 @@ end end - describe "#source_from_lock" do + describe "#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 @@ expect(SClass).to receive(:new). with(hash_including("type" => "l_source", "uri" => "xyz", "other" => "random")) { s_instance } - expect(subject.source_from_lock(opts)).to be(s_instance) + expect(subject.from_lock(opts)).to be(s_instance) end end diff --git a/spec/bundler/bundler/ruby_dsl_spec.rb b/spec/bundler/bundler/ruby_dsl_spec.rb index 4af271ad59fff1..6b001615713880 100644 --- a/spec/bundler/bundler/ruby_dsl_spec.rb +++ b/spec/bundler/bundler/ruby_dsl_spec.rb @@ -21,11 +21,13 @@ class MockDSL :engine => engine, :engine_version => engine_version } end + let(:project_root) { Pathname.new("/path/to/project") } + before { allow(Bundler).to receive(:root).and_return(project_root) } let(:invoke) do proc do args = [] - args << Array(ruby_version_arg) if ruby_version_arg + args << ruby_version_arg if ruby_version_arg args << options dsl.ruby(*args) @@ -97,53 +99,67 @@ class MockDSL end context "with a file option" do - let(:options) { { :file => "foo" } } - let(:version) { "3.2.2" } - let(:ruby_version) { "3.2.2" } + let(:file) { ".ruby-version" } + let(:options) do + { :file => file, + :patchlevel => patchlevel, + :engine => engine, + :engine_version => engine_version } + end let(:ruby_version_arg) { nil } - let(:engine_version) { version } - let(:patchlevel) { nil } - let(:engine) { "ruby" } - let(:project_root) { Pathname.new("/path/to/project") } + let(:file_content) { "#{version}\n" } before do - allow(Bundler).to receive(:read_file).with(project_root.join("foo")).and_return("#{version}\n") - allow(Bundler).to receive(:root).and_return(Pathname.new("/path/to/project")) + allow(Bundler).to receive(:read_file).with(project_root.join(file)).and_return(file_content) end it_behaves_like "it stores the ruby version" + 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) { "2.0.0" } + let(:ruby_version_arg) { version } it "raises an error" do - expect { subject }.to raise_error(Bundler::GemfileError, "Cannot specify version when using the file option") + expect { subject }.to raise_error(Bundler::GemfileError, "Do not pass version argument when using :file option") end end - end - context "with a (.tool-versions) file option" do - let(:options) { { :file => "foo" } } - let(:version) { "3.2.2" } - let(:ruby_version) { "3.2.2" } - let(:ruby_version_arg) { nil } - let(:engine_version) { version } - let(:patchlevel) { nil } - let(:engine) { "ruby" } - let(:project_root) { Pathname.new("/path/to/project") } + context "with a @gemset" do + let(:file_content) { "ruby-#{version}@gemset\n" } - before do - allow(Bundler).to receive(:read_file).with(project_root.join("foo")).and_return("nodejs 18.16.0\nruby #{version} # This is a comment\npnpm 8.6.12\n") - allow(Bundler).to receive(:root).and_return(Pathname.new("/path/to/project")) + it "raises an error" do + expect { subject }.to raise_error(Gem::Requirement::BadRequirementError, "Illformed requirement [\"#{version}@gemset\"]") + end end - it_behaves_like "it stores the ruby version" + 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 - context "and a version" do - let(:ruby_version_arg) { "2.0.0" } + it_behaves_like "it stores the ruby version" - it "raises an error" do - expect { subject }.to raise_error(Bundler::GemfileError, "Cannot specify version when using the file option") + 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" end end end diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index 76ea4178aeb415..40d8ebca000e33 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -289,6 +289,47 @@ 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 3.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-3.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" diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb index 045d643a8f6854..f7b41595bedaf2 100644 --- a/spec/bundler/install/deploy_spec.rb +++ b/spec/bundler/install/deploy_spec.rb @@ -11,12 +11,12 @@ 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 Gemfile.lock") + expect(err).to include("The --deployment flag requires a lockfile") 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 Gemfile.lock") + expect(err).to include("The --frozen flag requires a lockfile") end it "disallows --deployment --system" do diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index acaadea6321938..0c87948bb74c93 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -106,7 +106,7 @@ 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)) diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb index 882f2a2d422767..954fd39efeda37 100644 --- a/spec/bundler/install/git_spec.rb +++ b/spec/bundler/install/git_spec.rb @@ -170,5 +170,36 @@ 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/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index ccf23a9e3c2144..5a236dd5d227a6 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -1584,7 +1584,7 @@ def set_lockfile_mtime_to_known_value gem "rack" G - expect(err).to match(/your Gemfile.lock contains merge conflicts/i) + expect(err).to match(/your lockfile contains merge conflicts/i) expect(err).to match(/git checkout HEAD -- Gemfile.lock/i) end diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index f02f81f6974104..5be9c49fef0ada 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -727,6 +727,27 @@ def clean_load_path(lp) 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 diff --git a/spec/ruby/core/kernel/lambda_spec.rb b/spec/ruby/core/kernel/lambda_spec.rb index 2f7abc749cb739..565536ac0d6f5e 100644 --- a/spec/ruby/core/kernel/lambda_spec.rb +++ b/spec/ruby/core/kernel/lambda_spec.rb @@ -26,42 +26,44 @@ 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 + 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 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) + lambda { l.call(:extra) }.should raise_error(ArgumentError) + end 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 + 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 end it "checks the arity of the call when no args are specified" do @@ -137,8 +139,16 @@ def ret end 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") + ruby_version_is ""..."3.3" 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/) + end end it "doesn't warn when proc is lambda" do diff --git a/spec/ruby/core/proc/lambda_spec.rb b/spec/ruby/core/proc/lambda_spec.rb index b2d3f503502463..5c3c38fc2a64c1 100644 --- a/spec/ruby/core/proc/lambda_spec.rb +++ b/spec/ruby/core/proc/lambda_spec.rb @@ -14,9 +14,11 @@ Proc.new {}.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 + 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 end it "is preserved when passing a Proc with & to the proc keyword" do diff --git a/spec/ruby/library/cgi/initialize_spec.rb b/spec/ruby/library/cgi/initialize_spec.rb index f794f157f0871a..61bc971d491604 100644 --- a/spec/ruby/library/cgi/initialize_spec.rb +++ b/spec/ruby/library/cgi/initialize_spec.rb @@ -29,8 +29,8 @@ it "does not extend self with any of the other HTML modules" do @cgi.send(:initialize) - @cgi.should_not be_kind_of(CGI::Html3) @cgi.should_not be_kind_of(CGI::HtmlExtension) + @cgi.should_not be_kind_of(CGI::Html3) @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/string.c b/string.c index bf5d3b3a72cfbf..5e873977118be2 100644 --- a/string.c +++ b/string.c @@ -2992,6 +2992,33 @@ rb_str_set_len(VALUE str, long len) if (len > (capa = (long)str_capacity(str, termlen)) || len < 0) { rb_bug("probable buffer overflow: %ld for %ld", len, capa); } + + int cr = ENC_CODERANGE(str); + if (cr == ENC_CODERANGE_UNKNOWN) { + /* Leave unknown. */ + } + else if (len > RSTRING_LEN(str)) { + if (ENC_CODERANGE_CLEAN_P(cr)) { + /* Update the coderange regarding the extended part. */ + const char *const prev_end = RSTRING_END(str); + const char *const new_end = RSTRING_PTR(str) + len; + rb_encoding *enc = rb_enc_get(str); + rb_str_coderange_scan_restartable(prev_end, new_end, enc, &cr); + ENC_CODERANGE_SET(str, cr); + } + else if (cr == ENC_CODERANGE_BROKEN) { + /* May be valid now, by appended part. */ + ENC_CODERANGE_SET(str, ENC_CODERANGE_UNKNOWN); + } + } + else if (len < RSTRING_LEN(str)) { + if (cr != ENC_CODERANGE_7BIT) { + /* ASCII-only string is keeping after truncated. Valid + * and broken may be invalid or valid, leave unknown. */ + ENC_CODERANGE_SET(str, ENC_CODERANGE_UNKNOWN); + } + } + STR_SET_LEN(str, len); TERM_FILL(&RSTRING_PTR(str)[len], termlen); } @@ -6467,7 +6494,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: * diff --git a/symbol.h b/symbol.h index 4dce618aeb7717..a928a0a78f5500 100644 --- a/symbol.h +++ b/symbol.h @@ -117,10 +117,9 @@ 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/template/Makefile.in b/template/Makefile.in index 893581c4571abd..a3b512b3a86c9b 100644 --- a/template/Makefile.in +++ b/template/Makefile.in @@ -89,6 +89,7 @@ optflags = @optflags@ debugflags = @debugflags@ warnflags = @warnflags@ @strict_warnflags@ cppflags = @cppflags@ +incflags = @incflags@ RUBY_DEVEL = @RUBY_DEVEL@ # "yes" or empty _RUBY_DEVEL_enabled = $(RUBY_DEVEL:no=) XCFLAGS = @XCFLAGS@ $(INCFLAGS) $(_RUBY_DEVEL_enabled:yes=-DRUBY_DEVEL=1) @@ -101,7 +102,6 @@ YJIT_LIBS=@YJIT_LIBS@ YJIT_OBJ=@YJIT_OBJ@ YJIT_LIBOBJ = $(YJIT_LIBS:.a=.@OBJEXT@) CARGO_TARGET_DIR=@abs_top_builddir@/yjit/target -YARP_BUILD_DIR=@abs_top_builddir@/yarp CARGO_BUILD_ARGS=@CARGO_BUILD_ARGS@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@ EXE_LDFLAGS = $(LDFLAGS) diff --git a/test/-ext-/string/test_set_len.rb b/test/-ext-/string/test_set_len.rb index 67ba961194ec4d..e3eff75d9b98cb 100644 --- a/test/-ext-/string/test_set_len.rb +++ b/test/-ext-/string/test_set_len.rb @@ -34,4 +34,33 @@ def test_capacity_equals_to_new_size assert_equal 128, Bug::String.capacity(str) assert_equal 127, str.set_len(127).bytesize, bug12757 end + + def test_coderange_after_append + u = -"\u3042" + str = Bug::String.new(encoding: Encoding::UTF_8) + bsize = u.bytesize + str.append(u) + assert_equal 0, str.bytesize + str.set_len(bsize) + assert_equal bsize, str.bytesize + assert_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + assert_equal u, str + end + + def test_coderange_after_trunc + u = -"\u3042" + bsize = u.bytesize + str = Bug::String.new(u) + str.set_len(bsize - 1) + assert_equal bsize - 1, str.bytesize + assert_not_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + str.append(u.byteslice(-1)) + str.set_len(bsize) + assert_equal bsize, str.bytesize + assert_predicate str, :valid_encoding? + assert_not_predicate str, :ascii_only? + assert_equal u, str + end end diff --git a/test/fiber/test_io.rb b/test/fiber/test_io.rb index c1ad56a8cfe25a..0e3e086d5aee52 100644 --- a/test/fiber/test_io.rb +++ b/test/fiber/test_io.rb @@ -219,4 +219,19 @@ def test_io_select 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/irb/helper.rb b/test/irb/helper.rb index 122eb607f1409a..ede48be6493c3d 100644 --- a/test/irb/helper.rb +++ b/test/irb/helper.rb @@ -110,6 +110,11 @@ def run_ruby_file(&block) yield + # Test should not depend on user's irbrc file + @envs["HOME"] ||= tmp_dir + @envs["XDG_CONFIG_HOME"] ||= tmp_dir + @envs["IRBRC"] = nil unless @envs.key?("IRBRC") + PTY.spawn(@envs.merge("TERM" => "dumb"), *cmd) do |read, write, pid| Timeout.timeout(TIMEOUT_SEC) do while line = safe_gets(read) diff --git a/test/irb/test_cmd.rb b/test/irb/test_cmd.rb index e8c959ec39956f..fd0a02a7afd55e 100644 --- a/test/irb/test_cmd.rb +++ b/test/irb/test_cmd.rb @@ -23,6 +23,9 @@ def setup save_encodings IRB.instance_variable_get(:@CONF).clear @is_win = (RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/) + STDIN.singleton_class.define_method :tty? do + false + end end def teardown @@ -31,6 +34,7 @@ def teardown Dir.chdir(@pwd) FileUtils.rm_rf(@tmpdir) restore_encodings + STDIN.singleton_class.remove_method :tty? end def execute_lines(*lines, conf: {}, main: self, irb_path: nil) @@ -665,16 +669,6 @@ def test_whereami_alias class ShowCmdsTest < CommandTestCase - def setup - STDIN.singleton_class.define_method :tty? do - false - end - end - - def teardown - STDIN.singleton_class.remove_method :tty? - end - def test_show_cmds out, err = execute_lines( "show_cmds\n" @@ -687,16 +681,6 @@ def test_show_cmds end class LsTest < CommandTestCase - def setup - STDIN.singleton_class.define_method :tty? do - false - end - end - - def teardown - STDIN.singleton_class.remove_method :tty? - end - def test_ls out, err = execute_lines( "class P\n", diff --git a/test/irb/test_history.rb b/test/irb/test_history.rb index 15628e66e2d46e..868c05369cb2eb 100644 --- a/test/irb/test_history.rb +++ b/test/irb/test_history.rb @@ -17,8 +17,16 @@ def teardown IRB.conf[:RC_NAME_GENERATOR] = nil end - class TestInputMethodWithHistory < TestInputMethod - HISTORY = Array.new + class TestInputMethodWithRelineHistory < TestInputMethod + # When IRB.conf[:USE_MULTILINE] is true, IRB::RelineInputMethod uses Reline::History + HISTORY = Reline::History.new(Reline.core.config) + + include IRB::HistorySavingAbility + end + + class TestInputMethodWithReadlineHistory < TestInputMethod + # When IRB.conf[:USE_MULTILINE] is false, IRB::ReadlineInputMethod uses Readline::HISTORY + HISTORY = Readline::HISTORY include IRB::HistorySavingAbility end @@ -102,35 +110,16 @@ def test_history_save_minus_as_infinity INPUT end - def test_history_concurrent_use + def test_history_concurrent_use_reline omit "Skip Editline" if /EditLine/n.match(Readline::VERSION) IRB.conf[:SAVE_HISTORY] = 1 - assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT) do |history_file| - exit - 5 - exit - EXPECTED_HISTORY - 1 - 2 - 3 - 4 - INITIAL_HISTORY - 5 - exit - INPUT - assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2) - exit - EXPECTED_HISTORY2 - 1 - 2 - 3 - 4 - INITIAL_HISTORY2 - 5 - exit - INPUT2 - File.utime(File.atime(history_file), File.mtime(history_file) + 2, history_file) - end + history_concurrent_use_for_input_method(TestInputMethodWithRelineHistory) + end + + def test_history_concurrent_use_readline + omit "Skip Editline" if /EditLine/n.match(Readline::VERSION) + IRB.conf[:SAVE_HISTORY] = 1 + history_concurrent_use_for_input_method(TestInputMethodWithReadlineHistory) end def test_history_concurrent_use_not_present @@ -141,10 +130,11 @@ def test_history_concurrent_use_not_present IRB.conf[:SAVE_HISTORY] = 1 Dir.mktmpdir("test_irb_history_") do |tmpdir| ENV["HOME"] = tmpdir - io = TestInputMethodWithHistory.new + io = TestInputMethodWithRelineHistory.new io.class::HISTORY.clear io.load_history - io.class::HISTORY.concat(%w"line1 line2") + io.class::HISTORY << 'line1' + io.class::HISTORY << 'line2' history_file = IRB.rc_file("_history") assert_not_send [File, :file?, history_file] @@ -160,7 +150,36 @@ def test_history_concurrent_use_not_present private - def assert_history(expected_history, initial_irb_history, input) + def history_concurrent_use_for_input_method(input_method) + assert_history(<<~EXPECTED_HISTORY, <<~INITIAL_HISTORY, <<~INPUT, input_method) do |history_file| + exit + 5 + exit + EXPECTED_HISTORY + 1 + 2 + 3 + 4 + INITIAL_HISTORY + 5 + exit + INPUT + assert_history(<<~EXPECTED_HISTORY2, <<~INITIAL_HISTORY2, <<~INPUT2, input_method) + exit + EXPECTED_HISTORY2 + 1 + 2 + 3 + 4 + INITIAL_HISTORY2 + 5 + exit + INPUT2 + File.utime(File.atime(history_file), File.mtime(history_file) + 2, history_file) + end + end + + def assert_history(expected_history, initial_irb_history, input, input_method = TestInputMethodWithRelineHistory) backup_verbose, $VERBOSE = $VERBOSE, nil backup_home = ENV["HOME"] backup_xdg_config_home = ENV.delete("XDG_CONFIG_HOME") @@ -172,15 +191,17 @@ def assert_history(expected_history, initial_irb_history, input) f.write(initial_irb_history) end - io = TestInputMethodWithHistory.new + io = input_method.new io.class::HISTORY.clear io.load_history if block_given? - history = io.class::HISTORY.dup + previous_history = [] + io.class::HISTORY.each { |line| previous_history << line } yield IRB.rc_file("_history") - io.class::HISTORY.replace(history) + io.class::HISTORY.clear + previous_history.each { |line| io.class::HISTORY << line } end - io.class::HISTORY.concat(input.split) + input.split.each { |line| io.class::HISTORY << line } io.save_history io.load_history diff --git a/test/irb/test_irb.rb b/test/irb/test_irb.rb index 08fe41f5e7854e..0c77bb0f76cf1b 100644 --- a/test/irb/test_irb.rb +++ b/test/irb/test_irb.rb @@ -6,6 +6,11 @@ module TestIRB class InputTest < IntegrationTestCase def test_symbol_aliases_are_handled_correctly + write_rc <<~RUBY + # disable pager + STDIN.singleton_class.define_method(:tty?) { false } + RUBY + write_ruby <<~'RUBY' class Foo end @@ -21,12 +26,11 @@ class Foo end def test_symbol_aliases_are_handled_correctly_with_singleline_mode - @irbrc = Tempfile.new('irbrc') - @irbrc.write <<~RUBY + write_rc <<~RUBY + # disable pager + STDIN.singleton_class.define_method(:tty?) { false } IRB.conf[:USE_SINGLELINE] = true RUBY - @irbrc.close - @envs['IRBRC'] = @irbrc.path write_ruby <<~'RUBY' class Foo @@ -43,8 +47,6 @@ class Foo # Make sure it's tested in singleline mode assert_include output, "InputMethod: ReadlineInputMethod" assert_include output, "From: #{@ruby_file.path}:1" - ensure - @irbrc.unlink if @irbrc end def test_symbol_aliases_dont_affect_ruby_syntax diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 5f0101d5f68e82..20f652dc9ddd7f 100755 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -395,7 +395,7 @@ def to_s; self; end def test_string_ext_included_calls_super included = false - Module.alias_method(:included_orig, :included) + Module.send(:alias_method, :included_orig, :included) Module.remove_method(:included) Module.define_method(:included) do |base| included_orig(base) @@ -410,7 +410,7 @@ def test_string_ext_included_calls_super ensure if Module.private_method_defined?(:included_orig) Module.remove_method(:included) if Module.method_defined?(:included) - Module.alias_method(:included, :included_orig) + Module.send(:alias_method, :included, :included_orig) Module.remove_method(:included_orig) end end diff --git a/test/openssl/test_fips.rb b/test/openssl/test_fips.rb index 43042beab866ed..4a3dd43a4183a0 100644 --- a/test/openssl/test_fips.rb +++ b/test/openssl/test_fips.rb @@ -28,8 +28,10 @@ def test_fips_mode_get_is_false_on_fips_mode_disabled end def test_fips_mode_is_reentrant - OpenSSL.fips_mode = false - OpenSSL.fips_mode = false + assert_separately(["-ropenssl"], <<~"end;") + OpenSSL.fips_mode = false + OpenSSL.fips_mode = false + end; end def test_fips_mode_get_with_fips_mode_set diff --git a/test/openssl/test_pkey.rb b/test/openssl/test_pkey.rb index 5fe37e2d6426d1..aee0546f63f2ff 100644 --- a/test/openssl/test_pkey.rb +++ b/test/openssl/test_pkey.rb @@ -82,6 +82,9 @@ def test_hmac_sign_verify 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----- @@ -96,15 +99,11 @@ def test_ed25519 begin priv = OpenSSL::PKey.read(priv_pem) pub = OpenSSL::PKey.read(pub_pem) - rescue OpenSSL::PKey::PKeyError + rescue OpenSSL::PKey::PKeyError => e # OpenSSL < 1.1.1 - if !openssl?(1, 1, 1) - pend "Ed25519 is not implemented" - elsif OpenSSL.fips_mode && openssl?(3, 1, 0, 0) - # See OpenSSL providers/fips/fipsprov.c PROV_NAMES_ED25519 entries - # with FIPS_UNAPPROVED_PROPERTIES in OpenSSL 3.1+. - pend "Ed25519 is not approved in OpenSSL 3.1+ FIPS code" - end + pend "Ed25519 is not implemented" unless openssl?(1, 1, 1) + + raise e end assert_instance_of OpenSSL::PKey::PKey, priv assert_instance_of OpenSSL::PKey::PKey, pub @@ -145,6 +144,32 @@ def test_ed25519 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 diff --git a/test/openssl/test_pkey_ec.rb b/test/openssl/test_pkey_ec.rb index 126c1347cf22c9..2cb8e287ab71e5 100644 --- a/test/openssl/test_pkey_ec.rb +++ b/test/openssl/test_pkey_ec.rb @@ -229,6 +229,8 @@ def test_ECPrivateKey_with_parameters end def test_ECPrivateKey_encrypted + omit_on_fips + p256 = Fixtures.pkey("p256") # key = abcdef pem = <<~EOF diff --git a/test/openssl/utils.rb b/test/openssl/utils.rb index 3856bea875d5e7..cd70d4886f614e 100644 --- a/test/openssl/utils.rb +++ b/test/openssl/utils.rb @@ -139,6 +139,26 @@ def teardown # 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 'An encryption used in the test is not FIPS-approved' + 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/ostruct/test_ostruct.rb b/test/ostruct/test_ostruct.rb index 256db7a0c71203..19bb606145762d 100644 --- a/test/ostruct/test_ostruct.rb +++ b/test/ostruct/test_ostruct.rb @@ -412,4 +412,23 @@ def test_class 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/yarp/bom_test.rb b/test/prism/bom_test.rb similarity index 92% rename from test/yarp/bom_test.rb rename to test/prism/bom_test.rb index 3a4e04a900afd2..1525caf458dc12 100644 --- a/test/yarp/bom_test.rb +++ b/test/prism/bom_test.rb @@ -6,7 +6,7 @@ require_relative "test_helper" -module YARP +module Prism class BOMTest < TestCase def test_ident assert_bom("foo") @@ -53,7 +53,7 @@ def test_string def assert_bom(source) bommed = "\xEF\xBB\xBF#{source}" - assert_equal YARP.lex_ripper(bommed), YARP.lex_compat(bommed).value + 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 new file mode 100644 index 00000000000000..0748beb39129fd --- /dev/null +++ b/test/prism/comments_test.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require_relative "test_helper" + +module Prism + class CommentsTest < TestCase + def test_comment_inline + source = "# comment" + + assert_comment source, :inline, [0, 9, 1, 1, 0, 9] + assert_equal [0], Debug.newlines(source) + end + + def test_comment_inline_def + source = <<~RUBY + def foo + # a comment + end + RUBY + + assert_comment source, :inline, [10, 21, 2, 2, 2, 13] + end + + def test_comment___END__ + source = <<~RUBY + __END__ + comment + RUBY + + assert_comment source, :__END__, [0, 16, 1, 2, 0, 0] + end + + def test_comment___END__crlf + source = "__END__\r\ncomment\r\n" + + assert_comment source, :__END__, [0, 18, 1, 2, 0, 0] + end + + def test_comment_embedded_document + source = <<~RUBY + =begin + comment + =end + RUBY + + assert_comment source, :embdoc, [0, 20, 1, 3, 0, 0] + end + + def test_comment_embedded_document_with_content_on_same_line + source = <<~RUBY + =begin other stuff + =end + RUBY + + assert_comment source, :embdoc, [0, 24, 1, 2, 0, 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, locations) + start_offset, end_offset, start_line, end_line, start_column, end_column = locations + expected = { + start_offset: start_offset, + end_offset: end_offset, + start_line: start_line, + end_line: end_line, + start_column: start_column, + end_column: end_column + } + + result = Prism.parse(source) + assert result.errors.empty?, result.errors.map(&:message).join("\n") + assert_equal type, result.comments.first.type + + first_comment_location = result.comments.first.location + + actual = { + start_offset: first_comment_location.start_offset, + end_offset: first_comment_location.end_offset, + start_line: first_comment_location.start_line, + end_line: first_comment_location.end_line, + start_column: first_comment_location.start_column, + end_column: first_comment_location.end_column + } + + assert_equal expected, actual + end + end +end diff --git a/test/prism/compiler_test.rb b/test/prism/compiler_test.rb new file mode 100644 index 00000000000000..ed028d03d89486 --- /dev/null +++ b/test/prism/compiler_test.rb @@ -0,0 +1,30 @@ +# 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/desugar_compiler_test.rb b/test/prism/desugar_compiler_test.rb new file mode 100644 index 00000000000000..c72e141c6b7a3f --- /dev/null +++ b/test/prism/desugar_compiler_test.rb @@ -0,0 +1,86 @@ +# 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 new file mode 100644 index 00000000000000..0d8a6d35e90ae7 --- /dev/null +++ b/test/prism/dispatcher_test.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require_relative "test_helper" + +module Prism + class DispatcherTest < TestCase + class TestListener + attr_reader :events_received + + def initialize + @events_received = [] + end + + def on_call_node_enter(node) + events_received << :on_call_node_enter + end + + def on_call_node_leave(node) + events_received << :on_call_node_leave + end + + def on_integer_node_enter(node) + events_received << :on_integer_node_enter + end + end + + def test_dispatching_events + listener = TestListener.new + dispatcher = Dispatcher.new + dispatcher.register(listener, :on_call_node_enter, :on_call_node_leave, :on_integer_node_enter) + + root = Prism.parse(<<~RUBY).value + def foo + something(1, 2, 3) + end + RUBY + + dispatcher.dispatch(root) + assert_equal([:on_call_node_enter, :on_integer_node_enter, :on_integer_node_enter, :on_integer_node_enter, :on_call_node_leave], listener.events_received) + + listener.events_received.clear + dispatcher.dispatch_once(root.statements.body.first.body.body.first) + assert_equal([:on_call_node_enter, :on_call_node_leave], listener.events_received) + end + end +end diff --git a/test/yarp/encoding_test.rb b/test/prism/encoding_test.rb similarity index 81% rename from test/yarp/encoding_test.rb rename to test/prism/encoding_test.rb index 8427bddcbefa58..b2e602b286062c 100644 --- a/test/yarp/encoding_test.rb +++ b/test/prism/encoding_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class EncodingTest < TestCase %w[ ascii @@ -39,27 +39,27 @@ class EncodingTest < TestCase CP1252 ].each do |encoding| define_method "test_encoding_#{encoding}" do - result = YARP.parse("# encoding: #{encoding}\nident") + result = Prism.parse("# encoding: #{encoding}\nident") actual = result.value.statements.body.first.name.encoding assert_equal Encoding.find(encoding), actual end end def test_coding - result = YARP.parse("# coding: utf-8\nident") + result = Prism.parse("# coding: utf-8\nident") actual = result.value.statements.body.first.name.encoding assert_equal Encoding.find("utf-8"), actual end def test_coding_with_whitespace - result = YARP.parse("# coding \t \r \v : \t \v \r ascii-8bit \nident") + result = Prism.parse("# coding \t \r \v : \t \v \r ascii-8bit \nident") actual = result.value.statements.body.first.name.encoding assert_equal Encoding.find("ascii-8bit"), actual end def test_emacs_style - result = YARP.parse("# -*- coding: utf-8 -*-\nident") + result = Prism.parse("# -*- coding: utf-8 -*-\nident") actual = result.value.statements.body.first.name.encoding assert_equal Encoding.find("utf-8"), actual end @@ -67,7 +67,7 @@ def test_emacs_style # 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 = YARP.parse(<<~RUBY) + result = Prism.parse(<<~RUBY) # encoding: Shift_JIS %w[\x81\x5c] RUBY @@ -86,19 +86,19 @@ def test_utf_8_variations utf-8-mac utf-8-* ].each do |encoding| - result = YARP.parse("# coding: #{encoding}\nident") + result = Prism.parse("# coding: #{encoding}\nident") actual = result.value.statements.body.first.name.encoding assert_equal Encoding.find("utf-8"), actual end end def test_first_lexed_token - encoding = YARP.lex("# encoding: ascii-8bit").value[0][0].value.encoding + encoding = Prism.lex("# encoding: ascii-8bit").value[0][0].value.encoding assert_equal Encoding.find("ascii-8bit"), encoding end def test_slice_encoding - slice = YARP.parse("# encoding: Shift_JIS\nア").value.slice + 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 diff --git a/test/yarp/errors_test.rb b/test/prism/errors_test.rb similarity index 75% rename from test/yarp/errors_test.rb rename to test/prism/errors_test.rb index 61955d612f6969..a101dfa87e6b44 100644 --- a/test/yarp/errors_test.rb +++ b/test/prism/errors_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class ErrorsTest < TestCase include DSL @@ -42,7 +42,7 @@ def test_for_loops_index_missing ) assert_errors expected, "for in 1..10\ni\nend", [ - ["Expected an index after `for`", 0..0] + ["Expected an index after `for`", 0..3] ] end @@ -58,7 +58,7 @@ def test_for_loops_only_end ) assert_errors expected, "for end", [ - ["Expected an index after `for`", 0..0], + ["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] ] @@ -152,6 +152,13 @@ def test_unterminated_string ] 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", 3..3] @@ -160,11 +167,18 @@ def test_unterminated_s_symbol 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], @@ -172,6 +186,12 @@ def test_unterminated_argument_expression ] 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], @@ -180,6 +200,7 @@ def test_cr_without_lf_in_percent_expression 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], @@ -187,16 +208,17 @@ def test_1_2_3 ["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], + ["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", + "Cannot parse the expression" ] end @@ -208,10 +230,11 @@ def test_return_1 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], + ["Cannot parse the expression", 12..12] ] end @@ -223,10 +246,11 @@ def test_next_1 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], + ["Cannot parse the expression", 13..13] ] end @@ -283,7 +307,8 @@ def test_aliasing_global_variable_with_global_number_variable 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 `.` or `::` after the receiver in a method definition", 7..7], + ["Expected a method name", 7..7] ] end @@ -291,6 +316,7 @@ 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] ] @@ -338,12 +364,9 @@ def test_arguments_after_block nil, Location(), Location(), - ArgumentsNode([ - BlockArgumentNode(expression("block"), Location()), - expression("foo") - ]), + ArgumentsNode([expression("foo")]), Location(), - nil, + BlockArgumentNode(expression("block"), Location()), 0, "a" ) @@ -494,7 +517,7 @@ def test_bad_arguments RequiredParameterNode(:@a), RequiredParameterNode(:$A), RequiredParameterNode(:@@a), - ], [], [], nil, [], nil, nil), + ], [], nil, [], [], nil, nil), nil, [:A, :@a, :$A, :@@a], Location(), @@ -560,9 +583,9 @@ def test_do_not_allow_trailing_commas_in_method_parameters ParametersNode( [RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:c)], [], - [], nil, [], + [], nil, nil ), @@ -588,7 +611,7 @@ def test_do_not_allow_trailing_commas_in_lambda_parameters Location(), Location(), BlockParametersNode( - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], nil, nil), [], Location(), Location() @@ -601,7 +624,7 @@ def test_do_not_allow_trailing_commas_in_lambda_parameters end def test_do_not_allow_multiple_codepoints_in_a_single_character_literal - expected = StringNode(Location(), Location(), nil, "\u0001\u0002") + expected = StringNode(0, 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] @@ -615,7 +638,7 @@ def test_invalid_hex_escape end def test_do_not_allow_more_than_6_hexadecimal_digits_in_u_Unicode_character_notation - expected = StringNode(Location(), Location(), Location(), "\u0001") + expected = StringNode(0, Location(), Location(), Location(), "\u0001") assert_errors expected, '"\u{0000001}"', [ ["Invalid Unicode escape sequence; maximum length is 6 digits", 4..11], @@ -623,7 +646,7 @@ def test_do_not_allow_more_than_6_hexadecimal_digits_in_u_Unicode_character_nota end def test_do_not_allow_characters_other_than_0_9_a_f_and_A_F_in_u_Unicode_character_notation - expected = StringNode(Location(), Location(), Location(), "\u0000z}") + expected = StringNode(0, Location(), Location(), Location(), "\u0000z}") assert_errors expected, '"\u{000z}"', [ ["Invalid Unicode escape sequence", 7..7], @@ -644,8 +667,8 @@ def test_method_parameters_after_block ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [], nil, BlockParameterNode(:block, Location(), Location()) @@ -669,7 +692,7 @@ def test_method_with_arguments_after_anonymous_block :foo, Location(), nil, - ParametersNode([], [], [RequiredParameterNode(:a)], nil, [], nil, BlockParameterNode(nil, nil, Location())), + ParametersNode([], [], nil, [RequiredParameterNode(:a)], [], nil, BlockParameterNode(nil, nil, Location())), nil, [:&, :a], Location(), @@ -693,8 +716,8 @@ def test_method_parameters_after_arguments_forwarding ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [], ForwardingParameterNode(), nil @@ -721,8 +744,8 @@ def test_keywords_parameters_before_required_parameters ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [KeywordParameterNode(:b, Location(), nil)], nil, nil @@ -747,10 +770,10 @@ def test_rest_keywords_parameters_before_required_parameters Location(), nil, ParametersNode( - [], [], [], nil, + [], [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(:rest, Location(), Location()), nil @@ -775,7 +798,7 @@ def test_double_arguments_forwarding :foo, Location(), nil, - ParametersNode([], [], [], nil, [], ForwardingParameterNode(), nil), + ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), nil, [:"..."], Location(), @@ -799,8 +822,8 @@ def test_multiple_error_in_parameters_order ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(:args, Location(), Location()), nil @@ -829,8 +852,8 @@ def test_switching_to_optional_arguments_twice ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(:args, Location(), Location()), nil @@ -859,8 +882,8 @@ def test_switching_to_named_arguments_twice ParametersNode( [], [], - [RequiredParameterNode(:a)], nil, + [RequiredParameterNode(:a)], [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(:args, Location(), Location()), nil @@ -889,11 +912,11 @@ def test_returning_to_optional_parameters_multiple_times ParametersNode( [RequiredParameterNode(:a)], [ - OptionalParameterNode(:b, Location(), Location(), IntegerNode()), - OptionalParameterNode(:d, Location(), Location(), IntegerNode()) + OptionalParameterNode(:b, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL)), + OptionalParameterNode(:d, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL)) ], - [RequiredParameterNode(:c), RequiredParameterNode(:e)], nil, + [RequiredParameterNode(:c), RequiredParameterNode(:e)], [], nil, nil @@ -923,7 +946,21 @@ def test_case_without_when_clauses_errors_on_else_clause ) assert_errors expected, "case :a\nelse\nend", [ - ["Unexpected `else` in `case` statement; a `when` clause must precede `else`", 8..12] + ["Expected a `when` or `in` clause after `case`", 0..4] + ] + end + + def test_case_without_clauses + expected = CaseNode( + SymbolNode(Location(), Location(), nil, "a"), + [], + nil, + Location(), + Location() + ) + + assert_errors expected, "case :a\nend", [ + ["Expected a `when` or `in` clause after `case`", 0..4] ] end @@ -933,7 +970,7 @@ def test_setter_method_cannot_be_defined_in_an_endless_method_definition Location(), nil, nil, - StatementsNode([IntegerNode()]), + StatementsNode([IntegerNode(IntegerBaseFlags::DECIMAL)]), [], Location(), nil, @@ -954,7 +991,7 @@ def test_do_not_allow_forward_arguments_in_lambda_literals Location(), Location(), Location(), - BlockParametersNode(ParametersNode([], [], [], nil, [], ForwardingParameterNode(), nil), [], Location(), Location()), + BlockParametersNode(ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), [], Location(), Location()), nil ) @@ -973,7 +1010,7 @@ def test_do_not_allow_forward_arguments_in_blocks nil, BlockNode( [:"..."], - BlockParametersNode(ParametersNode([], [], [], nil, [], ForwardingParameterNode(), nil), [], Location(), Location()), + BlockParametersNode(ParametersNode([], [], nil, [], [], ForwardingParameterNode(), nil), [], Location(), Location()), nil, Location(), Location() @@ -1046,7 +1083,7 @@ def test_duplicated_parameter_names :foo, Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], [], nil, [], nil, nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], nil, [], [], nil, nil), nil, [:a, :b], Location(), @@ -1066,7 +1103,7 @@ def test_duplicated_parameter_names :foo, Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], RestParameterNode(:a, Location(), Location()), [], nil, nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], RestParameterNode(:a, Location(), Location()), [], [], nil, nil), nil, [:a, :b], Location(), @@ -1085,7 +1122,7 @@ def test_duplicated_parameter_names :foo, Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], KeywordRestParameterNode(:a, Location(), Location()), nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], KeywordRestParameterNode(:a, Location(), Location()), nil), nil, [:a, :b], Location(), @@ -1104,7 +1141,7 @@ def test_duplicated_parameter_names :foo, Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, BlockParameterNode(:a, Location(), Location())), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], nil, [], [], nil, BlockParameterNode(:a, Location(), Location())), nil, [:a, :b], Location(), @@ -1123,7 +1160,7 @@ def test_duplicated_parameter_names :foo, Location(), nil, - ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode())], [RequiredParameterNode(:b)], RestParameterNode(:c, Location(), Location()), [], nil, nil), + ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode(IntegerBaseFlags::DECIMAL))], RestParameterNode(:c, Location(), Location()), [RequiredParameterNode(:b)], [], nil, nil), nil, [:a, :b, :c], Location(), @@ -1137,33 +1174,216 @@ def test_duplicated_parameter_names 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..3] + ] + 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 + 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_writing_numbered_parameter + assert_errors expression("-> { _1 = 0 }"), "-> { _1 = 0 }", [ + ["Token reserved for a numbered parameter", 5..7] + ] + end + + def test_targeting_numbered_parameter + assert_errors expression("-> { _1, = 0 }"), "-> { _1, = 0 }", [ + ["Token reserved for a numbered parameter", 5..7] + ] + 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, [ + ["Token reserved for a numbered parameter", 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 + private - def assert_errors(expected, source, errors) + 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 RUBY_ENGINE == "ruby" + assert_nil Ripper.sexp_raw(source) if compare_ripper - result = YARP.parse(source) + 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) - assert_nil Ripper.sexp_raw(source) - result = YARP.parse(source) + 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 expression(source) - YARP.parse(source).value.statements.body.last + Prism.parse(source).value.statements.body.last end end end diff --git a/test/yarp/fixtures/alias.txt b/test/prism/fixtures/alias.txt similarity index 100% rename from test/yarp/fixtures/alias.txt rename to test/prism/fixtures/alias.txt diff --git a/test/prism/fixtures/arithmetic.txt b/test/prism/fixtures/arithmetic.txt new file mode 100644 index 00000000000000..b1e1267b95c2de --- /dev/null +++ b/test/prism/fixtures/arithmetic.txt @@ -0,0 +1,13 @@ +foo !bar + +-foo*bar + ++foo**bar + +foo ~bar + +foo << bar << baz + +-1**2 + +-1.zero? diff --git a/test/yarp/fixtures/arrays.txt b/test/prism/fixtures/arrays.txt similarity index 100% rename from test/yarp/fixtures/arrays.txt rename to test/prism/fixtures/arrays.txt diff --git a/test/yarp/fixtures/begin_ensure.txt b/test/prism/fixtures/begin_ensure.txt similarity index 100% rename from test/yarp/fixtures/begin_ensure.txt rename to test/prism/fixtures/begin_ensure.txt diff --git a/test/yarp/fixtures/begin_rescue.txt b/test/prism/fixtures/begin_rescue.txt similarity index 100% rename from test/yarp/fixtures/begin_rescue.txt rename to test/prism/fixtures/begin_rescue.txt diff --git a/test/yarp/fixtures/blocks.txt b/test/prism/fixtures/blocks.txt similarity index 100% rename from test/yarp/fixtures/blocks.txt rename to test/prism/fixtures/blocks.txt diff --git a/test/yarp/fixtures/boolean_operators.txt b/test/prism/fixtures/boolean_operators.txt similarity index 100% rename from test/yarp/fixtures/boolean_operators.txt rename to test/prism/fixtures/boolean_operators.txt diff --git a/test/yarp/fixtures/booleans.txt b/test/prism/fixtures/booleans.txt similarity index 100% rename from test/yarp/fixtures/booleans.txt rename to test/prism/fixtures/booleans.txt diff --git a/test/yarp/fixtures/break.txt b/test/prism/fixtures/break.txt similarity index 100% rename from test/yarp/fixtures/break.txt rename to test/prism/fixtures/break.txt diff --git a/test/prism/fixtures/case.txt b/test/prism/fixtures/case.txt new file mode 100644 index 00000000000000..1b720bc5ac0c89 --- /dev/null +++ b/test/prism/fixtures/case.txt @@ -0,0 +1,32 @@ +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 diff --git a/test/yarp/fixtures/classes.txt b/test/prism/fixtures/classes.txt similarity index 100% rename from test/yarp/fixtures/classes.txt rename to test/prism/fixtures/classes.txt diff --git a/test/yarp/fixtures/comments.txt b/test/prism/fixtures/comments.txt similarity index 100% rename from test/yarp/fixtures/comments.txt rename to test/prism/fixtures/comments.txt diff --git a/test/yarp/fixtures/constants.txt b/test/prism/fixtures/constants.txt similarity index 100% rename from test/yarp/fixtures/constants.txt rename to test/prism/fixtures/constants.txt diff --git a/test/yarp/fixtures/dash_heredocs.txt b/test/prism/fixtures/dash_heredocs.txt similarity index 100% rename from test/yarp/fixtures/dash_heredocs.txt rename to test/prism/fixtures/dash_heredocs.txt diff --git a/test/yarp/fixtures/defined.txt b/test/prism/fixtures/defined.txt similarity index 100% rename from test/yarp/fixtures/defined.txt rename to test/prism/fixtures/defined.txt diff --git a/test/yarp/fixtures/dos_endings.txt b/test/prism/fixtures/dos_endings.txt similarity index 100% rename from test/yarp/fixtures/dos_endings.txt rename to test/prism/fixtures/dos_endings.txt diff --git a/test/yarp/fixtures/embdoc_no_newline_at_end.txt b/test/prism/fixtures/embdoc_no_newline_at_end.txt similarity index 100% rename from test/yarp/fixtures/embdoc_no_newline_at_end.txt rename to test/prism/fixtures/embdoc_no_newline_at_end.txt diff --git a/test/yarp/fixtures/endless_methods.txt b/test/prism/fixtures/endless_methods.txt similarity index 100% rename from test/yarp/fixtures/endless_methods.txt rename to test/prism/fixtures/endless_methods.txt diff --git a/test/yarp/fixtures/endless_range_in_conditional.txt b/test/prism/fixtures/endless_range_in_conditional.txt similarity index 100% rename from test/yarp/fixtures/endless_range_in_conditional.txt rename to test/prism/fixtures/endless_range_in_conditional.txt diff --git a/test/yarp/fixtures/for.txt b/test/prism/fixtures/for.txt similarity index 100% rename from test/yarp/fixtures/for.txt rename to test/prism/fixtures/for.txt diff --git a/test/yarp/fixtures/global_variables.txt b/test/prism/fixtures/global_variables.txt similarity index 100% rename from test/yarp/fixtures/global_variables.txt rename to test/prism/fixtures/global_variables.txt diff --git a/test/prism/fixtures/hashes.txt b/test/prism/fixtures/hashes.txt new file mode 100644 index 00000000000000..443b2359c62c02 --- /dev/null +++ b/test/prism/fixtures/hashes.txt @@ -0,0 +1,26 @@ +{} + +{ +} + +{ 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/yarp/fixtures/heredoc_with_escaped_newline_at_start.txt b/test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt similarity index 100% rename from test/yarp/fixtures/heredoc_with_escaped_newline_at_start.txt rename to test/prism/fixtures/heredoc_with_escaped_newline_at_start.txt diff --git a/test/yarp/fixtures/heredoc_with_trailing_newline.txt b/test/prism/fixtures/heredoc_with_trailing_newline.txt similarity index 100% rename from test/yarp/fixtures/heredoc_with_trailing_newline.txt rename to test/prism/fixtures/heredoc_with_trailing_newline.txt diff --git a/test/yarp/fixtures/heredocs_nested.txt b/test/prism/fixtures/heredocs_nested.txt similarity index 100% rename from test/yarp/fixtures/heredocs_nested.txt rename to test/prism/fixtures/heredocs_nested.txt diff --git a/test/yarp/fixtures/heredocs_with_ignored_newlines.txt b/test/prism/fixtures/heredocs_with_ignored_newlines.txt similarity index 100% rename from test/yarp/fixtures/heredocs_with_ignored_newlines.txt rename to test/prism/fixtures/heredocs_with_ignored_newlines.txt diff --git a/test/yarp/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt b/test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt similarity index 100% rename from test/yarp/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt rename to test/prism/fixtures/heredocs_with_ignored_newlines_and_non_empty.txt diff --git a/test/yarp/fixtures/if.txt b/test/prism/fixtures/if.txt similarity index 100% rename from test/yarp/fixtures/if.txt rename to test/prism/fixtures/if.txt diff --git a/test/yarp/fixtures/indented_file_end.txt b/test/prism/fixtures/indented_file_end.txt similarity index 100% rename from test/yarp/fixtures/indented_file_end.txt rename to test/prism/fixtures/indented_file_end.txt diff --git a/test/yarp/fixtures/integer_operations.txt b/test/prism/fixtures/integer_operations.txt similarity index 100% rename from test/yarp/fixtures/integer_operations.txt rename to test/prism/fixtures/integer_operations.txt diff --git a/test/yarp/fixtures/keyword_method_names.txt b/test/prism/fixtures/keyword_method_names.txt similarity index 100% rename from test/yarp/fixtures/keyword_method_names.txt rename to test/prism/fixtures/keyword_method_names.txt diff --git a/test/yarp/fixtures/keywords.txt b/test/prism/fixtures/keywords.txt similarity index 100% rename from test/yarp/fixtures/keywords.txt rename to test/prism/fixtures/keywords.txt diff --git a/test/yarp/fixtures/lambda.txt b/test/prism/fixtures/lambda.txt similarity index 100% rename from test/yarp/fixtures/lambda.txt rename to test/prism/fixtures/lambda.txt diff --git a/test/yarp/fixtures/method_calls.txt b/test/prism/fixtures/method_calls.txt similarity index 100% rename from test/yarp/fixtures/method_calls.txt rename to test/prism/fixtures/method_calls.txt diff --git a/test/prism/fixtures/methods.txt b/test/prism/fixtures/methods.txt new file mode 100644 index 00000000000000..ac561363f89142 --- /dev/null +++ b/test/prism/fixtures/methods.txt @@ -0,0 +1,168 @@ +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 diff --git a/test/yarp/fixtures/modules.txt b/test/prism/fixtures/modules.txt similarity index 100% rename from test/yarp/fixtures/modules.txt rename to test/prism/fixtures/modules.txt diff --git a/test/yarp/fixtures/newline_terminated.txt b/test/prism/fixtures/newline_terminated.txt similarity index 100% rename from test/yarp/fixtures/newline_terminated.txt rename to test/prism/fixtures/newline_terminated.txt diff --git a/test/yarp/fixtures/next.txt b/test/prism/fixtures/next.txt similarity index 100% rename from test/yarp/fixtures/next.txt rename to test/prism/fixtures/next.txt diff --git a/test/yarp/fixtures/nils.txt b/test/prism/fixtures/nils.txt similarity index 100% rename from test/yarp/fixtures/nils.txt rename to test/prism/fixtures/nils.txt diff --git a/test/yarp/fixtures/non_alphanumeric_methods.txt b/test/prism/fixtures/non_alphanumeric_methods.txt similarity index 100% rename from test/yarp/fixtures/non_alphanumeric_methods.txt rename to test/prism/fixtures/non_alphanumeric_methods.txt diff --git a/test/yarp/fixtures/not.txt b/test/prism/fixtures/not.txt similarity index 100% rename from test/yarp/fixtures/not.txt rename to test/prism/fixtures/not.txt diff --git a/test/yarp/fixtures/numbers.txt b/test/prism/fixtures/numbers.txt similarity index 100% rename from test/yarp/fixtures/numbers.txt rename to test/prism/fixtures/numbers.txt diff --git a/test/yarp/fixtures/patterns.txt b/test/prism/fixtures/patterns.txt similarity index 100% rename from test/yarp/fixtures/patterns.txt rename to test/prism/fixtures/patterns.txt diff --git a/test/yarp/fixtures/procs.txt b/test/prism/fixtures/procs.txt similarity index 100% rename from test/yarp/fixtures/procs.txt rename to test/prism/fixtures/procs.txt diff --git a/test/yarp/fixtures/range_begin_open_exclusive.txt b/test/prism/fixtures/range_begin_open_exclusive.txt similarity index 100% rename from test/yarp/fixtures/range_begin_open_exclusive.txt rename to test/prism/fixtures/range_begin_open_exclusive.txt diff --git a/test/yarp/fixtures/range_begin_open_inclusive.txt b/test/prism/fixtures/range_begin_open_inclusive.txt similarity index 100% rename from test/yarp/fixtures/range_begin_open_inclusive.txt rename to test/prism/fixtures/range_begin_open_inclusive.txt diff --git a/test/yarp/fixtures/range_end_open_exclusive.txt b/test/prism/fixtures/range_end_open_exclusive.txt similarity index 100% rename from test/yarp/fixtures/range_end_open_exclusive.txt rename to test/prism/fixtures/range_end_open_exclusive.txt diff --git a/test/yarp/fixtures/range_end_open_inclusive.txt b/test/prism/fixtures/range_end_open_inclusive.txt similarity index 100% rename from test/yarp/fixtures/range_end_open_inclusive.txt rename to test/prism/fixtures/range_end_open_inclusive.txt diff --git a/test/yarp/fixtures/ranges.txt b/test/prism/fixtures/ranges.txt similarity index 100% rename from test/yarp/fixtures/ranges.txt rename to test/prism/fixtures/ranges.txt diff --git a/test/yarp/fixtures/regex.txt b/test/prism/fixtures/regex.txt similarity index 100% rename from test/yarp/fixtures/regex.txt rename to test/prism/fixtures/regex.txt diff --git a/test/yarp/fixtures/rescue.txt b/test/prism/fixtures/rescue.txt similarity index 100% rename from test/yarp/fixtures/rescue.txt rename to test/prism/fixtures/rescue.txt diff --git a/test/yarp/fixtures/return.txt b/test/prism/fixtures/return.txt similarity index 100% rename from test/yarp/fixtures/return.txt rename to test/prism/fixtures/return.txt diff --git a/test/yarp/fixtures/seattlerb/BEGIN.txt b/test/prism/fixtures/seattlerb/BEGIN.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/BEGIN.txt rename to test/prism/fixtures/seattlerb/BEGIN.txt diff --git a/test/yarp/fixtures/seattlerb/README.rdoc b/test/prism/fixtures/seattlerb/README.rdoc similarity index 100% rename from test/yarp/fixtures/seattlerb/README.rdoc rename to test/prism/fixtures/seattlerb/README.rdoc diff --git a/test/yarp/fixtures/seattlerb/TestRubyParserShared.txt b/test/prism/fixtures/seattlerb/TestRubyParserShared.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/TestRubyParserShared.txt rename to test/prism/fixtures/seattlerb/TestRubyParserShared.txt diff --git a/test/yarp/fixtures/seattlerb/__ENCODING__.txt b/test/prism/fixtures/seattlerb/__ENCODING__.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/__ENCODING__.txt rename to test/prism/fixtures/seattlerb/__ENCODING__.txt diff --git a/test/yarp/fixtures/seattlerb/alias_gvar_backref.txt b/test/prism/fixtures/seattlerb/alias_gvar_backref.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/alias_gvar_backref.txt rename to test/prism/fixtures/seattlerb/alias_gvar_backref.txt diff --git a/test/yarp/fixtures/seattlerb/alias_resword.txt b/test/prism/fixtures/seattlerb/alias_resword.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/alias_resword.txt rename to test/prism/fixtures/seattlerb/alias_resword.txt diff --git a/test/yarp/fixtures/seattlerb/and_multi.txt b/test/prism/fixtures/seattlerb/and_multi.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/and_multi.txt rename to test/prism/fixtures/seattlerb/and_multi.txt diff --git a/test/yarp/fixtures/seattlerb/aref_args_assocs.txt b/test/prism/fixtures/seattlerb/aref_args_assocs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/aref_args_assocs.txt rename to test/prism/fixtures/seattlerb/aref_args_assocs.txt diff --git a/test/yarp/fixtures/seattlerb/aref_args_lit_assocs.txt b/test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/aref_args_lit_assocs.txt rename to test/prism/fixtures/seattlerb/aref_args_lit_assocs.txt diff --git a/test/yarp/fixtures/seattlerb/args_kw_block.txt b/test/prism/fixtures/seattlerb/args_kw_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/args_kw_block.txt rename to test/prism/fixtures/seattlerb/args_kw_block.txt diff --git a/test/yarp/fixtures/seattlerb/array_line_breaks.txt b/test/prism/fixtures/seattlerb/array_line_breaks.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/array_line_breaks.txt rename to test/prism/fixtures/seattlerb/array_line_breaks.txt diff --git a/test/yarp/fixtures/seattlerb/array_lits_trailing_calls.txt b/test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/array_lits_trailing_calls.txt rename to test/prism/fixtures/seattlerb/array_lits_trailing_calls.txt diff --git a/test/yarp/fixtures/seattlerb/assoc__bare.txt b/test/prism/fixtures/seattlerb/assoc__bare.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/assoc__bare.txt rename to test/prism/fixtures/seattlerb/assoc__bare.txt diff --git a/test/yarp/fixtures/seattlerb/assoc_label.txt b/test/prism/fixtures/seattlerb/assoc_label.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/assoc_label.txt rename to test/prism/fixtures/seattlerb/assoc_label.txt diff --git a/test/yarp/fixtures/seattlerb/attr_asgn_colon_id.txt b/test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/attr_asgn_colon_id.txt rename to test/prism/fixtures/seattlerb/attr_asgn_colon_id.txt diff --git a/test/yarp/fixtures/seattlerb/attrasgn_array_arg.txt b/test/prism/fixtures/seattlerb/attrasgn_array_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/attrasgn_array_arg.txt rename to test/prism/fixtures/seattlerb/attrasgn_array_arg.txt diff --git a/test/yarp/fixtures/seattlerb/attrasgn_array_lhs.txt b/test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/attrasgn_array_lhs.txt rename to test/prism/fixtures/seattlerb/attrasgn_array_lhs.txt diff --git a/test/yarp/fixtures/seattlerb/attrasgn_primary_dot_constant.txt b/test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/attrasgn_primary_dot_constant.txt rename to test/prism/fixtures/seattlerb/attrasgn_primary_dot_constant.txt diff --git a/test/yarp/fixtures/seattlerb/backticks_interpolation_line.txt b/test/prism/fixtures/seattlerb/backticks_interpolation_line.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/backticks_interpolation_line.txt rename to test/prism/fixtures/seattlerb/backticks_interpolation_line.txt diff --git a/test/yarp/fixtures/seattlerb/bang_eq.txt b/test/prism/fixtures/seattlerb/bang_eq.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bang_eq.txt rename to test/prism/fixtures/seattlerb/bang_eq.txt diff --git a/test/yarp/fixtures/seattlerb/bdot2.txt b/test/prism/fixtures/seattlerb/bdot2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bdot2.txt rename to test/prism/fixtures/seattlerb/bdot2.txt diff --git a/test/yarp/fixtures/seattlerb/bdot3.txt b/test/prism/fixtures/seattlerb/bdot3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bdot3.txt rename to test/prism/fixtures/seattlerb/bdot3.txt diff --git a/test/yarp/fixtures/seattlerb/begin_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/begin_ensure_no_bodies.txt rename to test/prism/fixtures/seattlerb/begin_ensure_no_bodies.txt diff --git a/test/yarp/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt rename to test/prism/fixtures/seattlerb/begin_rescue_else_ensure_bodies.txt diff --git a/test/yarp/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt rename to test/prism/fixtures/seattlerb/begin_rescue_else_ensure_no_bodies.txt diff --git a/test/yarp/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt b/test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt rename to test/prism/fixtures/seattlerb/begin_rescue_ensure_no_bodies.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg__bare.txt b/test/prism/fixtures/seattlerb/block_arg__bare.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg__bare.txt rename to test/prism/fixtures/seattlerb/block_arg__bare.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_kwsplat.txt b/test/prism/fixtures/seattlerb/block_arg_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_kwsplat.txt rename to test/prism/fixtures/seattlerb/block_arg_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_opt_arg_block.txt b/test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_opt_arg_block.txt rename to test/prism/fixtures/seattlerb/block_arg_opt_arg_block.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_opt_splat.txt b/test/prism/fixtures/seattlerb/block_arg_opt_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_opt_splat.txt rename to test/prism/fixtures/seattlerb/block_arg_opt_splat.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt rename to test/prism/fixtures/seattlerb/block_arg_opt_splat_arg_block_omfg.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_optional.txt b/test/prism/fixtures/seattlerb/block_arg_optional.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_optional.txt rename to test/prism/fixtures/seattlerb/block_arg_optional.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_scope.txt b/test/prism/fixtures/seattlerb/block_arg_scope.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_scope.txt rename to test/prism/fixtures/seattlerb/block_arg_scope.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_scope2.txt b/test/prism/fixtures/seattlerb/block_arg_scope2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_scope2.txt rename to test/prism/fixtures/seattlerb/block_arg_scope2.txt diff --git a/test/yarp/fixtures/seattlerb/block_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/block_arg_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_arg_splat_arg.txt rename to test/prism/fixtures/seattlerb/block_arg_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_kwargs.txt b/test/prism/fixtures/seattlerb/block_args_kwargs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_kwargs.txt rename to test/prism/fixtures/seattlerb/block_args_kwargs.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_no_kwargs.txt b/test/prism/fixtures/seattlerb/block_args_no_kwargs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_no_kwargs.txt rename to test/prism/fixtures/seattlerb/block_args_no_kwargs.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_opt1.txt b/test/prism/fixtures/seattlerb/block_args_opt1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_opt1.txt rename to test/prism/fixtures/seattlerb/block_args_opt1.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_opt2.txt b/test/prism/fixtures/seattlerb/block_args_opt2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_opt2.txt rename to test/prism/fixtures/seattlerb/block_args_opt2.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_opt2_2.txt b/test/prism/fixtures/seattlerb/block_args_opt2_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_opt2_2.txt rename to test/prism/fixtures/seattlerb/block_args_opt2_2.txt diff --git a/test/yarp/fixtures/seattlerb/block_args_opt3.txt b/test/prism/fixtures/seattlerb/block_args_opt3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_args_opt3.txt rename to test/prism/fixtures/seattlerb/block_args_opt3.txt diff --git a/test/yarp/fixtures/seattlerb/block_break.txt b/test/prism/fixtures/seattlerb/block_break.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_break.txt rename to test/prism/fixtures/seattlerb/block_break.txt diff --git a/test/yarp/fixtures/seattlerb/block_call_defn_call_block_call.txt b/test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_defn_call_block_call.txt rename to test/prism/fixtures/seattlerb/block_call_defn_call_block_call.txt diff --git a/test/yarp/fixtures/seattlerb/block_call_dot_op2_brace_block.txt b/test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_dot_op2_brace_block.txt rename to test/prism/fixtures/seattlerb/block_call_dot_op2_brace_block.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt rename to test/prism/fixtures/seattlerb/block_call_dot_op2_cmd_args_do_block.txt diff --git a/test/yarp/fixtures/seattlerb/block_call_operation_colon.txt b/test/prism/fixtures/seattlerb/block_call_operation_colon.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_operation_colon.txt rename to test/prism/fixtures/seattlerb/block_call_operation_colon.txt diff --git a/test/yarp/fixtures/seattlerb/block_call_operation_dot.txt b/test/prism/fixtures/seattlerb/block_call_operation_dot.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_operation_dot.txt rename to test/prism/fixtures/seattlerb/block_call_operation_dot.txt diff --git a/test/yarp/fixtures/seattlerb/block_call_paren_call_block_call.txt b/test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_call_paren_call_block_call.txt rename to test/prism/fixtures/seattlerb/block_call_paren_call_block_call.txt diff --git a/test/yarp/fixtures/seattlerb/block_command_operation_colon.txt b/test/prism/fixtures/seattlerb/block_command_operation_colon.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_command_operation_colon.txt rename to test/prism/fixtures/seattlerb/block_command_operation_colon.txt diff --git a/test/yarp/fixtures/seattlerb/block_command_operation_dot.txt b/test/prism/fixtures/seattlerb/block_command_operation_dot.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_command_operation_dot.txt rename to test/prism/fixtures/seattlerb/block_command_operation_dot.txt diff --git a/test/yarp/fixtures/seattlerb/block_decomp_anon_splat_arg.txt b/test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_decomp_anon_splat_arg.txt rename to test/prism/fixtures/seattlerb/block_decomp_anon_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/block_decomp_arg_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_decomp_arg_splat.txt rename to test/prism/fixtures/seattlerb/block_decomp_arg_splat.txt diff --git a/test/yarp/fixtures/seattlerb/block_decomp_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_decomp_arg_splat_arg.txt rename to test/prism/fixtures/seattlerb/block_decomp_arg_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/block_decomp_splat.txt b/test/prism/fixtures/seattlerb/block_decomp_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_decomp_splat.txt rename to test/prism/fixtures/seattlerb/block_decomp_splat.txt diff --git a/test/yarp/fixtures/seattlerb/block_kw.txt b/test/prism/fixtures/seattlerb/block_kw.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_kw.txt rename to test/prism/fixtures/seattlerb/block_kw.txt diff --git a/test/yarp/fixtures/seattlerb/block_kw__required.txt b/test/prism/fixtures/seattlerb/block_kw__required.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_kw__required.txt rename to test/prism/fixtures/seattlerb/block_kw__required.txt diff --git a/test/yarp/fixtures/seattlerb/block_kwarg_lvar.txt b/test/prism/fixtures/seattlerb/block_kwarg_lvar.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_kwarg_lvar.txt rename to test/prism/fixtures/seattlerb/block_kwarg_lvar.txt diff --git a/test/yarp/fixtures/seattlerb/block_kwarg_lvar_multiple.txt b/test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_kwarg_lvar_multiple.txt rename to test/prism/fixtures/seattlerb/block_kwarg_lvar_multiple.txt diff --git a/test/yarp/fixtures/seattlerb/block_next.txt b/test/prism/fixtures/seattlerb/block_next.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_next.txt rename to test/prism/fixtures/seattlerb/block_next.txt diff --git a/test/yarp/fixtures/seattlerb/block_opt_arg.txt b/test/prism/fixtures/seattlerb/block_opt_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_opt_arg.txt rename to test/prism/fixtures/seattlerb/block_opt_arg.txt diff --git a/test/yarp/fixtures/seattlerb/block_opt_splat.txt b/test/prism/fixtures/seattlerb/block_opt_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_opt_splat.txt rename to test/prism/fixtures/seattlerb/block_opt_splat.txt diff --git a/test/yarp/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt rename to test/prism/fixtures/seattlerb/block_opt_splat_arg_block_omfg.txt diff --git a/test/yarp/fixtures/seattlerb/block_optarg.txt b/test/prism/fixtures/seattlerb/block_optarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_optarg.txt rename to test/prism/fixtures/seattlerb/block_optarg.txt diff --git a/test/yarp/fixtures/seattlerb/block_paren_splat.txt b/test/prism/fixtures/seattlerb/block_paren_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_paren_splat.txt rename to test/prism/fixtures/seattlerb/block_paren_splat.txt diff --git a/test/yarp/fixtures/seattlerb/block_reg_optarg.txt b/test/prism/fixtures/seattlerb/block_reg_optarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_reg_optarg.txt rename to test/prism/fixtures/seattlerb/block_reg_optarg.txt diff --git a/test/yarp/fixtures/seattlerb/block_return.txt b/test/prism/fixtures/seattlerb/block_return.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_return.txt rename to test/prism/fixtures/seattlerb/block_return.txt diff --git a/test/yarp/fixtures/seattlerb/block_scope.txt b/test/prism/fixtures/seattlerb/block_scope.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_scope.txt rename to test/prism/fixtures/seattlerb/block_scope.txt diff --git a/test/yarp/fixtures/seattlerb/block_splat_reg.txt b/test/prism/fixtures/seattlerb/block_splat_reg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/block_splat_reg.txt rename to test/prism/fixtures/seattlerb/block_splat_reg.txt diff --git a/test/yarp/fixtures/seattlerb/bug169.txt b/test/prism/fixtures/seattlerb/bug169.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug169.txt rename to test/prism/fixtures/seattlerb/bug169.txt diff --git a/test/yarp/fixtures/seattlerb/bug179.txt b/test/prism/fixtures/seattlerb/bug179.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug179.txt rename to test/prism/fixtures/seattlerb/bug179.txt diff --git a/test/yarp/fixtures/seattlerb/bug190.txt b/test/prism/fixtures/seattlerb/bug190.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug190.txt rename to test/prism/fixtures/seattlerb/bug190.txt diff --git a/test/yarp/fixtures/seattlerb/bug191.txt b/test/prism/fixtures/seattlerb/bug191.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug191.txt rename to test/prism/fixtures/seattlerb/bug191.txt diff --git a/test/yarp/fixtures/seattlerb/bug202.txt b/test/prism/fixtures/seattlerb/bug202.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug202.txt rename to test/prism/fixtures/seattlerb/bug202.txt diff --git a/test/yarp/fixtures/seattlerb/bug236.txt b/test/prism/fixtures/seattlerb/bug236.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug236.txt rename to test/prism/fixtures/seattlerb/bug236.txt diff --git a/test/yarp/fixtures/seattlerb/bug290.txt b/test/prism/fixtures/seattlerb/bug290.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug290.txt rename to test/prism/fixtures/seattlerb/bug290.txt diff --git a/test/yarp/fixtures/seattlerb/bug_187.txt b/test/prism/fixtures/seattlerb/bug_187.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_187.txt rename to test/prism/fixtures/seattlerb/bug_187.txt diff --git a/test/yarp/fixtures/seattlerb/bug_215.txt b/test/prism/fixtures/seattlerb/bug_215.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_215.txt rename to test/prism/fixtures/seattlerb/bug_215.txt diff --git a/test/yarp/fixtures/seattlerb/bug_249.txt b/test/prism/fixtures/seattlerb/bug_249.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_249.txt rename to test/prism/fixtures/seattlerb/bug_249.txt diff --git a/test/yarp/fixtures/seattlerb/bug_and.txt b/test/prism/fixtures/seattlerb/bug_and.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_and.txt rename to test/prism/fixtures/seattlerb/bug_and.txt diff --git a/test/yarp/fixtures/seattlerb/bug_args__19.txt b/test/prism/fixtures/seattlerb/bug_args__19.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_args__19.txt rename to test/prism/fixtures/seattlerb/bug_args__19.txt diff --git a/test/yarp/fixtures/seattlerb/bug_args_masgn.txt b/test/prism/fixtures/seattlerb/bug_args_masgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_args_masgn.txt rename to test/prism/fixtures/seattlerb/bug_args_masgn.txt diff --git a/test/yarp/fixtures/seattlerb/bug_args_masgn2.txt b/test/prism/fixtures/seattlerb/bug_args_masgn2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_args_masgn2.txt rename to test/prism/fixtures/seattlerb/bug_args_masgn2.txt diff --git a/test/yarp/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt b/test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt rename to test/prism/fixtures/seattlerb/bug_args_masgn_outer_parens__19.txt diff --git a/test/yarp/fixtures/seattlerb/bug_call_arglist_parens.txt b/test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_call_arglist_parens.txt rename to test/prism/fixtures/seattlerb/bug_call_arglist_parens.txt diff --git a/test/yarp/fixtures/seattlerb/bug_case_when_regexp.txt b/test/prism/fixtures/seattlerb/bug_case_when_regexp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_case_when_regexp.txt rename to test/prism/fixtures/seattlerb/bug_case_when_regexp.txt diff --git a/test/yarp/fixtures/seattlerb/bug_comma.txt b/test/prism/fixtures/seattlerb/bug_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_comma.txt rename to test/prism/fixtures/seattlerb/bug_comma.txt diff --git a/test/yarp/fixtures/seattlerb/bug_cond_pct.txt b/test/prism/fixtures/seattlerb/bug_cond_pct.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_cond_pct.txt rename to test/prism/fixtures/seattlerb/bug_cond_pct.txt diff --git a/test/yarp/fixtures/seattlerb/bug_hash_args.txt b/test/prism/fixtures/seattlerb/bug_hash_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_hash_args.txt rename to test/prism/fixtures/seattlerb/bug_hash_args.txt diff --git a/test/yarp/fixtures/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_hash_args_trailing_comma.txt rename to test/prism/fixtures/seattlerb/bug_hash_args_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/bug_hash_interp_array.txt b/test/prism/fixtures/seattlerb/bug_hash_interp_array.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_hash_interp_array.txt rename to test/prism/fixtures/seattlerb/bug_hash_interp_array.txt diff --git a/test/yarp/fixtures/seattlerb/bug_masgn_right.txt b/test/prism/fixtures/seattlerb/bug_masgn_right.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_masgn_right.txt rename to test/prism/fixtures/seattlerb/bug_masgn_right.txt diff --git a/test/yarp/fixtures/seattlerb/bug_not_parens.txt b/test/prism/fixtures/seattlerb/bug_not_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_not_parens.txt rename to test/prism/fixtures/seattlerb/bug_not_parens.txt diff --git a/test/yarp/fixtures/seattlerb/bug_op_asgn_rescue.txt b/test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/bug_op_asgn_rescue.txt rename to test/prism/fixtures/seattlerb/bug_op_asgn_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/call_and.txt b/test/prism/fixtures/seattlerb/call_and.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_and.txt rename to test/prism/fixtures/seattlerb/call_and.txt diff --git a/test/yarp/fixtures/seattlerb/call_arg_assoc.txt b/test/prism/fixtures/seattlerb/call_arg_assoc.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_arg_assoc.txt rename to test/prism/fixtures/seattlerb/call_arg_assoc.txt diff --git a/test/yarp/fixtures/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_arg_assoc_kwsplat.txt rename to test/prism/fixtures/seattlerb/call_arg_assoc_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/call_arg_kwsplat.txt b/test/prism/fixtures/seattlerb/call_arg_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_arg_kwsplat.txt rename to test/prism/fixtures/seattlerb/call_arg_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/call_args_assoc_quoted.txt b/test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_args_assoc_quoted.txt rename to test/prism/fixtures/seattlerb/call_args_assoc_quoted.txt diff --git a/test/yarp/fixtures/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_args_assoc_trailing_comma.txt rename to test/prism/fixtures/seattlerb/call_args_assoc_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/call_args_command.txt b/test/prism/fixtures/seattlerb/call_args_command.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_args_command.txt rename to test/prism/fixtures/seattlerb/call_args_command.txt diff --git a/test/yarp/fixtures/seattlerb/call_array_arg.txt b/test/prism/fixtures/seattlerb/call_array_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_array_arg.txt rename to test/prism/fixtures/seattlerb/call_array_arg.txt diff --git a/test/yarp/fixtures/seattlerb/call_array_block_call.txt b/test/prism/fixtures/seattlerb/call_array_block_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_array_block_call.txt rename to test/prism/fixtures/seattlerb/call_array_block_call.txt diff --git a/test/yarp/fixtures/seattlerb/call_array_lambda_block_call.txt b/test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_array_lambda_block_call.txt rename to test/prism/fixtures/seattlerb/call_array_lambda_block_call.txt diff --git a/test/yarp/fixtures/seattlerb/call_array_lit_inline_hash.txt b/test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_array_lit_inline_hash.txt rename to test/prism/fixtures/seattlerb/call_array_lit_inline_hash.txt diff --git a/test/yarp/fixtures/seattlerb/call_assoc.txt b/test/prism/fixtures/seattlerb/call_assoc.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_assoc.txt rename to test/prism/fixtures/seattlerb/call_assoc.txt diff --git a/test/yarp/fixtures/seattlerb/call_assoc_new.txt b/test/prism/fixtures/seattlerb/call_assoc_new.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_assoc_new.txt rename to test/prism/fixtures/seattlerb/call_assoc_new.txt diff --git a/test/yarp/fixtures/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_assoc_new_if_multiline.txt rename to test/prism/fixtures/seattlerb/call_assoc_new_if_multiline.txt diff --git a/test/yarp/fixtures/seattlerb/call_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_assoc_trailing_comma.txt rename to test/prism/fixtures/seattlerb/call_assoc_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/call_bang_command_call.txt b/test/prism/fixtures/seattlerb/call_bang_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_bang_command_call.txt rename to test/prism/fixtures/seattlerb/call_bang_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/call_bang_squiggle.txt b/test/prism/fixtures/seattlerb/call_bang_squiggle.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_bang_squiggle.txt rename to test/prism/fixtures/seattlerb/call_bang_squiggle.txt diff --git a/test/yarp/fixtures/seattlerb/call_begin_call_block_call.txt b/test/prism/fixtures/seattlerb/call_begin_call_block_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_begin_call_block_call.txt rename to test/prism/fixtures/seattlerb/call_begin_call_block_call.txt diff --git a/test/yarp/fixtures/seattlerb/call_block_arg_named.txt b/test/prism/fixtures/seattlerb/call_block_arg_named.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_block_arg_named.txt rename to test/prism/fixtures/seattlerb/call_block_arg_named.txt diff --git a/test/yarp/fixtures/seattlerb/call_carat.txt b/test/prism/fixtures/seattlerb/call_carat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_carat.txt rename to test/prism/fixtures/seattlerb/call_carat.txt diff --git a/test/yarp/fixtures/seattlerb/call_colon2.txt b/test/prism/fixtures/seattlerb/call_colon2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_colon2.txt rename to test/prism/fixtures/seattlerb/call_colon2.txt diff --git a/test/yarp/fixtures/seattlerb/call_colon_parens.txt b/test/prism/fixtures/seattlerb/call_colon_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_colon_parens.txt rename to test/prism/fixtures/seattlerb/call_colon_parens.txt diff --git a/test/yarp/fixtures/seattlerb/call_div.txt b/test/prism/fixtures/seattlerb/call_div.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_div.txt rename to test/prism/fixtures/seattlerb/call_div.txt diff --git a/test/yarp/fixtures/seattlerb/call_dot_parens.txt b/test/prism/fixtures/seattlerb/call_dot_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_dot_parens.txt rename to test/prism/fixtures/seattlerb/call_dot_parens.txt diff --git a/test/yarp/fixtures/seattlerb/call_env.txt b/test/prism/fixtures/seattlerb/call_env.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_env.txt rename to test/prism/fixtures/seattlerb/call_env.txt diff --git a/test/yarp/fixtures/seattlerb/call_eq3.txt b/test/prism/fixtures/seattlerb/call_eq3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_eq3.txt rename to test/prism/fixtures/seattlerb/call_eq3.txt diff --git a/test/yarp/fixtures/seattlerb/call_gt.txt b/test/prism/fixtures/seattlerb/call_gt.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_gt.txt rename to test/prism/fixtures/seattlerb/call_gt.txt diff --git a/test/yarp/fixtures/seattlerb/call_kwsplat.txt b/test/prism/fixtures/seattlerb/call_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_kwsplat.txt rename to test/prism/fixtures/seattlerb/call_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/call_leading_dots.txt b/test/prism/fixtures/seattlerb/call_leading_dots.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_leading_dots.txt rename to test/prism/fixtures/seattlerb/call_leading_dots.txt diff --git a/test/yarp/fixtures/seattlerb/call_leading_dots_comment.txt b/test/prism/fixtures/seattlerb/call_leading_dots_comment.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_leading_dots_comment.txt rename to test/prism/fixtures/seattlerb/call_leading_dots_comment.txt diff --git a/test/yarp/fixtures/seattlerb/call_lt.txt b/test/prism/fixtures/seattlerb/call_lt.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_lt.txt rename to test/prism/fixtures/seattlerb/call_lt.txt diff --git a/test/yarp/fixtures/seattlerb/call_lte.txt b/test/prism/fixtures/seattlerb/call_lte.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_lte.txt rename to test/prism/fixtures/seattlerb/call_lte.txt diff --git a/test/yarp/fixtures/seattlerb/call_not.txt b/test/prism/fixtures/seattlerb/call_not.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_not.txt rename to test/prism/fixtures/seattlerb/call_not.txt diff --git a/test/yarp/fixtures/seattlerb/call_pipe.txt b/test/prism/fixtures/seattlerb/call_pipe.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_pipe.txt rename to test/prism/fixtures/seattlerb/call_pipe.txt diff --git a/test/yarp/fixtures/seattlerb/call_rshift.txt b/test/prism/fixtures/seattlerb/call_rshift.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_rshift.txt rename to test/prism/fixtures/seattlerb/call_rshift.txt diff --git a/test/yarp/fixtures/seattlerb/call_self_brackets.txt b/test/prism/fixtures/seattlerb/call_self_brackets.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_self_brackets.txt rename to test/prism/fixtures/seattlerb/call_self_brackets.txt diff --git a/test/yarp/fixtures/seattlerb/call_spaceship.txt b/test/prism/fixtures/seattlerb/call_spaceship.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_spaceship.txt rename to test/prism/fixtures/seattlerb/call_spaceship.txt diff --git a/test/yarp/fixtures/seattlerb/call_stabby_do_end_with_block.txt b/test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_stabby_do_end_with_block.txt rename to test/prism/fixtures/seattlerb/call_stabby_do_end_with_block.txt diff --git a/test/yarp/fixtures/seattlerb/call_stabby_with_braces_block.txt b/test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_stabby_with_braces_block.txt rename to test/prism/fixtures/seattlerb/call_stabby_with_braces_block.txt diff --git a/test/yarp/fixtures/seattlerb/call_star.txt b/test/prism/fixtures/seattlerb/call_star.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_star.txt rename to test/prism/fixtures/seattlerb/call_star.txt diff --git a/test/yarp/fixtures/seattlerb/call_star2.txt b/test/prism/fixtures/seattlerb/call_star2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_star2.txt rename to test/prism/fixtures/seattlerb/call_star2.txt diff --git a/test/yarp/fixtures/seattlerb/call_trailing_comma.txt b/test/prism/fixtures/seattlerb/call_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_trailing_comma.txt rename to test/prism/fixtures/seattlerb/call_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/call_trailing_dots.txt b/test/prism/fixtures/seattlerb/call_trailing_dots.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_trailing_dots.txt rename to test/prism/fixtures/seattlerb/call_trailing_dots.txt diff --git a/test/yarp/fixtures/seattlerb/call_unary_bang.txt b/test/prism/fixtures/seattlerb/call_unary_bang.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/call_unary_bang.txt rename to test/prism/fixtures/seattlerb/call_unary_bang.txt diff --git a/test/yarp/fixtures/seattlerb/case_in.txt b/test/prism/fixtures/seattlerb/case_in.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in.txt rename to test/prism/fixtures/seattlerb/case_in.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_31.txt b/test/prism/fixtures/seattlerb/case_in_31.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_31.txt rename to test/prism/fixtures/seattlerb/case_in_31.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_37.txt b/test/prism/fixtures/seattlerb/case_in_37.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_37.txt rename to test/prism/fixtures/seattlerb/case_in_37.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_42.txt b/test/prism/fixtures/seattlerb/case_in_42.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_42.txt rename to test/prism/fixtures/seattlerb/case_in_42.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_42_2.txt b/test/prism/fixtures/seattlerb/case_in_42_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_42_2.txt rename to test/prism/fixtures/seattlerb/case_in_42_2.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_47.txt b/test/prism/fixtures/seattlerb/case_in_47.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_47.txt rename to test/prism/fixtures/seattlerb/case_in_47.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_67.txt b/test/prism/fixtures/seattlerb/case_in_67.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_67.txt rename to test/prism/fixtures/seattlerb/case_in_67.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_86.txt b/test/prism/fixtures/seattlerb/case_in_86.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_86.txt rename to test/prism/fixtures/seattlerb/case_in_86.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_86_2.txt b/test/prism/fixtures/seattlerb/case_in_86_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_86_2.txt rename to test/prism/fixtures/seattlerb/case_in_86_2.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_array_pat_const.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_const.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_array_pat_const.txt rename to test/prism/fixtures/seattlerb/case_in_array_pat_const.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_array_pat_const2.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_array_pat_const2.txt rename to test/prism/fixtures/seattlerb/case_in_array_pat_const2.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_array_pat_paren_assign.txt b/test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_array_pat_paren_assign.txt rename to test/prism/fixtures/seattlerb/case_in_array_pat_paren_assign.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_const.txt b/test/prism/fixtures/seattlerb/case_in_const.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_const.txt rename to test/prism/fixtures/seattlerb/case_in_const.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_else.txt b/test/prism/fixtures/seattlerb/case_in_else.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_else.txt rename to test/prism/fixtures/seattlerb/case_in_else.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_find.txt b/test/prism/fixtures/seattlerb/case_in_find.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_find.txt rename to test/prism/fixtures/seattlerb/case_in_find.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_find_array.txt b/test/prism/fixtures/seattlerb/case_in_find_array.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_find_array.txt rename to test/prism/fixtures/seattlerb/case_in_find_array.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat_assign.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat_assign.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat_assign.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat_paren_assign.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat_paren_true.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat_paren_true.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat_paren_true.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat_rest.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat_rest.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat_rest.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt b/test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt rename to test/prism/fixtures/seattlerb/case_in_hash_pat_rest_solo.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_if_unless_post_mod.txt b/test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_if_unless_post_mod.txt rename to test/prism/fixtures/seattlerb/case_in_if_unless_post_mod.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_multiple.txt b/test/prism/fixtures/seattlerb/case_in_multiple.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_multiple.txt rename to test/prism/fixtures/seattlerb/case_in_multiple.txt diff --git a/test/yarp/fixtures/seattlerb/case_in_or.txt b/test/prism/fixtures/seattlerb/case_in_or.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/case_in_or.txt rename to test/prism/fixtures/seattlerb/case_in_or.txt diff --git a/test/yarp/fixtures/seattlerb/class_comments.txt b/test/prism/fixtures/seattlerb/class_comments.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/class_comments.txt rename to test/prism/fixtures/seattlerb/class_comments.txt diff --git a/test/yarp/fixtures/seattlerb/cond_unary_minus.txt b/test/prism/fixtures/seattlerb/cond_unary_minus.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/cond_unary_minus.txt rename to test/prism/fixtures/seattlerb/cond_unary_minus.txt diff --git a/test/yarp/fixtures/seattlerb/const_2_op_asgn_or2.txt b/test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/const_2_op_asgn_or2.txt rename to test/prism/fixtures/seattlerb/const_2_op_asgn_or2.txt diff --git a/test/yarp/fixtures/seattlerb/const_3_op_asgn_or.txt b/test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/const_3_op_asgn_or.txt rename to test/prism/fixtures/seattlerb/const_3_op_asgn_or.txt diff --git a/test/yarp/fixtures/seattlerb/const_op_asgn_and1.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/const_op_asgn_and1.txt rename to test/prism/fixtures/seattlerb/const_op_asgn_and1.txt diff --git a/test/yarp/fixtures/seattlerb/const_op_asgn_and2.txt b/test/prism/fixtures/seattlerb/const_op_asgn_and2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/const_op_asgn_and2.txt rename to test/prism/fixtures/seattlerb/const_op_asgn_and2.txt diff --git a/test/yarp/fixtures/seattlerb/const_op_asgn_or.txt b/test/prism/fixtures/seattlerb/const_op_asgn_or.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/const_op_asgn_or.txt rename to test/prism/fixtures/seattlerb/const_op_asgn_or.txt diff --git a/test/yarp/fixtures/seattlerb/dasgn_icky2.txt b/test/prism/fixtures/seattlerb/dasgn_icky2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dasgn_icky2.txt rename to test/prism/fixtures/seattlerb/dasgn_icky2.txt diff --git a/test/yarp/fixtures/seattlerb/defined_eh_parens.txt b/test/prism/fixtures/seattlerb/defined_eh_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defined_eh_parens.txt rename to test/prism/fixtures/seattlerb/defined_eh_parens.txt diff --git a/test/yarp/fixtures/seattlerb/defn_arg_asplat_arg.txt b/test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_arg_asplat_arg.txt rename to test/prism/fixtures/seattlerb/defn_arg_asplat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_arg_forward_args.txt b/test/prism/fixtures/seattlerb/defn_arg_forward_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_arg_forward_args.txt rename to test/prism/fixtures/seattlerb/defn_arg_forward_args.txt diff --git a/test/yarp/fixtures/seattlerb/defn_args_forward_args.txt b/test/prism/fixtures/seattlerb/defn_args_forward_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_args_forward_args.txt rename to test/prism/fixtures/seattlerb/defn_args_forward_args.txt diff --git a/test/yarp/fixtures/seattlerb/defn_comments.txt b/test/prism/fixtures/seattlerb/defn_comments.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_comments.txt rename to test/prism/fixtures/seattlerb/defn_comments.txt diff --git a/test/yarp/fixtures/seattlerb/defn_endless_command.txt b/test/prism/fixtures/seattlerb/defn_endless_command.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_endless_command.txt rename to test/prism/fixtures/seattlerb/defn_endless_command.txt diff --git a/test/yarp/fixtures/seattlerb/defn_endless_command_rescue.txt b/test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_endless_command_rescue.txt rename to test/prism/fixtures/seattlerb/defn_endless_command_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/defn_forward_args.txt b/test/prism/fixtures/seattlerb/defn_forward_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_forward_args.txt rename to test/prism/fixtures/seattlerb/defn_forward_args.txt diff --git a/test/yarp/fixtures/seattlerb/defn_forward_args__no_parens.txt b/test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_forward_args__no_parens.txt rename to test/prism/fixtures/seattlerb/defn_forward_args__no_parens.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_env.txt b/test/prism/fixtures/seattlerb/defn_kwarg_env.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_env.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_env.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_kwarg.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_kwarg.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_kwarg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_kwsplat.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_kwsplat.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_kwsplat_anon.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_lvar.txt b/test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_lvar.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_lvar.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_no_parens.txt b/test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_no_parens.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_no_parens.txt diff --git a/test/yarp/fixtures/seattlerb/defn_kwarg_val.txt b/test/prism/fixtures/seattlerb/defn_kwarg_val.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_kwarg_val.txt rename to test/prism/fixtures/seattlerb/defn_kwarg_val.txt diff --git a/test/yarp/fixtures/seattlerb/defn_no_kwargs.txt b/test/prism/fixtures/seattlerb/defn_no_kwargs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_no_kwargs.txt rename to test/prism/fixtures/seattlerb/defn_no_kwargs.txt diff --git a/test/yarp/fixtures/seattlerb/defn_oneliner.txt b/test/prism/fixtures/seattlerb/defn_oneliner.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_oneliner.txt rename to test/prism/fixtures/seattlerb/defn_oneliner.txt diff --git a/test/yarp/fixtures/seattlerb/defn_oneliner_eq2.txt b/test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_oneliner_eq2.txt rename to test/prism/fixtures/seattlerb/defn_oneliner_eq2.txt diff --git a/test/yarp/fixtures/seattlerb/defn_oneliner_noargs.txt b/test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_oneliner_noargs.txt rename to test/prism/fixtures/seattlerb/defn_oneliner_noargs.txt diff --git a/test/yarp/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt rename to test/prism/fixtures/seattlerb/defn_oneliner_noargs_parentheses.txt diff --git a/test/yarp/fixtures/seattlerb/defn_oneliner_rescue.txt b/test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_oneliner_rescue.txt rename to test/prism/fixtures/seattlerb/defn_oneliner_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/defn_opt_last_arg.txt b/test/prism/fixtures/seattlerb/defn_opt_last_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_opt_last_arg.txt rename to test/prism/fixtures/seattlerb/defn_opt_last_arg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_opt_reg.txt b/test/prism/fixtures/seattlerb/defn_opt_reg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_opt_reg.txt rename to test/prism/fixtures/seattlerb/defn_opt_reg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_opt_splat_arg.txt b/test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_opt_splat_arg.txt rename to test/prism/fixtures/seattlerb/defn_opt_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_powarg.txt b/test/prism/fixtures/seattlerb/defn_powarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_powarg.txt rename to test/prism/fixtures/seattlerb/defn_powarg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_reg_opt_reg.txt b/test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_reg_opt_reg.txt rename to test/prism/fixtures/seattlerb/defn_reg_opt_reg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_splat_arg.txt b/test/prism/fixtures/seattlerb/defn_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_splat_arg.txt rename to test/prism/fixtures/seattlerb/defn_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/defn_unary_not.txt b/test/prism/fixtures/seattlerb/defn_unary_not.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defn_unary_not.txt rename to test/prism/fixtures/seattlerb/defn_unary_not.txt diff --git a/test/yarp/fixtures/seattlerb/defns_reserved.txt b/test/prism/fixtures/seattlerb/defns_reserved.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defns_reserved.txt rename to test/prism/fixtures/seattlerb/defns_reserved.txt diff --git a/test/yarp/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt rename to test/prism/fixtures/seattlerb/defs_as_arg_with_do_block_inside.txt diff --git a/test/yarp/fixtures/seattlerb/defs_comments.txt b/test/prism/fixtures/seattlerb/defs_comments.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_comments.txt rename to test/prism/fixtures/seattlerb/defs_comments.txt diff --git a/test/yarp/fixtures/seattlerb/defs_endless_command.txt b/test/prism/fixtures/seattlerb/defs_endless_command.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_endless_command.txt rename to test/prism/fixtures/seattlerb/defs_endless_command.txt diff --git a/test/yarp/fixtures/seattlerb/defs_endless_command_rescue.txt b/test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_endless_command_rescue.txt rename to test/prism/fixtures/seattlerb/defs_endless_command_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/defs_kwarg.txt b/test/prism/fixtures/seattlerb/defs_kwarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_kwarg.txt rename to test/prism/fixtures/seattlerb/defs_kwarg.txt diff --git a/test/yarp/fixtures/seattlerb/defs_oneliner.txt b/test/prism/fixtures/seattlerb/defs_oneliner.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_oneliner.txt rename to test/prism/fixtures/seattlerb/defs_oneliner.txt diff --git a/test/yarp/fixtures/seattlerb/defs_oneliner_eq2.txt b/test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_oneliner_eq2.txt rename to test/prism/fixtures/seattlerb/defs_oneliner_eq2.txt diff --git a/test/yarp/fixtures/seattlerb/defs_oneliner_rescue.txt b/test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/defs_oneliner_rescue.txt rename to test/prism/fixtures/seattlerb/defs_oneliner_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/difficult0_.txt b/test/prism/fixtures/seattlerb/difficult0_.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult0_.txt rename to test/prism/fixtures/seattlerb/difficult0_.txt diff --git a/test/yarp/fixtures/seattlerb/difficult1_line_numbers.txt b/test/prism/fixtures/seattlerb/difficult1_line_numbers.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult1_line_numbers.txt rename to test/prism/fixtures/seattlerb/difficult1_line_numbers.txt diff --git a/test/yarp/fixtures/seattlerb/difficult1_line_numbers2.txt b/test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult1_line_numbers2.txt rename to test/prism/fixtures/seattlerb/difficult1_line_numbers2.txt diff --git a/test/yarp/fixtures/seattlerb/difficult2_.txt b/test/prism/fixtures/seattlerb/difficult2_.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult2_.txt rename to test/prism/fixtures/seattlerb/difficult2_.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3_.txt b/test/prism/fixtures/seattlerb/difficult3_.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3_.txt rename to test/prism/fixtures/seattlerb/difficult3_.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3_2.txt b/test/prism/fixtures/seattlerb/difficult3_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3_2.txt rename to test/prism/fixtures/seattlerb/difficult3_2.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3_3.txt b/test/prism/fixtures/seattlerb/difficult3_3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3_3.txt rename to test/prism/fixtures/seattlerb/difficult3_3.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3_4.txt b/test/prism/fixtures/seattlerb/difficult3_4.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3_4.txt rename to test/prism/fixtures/seattlerb/difficult3_4.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3_5.txt b/test/prism/fixtures/seattlerb/difficult3_5.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3_5.txt rename to test/prism/fixtures/seattlerb/difficult3_5.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__10.txt b/test/prism/fixtures/seattlerb/difficult3__10.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__10.txt rename to test/prism/fixtures/seattlerb/difficult3__10.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__11.txt b/test/prism/fixtures/seattlerb/difficult3__11.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__11.txt rename to test/prism/fixtures/seattlerb/difficult3__11.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__12.txt b/test/prism/fixtures/seattlerb/difficult3__12.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__12.txt rename to test/prism/fixtures/seattlerb/difficult3__12.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__6.txt b/test/prism/fixtures/seattlerb/difficult3__6.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__6.txt rename to test/prism/fixtures/seattlerb/difficult3__6.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__7.txt b/test/prism/fixtures/seattlerb/difficult3__7.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__7.txt rename to test/prism/fixtures/seattlerb/difficult3__7.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__8.txt b/test/prism/fixtures/seattlerb/difficult3__8.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__8.txt rename to test/prism/fixtures/seattlerb/difficult3__8.txt diff --git a/test/yarp/fixtures/seattlerb/difficult3__9.txt b/test/prism/fixtures/seattlerb/difficult3__9.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult3__9.txt rename to test/prism/fixtures/seattlerb/difficult3__9.txt diff --git a/test/yarp/fixtures/seattlerb/difficult4__leading_dots.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult4__leading_dots.txt rename to test/prism/fixtures/seattlerb/difficult4__leading_dots.txt diff --git a/test/yarp/fixtures/seattlerb/difficult4__leading_dots2.txt b/test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult4__leading_dots2.txt rename to test/prism/fixtures/seattlerb/difficult4__leading_dots2.txt diff --git a/test/yarp/fixtures/seattlerb/difficult6_.txt b/test/prism/fixtures/seattlerb/difficult6_.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult6_.txt rename to test/prism/fixtures/seattlerb/difficult6_.txt diff --git a/test/yarp/fixtures/seattlerb/difficult6__7.txt b/test/prism/fixtures/seattlerb/difficult6__7.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult6__7.txt rename to test/prism/fixtures/seattlerb/difficult6__7.txt diff --git a/test/yarp/fixtures/seattlerb/difficult6__8.txt b/test/prism/fixtures/seattlerb/difficult6__8.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult6__8.txt rename to test/prism/fixtures/seattlerb/difficult6__8.txt diff --git a/test/yarp/fixtures/seattlerb/difficult7_.txt b/test/prism/fixtures/seattlerb/difficult7_.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/difficult7_.txt rename to test/prism/fixtures/seattlerb/difficult7_.txt diff --git a/test/yarp/fixtures/seattlerb/do_bug.txt b/test/prism/fixtures/seattlerb/do_bug.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/do_bug.txt rename to test/prism/fixtures/seattlerb/do_bug.txt diff --git a/test/yarp/fixtures/seattlerb/do_lambda.txt b/test/prism/fixtures/seattlerb/do_lambda.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/do_lambda.txt rename to test/prism/fixtures/seattlerb/do_lambda.txt diff --git a/test/yarp/fixtures/seattlerb/dot2_nil__26.txt b/test/prism/fixtures/seattlerb/dot2_nil__26.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dot2_nil__26.txt rename to test/prism/fixtures/seattlerb/dot2_nil__26.txt diff --git a/test/yarp/fixtures/seattlerb/dot3_nil__26.txt b/test/prism/fixtures/seattlerb/dot3_nil__26.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dot3_nil__26.txt rename to test/prism/fixtures/seattlerb/dot3_nil__26.txt diff --git a/test/yarp/fixtures/seattlerb/dstr_evstr.txt b/test/prism/fixtures/seattlerb/dstr_evstr.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dstr_evstr.txt rename to test/prism/fixtures/seattlerb/dstr_evstr.txt diff --git a/test/yarp/fixtures/seattlerb/dstr_evstr_empty_end.txt b/test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dstr_evstr_empty_end.txt rename to test/prism/fixtures/seattlerb/dstr_evstr_empty_end.txt diff --git a/test/yarp/fixtures/seattlerb/dstr_lex_state.txt b/test/prism/fixtures/seattlerb/dstr_lex_state.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dstr_lex_state.txt rename to test/prism/fixtures/seattlerb/dstr_lex_state.txt diff --git a/test/yarp/fixtures/seattlerb/dstr_str.txt b/test/prism/fixtures/seattlerb/dstr_str.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dstr_str.txt rename to test/prism/fixtures/seattlerb/dstr_str.txt diff --git a/test/yarp/fixtures/seattlerb/dsym_esc_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dsym_esc_to_sym.txt rename to test/prism/fixtures/seattlerb/dsym_esc_to_sym.txt diff --git a/test/yarp/fixtures/seattlerb/dsym_to_sym.txt b/test/prism/fixtures/seattlerb/dsym_to_sym.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/dsym_to_sym.txt rename to test/prism/fixtures/seattlerb/dsym_to_sym.txt diff --git a/test/yarp/fixtures/seattlerb/eq_begin_line_numbers.txt b/test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/eq_begin_line_numbers.txt rename to test/prism/fixtures/seattlerb/eq_begin_line_numbers.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt rename to test/prism/fixtures/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt diff --git a/test/yarp/fixtures/seattlerb/evstr_evstr.txt b/test/prism/fixtures/seattlerb/evstr_evstr.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/evstr_evstr.txt rename to test/prism/fixtures/seattlerb/evstr_evstr.txt diff --git a/test/yarp/fixtures/seattlerb/evstr_str.txt b/test/prism/fixtures/seattlerb/evstr_str.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/evstr_str.txt rename to test/prism/fixtures/seattlerb/evstr_str.txt diff --git a/test/yarp/fixtures/seattlerb/expr_not_bang.txt b/test/prism/fixtures/seattlerb/expr_not_bang.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/expr_not_bang.txt rename to test/prism/fixtures/seattlerb/expr_not_bang.txt diff --git a/test/yarp/fixtures/seattlerb/f_kw.txt b/test/prism/fixtures/seattlerb/f_kw.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/f_kw.txt rename to test/prism/fixtures/seattlerb/f_kw.txt diff --git a/test/yarp/fixtures/seattlerb/f_kw__required.txt b/test/prism/fixtures/seattlerb/f_kw__required.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/f_kw__required.txt rename to test/prism/fixtures/seattlerb/f_kw__required.txt diff --git a/test/yarp/fixtures/seattlerb/flip2_env_lvar.txt b/test/prism/fixtures/seattlerb/flip2_env_lvar.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/flip2_env_lvar.txt rename to test/prism/fixtures/seattlerb/flip2_env_lvar.txt diff --git a/test/yarp/fixtures/seattlerb/float_with_if_modifier.txt b/test/prism/fixtures/seattlerb/float_with_if_modifier.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/float_with_if_modifier.txt rename to test/prism/fixtures/seattlerb/float_with_if_modifier.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc__backslash_dos_format.txt b/test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc__backslash_dos_format.txt rename to test/prism/fixtures/seattlerb/heredoc__backslash_dos_format.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_backslash_nl.txt b/test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_backslash_nl.txt rename to test/prism/fixtures/seattlerb/heredoc_backslash_nl.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_bad_hex_escape.txt b/test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_bad_hex_escape.txt rename to test/prism/fixtures/seattlerb/heredoc_bad_hex_escape.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_bad_oct_escape.txt b/test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_bad_oct_escape.txt rename to test/prism/fixtures/seattlerb/heredoc_bad_oct_escape.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_comma_arg.txt b/test/prism/fixtures/seattlerb/heredoc_comma_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_comma_arg.txt rename to test/prism/fixtures/seattlerb/heredoc_comma_arg.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_lineno.txt b/test/prism/fixtures/seattlerb/heredoc_lineno.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_lineno.txt rename to test/prism/fixtures/seattlerb/heredoc_lineno.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_nested.txt b/test/prism/fixtures/seattlerb/heredoc_nested.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_nested.txt rename to test/prism/fixtures/seattlerb/heredoc_nested.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_blank_lines.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_empty.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_empty.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_empty.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_interp.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_interp.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_interp.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_no_indent.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_no_indent.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_no_indent.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_tabs.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_tabs.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_tabs.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_tabs_extra.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt b/test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt rename to test/prism/fixtures/seattlerb/heredoc_squiggly_visually_blank_lines.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt b/test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt rename to test/prism/fixtures/seattlerb/heredoc_trailing_slash_continued_call.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_unicode.txt b/test/prism/fixtures/seattlerb/heredoc_unicode.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_unicode.txt rename to test/prism/fixtures/seattlerb/heredoc_unicode.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt rename to test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt rename to test/prism/fixtures/seattlerb/heredoc_with_carriage_return_escapes_windows.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt rename to test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt rename to test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt rename to test/prism/fixtures/seattlerb/heredoc_with_extra_carriage_returns_windows.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt b/test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt rename to test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt rename to test/prism/fixtures/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt b/test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt rename to test/prism/fixtures/seattlerb/heredoc_with_not_global_interpolation.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt rename to test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns.txt diff --git a/test/yarp/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt b/test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt rename to test/prism/fixtures/seattlerb/heredoc_with_only_carriage_returns_windows.txt diff --git a/test/yarp/fixtures/seattlerb/if_elsif.txt b/test/prism/fixtures/seattlerb/if_elsif.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/if_elsif.txt rename to test/prism/fixtures/seattlerb/if_elsif.txt diff --git a/test/yarp/fixtures/seattlerb/if_symbol.txt b/test/prism/fixtures/seattlerb/if_symbol.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/if_symbol.txt rename to test/prism/fixtures/seattlerb/if_symbol.txt diff --git a/test/yarp/fixtures/seattlerb/in_expr_no_case.txt b/test/prism/fixtures/seattlerb/in_expr_no_case.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/in_expr_no_case.txt rename to test/prism/fixtures/seattlerb/in_expr_no_case.txt diff --git a/test/yarp/fixtures/seattlerb/index_0.txt b/test/prism/fixtures/seattlerb/index_0.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/index_0.txt rename to test/prism/fixtures/seattlerb/index_0.txt diff --git a/test/yarp/fixtures/seattlerb/index_0_opasgn.txt b/test/prism/fixtures/seattlerb/index_0_opasgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/index_0_opasgn.txt rename to test/prism/fixtures/seattlerb/index_0_opasgn.txt diff --git a/test/yarp/fixtures/seattlerb/integer_with_if_modifier.txt b/test/prism/fixtures/seattlerb/integer_with_if_modifier.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/integer_with_if_modifier.txt rename to test/prism/fixtures/seattlerb/integer_with_if_modifier.txt diff --git a/test/yarp/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt b/test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt rename to test/prism/fixtures/seattlerb/interpolated_symbol_array_line_breaks.txt diff --git a/test/yarp/fixtures/seattlerb/interpolated_word_array_line_breaks.txt b/test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/interpolated_word_array_line_breaks.txt rename to test/prism/fixtures/seattlerb/interpolated_word_array_line_breaks.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_1.txt b/test/prism/fixtures/seattlerb/iter_args_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_1.txt rename to test/prism/fixtures/seattlerb/iter_args_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_10_1.txt b/test/prism/fixtures/seattlerb/iter_args_10_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_10_1.txt rename to test/prism/fixtures/seattlerb/iter_args_10_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_10_2.txt b/test/prism/fixtures/seattlerb/iter_args_10_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_10_2.txt rename to test/prism/fixtures/seattlerb/iter_args_10_2.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_11_1.txt b/test/prism/fixtures/seattlerb/iter_args_11_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_11_1.txt rename to test/prism/fixtures/seattlerb/iter_args_11_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_11_2.txt b/test/prism/fixtures/seattlerb/iter_args_11_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_11_2.txt rename to test/prism/fixtures/seattlerb/iter_args_11_2.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_2__19.txt b/test/prism/fixtures/seattlerb/iter_args_2__19.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_2__19.txt rename to test/prism/fixtures/seattlerb/iter_args_2__19.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_3.txt b/test/prism/fixtures/seattlerb/iter_args_3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_3.txt rename to test/prism/fixtures/seattlerb/iter_args_3.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_4.txt b/test/prism/fixtures/seattlerb/iter_args_4.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_4.txt rename to test/prism/fixtures/seattlerb/iter_args_4.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_5.txt b/test/prism/fixtures/seattlerb/iter_args_5.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_5.txt rename to test/prism/fixtures/seattlerb/iter_args_5.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_6.txt b/test/prism/fixtures/seattlerb/iter_args_6.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_6.txt rename to test/prism/fixtures/seattlerb/iter_args_6.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_7_1.txt b/test/prism/fixtures/seattlerb/iter_args_7_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_7_1.txt rename to test/prism/fixtures/seattlerb/iter_args_7_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_7_2.txt b/test/prism/fixtures/seattlerb/iter_args_7_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_7_2.txt rename to test/prism/fixtures/seattlerb/iter_args_7_2.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_8_1.txt b/test/prism/fixtures/seattlerb/iter_args_8_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_8_1.txt rename to test/prism/fixtures/seattlerb/iter_args_8_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_8_2.txt b/test/prism/fixtures/seattlerb/iter_args_8_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_8_2.txt rename to test/prism/fixtures/seattlerb/iter_args_8_2.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_9_1.txt b/test/prism/fixtures/seattlerb/iter_args_9_1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_9_1.txt rename to test/prism/fixtures/seattlerb/iter_args_9_1.txt diff --git a/test/yarp/fixtures/seattlerb/iter_args_9_2.txt b/test/prism/fixtures/seattlerb/iter_args_9_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_args_9_2.txt rename to test/prism/fixtures/seattlerb/iter_args_9_2.txt diff --git a/test/yarp/fixtures/seattlerb/iter_kwarg.txt b/test/prism/fixtures/seattlerb/iter_kwarg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_kwarg.txt rename to test/prism/fixtures/seattlerb/iter_kwarg.txt diff --git a/test/yarp/fixtures/seattlerb/iter_kwarg_kwsplat.txt b/test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/iter_kwarg_kwsplat.txt rename to test/prism/fixtures/seattlerb/iter_kwarg_kwsplat.txt diff --git a/test/yarp/fixtures/seattlerb/label_vs_string.txt b/test/prism/fixtures/seattlerb/label_vs_string.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/label_vs_string.txt rename to test/prism/fixtures/seattlerb/label_vs_string.txt diff --git a/test/yarp/fixtures/seattlerb/lambda_do_vs_brace.txt b/test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lambda_do_vs_brace.txt rename to test/prism/fixtures/seattlerb/lambda_do_vs_brace.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_arg_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_arg_rescue_arg.txt rename to test/prism/fixtures/seattlerb/lasgn_arg_rescue_arg.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt rename to test/prism/fixtures/seattlerb/lasgn_call_bracket_rescue_arg.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt b/test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt rename to test/prism/fixtures/seattlerb/lasgn_call_nobracket_rescue_arg.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_command.txt b/test/prism/fixtures/seattlerb/lasgn_command.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_command.txt rename to test/prism/fixtures/seattlerb/lasgn_command.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_env.txt b/test/prism/fixtures/seattlerb/lasgn_env.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_env.txt rename to test/prism/fixtures/seattlerb/lasgn_env.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_ivar_env.txt b/test/prism/fixtures/seattlerb/lasgn_ivar_env.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_ivar_env.txt rename to test/prism/fixtures/seattlerb/lasgn_ivar_env.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_lasgn_command_call.txt b/test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_lasgn_command_call.txt rename to test/prism/fixtures/seattlerb/lasgn_lasgn_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/lasgn_middle_splat.txt b/test/prism/fixtures/seattlerb/lasgn_middle_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/lasgn_middle_splat.txt rename to test/prism/fixtures/seattlerb/lasgn_middle_splat.txt diff --git a/test/yarp/fixtures/seattlerb/magic_encoding_comment.txt b/test/prism/fixtures/seattlerb/magic_encoding_comment.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/magic_encoding_comment.txt rename to test/prism/fixtures/seattlerb/magic_encoding_comment.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_anon_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_anon_splat_arg.txt rename to test/prism/fixtures/seattlerb/masgn_anon_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_arg_colon_arg.txt b/test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_arg_colon_arg.txt rename to test/prism/fixtures/seattlerb/masgn_arg_colon_arg.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_arg_ident.txt b/test/prism/fixtures/seattlerb/masgn_arg_ident.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_arg_ident.txt rename to test/prism/fixtures/seattlerb/masgn_arg_ident.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_arg_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_arg_splat_arg.txt rename to test/prism/fixtures/seattlerb/masgn_arg_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_colon2.txt b/test/prism/fixtures/seattlerb/masgn_colon2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_colon2.txt rename to test/prism/fixtures/seattlerb/masgn_colon2.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_colon3.txt b/test/prism/fixtures/seattlerb/masgn_colon3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_colon3.txt rename to test/prism/fixtures/seattlerb/masgn_colon3.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_command_call.txt b/test/prism/fixtures/seattlerb/masgn_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_command_call.txt rename to test/prism/fixtures/seattlerb/masgn_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_double_paren.txt b/test/prism/fixtures/seattlerb/masgn_double_paren.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_double_paren.txt rename to test/prism/fixtures/seattlerb/masgn_double_paren.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_lhs_splat.txt b/test/prism/fixtures/seattlerb/masgn_lhs_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_lhs_splat.txt rename to test/prism/fixtures/seattlerb/masgn_lhs_splat.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_paren.txt b/test/prism/fixtures/seattlerb/masgn_paren.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_paren.txt rename to test/prism/fixtures/seattlerb/masgn_paren.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_splat_arg.txt b/test/prism/fixtures/seattlerb/masgn_splat_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_splat_arg.txt rename to test/prism/fixtures/seattlerb/masgn_splat_arg.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_splat_arg_arg.txt b/test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_splat_arg_arg.txt rename to test/prism/fixtures/seattlerb/masgn_splat_arg_arg.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_star.txt b/test/prism/fixtures/seattlerb/masgn_star.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_star.txt rename to test/prism/fixtures/seattlerb/masgn_star.txt diff --git a/test/yarp/fixtures/seattlerb/masgn_var_star_var.txt b/test/prism/fixtures/seattlerb/masgn_var_star_var.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/masgn_var_star_var.txt rename to test/prism/fixtures/seattlerb/masgn_var_star_var.txt diff --git a/test/yarp/fixtures/seattlerb/messy_op_asgn_lineno.txt b/test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/messy_op_asgn_lineno.txt rename to test/prism/fixtures/seattlerb/messy_op_asgn_lineno.txt diff --git a/test/yarp/fixtures/seattlerb/method_call_assoc_trailing_comma.txt b/test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/method_call_assoc_trailing_comma.txt rename to test/prism/fixtures/seattlerb/method_call_assoc_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/method_call_trailing_comma.txt b/test/prism/fixtures/seattlerb/method_call_trailing_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/method_call_trailing_comma.txt rename to test/prism/fixtures/seattlerb/method_call_trailing_comma.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_back_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_back_anonsplat.txt rename to test/prism/fixtures/seattlerb/mlhs_back_anonsplat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_back_splat.txt b/test/prism/fixtures/seattlerb/mlhs_back_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_back_splat.txt rename to test/prism/fixtures/seattlerb/mlhs_back_splat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_front_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_front_anonsplat.txt rename to test/prism/fixtures/seattlerb/mlhs_front_anonsplat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_front_splat.txt b/test/prism/fixtures/seattlerb/mlhs_front_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_front_splat.txt rename to test/prism/fixtures/seattlerb/mlhs_front_splat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_keyword.txt b/test/prism/fixtures/seattlerb/mlhs_keyword.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_keyword.txt rename to test/prism/fixtures/seattlerb/mlhs_keyword.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_mid_anonsplat.txt b/test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_mid_anonsplat.txt rename to test/prism/fixtures/seattlerb/mlhs_mid_anonsplat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_mid_splat.txt b/test/prism/fixtures/seattlerb/mlhs_mid_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_mid_splat.txt rename to test/prism/fixtures/seattlerb/mlhs_mid_splat.txt diff --git a/test/yarp/fixtures/seattlerb/mlhs_rescue.txt b/test/prism/fixtures/seattlerb/mlhs_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/mlhs_rescue.txt rename to test/prism/fixtures/seattlerb/mlhs_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/module_comments.txt b/test/prism/fixtures/seattlerb/module_comments.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/module_comments.txt rename to test/prism/fixtures/seattlerb/module_comments.txt diff --git a/test/yarp/fixtures/seattlerb/multiline_hash_declaration.txt b/test/prism/fixtures/seattlerb/multiline_hash_declaration.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/multiline_hash_declaration.txt rename to test/prism/fixtures/seattlerb/multiline_hash_declaration.txt diff --git a/test/yarp/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt b/test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt rename to test/prism/fixtures/seattlerb/non_interpolated_symbol_array_line_breaks.txt diff --git a/test/yarp/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt b/test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt rename to test/prism/fixtures/seattlerb/non_interpolated_word_array_line_breaks.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_dot_ident_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_index_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_index_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_index_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_primary_colon_const_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt rename to test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier1.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_primary_colon_identifier_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt b/test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt rename to test/prism/fixtures/seattlerb/op_asgn_val_dot_ident_command_call.txt diff --git a/test/yarp/fixtures/seattlerb/parse_def_special_name.txt b/test/prism/fixtures/seattlerb/parse_def_special_name.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_def_special_name.txt rename to test/prism/fixtures/seattlerb/parse_def_special_name.txt diff --git a/test/yarp/fixtures/seattlerb/parse_if_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_if_not_canonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_if_not_canonical.txt rename to test/prism/fixtures/seattlerb/parse_if_not_canonical.txt diff --git a/test/yarp/fixtures/seattlerb/parse_if_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_if_not_noncanonical.txt rename to test/prism/fixtures/seattlerb/parse_if_not_noncanonical.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_block.txt b/test/prism/fixtures/seattlerb/parse_line_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_block.txt rename to test/prism/fixtures/seattlerb/parse_line_block.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_block_inline_comment.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_block_inline_comment.txt rename to test/prism/fixtures/seattlerb/parse_line_block_inline_comment.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt rename to test/prism/fixtures/seattlerb/parse_line_block_inline_comment_leading_newlines.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt b/test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt rename to test/prism/fixtures/seattlerb/parse_line_block_inline_multiline_comment.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt rename to test/prism/fixtures/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt b/test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt rename to test/prism/fixtures/seattlerb/parse_line_call_ivar_line_break_paren.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_call_no_args.txt b/test/prism/fixtures/seattlerb/parse_line_call_no_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_call_no_args.txt rename to test/prism/fixtures/seattlerb/parse_line_call_no_args.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_defn_complex.txt b/test/prism/fixtures/seattlerb/parse_line_defn_complex.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_defn_complex.txt rename to test/prism/fixtures/seattlerb/parse_line_defn_complex.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_defn_no_parens.txt b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_defn_no_parens.txt rename to test/prism/fixtures/seattlerb/parse_line_defn_no_parens.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_defn_no_parens_args.txt b/test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_defn_no_parens_args.txt rename to test/prism/fixtures/seattlerb/parse_line_defn_no_parens_args.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dot2.txt b/test/prism/fixtures/seattlerb/parse_line_dot2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dot2.txt rename to test/prism/fixtures/seattlerb/parse_line_dot2.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dot2_open.txt b/test/prism/fixtures/seattlerb/parse_line_dot2_open.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dot2_open.txt rename to test/prism/fixtures/seattlerb/parse_line_dot2_open.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dot3.txt b/test/prism/fixtures/seattlerb/parse_line_dot3.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dot3.txt rename to test/prism/fixtures/seattlerb/parse_line_dot3.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dot3_open.txt b/test/prism/fixtures/seattlerb/parse_line_dot3_open.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dot3_open.txt rename to test/prism/fixtures/seattlerb/parse_line_dot3_open.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt b/test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt rename to test/prism/fixtures/seattlerb/parse_line_dstr_escaped_newline.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_dstr_soft_newline.txt b/test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_dstr_soft_newline.txt rename to test/prism/fixtures/seattlerb/parse_line_dstr_soft_newline.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_evstr_after_break.txt b/test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_evstr_after_break.txt rename to test/prism/fixtures/seattlerb/parse_line_evstr_after_break.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_hash_lit.txt b/test/prism/fixtures/seattlerb/parse_line_hash_lit.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_hash_lit.txt rename to test/prism/fixtures/seattlerb/parse_line_hash_lit.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_heredoc.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_heredoc.txt rename to test/prism/fixtures/seattlerb/parse_line_heredoc.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_heredoc_evstr.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_heredoc_evstr.txt rename to test/prism/fixtures/seattlerb/parse_line_heredoc_evstr.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt rename to test/prism/fixtures/seattlerb/parse_line_heredoc_hardnewline.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt b/test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt rename to test/prism/fixtures/seattlerb/parse_line_heredoc_regexp_chars.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_iter_call_no_parens.txt b/test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_iter_call_no_parens.txt rename to test/prism/fixtures/seattlerb/parse_line_iter_call_no_parens.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_iter_call_parens.txt b/test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_iter_call_parens.txt rename to test/prism/fixtures/seattlerb/parse_line_iter_call_parens.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_multiline_str.txt b/test/prism/fixtures/seattlerb/parse_line_multiline_str.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_multiline_str.txt rename to test/prism/fixtures/seattlerb/parse_line_multiline_str.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt b/test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt rename to test/prism/fixtures/seattlerb/parse_line_multiline_str_literal_n.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_newlines.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_newlines.txt rename to test/prism/fixtures/seattlerb/parse_line_newlines.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_op_asgn.txt b/test/prism/fixtures/seattlerb/parse_line_op_asgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_op_asgn.txt rename to test/prism/fixtures/seattlerb/parse_line_op_asgn.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_postexe.txt b/test/prism/fixtures/seattlerb/parse_line_postexe.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_postexe.txt rename to test/prism/fixtures/seattlerb/parse_line_postexe.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_preexe.txt b/test/prism/fixtures/seattlerb/parse_line_preexe.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_preexe.txt rename to test/prism/fixtures/seattlerb/parse_line_preexe.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_rescue.txt b/test/prism/fixtures/seattlerb/parse_line_rescue.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_rescue.txt rename to test/prism/fixtures/seattlerb/parse_line_rescue.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_return.txt b/test/prism/fixtures/seattlerb/parse_line_return.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_return.txt rename to test/prism/fixtures/seattlerb/parse_line_return.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_str_with_newline_escape.txt b/test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_str_with_newline_escape.txt rename to test/prism/fixtures/seattlerb/parse_line_str_with_newline_escape.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_to_ary.txt b/test/prism/fixtures/seattlerb/parse_line_to_ary.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_to_ary.txt rename to test/prism/fixtures/seattlerb/parse_line_to_ary.txt diff --git a/test/yarp/fixtures/seattlerb/parse_line_trailing_newlines.txt b/test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_line_trailing_newlines.txt rename to test/prism/fixtures/seattlerb/parse_line_trailing_newlines.txt diff --git a/test/yarp/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt b/test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt rename to test/prism/fixtures/seattlerb/parse_opt_call_args_assocs_comma.txt diff --git a/test/yarp/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt b/test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt rename to test/prism/fixtures/seattlerb/parse_opt_call_args_lit_comma.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_019.txt b/test/prism/fixtures/seattlerb/parse_pattern_019.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_019.txt rename to test/prism/fixtures/seattlerb/parse_pattern_019.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_044.txt b/test/prism/fixtures/seattlerb/parse_pattern_044.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_044.txt rename to test/prism/fixtures/seattlerb/parse_pattern_044.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_051.txt b/test/prism/fixtures/seattlerb/parse_pattern_051.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_051.txt rename to test/prism/fixtures/seattlerb/parse_pattern_051.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_058.txt b/test/prism/fixtures/seattlerb/parse_pattern_058.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_058.txt rename to test/prism/fixtures/seattlerb/parse_pattern_058.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_058_2.txt b/test/prism/fixtures/seattlerb/parse_pattern_058_2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_058_2.txt rename to test/prism/fixtures/seattlerb/parse_pattern_058_2.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_069.txt b/test/prism/fixtures/seattlerb/parse_pattern_069.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_069.txt rename to test/prism/fixtures/seattlerb/parse_pattern_069.txt diff --git a/test/yarp/fixtures/seattlerb/parse_pattern_076.txt b/test/prism/fixtures/seattlerb/parse_pattern_076.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_pattern_076.txt rename to test/prism/fixtures/seattlerb/parse_pattern_076.txt diff --git a/test/yarp/fixtures/seattlerb/parse_until_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_until_not_canonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_until_not_canonical.txt rename to test/prism/fixtures/seattlerb/parse_until_not_canonical.txt diff --git a/test/yarp/fixtures/seattlerb/parse_until_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_until_not_noncanonical.txt rename to test/prism/fixtures/seattlerb/parse_until_not_noncanonical.txt diff --git a/test/yarp/fixtures/seattlerb/parse_while_not_canonical.txt b/test/prism/fixtures/seattlerb/parse_while_not_canonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_while_not_canonical.txt rename to test/prism/fixtures/seattlerb/parse_while_not_canonical.txt diff --git a/test/yarp/fixtures/seattlerb/parse_while_not_noncanonical.txt b/test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/parse_while_not_noncanonical.txt rename to test/prism/fixtures/seattlerb/parse_while_not_noncanonical.txt diff --git a/test/yarp/fixtures/seattlerb/pctW_lineno.txt b/test/prism/fixtures/seattlerb/pctW_lineno.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pctW_lineno.txt rename to test/prism/fixtures/seattlerb/pctW_lineno.txt diff --git a/test/yarp/fixtures/seattlerb/pct_Q_backslash_nl.txt b/test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pct_Q_backslash_nl.txt rename to test/prism/fixtures/seattlerb/pct_Q_backslash_nl.txt diff --git a/test/yarp/fixtures/seattlerb/pct_nl.txt b/test/prism/fixtures/seattlerb/pct_nl.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pct_nl.txt rename to test/prism/fixtures/seattlerb/pct_nl.txt diff --git a/test/yarp/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt b/test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt rename to test/prism/fixtures/seattlerb/pct_w_heredoc_interp_nested.txt diff --git a/test/yarp/fixtures/seattlerb/pipe_semicolon.txt b/test/prism/fixtures/seattlerb/pipe_semicolon.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pipe_semicolon.txt rename to test/prism/fixtures/seattlerb/pipe_semicolon.txt diff --git a/test/yarp/fixtures/seattlerb/pipe_space.txt b/test/prism/fixtures/seattlerb/pipe_space.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/pipe_space.txt rename to test/prism/fixtures/seattlerb/pipe_space.txt diff --git a/test/yarp/fixtures/seattlerb/qWords_space.txt b/test/prism/fixtures/seattlerb/qWords_space.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qWords_space.txt rename to test/prism/fixtures/seattlerb/qWords_space.txt diff --git a/test/yarp/fixtures/seattlerb/qsymbols.txt b/test/prism/fixtures/seattlerb/qsymbols.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qsymbols.txt rename to test/prism/fixtures/seattlerb/qsymbols.txt diff --git a/test/yarp/fixtures/seattlerb/qsymbols_empty.txt b/test/prism/fixtures/seattlerb/qsymbols_empty.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qsymbols_empty.txt rename to test/prism/fixtures/seattlerb/qsymbols_empty.txt diff --git a/test/yarp/fixtures/seattlerb/qsymbols_empty_space.txt b/test/prism/fixtures/seattlerb/qsymbols_empty_space.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qsymbols_empty_space.txt rename to test/prism/fixtures/seattlerb/qsymbols_empty_space.txt diff --git a/test/yarp/fixtures/seattlerb/qsymbols_interp.txt b/test/prism/fixtures/seattlerb/qsymbols_interp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qsymbols_interp.txt rename to test/prism/fixtures/seattlerb/qsymbols_interp.txt diff --git a/test/yarp/fixtures/seattlerb/quoted_symbol_hash_arg.txt b/test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/quoted_symbol_hash_arg.txt rename to test/prism/fixtures/seattlerb/quoted_symbol_hash_arg.txt diff --git a/test/yarp/fixtures/seattlerb/quoted_symbol_keys.txt b/test/prism/fixtures/seattlerb/quoted_symbol_keys.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/quoted_symbol_keys.txt rename to test/prism/fixtures/seattlerb/quoted_symbol_keys.txt diff --git a/test/yarp/fixtures/seattlerb/qw_escape.txt b/test/prism/fixtures/seattlerb/qw_escape.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qw_escape.txt rename to test/prism/fixtures/seattlerb/qw_escape.txt diff --git a/test/yarp/fixtures/seattlerb/qw_escape_term.txt b/test/prism/fixtures/seattlerb/qw_escape_term.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qw_escape_term.txt rename to test/prism/fixtures/seattlerb/qw_escape_term.txt diff --git a/test/yarp/fixtures/seattlerb/qwords_empty.txt b/test/prism/fixtures/seattlerb/qwords_empty.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/qwords_empty.txt rename to test/prism/fixtures/seattlerb/qwords_empty.txt diff --git a/test/yarp/fixtures/seattlerb/read_escape_unicode_curlies.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/read_escape_unicode_curlies.txt rename to test/prism/fixtures/seattlerb/read_escape_unicode_curlies.txt diff --git a/test/yarp/fixtures/seattlerb/read_escape_unicode_h4.txt b/test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/read_escape_unicode_h4.txt rename to test/prism/fixtures/seattlerb/read_escape_unicode_h4.txt diff --git a/test/yarp/fixtures/seattlerb/regexp.txt b/test/prism/fixtures/seattlerb/regexp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/regexp.txt rename to test/prism/fixtures/seattlerb/regexp.txt diff --git a/test/yarp/fixtures/seattlerb/regexp_esc_C_slash.txt b/test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/regexp_esc_C_slash.txt rename to test/prism/fixtures/seattlerb/regexp_esc_C_slash.txt diff --git a/test/yarp/fixtures/seattlerb/regexp_esc_u.txt b/test/prism/fixtures/seattlerb/regexp_esc_u.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/regexp_esc_u.txt rename to test/prism/fixtures/seattlerb/regexp_esc_u.txt diff --git a/test/yarp/fixtures/seattlerb/regexp_escape_extended.txt b/test/prism/fixtures/seattlerb/regexp_escape_extended.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/regexp_escape_extended.txt rename to test/prism/fixtures/seattlerb/regexp_escape_extended.txt diff --git a/test/yarp/fixtures/seattlerb/regexp_unicode_curlies.txt b/test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/regexp_unicode_curlies.txt rename to test/prism/fixtures/seattlerb/regexp_unicode_curlies.txt diff --git a/test/yarp/fixtures/seattlerb/required_kwarg_no_value.txt b/test/prism/fixtures/seattlerb/required_kwarg_no_value.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/required_kwarg_no_value.txt rename to test/prism/fixtures/seattlerb/required_kwarg_no_value.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_do_end_ensure_result.txt b/test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_do_end_ensure_result.txt rename to test/prism/fixtures/seattlerb/rescue_do_end_ensure_result.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_do_end_no_raise.txt b/test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_do_end_no_raise.txt rename to test/prism/fixtures/seattlerb/rescue_do_end_no_raise.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_do_end_raised.txt b/test/prism/fixtures/seattlerb/rescue_do_end_raised.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_do_end_raised.txt rename to test/prism/fixtures/seattlerb/rescue_do_end_raised.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_do_end_rescued.txt b/test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_do_end_rescued.txt rename to test/prism/fixtures/seattlerb/rescue_do_end_rescued.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_in_block.txt b/test/prism/fixtures/seattlerb/rescue_in_block.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_in_block.txt rename to test/prism/fixtures/seattlerb/rescue_in_block.txt diff --git a/test/yarp/fixtures/seattlerb/rescue_parens.txt b/test/prism/fixtures/seattlerb/rescue_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rescue_parens.txt rename to test/prism/fixtures/seattlerb/rescue_parens.txt diff --git a/test/yarp/fixtures/seattlerb/return_call_assocs.txt b/test/prism/fixtures/seattlerb/return_call_assocs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/return_call_assocs.txt rename to test/prism/fixtures/seattlerb/return_call_assocs.txt diff --git a/test/yarp/fixtures/seattlerb/rhs_asgn.txt b/test/prism/fixtures/seattlerb/rhs_asgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/rhs_asgn.txt rename to test/prism/fixtures/seattlerb/rhs_asgn.txt diff --git a/test/yarp/fixtures/seattlerb/ruby21_numbers.txt b/test/prism/fixtures/seattlerb/ruby21_numbers.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/ruby21_numbers.txt rename to test/prism/fixtures/seattlerb/ruby21_numbers.txt diff --git a/test/yarp/fixtures/seattlerb/safe_attrasgn.txt b/test/prism/fixtures/seattlerb/safe_attrasgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_attrasgn.txt rename to test/prism/fixtures/seattlerb/safe_attrasgn.txt diff --git a/test/yarp/fixtures/seattlerb/safe_attrasgn_constant.txt b/test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_attrasgn_constant.txt rename to test/prism/fixtures/seattlerb/safe_attrasgn_constant.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call.txt b/test/prism/fixtures/seattlerb/safe_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call.txt rename to test/prism/fixtures/seattlerb/safe_call.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call_after_newline.txt b/test/prism/fixtures/seattlerb/safe_call_after_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call_after_newline.txt rename to test/prism/fixtures/seattlerb/safe_call_after_newline.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call_dot_parens.txt b/test/prism/fixtures/seattlerb/safe_call_dot_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call_dot_parens.txt rename to test/prism/fixtures/seattlerb/safe_call_dot_parens.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call_newline.txt b/test/prism/fixtures/seattlerb/safe_call_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call_newline.txt rename to test/prism/fixtures/seattlerb/safe_call_newline.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call_operator.txt b/test/prism/fixtures/seattlerb/safe_call_operator.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call_operator.txt rename to test/prism/fixtures/seattlerb/safe_call_operator.txt diff --git a/test/yarp/fixtures/seattlerb/safe_call_rhs_newline.txt b/test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_call_rhs_newline.txt rename to test/prism/fixtures/seattlerb/safe_call_rhs_newline.txt diff --git a/test/yarp/fixtures/seattlerb/safe_calls.txt b/test/prism/fixtures/seattlerb/safe_calls.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_calls.txt rename to test/prism/fixtures/seattlerb/safe_calls.txt diff --git a/test/yarp/fixtures/seattlerb/safe_op_asgn.txt b/test/prism/fixtures/seattlerb/safe_op_asgn.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_op_asgn.txt rename to test/prism/fixtures/seattlerb/safe_op_asgn.txt diff --git a/test/yarp/fixtures/seattlerb/safe_op_asgn2.txt b/test/prism/fixtures/seattlerb/safe_op_asgn2.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/safe_op_asgn2.txt rename to test/prism/fixtures/seattlerb/safe_op_asgn2.txt diff --git a/test/yarp/fixtures/seattlerb/slashy_newlines_within_string.txt b/test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/slashy_newlines_within_string.txt rename to test/prism/fixtures/seattlerb/slashy_newlines_within_string.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_arg_no_paren.txt b/test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_arg_no_paren.txt rename to test/prism/fixtures/seattlerb/stabby_arg_no_paren.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt rename to test/prism/fixtures/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_block_iter_call.txt b/test/prism/fixtures/seattlerb/stabby_block_iter_call.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_block_iter_call.txt rename to test/prism/fixtures/seattlerb/stabby_block_iter_call.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt rename to test/prism/fixtures/seattlerb/stabby_block_iter_call_no_target_with_arg.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_block_kw.txt b/test/prism/fixtures/seattlerb/stabby_block_kw.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_block_kw.txt rename to test/prism/fixtures/seattlerb/stabby_block_kw.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_block_kw__required.txt b/test/prism/fixtures/seattlerb/stabby_block_kw__required.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_block_kw__required.txt rename to test/prism/fixtures/seattlerb/stabby_block_kw__required.txt diff --git a/test/yarp/fixtures/seattlerb/stabby_proc_scope.txt b/test/prism/fixtures/seattlerb/stabby_proc_scope.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/stabby_proc_scope.txt rename to test/prism/fixtures/seattlerb/stabby_proc_scope.txt diff --git a/test/yarp/fixtures/seattlerb/str_backslashes.txt b/test/prism/fixtures/seattlerb/str_backslashes.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_backslashes.txt rename to test/prism/fixtures/seattlerb/str_backslashes.txt diff --git a/test/yarp/fixtures/seattlerb/str_double_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_double_double_escaped_newline.txt rename to test/prism/fixtures/seattlerb/str_double_double_escaped_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_double_escaped_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_double_escaped_newline.txt rename to test/prism/fixtures/seattlerb/str_double_escaped_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_double_newline.txt b/test/prism/fixtures/seattlerb/str_double_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_double_newline.txt rename to test/prism/fixtures/seattlerb/str_double_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_evstr.txt b/test/prism/fixtures/seattlerb/str_evstr.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_evstr.txt rename to test/prism/fixtures/seattlerb/str_evstr.txt diff --git a/test/yarp/fixtures/seattlerb/str_evstr_escape.txt b/test/prism/fixtures/seattlerb/str_evstr_escape.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_evstr_escape.txt rename to test/prism/fixtures/seattlerb/str_evstr_escape.txt diff --git a/test/yarp/fixtures/seattlerb/str_heredoc_interp.txt b/test/prism/fixtures/seattlerb/str_heredoc_interp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_heredoc_interp.txt rename to test/prism/fixtures/seattlerb/str_heredoc_interp.txt diff --git a/test/yarp/fixtures/seattlerb/str_interp_ternary_or_label.txt b/test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_interp_ternary_or_label.txt rename to test/prism/fixtures/seattlerb/str_interp_ternary_or_label.txt diff --git a/test/yarp/fixtures/seattlerb/str_lit_concat_bad_encodings.txt b/test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_lit_concat_bad_encodings.txt rename to test/prism/fixtures/seattlerb/str_lit_concat_bad_encodings.txt diff --git a/test/yarp/fixtures/seattlerb/str_newline_hash_line_number.txt b/test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_newline_hash_line_number.txt rename to test/prism/fixtures/seattlerb/str_newline_hash_line_number.txt diff --git a/test/yarp/fixtures/seattlerb/str_pct_Q_nested.txt b/test/prism/fixtures/seattlerb/str_pct_Q_nested.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_pct_Q_nested.txt rename to test/prism/fixtures/seattlerb/str_pct_Q_nested.txt diff --git a/test/yarp/fixtures/seattlerb/str_pct_nested_nested.txt b/test/prism/fixtures/seattlerb/str_pct_nested_nested.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_pct_nested_nested.txt rename to test/prism/fixtures/seattlerb/str_pct_nested_nested.txt diff --git a/test/yarp/fixtures/seattlerb/str_pct_q.txt b/test/prism/fixtures/seattlerb/str_pct_q.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_pct_q.txt rename to test/prism/fixtures/seattlerb/str_pct_q.txt diff --git a/test/yarp/fixtures/seattlerb/str_single_double_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_single_double_escaped_newline.txt rename to test/prism/fixtures/seattlerb/str_single_double_escaped_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_single_escaped_newline.txt b/test/prism/fixtures/seattlerb/str_single_escaped_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_single_escaped_newline.txt rename to test/prism/fixtures/seattlerb/str_single_escaped_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_single_newline.txt b/test/prism/fixtures/seattlerb/str_single_newline.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_single_newline.txt rename to test/prism/fixtures/seattlerb/str_single_newline.txt diff --git a/test/yarp/fixtures/seattlerb/str_str.txt b/test/prism/fixtures/seattlerb/str_str.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_str.txt rename to test/prism/fixtures/seattlerb/str_str.txt diff --git a/test/yarp/fixtures/seattlerb/str_str_str.txt b/test/prism/fixtures/seattlerb/str_str_str.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/str_str_str.txt rename to test/prism/fixtures/seattlerb/str_str_str.txt diff --git a/test/yarp/fixtures/seattlerb/super_arg.txt b/test/prism/fixtures/seattlerb/super_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/super_arg.txt rename to test/prism/fixtures/seattlerb/super_arg.txt diff --git a/test/yarp/fixtures/seattlerb/symbol_empty.txt b/test/prism/fixtures/seattlerb/symbol_empty.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbol_empty.txt rename to test/prism/fixtures/seattlerb/symbol_empty.txt diff --git a/test/yarp/fixtures/seattlerb/symbol_list.txt b/test/prism/fixtures/seattlerb/symbol_list.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbol_list.txt rename to test/prism/fixtures/seattlerb/symbol_list.txt diff --git a/test/yarp/fixtures/seattlerb/symbols.txt b/test/prism/fixtures/seattlerb/symbols.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbols.txt rename to test/prism/fixtures/seattlerb/symbols.txt diff --git a/test/yarp/fixtures/seattlerb/symbols_empty.txt b/test/prism/fixtures/seattlerb/symbols_empty.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbols_empty.txt rename to test/prism/fixtures/seattlerb/symbols_empty.txt diff --git a/test/yarp/fixtures/seattlerb/symbols_empty_space.txt b/test/prism/fixtures/seattlerb/symbols_empty_space.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbols_empty_space.txt rename to test/prism/fixtures/seattlerb/symbols_empty_space.txt diff --git a/test/yarp/fixtures/seattlerb/symbols_interp.txt b/test/prism/fixtures/seattlerb/symbols_interp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/symbols_interp.txt rename to test/prism/fixtures/seattlerb/symbols_interp.txt diff --git a/test/yarp/fixtures/seattlerb/thingy.txt b/test/prism/fixtures/seattlerb/thingy.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/thingy.txt rename to test/prism/fixtures/seattlerb/thingy.txt diff --git a/test/yarp/fixtures/seattlerb/uminus_float.txt b/test/prism/fixtures/seattlerb/uminus_float.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/uminus_float.txt rename to test/prism/fixtures/seattlerb/uminus_float.txt diff --git a/test/yarp/fixtures/seattlerb/unary_minus.txt b/test/prism/fixtures/seattlerb/unary_minus.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/unary_minus.txt rename to test/prism/fixtures/seattlerb/unary_minus.txt diff --git a/test/yarp/fixtures/seattlerb/unary_plus.txt b/test/prism/fixtures/seattlerb/unary_plus.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/unary_plus.txt rename to test/prism/fixtures/seattlerb/unary_plus.txt diff --git a/test/yarp/fixtures/seattlerb/unary_plus_on_literal.txt b/test/prism/fixtures/seattlerb/unary_plus_on_literal.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/unary_plus_on_literal.txt rename to test/prism/fixtures/seattlerb/unary_plus_on_literal.txt diff --git a/test/yarp/fixtures/seattlerb/unary_tilde.txt b/test/prism/fixtures/seattlerb/unary_tilde.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/unary_tilde.txt rename to test/prism/fixtures/seattlerb/unary_tilde.txt diff --git a/test/yarp/fixtures/seattlerb/utf8_bom.txt b/test/prism/fixtures/seattlerb/utf8_bom.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/utf8_bom.txt rename to test/prism/fixtures/seattlerb/utf8_bom.txt diff --git a/test/yarp/fixtures/seattlerb/when_splat.txt b/test/prism/fixtures/seattlerb/when_splat.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/when_splat.txt rename to test/prism/fixtures/seattlerb/when_splat.txt diff --git a/test/yarp/fixtures/seattlerb/words_interp.txt b/test/prism/fixtures/seattlerb/words_interp.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/words_interp.txt rename to test/prism/fixtures/seattlerb/words_interp.txt diff --git a/test/yarp/fixtures/seattlerb/yield_arg.txt b/test/prism/fixtures/seattlerb/yield_arg.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/yield_arg.txt rename to test/prism/fixtures/seattlerb/yield_arg.txt diff --git a/test/yarp/fixtures/seattlerb/yield_call_assocs.txt b/test/prism/fixtures/seattlerb/yield_call_assocs.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/yield_call_assocs.txt rename to test/prism/fixtures/seattlerb/yield_call_assocs.txt diff --git a/test/yarp/fixtures/seattlerb/yield_empty_parens.txt b/test/prism/fixtures/seattlerb/yield_empty_parens.txt similarity index 100% rename from test/yarp/fixtures/seattlerb/yield_empty_parens.txt rename to test/prism/fixtures/seattlerb/yield_empty_parens.txt diff --git a/test/yarp/fixtures/single_quote_heredocs.txt b/test/prism/fixtures/single_quote_heredocs.txt similarity index 100% rename from test/yarp/fixtures/single_quote_heredocs.txt rename to test/prism/fixtures/single_quote_heredocs.txt diff --git a/test/prism/fixtures/spanning_heredoc.txt b/test/prism/fixtures/spanning_heredoc.txt new file mode 100644 index 00000000000000..d88e0e4be1eed6 --- /dev/null +++ b/test/prism/fixtures/spanning_heredoc.txt @@ -0,0 +1,51 @@ +# 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] diff --git a/test/prism/fixtures/strings.txt b/test/prism/fixtures/strings.txt new file mode 100644 index 00000000000000..2ce8b738a39e18 --- /dev/null +++ b/test/prism/fixtures/strings.txt @@ -0,0 +1,105 @@ +%%abc% + +%^abc^ + +%&abc& + +%*abc* + +%_abc_ + +%+abc+ + +%-abc- + +%:abc: + +%;abc; + +%'abc' + +%~abc~ + +%?abc? + +%w{ } + +%/abc/ + +%`abc` + +"#@@foo" + +%\abc\ + +%{aaa #{bbb} ccc} + +%[foo[]] + +"foo" + +# +"bar" + +%q{abc} + +%s[abc] + +%{abc} + +'' + +"abc" + +"#@---" + +"aaa #{bbb} ccc" + +'abc' + +%w[a b c] + +%w[a[] b[[]] c[]] + +%w[foo\ bar \#{1}] + +%w[foo\ bar baz] + +%W[a b#{c}d e] + +%W[a b c] + +%w[ + a + b + c +] + +'\' foo \' bar' + +'\\ foo \\ bar' + +"#$foo" + +"#@foo" + +"\x7 \x23 \x61" + +"\7 \43 \141" + +%[abc] + +%(abc) + +%@abc@ + +%$abc$ + +?a + +?a "a" + +%Q{abc} + +%^#$^# + +%@#@# diff --git a/test/yarp/fixtures/super.txt b/test/prism/fixtures/super.txt similarity index 100% rename from test/yarp/fixtures/super.txt rename to test/prism/fixtures/super.txt diff --git a/test/yarp/fixtures/symbols.txt b/test/prism/fixtures/symbols.txt similarity index 100% rename from test/yarp/fixtures/symbols.txt rename to test/prism/fixtures/symbols.txt diff --git a/test/yarp/fixtures/ternary_operator.txt b/test/prism/fixtures/ternary_operator.txt similarity index 100% rename from test/yarp/fixtures/ternary_operator.txt rename to test/prism/fixtures/ternary_operator.txt diff --git a/test/yarp/fixtures/tilde_heredocs.txt b/test/prism/fixtures/tilde_heredocs.txt similarity index 100% rename from test/yarp/fixtures/tilde_heredocs.txt rename to test/prism/fixtures/tilde_heredocs.txt diff --git a/test/yarp/fixtures/undef.txt b/test/prism/fixtures/undef.txt similarity index 100% rename from test/yarp/fixtures/undef.txt rename to test/prism/fixtures/undef.txt diff --git a/test/yarp/fixtures/unescaping.txt b/test/prism/fixtures/unescaping.txt similarity index 100% rename from test/yarp/fixtures/unescaping.txt rename to test/prism/fixtures/unescaping.txt diff --git a/test/yarp/fixtures/unless.txt b/test/prism/fixtures/unless.txt similarity index 100% rename from test/yarp/fixtures/unless.txt rename to test/prism/fixtures/unless.txt diff --git a/test/yarp/fixtures/unparser/LICENSE b/test/prism/fixtures/unparser/LICENSE similarity index 100% rename from test/yarp/fixtures/unparser/LICENSE rename to test/prism/fixtures/unparser/LICENSE diff --git a/test/yarp/fixtures/unparser/corpus/literal/alias.txt b/test/prism/fixtures/unparser/corpus/literal/alias.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/alias.txt rename to test/prism/fixtures/unparser/corpus/literal/alias.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/assignment.txt b/test/prism/fixtures/unparser/corpus/literal/assignment.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/assignment.txt rename to test/prism/fixtures/unparser/corpus/literal/assignment.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/block.txt b/test/prism/fixtures/unparser/corpus/literal/block.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/block.txt rename to test/prism/fixtures/unparser/corpus/literal/block.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/case.txt b/test/prism/fixtures/unparser/corpus/literal/case.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/case.txt rename to test/prism/fixtures/unparser/corpus/literal/case.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/class.txt b/test/prism/fixtures/unparser/corpus/literal/class.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/class.txt rename to test/prism/fixtures/unparser/corpus/literal/class.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/control.txt b/test/prism/fixtures/unparser/corpus/literal/control.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/control.txt rename to test/prism/fixtures/unparser/corpus/literal/control.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/def.txt b/test/prism/fixtures/unparser/corpus/literal/def.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/def.txt rename to test/prism/fixtures/unparser/corpus/literal/def.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/defined.txt b/test/prism/fixtures/unparser/corpus/literal/defined.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/defined.txt rename to test/prism/fixtures/unparser/corpus/literal/defined.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/defs.txt b/test/prism/fixtures/unparser/corpus/literal/defs.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/defs.txt rename to test/prism/fixtures/unparser/corpus/literal/defs.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/dstr.txt b/test/prism/fixtures/unparser/corpus/literal/dstr.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/dstr.txt rename to test/prism/fixtures/unparser/corpus/literal/dstr.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/empty.txt b/test/prism/fixtures/unparser/corpus/literal/empty.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/empty.txt rename to test/prism/fixtures/unparser/corpus/literal/empty.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/empty_begin.txt b/test/prism/fixtures/unparser/corpus/literal/empty_begin.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/empty_begin.txt rename to test/prism/fixtures/unparser/corpus/literal/empty_begin.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/flipflop.txt b/test/prism/fixtures/unparser/corpus/literal/flipflop.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/flipflop.txt rename to test/prism/fixtures/unparser/corpus/literal/flipflop.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/for.txt b/test/prism/fixtures/unparser/corpus/literal/for.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/for.txt rename to test/prism/fixtures/unparser/corpus/literal/for.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/hookexe.txt b/test/prism/fixtures/unparser/corpus/literal/hookexe.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/hookexe.txt rename to test/prism/fixtures/unparser/corpus/literal/hookexe.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/if.txt b/test/prism/fixtures/unparser/corpus/literal/if.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/if.txt rename to test/prism/fixtures/unparser/corpus/literal/if.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/kwbegin.txt b/test/prism/fixtures/unparser/corpus/literal/kwbegin.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/kwbegin.txt rename to test/prism/fixtures/unparser/corpus/literal/kwbegin.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/lambda.txt b/test/prism/fixtures/unparser/corpus/literal/lambda.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/lambda.txt rename to test/prism/fixtures/unparser/corpus/literal/lambda.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/literal.txt b/test/prism/fixtures/unparser/corpus/literal/literal.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/literal.txt rename to test/prism/fixtures/unparser/corpus/literal/literal.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/module.txt b/test/prism/fixtures/unparser/corpus/literal/module.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/module.txt rename to test/prism/fixtures/unparser/corpus/literal/module.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/opasgn.txt b/test/prism/fixtures/unparser/corpus/literal/opasgn.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/opasgn.txt rename to test/prism/fixtures/unparser/corpus/literal/opasgn.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/pattern.txt b/test/prism/fixtures/unparser/corpus/literal/pattern.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/pattern.txt rename to test/prism/fixtures/unparser/corpus/literal/pattern.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/pragma.txt b/test/prism/fixtures/unparser/corpus/literal/pragma.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/pragma.txt rename to test/prism/fixtures/unparser/corpus/literal/pragma.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/range.txt b/test/prism/fixtures/unparser/corpus/literal/range.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/range.txt rename to test/prism/fixtures/unparser/corpus/literal/range.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/rescue.txt b/test/prism/fixtures/unparser/corpus/literal/rescue.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/rescue.txt rename to test/prism/fixtures/unparser/corpus/literal/rescue.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/send.txt b/test/prism/fixtures/unparser/corpus/literal/send.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/send.txt rename to test/prism/fixtures/unparser/corpus/literal/send.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/since/27.txt b/test/prism/fixtures/unparser/corpus/literal/since/27.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/since/27.txt rename to test/prism/fixtures/unparser/corpus/literal/since/27.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/since/30.txt b/test/prism/fixtures/unparser/corpus/literal/since/30.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/since/30.txt rename to test/prism/fixtures/unparser/corpus/literal/since/30.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/since/31.txt b/test/prism/fixtures/unparser/corpus/literal/since/31.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/since/31.txt rename to test/prism/fixtures/unparser/corpus/literal/since/31.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/since/32.txt b/test/prism/fixtures/unparser/corpus/literal/since/32.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/since/32.txt rename to test/prism/fixtures/unparser/corpus/literal/since/32.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/singletons.txt b/test/prism/fixtures/unparser/corpus/literal/singletons.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/singletons.txt rename to test/prism/fixtures/unparser/corpus/literal/singletons.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/super.txt b/test/prism/fixtures/unparser/corpus/literal/super.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/super.txt rename to test/prism/fixtures/unparser/corpus/literal/super.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/unary.txt b/test/prism/fixtures/unparser/corpus/literal/unary.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/unary.txt rename to test/prism/fixtures/unparser/corpus/literal/unary.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/undef.txt b/test/prism/fixtures/unparser/corpus/literal/undef.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/undef.txt rename to test/prism/fixtures/unparser/corpus/literal/undef.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/variables.txt b/test/prism/fixtures/unparser/corpus/literal/variables.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/variables.txt rename to test/prism/fixtures/unparser/corpus/literal/variables.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/while.txt b/test/prism/fixtures/unparser/corpus/literal/while.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/while.txt rename to test/prism/fixtures/unparser/corpus/literal/while.txt diff --git a/test/yarp/fixtures/unparser/corpus/literal/yield.txt b/test/prism/fixtures/unparser/corpus/literal/yield.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/literal/yield.txt rename to test/prism/fixtures/unparser/corpus/literal/yield.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/and.txt b/test/prism/fixtures/unparser/corpus/semantic/and.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/and.txt rename to test/prism/fixtures/unparser/corpus/semantic/and.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/block.txt b/test/prism/fixtures/unparser/corpus/semantic/block.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/block.txt rename to test/prism/fixtures/unparser/corpus/semantic/block.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/def.txt b/test/prism/fixtures/unparser/corpus/semantic/def.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/def.txt rename to test/prism/fixtures/unparser/corpus/semantic/def.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/dstr.txt b/test/prism/fixtures/unparser/corpus/semantic/dstr.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/dstr.txt rename to test/prism/fixtures/unparser/corpus/semantic/dstr.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/kwbegin.txt b/test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/kwbegin.txt rename to test/prism/fixtures/unparser/corpus/semantic/kwbegin.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/literal.txt b/test/prism/fixtures/unparser/corpus/semantic/literal.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/literal.txt rename to test/prism/fixtures/unparser/corpus/semantic/literal.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/send.txt b/test/prism/fixtures/unparser/corpus/semantic/send.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/send.txt rename to test/prism/fixtures/unparser/corpus/semantic/send.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/undef.txt b/test/prism/fixtures/unparser/corpus/semantic/undef.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/undef.txt rename to test/prism/fixtures/unparser/corpus/semantic/undef.txt diff --git a/test/yarp/fixtures/unparser/corpus/semantic/while.txt b/test/prism/fixtures/unparser/corpus/semantic/while.txt similarity index 100% rename from test/yarp/fixtures/unparser/corpus/semantic/while.txt rename to test/prism/fixtures/unparser/corpus/semantic/while.txt diff --git a/test/yarp/fixtures/until.txt b/test/prism/fixtures/until.txt similarity index 100% rename from test/yarp/fixtures/until.txt rename to test/prism/fixtures/until.txt diff --git a/test/yarp/fixtures/variables.txt b/test/prism/fixtures/variables.txt similarity index 100% rename from test/yarp/fixtures/variables.txt rename to test/prism/fixtures/variables.txt diff --git a/test/yarp/fixtures/while.txt b/test/prism/fixtures/while.txt similarity index 100% rename from test/yarp/fixtures/while.txt rename to test/prism/fixtures/while.txt diff --git a/test/yarp/fixtures/whitequark/LICENSE b/test/prism/fixtures/whitequark/LICENSE similarity index 100% rename from test/yarp/fixtures/whitequark/LICENSE rename to test/prism/fixtures/whitequark/LICENSE diff --git a/test/yarp/fixtures/whitequark/__ENCODING__.txt b/test/prism/fixtures/whitequark/__ENCODING__.txt similarity index 100% rename from test/yarp/fixtures/whitequark/__ENCODING__.txt rename to test/prism/fixtures/whitequark/__ENCODING__.txt diff --git a/test/yarp/fixtures/whitequark/__ENCODING___legacy_.txt b/test/prism/fixtures/whitequark/__ENCODING___legacy_.txt similarity index 100% rename from test/yarp/fixtures/whitequark/__ENCODING___legacy_.txt rename to test/prism/fixtures/whitequark/__ENCODING___legacy_.txt diff --git a/test/yarp/fixtures/whitequark/alias.txt b/test/prism/fixtures/whitequark/alias.txt similarity index 100% rename from test/yarp/fixtures/whitequark/alias.txt rename to test/prism/fixtures/whitequark/alias.txt diff --git a/test/yarp/fixtures/whitequark/alias_gvar.txt b/test/prism/fixtures/whitequark/alias_gvar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/alias_gvar.txt rename to test/prism/fixtures/whitequark/alias_gvar.txt diff --git a/test/yarp/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt b/test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt rename to test/prism/fixtures/whitequark/ambiuous_quoted_label_in_ternary_operator.txt diff --git a/test/yarp/fixtures/whitequark/and.txt b/test/prism/fixtures/whitequark/and.txt similarity index 100% rename from test/yarp/fixtures/whitequark/and.txt rename to test/prism/fixtures/whitequark/and.txt diff --git a/test/yarp/fixtures/whitequark/and_asgn.txt b/test/prism/fixtures/whitequark/and_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/and_asgn.txt rename to test/prism/fixtures/whitequark/and_asgn.txt diff --git a/test/yarp/fixtures/whitequark/and_or_masgn.txt b/test/prism/fixtures/whitequark/and_or_masgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/and_or_masgn.txt rename to test/prism/fixtures/whitequark/and_or_masgn.txt diff --git a/test/yarp/fixtures/whitequark/anonymous_blockarg.txt b/test/prism/fixtures/whitequark/anonymous_blockarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/anonymous_blockarg.txt rename to test/prism/fixtures/whitequark/anonymous_blockarg.txt diff --git a/test/yarp/fixtures/whitequark/arg.txt b/test/prism/fixtures/whitequark/arg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/arg.txt rename to test/prism/fixtures/whitequark/arg.txt diff --git a/test/yarp/fixtures/whitequark/arg_duplicate_ignored.txt b/test/prism/fixtures/whitequark/arg_duplicate_ignored.txt similarity index 100% rename from test/yarp/fixtures/whitequark/arg_duplicate_ignored.txt rename to test/prism/fixtures/whitequark/arg_duplicate_ignored.txt diff --git a/test/yarp/fixtures/whitequark/arg_label.txt b/test/prism/fixtures/whitequark/arg_label.txt similarity index 100% rename from test/yarp/fixtures/whitequark/arg_label.txt rename to test/prism/fixtures/whitequark/arg_label.txt diff --git a/test/yarp/fixtures/whitequark/arg_scope.txt b/test/prism/fixtures/whitequark/arg_scope.txt similarity index 100% rename from test/yarp/fixtures/whitequark/arg_scope.txt rename to test/prism/fixtures/whitequark/arg_scope.txt diff --git a/test/yarp/fixtures/whitequark/args.txt b/test/prism/fixtures/whitequark/args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args.txt rename to test/prism/fixtures/whitequark/args.txt diff --git a/test/yarp/fixtures/whitequark/args_args_assocs.txt b/test/prism/fixtures/whitequark/args_args_assocs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_args_assocs.txt rename to test/prism/fixtures/whitequark/args_args_assocs.txt diff --git a/test/yarp/fixtures/whitequark/args_args_assocs_comma.txt b/test/prism/fixtures/whitequark/args_args_assocs_comma.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_args_assocs_comma.txt rename to test/prism/fixtures/whitequark/args_args_assocs_comma.txt diff --git a/test/yarp/fixtures/whitequark/args_args_comma.txt b/test/prism/fixtures/whitequark/args_args_comma.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_args_comma.txt rename to test/prism/fixtures/whitequark/args_args_comma.txt diff --git a/test/yarp/fixtures/whitequark/args_args_star.txt b/test/prism/fixtures/whitequark/args_args_star.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_args_star.txt rename to test/prism/fixtures/whitequark/args_args_star.txt diff --git a/test/yarp/fixtures/whitequark/args_assocs.txt b/test/prism/fixtures/whitequark/args_assocs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_assocs.txt rename to test/prism/fixtures/whitequark/args_assocs.txt diff --git a/test/yarp/fixtures/whitequark/args_assocs_comma.txt b/test/prism/fixtures/whitequark/args_assocs_comma.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_assocs_comma.txt rename to test/prism/fixtures/whitequark/args_assocs_comma.txt diff --git a/test/yarp/fixtures/whitequark/args_assocs_legacy.txt b/test/prism/fixtures/whitequark/args_assocs_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_assocs_legacy.txt rename to test/prism/fixtures/whitequark/args_assocs_legacy.txt diff --git a/test/yarp/fixtures/whitequark/args_block_pass.txt b/test/prism/fixtures/whitequark/args_block_pass.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_block_pass.txt rename to test/prism/fixtures/whitequark/args_block_pass.txt diff --git a/test/yarp/fixtures/whitequark/args_cmd.txt b/test/prism/fixtures/whitequark/args_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_cmd.txt rename to test/prism/fixtures/whitequark/args_cmd.txt diff --git a/test/yarp/fixtures/whitequark/args_star.txt b/test/prism/fixtures/whitequark/args_star.txt similarity index 100% rename from test/yarp/fixtures/whitequark/args_star.txt rename to test/prism/fixtures/whitequark/args_star.txt diff --git a/test/yarp/fixtures/whitequark/array_assocs.txt b/test/prism/fixtures/whitequark/array_assocs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_assocs.txt rename to test/prism/fixtures/whitequark/array_assocs.txt diff --git a/test/yarp/fixtures/whitequark/array_plain.txt b/test/prism/fixtures/whitequark/array_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_plain.txt rename to test/prism/fixtures/whitequark/array_plain.txt diff --git a/test/yarp/fixtures/whitequark/array_splat.txt b/test/prism/fixtures/whitequark/array_splat.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_splat.txt rename to test/prism/fixtures/whitequark/array_splat.txt diff --git a/test/yarp/fixtures/whitequark/array_symbols.txt b/test/prism/fixtures/whitequark/array_symbols.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_symbols.txt rename to test/prism/fixtures/whitequark/array_symbols.txt diff --git a/test/yarp/fixtures/whitequark/array_symbols_empty.txt b/test/prism/fixtures/whitequark/array_symbols_empty.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_symbols_empty.txt rename to test/prism/fixtures/whitequark/array_symbols_empty.txt diff --git a/test/yarp/fixtures/whitequark/array_symbols_interp.txt b/test/prism/fixtures/whitequark/array_symbols_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_symbols_interp.txt rename to test/prism/fixtures/whitequark/array_symbols_interp.txt diff --git a/test/yarp/fixtures/whitequark/array_words.txt b/test/prism/fixtures/whitequark/array_words.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_words.txt rename to test/prism/fixtures/whitequark/array_words.txt diff --git a/test/yarp/fixtures/whitequark/array_words_empty.txt b/test/prism/fixtures/whitequark/array_words_empty.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_words_empty.txt rename to test/prism/fixtures/whitequark/array_words_empty.txt diff --git a/test/yarp/fixtures/whitequark/array_words_interp.txt b/test/prism/fixtures/whitequark/array_words_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/array_words_interp.txt rename to test/prism/fixtures/whitequark/array_words_interp.txt diff --git a/test/yarp/fixtures/whitequark/asgn_cmd.txt b/test/prism/fixtures/whitequark/asgn_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/asgn_cmd.txt rename to test/prism/fixtures/whitequark/asgn_cmd.txt diff --git a/test/yarp/fixtures/whitequark/asgn_mrhs.txt b/test/prism/fixtures/whitequark/asgn_mrhs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/asgn_mrhs.txt rename to test/prism/fixtures/whitequark/asgn_mrhs.txt diff --git a/test/yarp/fixtures/whitequark/back_ref.txt b/test/prism/fixtures/whitequark/back_ref.txt similarity index 100% rename from test/yarp/fixtures/whitequark/back_ref.txt rename to test/prism/fixtures/whitequark/back_ref.txt diff --git a/test/yarp/fixtures/whitequark/bang.txt b/test/prism/fixtures/whitequark/bang.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bang.txt rename to test/prism/fixtures/whitequark/bang.txt diff --git a/test/yarp/fixtures/whitequark/bang_cmd.txt b/test/prism/fixtures/whitequark/bang_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bang_cmd.txt rename to test/prism/fixtures/whitequark/bang_cmd.txt diff --git a/test/yarp/fixtures/whitequark/begin_cmdarg.txt b/test/prism/fixtures/whitequark/begin_cmdarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/begin_cmdarg.txt rename to test/prism/fixtures/whitequark/begin_cmdarg.txt diff --git a/test/yarp/fixtures/whitequark/beginless_erange_after_newline.txt b/test/prism/fixtures/whitequark/beginless_erange_after_newline.txt similarity index 100% rename from test/yarp/fixtures/whitequark/beginless_erange_after_newline.txt rename to test/prism/fixtures/whitequark/beginless_erange_after_newline.txt diff --git a/test/yarp/fixtures/whitequark/beginless_irange_after_newline.txt b/test/prism/fixtures/whitequark/beginless_irange_after_newline.txt similarity index 100% rename from test/yarp/fixtures/whitequark/beginless_irange_after_newline.txt rename to test/prism/fixtures/whitequark/beginless_irange_after_newline.txt diff --git a/test/yarp/fixtures/whitequark/beginless_range.txt b/test/prism/fixtures/whitequark/beginless_range.txt similarity index 100% rename from test/yarp/fixtures/whitequark/beginless_range.txt rename to test/prism/fixtures/whitequark/beginless_range.txt diff --git a/test/yarp/fixtures/whitequark/blockarg.txt b/test/prism/fixtures/whitequark/blockarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/blockarg.txt rename to test/prism/fixtures/whitequark/blockarg.txt diff --git a/test/yarp/fixtures/whitequark/blockargs.txt b/test/prism/fixtures/whitequark/blockargs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/blockargs.txt rename to test/prism/fixtures/whitequark/blockargs.txt diff --git a/test/yarp/fixtures/whitequark/break.txt b/test/prism/fixtures/whitequark/break.txt similarity index 100% rename from test/yarp/fixtures/whitequark/break.txt rename to test/prism/fixtures/whitequark/break.txt diff --git a/test/yarp/fixtures/whitequark/break_block.txt b/test/prism/fixtures/whitequark/break_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/break_block.txt rename to test/prism/fixtures/whitequark/break_block.txt diff --git a/test/yarp/fixtures/whitequark/bug_435.txt b/test/prism/fixtures/whitequark/bug_435.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_435.txt rename to test/prism/fixtures/whitequark/bug_435.txt diff --git a/test/yarp/fixtures/whitequark/bug_447.txt b/test/prism/fixtures/whitequark/bug_447.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_447.txt rename to test/prism/fixtures/whitequark/bug_447.txt diff --git a/test/yarp/fixtures/whitequark/bug_452.txt b/test/prism/fixtures/whitequark/bug_452.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_452.txt rename to test/prism/fixtures/whitequark/bug_452.txt diff --git a/test/yarp/fixtures/whitequark/bug_466.txt b/test/prism/fixtures/whitequark/bug_466.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_466.txt rename to test/prism/fixtures/whitequark/bug_466.txt diff --git a/test/yarp/fixtures/whitequark/bug_473.txt b/test/prism/fixtures/whitequark/bug_473.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_473.txt rename to test/prism/fixtures/whitequark/bug_473.txt diff --git a/test/yarp/fixtures/whitequark/bug_480.txt b/test/prism/fixtures/whitequark/bug_480.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_480.txt rename to test/prism/fixtures/whitequark/bug_480.txt diff --git a/test/yarp/fixtures/whitequark/bug_481.txt b/test/prism/fixtures/whitequark/bug_481.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_481.txt rename to test/prism/fixtures/whitequark/bug_481.txt diff --git a/test/yarp/fixtures/whitequark/bug_ascii_8bit_in_literal.txt b/test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_ascii_8bit_in_literal.txt rename to test/prism/fixtures/whitequark/bug_ascii_8bit_in_literal.txt diff --git a/test/yarp/fixtures/whitequark/bug_cmd_string_lookahead.txt b/test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_cmd_string_lookahead.txt rename to test/prism/fixtures/whitequark/bug_cmd_string_lookahead.txt diff --git a/test/yarp/fixtures/whitequark/bug_cmdarg.txt b/test/prism/fixtures/whitequark/bug_cmdarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_cmdarg.txt rename to test/prism/fixtures/whitequark/bug_cmdarg.txt diff --git a/test/yarp/fixtures/whitequark/bug_def_no_paren_eql_begin.txt b/test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_def_no_paren_eql_begin.txt rename to test/prism/fixtures/whitequark/bug_def_no_paren_eql_begin.txt diff --git a/test/yarp/fixtures/whitequark/bug_do_block_in_call_args.txt b/test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_do_block_in_call_args.txt rename to test/prism/fixtures/whitequark/bug_do_block_in_call_args.txt diff --git a/test/yarp/fixtures/whitequark/bug_do_block_in_cmdarg.txt b/test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_do_block_in_cmdarg.txt rename to test/prism/fixtures/whitequark/bug_do_block_in_cmdarg.txt diff --git a/test/yarp/fixtures/whitequark/bug_do_block_in_hash_brace.txt b/test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_do_block_in_hash_brace.txt rename to test/prism/fixtures/whitequark/bug_do_block_in_hash_brace.txt diff --git a/test/yarp/fixtures/whitequark/bug_heredoc_do.txt b/test/prism/fixtures/whitequark/bug_heredoc_do.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_heredoc_do.txt rename to test/prism/fixtures/whitequark/bug_heredoc_do.txt diff --git a/test/yarp/fixtures/whitequark/bug_interp_single.txt b/test/prism/fixtures/whitequark/bug_interp_single.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_interp_single.txt rename to test/prism/fixtures/whitequark/bug_interp_single.txt diff --git a/test/yarp/fixtures/whitequark/bug_lambda_leakage.txt b/test/prism/fixtures/whitequark/bug_lambda_leakage.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_lambda_leakage.txt rename to test/prism/fixtures/whitequark/bug_lambda_leakage.txt diff --git a/test/yarp/fixtures/whitequark/bug_regex_verification.txt b/test/prism/fixtures/whitequark/bug_regex_verification.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_regex_verification.txt rename to test/prism/fixtures/whitequark/bug_regex_verification.txt diff --git a/test/yarp/fixtures/whitequark/bug_rescue_empty_else.txt b/test/prism/fixtures/whitequark/bug_rescue_empty_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_rescue_empty_else.txt rename to test/prism/fixtures/whitequark/bug_rescue_empty_else.txt diff --git a/test/yarp/fixtures/whitequark/bug_while_not_parens_do.txt b/test/prism/fixtures/whitequark/bug_while_not_parens_do.txt similarity index 100% rename from test/yarp/fixtures/whitequark/bug_while_not_parens_do.txt rename to test/prism/fixtures/whitequark/bug_while_not_parens_do.txt diff --git a/test/yarp/fixtures/whitequark/case_cond.txt b/test/prism/fixtures/whitequark/case_cond.txt similarity index 100% rename from test/yarp/fixtures/whitequark/case_cond.txt rename to test/prism/fixtures/whitequark/case_cond.txt diff --git a/test/yarp/fixtures/whitequark/case_cond_else.txt b/test/prism/fixtures/whitequark/case_cond_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/case_cond_else.txt rename to test/prism/fixtures/whitequark/case_cond_else.txt diff --git a/test/yarp/fixtures/whitequark/case_expr.txt b/test/prism/fixtures/whitequark/case_expr.txt similarity index 100% rename from test/yarp/fixtures/whitequark/case_expr.txt rename to test/prism/fixtures/whitequark/case_expr.txt diff --git a/test/yarp/fixtures/whitequark/case_expr_else.txt b/test/prism/fixtures/whitequark/case_expr_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/case_expr_else.txt rename to test/prism/fixtures/whitequark/case_expr_else.txt diff --git a/test/yarp/fixtures/whitequark/casgn_scoped.txt b/test/prism/fixtures/whitequark/casgn_scoped.txt similarity index 100% rename from test/yarp/fixtures/whitequark/casgn_scoped.txt rename to test/prism/fixtures/whitequark/casgn_scoped.txt diff --git a/test/yarp/fixtures/whitequark/casgn_toplevel.txt b/test/prism/fixtures/whitequark/casgn_toplevel.txt similarity index 100% rename from test/yarp/fixtures/whitequark/casgn_toplevel.txt rename to test/prism/fixtures/whitequark/casgn_toplevel.txt diff --git a/test/yarp/fixtures/whitequark/casgn_unscoped.txt b/test/prism/fixtures/whitequark/casgn_unscoped.txt similarity index 100% rename from test/yarp/fixtures/whitequark/casgn_unscoped.txt rename to test/prism/fixtures/whitequark/casgn_unscoped.txt diff --git a/test/yarp/fixtures/whitequark/character.txt b/test/prism/fixtures/whitequark/character.txt similarity index 100% rename from test/yarp/fixtures/whitequark/character.txt rename to test/prism/fixtures/whitequark/character.txt diff --git a/test/yarp/fixtures/whitequark/class.txt b/test/prism/fixtures/whitequark/class.txt similarity index 100% rename from test/yarp/fixtures/whitequark/class.txt rename to test/prism/fixtures/whitequark/class.txt diff --git a/test/yarp/fixtures/whitequark/class_definition_in_while_cond.txt b/test/prism/fixtures/whitequark/class_definition_in_while_cond.txt similarity index 100% rename from test/yarp/fixtures/whitequark/class_definition_in_while_cond.txt rename to test/prism/fixtures/whitequark/class_definition_in_while_cond.txt diff --git a/test/yarp/fixtures/whitequark/class_super.txt b/test/prism/fixtures/whitequark/class_super.txt similarity index 100% rename from test/yarp/fixtures/whitequark/class_super.txt rename to test/prism/fixtures/whitequark/class_super.txt diff --git a/test/yarp/fixtures/whitequark/class_super_label.txt b/test/prism/fixtures/whitequark/class_super_label.txt similarity index 100% rename from test/yarp/fixtures/whitequark/class_super_label.txt rename to test/prism/fixtures/whitequark/class_super_label.txt diff --git a/test/yarp/fixtures/whitequark/comments_before_leading_dot__27.txt b/test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt similarity index 100% rename from test/yarp/fixtures/whitequark/comments_before_leading_dot__27.txt rename to test/prism/fixtures/whitequark/comments_before_leading_dot__27.txt diff --git a/test/yarp/fixtures/whitequark/complex.txt b/test/prism/fixtures/whitequark/complex.txt similarity index 100% rename from test/yarp/fixtures/whitequark/complex.txt rename to test/prism/fixtures/whitequark/complex.txt diff --git a/test/yarp/fixtures/whitequark/cond_begin.txt b/test/prism/fixtures/whitequark/cond_begin.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cond_begin.txt rename to test/prism/fixtures/whitequark/cond_begin.txt diff --git a/test/yarp/fixtures/whitequark/cond_begin_masgn.txt b/test/prism/fixtures/whitequark/cond_begin_masgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cond_begin_masgn.txt rename to test/prism/fixtures/whitequark/cond_begin_masgn.txt diff --git a/test/yarp/fixtures/whitequark/cond_eflipflop.txt b/test/prism/fixtures/whitequark/cond_eflipflop.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cond_eflipflop.txt rename to test/prism/fixtures/whitequark/cond_eflipflop.txt diff --git a/test/yarp/fixtures/whitequark/cond_iflipflop.txt b/test/prism/fixtures/whitequark/cond_iflipflop.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cond_iflipflop.txt rename to test/prism/fixtures/whitequark/cond_iflipflop.txt diff --git a/test/yarp/fixtures/whitequark/cond_match_current_line.txt b/test/prism/fixtures/whitequark/cond_match_current_line.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cond_match_current_line.txt rename to test/prism/fixtures/whitequark/cond_match_current_line.txt diff --git a/test/yarp/fixtures/whitequark/const_op_asgn.txt b/test/prism/fixtures/whitequark/const_op_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/const_op_asgn.txt rename to test/prism/fixtures/whitequark/const_op_asgn.txt diff --git a/test/yarp/fixtures/whitequark/const_scoped.txt b/test/prism/fixtures/whitequark/const_scoped.txt similarity index 100% rename from test/yarp/fixtures/whitequark/const_scoped.txt rename to test/prism/fixtures/whitequark/const_scoped.txt diff --git a/test/yarp/fixtures/whitequark/const_toplevel.txt b/test/prism/fixtures/whitequark/const_toplevel.txt similarity index 100% rename from test/yarp/fixtures/whitequark/const_toplevel.txt rename to test/prism/fixtures/whitequark/const_toplevel.txt diff --git a/test/yarp/fixtures/whitequark/const_unscoped.txt b/test/prism/fixtures/whitequark/const_unscoped.txt similarity index 100% rename from test/yarp/fixtures/whitequark/const_unscoped.txt rename to test/prism/fixtures/whitequark/const_unscoped.txt diff --git a/test/yarp/fixtures/whitequark/cpath.txt b/test/prism/fixtures/whitequark/cpath.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cpath.txt rename to test/prism/fixtures/whitequark/cpath.txt diff --git a/test/yarp/fixtures/whitequark/cvar.txt b/test/prism/fixtures/whitequark/cvar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cvar.txt rename to test/prism/fixtures/whitequark/cvar.txt diff --git a/test/yarp/fixtures/whitequark/cvasgn.txt b/test/prism/fixtures/whitequark/cvasgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/cvasgn.txt rename to test/prism/fixtures/whitequark/cvasgn.txt diff --git a/test/yarp/fixtures/whitequark/dedenting_heredoc.txt b/test/prism/fixtures/whitequark/dedenting_heredoc.txt similarity index 100% rename from test/yarp/fixtures/whitequark/dedenting_heredoc.txt rename to test/prism/fixtures/whitequark/dedenting_heredoc.txt diff --git a/test/yarp/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt b/test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt similarity index 100% rename from test/yarp/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt rename to test/prism/fixtures/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt diff --git a/test/yarp/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt b/test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt similarity index 100% rename from test/yarp/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt rename to test/prism/fixtures/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt diff --git a/test/yarp/fixtures/whitequark/def.txt b/test/prism/fixtures/whitequark/def.txt similarity index 100% rename from test/yarp/fixtures/whitequark/def.txt rename to test/prism/fixtures/whitequark/def.txt diff --git a/test/yarp/fixtures/whitequark/defined.txt b/test/prism/fixtures/whitequark/defined.txt similarity index 100% rename from test/yarp/fixtures/whitequark/defined.txt rename to test/prism/fixtures/whitequark/defined.txt diff --git a/test/yarp/fixtures/whitequark/defs.txt b/test/prism/fixtures/whitequark/defs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/defs.txt rename to test/prism/fixtures/whitequark/defs.txt diff --git a/test/yarp/fixtures/whitequark/empty_stmt.txt b/test/prism/fixtures/whitequark/empty_stmt.txt similarity index 100% rename from test/yarp/fixtures/whitequark/empty_stmt.txt rename to test/prism/fixtures/whitequark/empty_stmt.txt diff --git a/test/yarp/fixtures/whitequark/endless_comparison_method.txt b/test/prism/fixtures/whitequark/endless_comparison_method.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_comparison_method.txt rename to test/prism/fixtures/whitequark/endless_comparison_method.txt diff --git a/test/yarp/fixtures/whitequark/endless_method.txt b/test/prism/fixtures/whitequark/endless_method.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_method.txt rename to test/prism/fixtures/whitequark/endless_method.txt diff --git a/test/yarp/fixtures/whitequark/endless_method_command_syntax.txt b/test/prism/fixtures/whitequark/endless_method_command_syntax.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_method_command_syntax.txt rename to test/prism/fixtures/whitequark/endless_method_command_syntax.txt diff --git a/test/yarp/fixtures/whitequark/endless_method_forwarded_args_legacy.txt b/test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_method_forwarded_args_legacy.txt rename to test/prism/fixtures/whitequark/endless_method_forwarded_args_legacy.txt diff --git a/test/yarp/fixtures/whitequark/endless_method_with_rescue_mod.txt b/test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_method_with_rescue_mod.txt rename to test/prism/fixtures/whitequark/endless_method_with_rescue_mod.txt diff --git a/test/yarp/fixtures/whitequark/endless_method_without_args.txt b/test/prism/fixtures/whitequark/endless_method_without_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/endless_method_without_args.txt rename to test/prism/fixtures/whitequark/endless_method_without_args.txt diff --git a/test/yarp/fixtures/whitequark/ensure.txt b/test/prism/fixtures/whitequark/ensure.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ensure.txt rename to test/prism/fixtures/whitequark/ensure.txt diff --git a/test/yarp/fixtures/whitequark/ensure_empty.txt b/test/prism/fixtures/whitequark/ensure_empty.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ensure_empty.txt rename to test/prism/fixtures/whitequark/ensure_empty.txt diff --git a/test/yarp/fixtures/whitequark/false.txt b/test/prism/fixtures/whitequark/false.txt similarity index 100% rename from test/yarp/fixtures/whitequark/false.txt rename to test/prism/fixtures/whitequark/false.txt diff --git a/test/yarp/fixtures/whitequark/float.txt b/test/prism/fixtures/whitequark/float.txt similarity index 100% rename from test/yarp/fixtures/whitequark/float.txt rename to test/prism/fixtures/whitequark/float.txt diff --git a/test/yarp/fixtures/whitequark/for.txt b/test/prism/fixtures/whitequark/for.txt similarity index 100% rename from test/yarp/fixtures/whitequark/for.txt rename to test/prism/fixtures/whitequark/for.txt diff --git a/test/yarp/fixtures/whitequark/for_mlhs.txt b/test/prism/fixtures/whitequark/for_mlhs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/for_mlhs.txt rename to test/prism/fixtures/whitequark/for_mlhs.txt diff --git a/test/yarp/fixtures/whitequark/forward_arg.txt b/test/prism/fixtures/whitequark/forward_arg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forward_arg.txt rename to test/prism/fixtures/whitequark/forward_arg.txt diff --git a/test/yarp/fixtures/whitequark/forward_arg_with_open_args.txt b/test/prism/fixtures/whitequark/forward_arg_with_open_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forward_arg_with_open_args.txt rename to test/prism/fixtures/whitequark/forward_arg_with_open_args.txt diff --git a/test/yarp/fixtures/whitequark/forward_args_legacy.txt b/test/prism/fixtures/whitequark/forward_args_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forward_args_legacy.txt rename to test/prism/fixtures/whitequark/forward_args_legacy.txt diff --git a/test/yarp/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt rename to test/prism/fixtures/whitequark/forwarded_argument_with_kwrestarg.txt diff --git a/test/yarp/fixtures/whitequark/forwarded_argument_with_restarg.txt b/test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forwarded_argument_with_restarg.txt rename to test/prism/fixtures/whitequark/forwarded_argument_with_restarg.txt diff --git a/test/yarp/fixtures/whitequark/forwarded_kwrestarg.txt b/test/prism/fixtures/whitequark/forwarded_kwrestarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forwarded_kwrestarg.txt rename to test/prism/fixtures/whitequark/forwarded_kwrestarg.txt diff --git a/test/yarp/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt rename to test/prism/fixtures/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt diff --git a/test/yarp/fixtures/whitequark/forwarded_restarg.txt b/test/prism/fixtures/whitequark/forwarded_restarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/forwarded_restarg.txt rename to test/prism/fixtures/whitequark/forwarded_restarg.txt diff --git a/test/yarp/fixtures/whitequark/gvar.txt b/test/prism/fixtures/whitequark/gvar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/gvar.txt rename to test/prism/fixtures/whitequark/gvar.txt diff --git a/test/yarp/fixtures/whitequark/gvasgn.txt b/test/prism/fixtures/whitequark/gvasgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/gvasgn.txt rename to test/prism/fixtures/whitequark/gvasgn.txt diff --git a/test/yarp/fixtures/whitequark/hash_empty.txt b/test/prism/fixtures/whitequark/hash_empty.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_empty.txt rename to test/prism/fixtures/whitequark/hash_empty.txt diff --git a/test/yarp/fixtures/whitequark/hash_hashrocket.txt b/test/prism/fixtures/whitequark/hash_hashrocket.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_hashrocket.txt rename to test/prism/fixtures/whitequark/hash_hashrocket.txt diff --git a/test/yarp/fixtures/whitequark/hash_kwsplat.txt b/test/prism/fixtures/whitequark/hash_kwsplat.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_kwsplat.txt rename to test/prism/fixtures/whitequark/hash_kwsplat.txt diff --git a/test/yarp/fixtures/whitequark/hash_label.txt b/test/prism/fixtures/whitequark/hash_label.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_label.txt rename to test/prism/fixtures/whitequark/hash_label.txt diff --git a/test/yarp/fixtures/whitequark/hash_label_end.txt b/test/prism/fixtures/whitequark/hash_label_end.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_label_end.txt rename to test/prism/fixtures/whitequark/hash_label_end.txt diff --git a/test/yarp/fixtures/whitequark/hash_pair_value_omission.txt b/test/prism/fixtures/whitequark/hash_pair_value_omission.txt similarity index 100% rename from test/yarp/fixtures/whitequark/hash_pair_value_omission.txt rename to test/prism/fixtures/whitequark/hash_pair_value_omission.txt diff --git a/test/yarp/fixtures/whitequark/heredoc.txt b/test/prism/fixtures/whitequark/heredoc.txt similarity index 100% rename from test/yarp/fixtures/whitequark/heredoc.txt rename to test/prism/fixtures/whitequark/heredoc.txt diff --git a/test/yarp/fixtures/whitequark/if.txt b/test/prism/fixtures/whitequark/if.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if.txt rename to test/prism/fixtures/whitequark/if.txt diff --git a/test/yarp/fixtures/whitequark/if_else.txt b/test/prism/fixtures/whitequark/if_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_else.txt rename to test/prism/fixtures/whitequark/if_else.txt diff --git a/test/yarp/fixtures/whitequark/if_elsif.txt b/test/prism/fixtures/whitequark/if_elsif.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_elsif.txt rename to test/prism/fixtures/whitequark/if_elsif.txt diff --git a/test/yarp/fixtures/whitequark/if_masgn__24.txt b/test/prism/fixtures/whitequark/if_masgn__24.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_masgn__24.txt rename to test/prism/fixtures/whitequark/if_masgn__24.txt diff --git a/test/yarp/fixtures/whitequark/if_mod.txt b/test/prism/fixtures/whitequark/if_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_mod.txt rename to test/prism/fixtures/whitequark/if_mod.txt diff --git a/test/yarp/fixtures/whitequark/if_nl_then.txt b/test/prism/fixtures/whitequark/if_nl_then.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_nl_then.txt rename to test/prism/fixtures/whitequark/if_nl_then.txt diff --git a/test/yarp/fixtures/whitequark/if_while_after_class__since_32.txt b/test/prism/fixtures/whitequark/if_while_after_class__since_32.txt similarity index 100% rename from test/yarp/fixtures/whitequark/if_while_after_class__since_32.txt rename to test/prism/fixtures/whitequark/if_while_after_class__since_32.txt diff --git a/test/yarp/fixtures/whitequark/int.txt b/test/prism/fixtures/whitequark/int.txt similarity index 100% rename from test/yarp/fixtures/whitequark/int.txt rename to test/prism/fixtures/whitequark/int.txt diff --git a/test/yarp/fixtures/whitequark/int___LINE__.txt b/test/prism/fixtures/whitequark/int___LINE__.txt similarity index 100% rename from test/yarp/fixtures/whitequark/int___LINE__.txt rename to test/prism/fixtures/whitequark/int___LINE__.txt diff --git a/test/yarp/fixtures/whitequark/interp_digit_var.txt b/test/prism/fixtures/whitequark/interp_digit_var.txt similarity index 100% rename from test/yarp/fixtures/whitequark/interp_digit_var.txt rename to test/prism/fixtures/whitequark/interp_digit_var.txt diff --git a/test/yarp/fixtures/whitequark/ivar.txt b/test/prism/fixtures/whitequark/ivar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ivar.txt rename to test/prism/fixtures/whitequark/ivar.txt diff --git a/test/yarp/fixtures/whitequark/ivasgn.txt b/test/prism/fixtures/whitequark/ivasgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ivasgn.txt rename to test/prism/fixtures/whitequark/ivasgn.txt diff --git a/test/yarp/fixtures/whitequark/keyword_argument_omission.txt b/test/prism/fixtures/whitequark/keyword_argument_omission.txt similarity index 100% rename from test/yarp/fixtures/whitequark/keyword_argument_omission.txt rename to test/prism/fixtures/whitequark/keyword_argument_omission.txt diff --git a/test/yarp/fixtures/whitequark/kwarg.txt b/test/prism/fixtures/whitequark/kwarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwarg.txt rename to test/prism/fixtures/whitequark/kwarg.txt diff --git a/test/yarp/fixtures/whitequark/kwbegin_compstmt.txt b/test/prism/fixtures/whitequark/kwbegin_compstmt.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwbegin_compstmt.txt rename to test/prism/fixtures/whitequark/kwbegin_compstmt.txt diff --git a/test/yarp/fixtures/whitequark/kwnilarg.txt b/test/prism/fixtures/whitequark/kwnilarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwnilarg.txt rename to test/prism/fixtures/whitequark/kwnilarg.txt diff --git a/test/yarp/fixtures/whitequark/kwoptarg.txt b/test/prism/fixtures/whitequark/kwoptarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwoptarg.txt rename to test/prism/fixtures/whitequark/kwoptarg.txt diff --git a/test/yarp/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt rename to test/prism/fixtures/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt diff --git a/test/yarp/fixtures/whitequark/kwrestarg_named.txt b/test/prism/fixtures/whitequark/kwrestarg_named.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwrestarg_named.txt rename to test/prism/fixtures/whitequark/kwrestarg_named.txt diff --git a/test/yarp/fixtures/whitequark/kwrestarg_unnamed.txt b/test/prism/fixtures/whitequark/kwrestarg_unnamed.txt similarity index 100% rename from test/yarp/fixtures/whitequark/kwrestarg_unnamed.txt rename to test/prism/fixtures/whitequark/kwrestarg_unnamed.txt diff --git a/test/yarp/fixtures/whitequark/lbrace_arg_after_command_args.txt b/test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/lbrace_arg_after_command_args.txt rename to test/prism/fixtures/whitequark/lbrace_arg_after_command_args.txt diff --git a/test/yarp/fixtures/whitequark/lparenarg_after_lvar__since_25.txt b/test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt similarity index 100% rename from test/yarp/fixtures/whitequark/lparenarg_after_lvar__since_25.txt rename to test/prism/fixtures/whitequark/lparenarg_after_lvar__since_25.txt diff --git a/test/yarp/fixtures/whitequark/lvar.txt b/test/prism/fixtures/whitequark/lvar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/lvar.txt rename to test/prism/fixtures/whitequark/lvar.txt diff --git a/test/yarp/fixtures/whitequark/lvar_injecting_match.txt b/test/prism/fixtures/whitequark/lvar_injecting_match.txt similarity index 100% rename from test/yarp/fixtures/whitequark/lvar_injecting_match.txt rename to test/prism/fixtures/whitequark/lvar_injecting_match.txt diff --git a/test/yarp/fixtures/whitequark/lvasgn.txt b/test/prism/fixtures/whitequark/lvasgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/lvasgn.txt rename to test/prism/fixtures/whitequark/lvasgn.txt diff --git a/test/yarp/fixtures/whitequark/masgn.txt b/test/prism/fixtures/whitequark/masgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn.txt rename to test/prism/fixtures/whitequark/masgn.txt diff --git a/test/yarp/fixtures/whitequark/masgn_attr.txt b/test/prism/fixtures/whitequark/masgn_attr.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn_attr.txt rename to test/prism/fixtures/whitequark/masgn_attr.txt diff --git a/test/yarp/fixtures/whitequark/masgn_cmd.txt b/test/prism/fixtures/whitequark/masgn_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn_cmd.txt rename to test/prism/fixtures/whitequark/masgn_cmd.txt diff --git a/test/yarp/fixtures/whitequark/masgn_const.txt b/test/prism/fixtures/whitequark/masgn_const.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn_const.txt rename to test/prism/fixtures/whitequark/masgn_const.txt diff --git a/test/yarp/fixtures/whitequark/masgn_nested.txt b/test/prism/fixtures/whitequark/masgn_nested.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn_nested.txt rename to test/prism/fixtures/whitequark/masgn_nested.txt diff --git a/test/yarp/fixtures/whitequark/masgn_splat.txt b/test/prism/fixtures/whitequark/masgn_splat.txt similarity index 100% rename from test/yarp/fixtures/whitequark/masgn_splat.txt rename to test/prism/fixtures/whitequark/masgn_splat.txt diff --git a/test/yarp/fixtures/whitequark/method_definition_in_while_cond.txt b/test/prism/fixtures/whitequark/method_definition_in_while_cond.txt similarity index 100% rename from test/yarp/fixtures/whitequark/method_definition_in_while_cond.txt rename to test/prism/fixtures/whitequark/method_definition_in_while_cond.txt diff --git a/test/yarp/fixtures/whitequark/module.txt b/test/prism/fixtures/whitequark/module.txt similarity index 100% rename from test/yarp/fixtures/whitequark/module.txt rename to test/prism/fixtures/whitequark/module.txt diff --git a/test/yarp/fixtures/whitequark/multiple_pattern_matches.txt b/test/prism/fixtures/whitequark/multiple_pattern_matches.txt similarity index 100% rename from test/yarp/fixtures/whitequark/multiple_pattern_matches.txt rename to test/prism/fixtures/whitequark/multiple_pattern_matches.txt diff --git a/test/yarp/fixtures/whitequark/newline_in_hash_argument.txt b/test/prism/fixtures/whitequark/newline_in_hash_argument.txt similarity index 100% rename from test/yarp/fixtures/whitequark/newline_in_hash_argument.txt rename to test/prism/fixtures/whitequark/newline_in_hash_argument.txt diff --git a/test/yarp/fixtures/whitequark/next.txt b/test/prism/fixtures/whitequark/next.txt similarity index 100% rename from test/yarp/fixtures/whitequark/next.txt rename to test/prism/fixtures/whitequark/next.txt diff --git a/test/yarp/fixtures/whitequark/next_block.txt b/test/prism/fixtures/whitequark/next_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/next_block.txt rename to test/prism/fixtures/whitequark/next_block.txt diff --git a/test/yarp/fixtures/whitequark/nil.txt b/test/prism/fixtures/whitequark/nil.txt similarity index 100% rename from test/yarp/fixtures/whitequark/nil.txt rename to test/prism/fixtures/whitequark/nil.txt diff --git a/test/yarp/fixtures/whitequark/nil_expression.txt b/test/prism/fixtures/whitequark/nil_expression.txt similarity index 100% rename from test/yarp/fixtures/whitequark/nil_expression.txt rename to test/prism/fixtures/whitequark/nil_expression.txt diff --git a/test/yarp/fixtures/whitequark/non_lvar_injecting_match.txt b/test/prism/fixtures/whitequark/non_lvar_injecting_match.txt similarity index 100% rename from test/yarp/fixtures/whitequark/non_lvar_injecting_match.txt rename to test/prism/fixtures/whitequark/non_lvar_injecting_match.txt diff --git a/test/yarp/fixtures/whitequark/not.txt b/test/prism/fixtures/whitequark/not.txt similarity index 100% rename from test/yarp/fixtures/whitequark/not.txt rename to test/prism/fixtures/whitequark/not.txt diff --git a/test/yarp/fixtures/whitequark/not_cmd.txt b/test/prism/fixtures/whitequark/not_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/not_cmd.txt rename to test/prism/fixtures/whitequark/not_cmd.txt diff --git a/test/yarp/fixtures/whitequark/not_masgn__24.txt b/test/prism/fixtures/whitequark/not_masgn__24.txt similarity index 100% rename from test/yarp/fixtures/whitequark/not_masgn__24.txt rename to test/prism/fixtures/whitequark/not_masgn__24.txt diff --git a/test/yarp/fixtures/whitequark/nth_ref.txt b/test/prism/fixtures/whitequark/nth_ref.txt similarity index 100% rename from test/yarp/fixtures/whitequark/nth_ref.txt rename to test/prism/fixtures/whitequark/nth_ref.txt diff --git a/test/yarp/fixtures/whitequark/numbered_args_after_27.txt b/test/prism/fixtures/whitequark/numbered_args_after_27.txt similarity index 100% rename from test/yarp/fixtures/whitequark/numbered_args_after_27.txt rename to test/prism/fixtures/whitequark/numbered_args_after_27.txt diff --git a/test/yarp/fixtures/whitequark/numparam_outside_block.txt b/test/prism/fixtures/whitequark/numparam_outside_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/numparam_outside_block.txt rename to test/prism/fixtures/whitequark/numparam_outside_block.txt diff --git a/test/yarp/fixtures/whitequark/op_asgn.txt b/test/prism/fixtures/whitequark/op_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/op_asgn.txt rename to test/prism/fixtures/whitequark/op_asgn.txt diff --git a/test/yarp/fixtures/whitequark/op_asgn_cmd.txt b/test/prism/fixtures/whitequark/op_asgn_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/op_asgn_cmd.txt rename to test/prism/fixtures/whitequark/op_asgn_cmd.txt diff --git a/test/yarp/fixtures/whitequark/op_asgn_index.txt b/test/prism/fixtures/whitequark/op_asgn_index.txt similarity index 100% rename from test/yarp/fixtures/whitequark/op_asgn_index.txt rename to test/prism/fixtures/whitequark/op_asgn_index.txt diff --git a/test/yarp/fixtures/whitequark/op_asgn_index_cmd.txt b/test/prism/fixtures/whitequark/op_asgn_index_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/op_asgn_index_cmd.txt rename to test/prism/fixtures/whitequark/op_asgn_index_cmd.txt diff --git a/test/yarp/fixtures/whitequark/optarg.txt b/test/prism/fixtures/whitequark/optarg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/optarg.txt rename to test/prism/fixtures/whitequark/optarg.txt diff --git a/test/yarp/fixtures/whitequark/or.txt b/test/prism/fixtures/whitequark/or.txt similarity index 100% rename from test/yarp/fixtures/whitequark/or.txt rename to test/prism/fixtures/whitequark/or.txt diff --git a/test/yarp/fixtures/whitequark/or_asgn.txt b/test/prism/fixtures/whitequark/or_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/or_asgn.txt rename to test/prism/fixtures/whitequark/or_asgn.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_272.txt b/test/prism/fixtures/whitequark/parser_bug_272.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_272.txt rename to test/prism/fixtures/whitequark/parser_bug_272.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_490.txt b/test/prism/fixtures/whitequark/parser_bug_490.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_490.txt rename to test/prism/fixtures/whitequark/parser_bug_490.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_507.txt b/test/prism/fixtures/whitequark/parser_bug_507.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_507.txt rename to test/prism/fixtures/whitequark/parser_bug_507.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_518.txt b/test/prism/fixtures/whitequark/parser_bug_518.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_518.txt rename to test/prism/fixtures/whitequark/parser_bug_518.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_525.txt b/test/prism/fixtures/whitequark/parser_bug_525.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_525.txt rename to test/prism/fixtures/whitequark/parser_bug_525.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_604.txt b/test/prism/fixtures/whitequark/parser_bug_604.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_604.txt rename to test/prism/fixtures/whitequark/parser_bug_604.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_640.txt b/test/prism/fixtures/whitequark/parser_bug_640.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_640.txt rename to test/prism/fixtures/whitequark/parser_bug_640.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_645.txt b/test/prism/fixtures/whitequark/parser_bug_645.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_645.txt rename to test/prism/fixtures/whitequark/parser_bug_645.txt diff --git a/test/yarp/fixtures/whitequark/parser_bug_830.txt b/test/prism/fixtures/whitequark/parser_bug_830.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_bug_830.txt rename to test/prism/fixtures/whitequark/parser_bug_830.txt diff --git a/test/yarp/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt b/test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt rename to test/prism/fixtures/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt diff --git a/test/yarp/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt similarity index 100% rename from test/yarp/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt rename to test/prism/fixtures/whitequark/parser_slash_slash_n_escaping_in_literals.txt diff --git a/test/yarp/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt similarity index 100% rename from test/yarp/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt rename to test/prism/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt diff --git a/test/yarp/fixtures/whitequark/pattern_matching_blank_else.txt b/test/prism/fixtures/whitequark/pattern_matching_blank_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/pattern_matching_blank_else.txt rename to test/prism/fixtures/whitequark/pattern_matching_blank_else.txt diff --git a/test/yarp/fixtures/whitequark/pattern_matching_else.txt b/test/prism/fixtures/whitequark/pattern_matching_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/pattern_matching_else.txt rename to test/prism/fixtures/whitequark/pattern_matching_else.txt diff --git a/test/yarp/fixtures/whitequark/pattern_matching_single_line.txt b/test/prism/fixtures/whitequark/pattern_matching_single_line.txt similarity index 100% rename from test/yarp/fixtures/whitequark/pattern_matching_single_line.txt rename to test/prism/fixtures/whitequark/pattern_matching_single_line.txt diff --git a/test/yarp/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 similarity index 100% rename from test/yarp/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt rename to test/prism/fixtures/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt diff --git a/test/yarp/fixtures/whitequark/postexe.txt b/test/prism/fixtures/whitequark/postexe.txt similarity index 100% rename from test/yarp/fixtures/whitequark/postexe.txt rename to test/prism/fixtures/whitequark/postexe.txt diff --git a/test/yarp/fixtures/whitequark/preexe.txt b/test/prism/fixtures/whitequark/preexe.txt similarity index 100% rename from test/yarp/fixtures/whitequark/preexe.txt rename to test/prism/fixtures/whitequark/preexe.txt diff --git a/test/yarp/fixtures/whitequark/procarg0.txt b/test/prism/fixtures/whitequark/procarg0.txt similarity index 100% rename from test/yarp/fixtures/whitequark/procarg0.txt rename to test/prism/fixtures/whitequark/procarg0.txt diff --git a/test/yarp/fixtures/whitequark/range_exclusive.txt b/test/prism/fixtures/whitequark/range_exclusive.txt similarity index 100% rename from test/yarp/fixtures/whitequark/range_exclusive.txt rename to test/prism/fixtures/whitequark/range_exclusive.txt diff --git a/test/yarp/fixtures/whitequark/range_inclusive.txt b/test/prism/fixtures/whitequark/range_inclusive.txt similarity index 100% rename from test/yarp/fixtures/whitequark/range_inclusive.txt rename to test/prism/fixtures/whitequark/range_inclusive.txt diff --git a/test/yarp/fixtures/whitequark/rational.txt b/test/prism/fixtures/whitequark/rational.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rational.txt rename to test/prism/fixtures/whitequark/rational.txt diff --git a/test/yarp/fixtures/whitequark/redo.txt b/test/prism/fixtures/whitequark/redo.txt similarity index 100% rename from test/yarp/fixtures/whitequark/redo.txt rename to test/prism/fixtures/whitequark/redo.txt diff --git a/test/yarp/fixtures/whitequark/regex_interp.txt b/test/prism/fixtures/whitequark/regex_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/regex_interp.txt rename to test/prism/fixtures/whitequark/regex_interp.txt diff --git a/test/yarp/fixtures/whitequark/regex_plain.txt b/test/prism/fixtures/whitequark/regex_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/regex_plain.txt rename to test/prism/fixtures/whitequark/regex_plain.txt diff --git a/test/yarp/fixtures/whitequark/resbody_list.txt b/test/prism/fixtures/whitequark/resbody_list.txt similarity index 100% rename from test/yarp/fixtures/whitequark/resbody_list.txt rename to test/prism/fixtures/whitequark/resbody_list.txt diff --git a/test/yarp/fixtures/whitequark/resbody_list_mrhs.txt b/test/prism/fixtures/whitequark/resbody_list_mrhs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/resbody_list_mrhs.txt rename to test/prism/fixtures/whitequark/resbody_list_mrhs.txt diff --git a/test/yarp/fixtures/whitequark/resbody_list_var.txt b/test/prism/fixtures/whitequark/resbody_list_var.txt similarity index 100% rename from test/yarp/fixtures/whitequark/resbody_list_var.txt rename to test/prism/fixtures/whitequark/resbody_list_var.txt diff --git a/test/yarp/fixtures/whitequark/resbody_var.txt b/test/prism/fixtures/whitequark/resbody_var.txt similarity index 100% rename from test/yarp/fixtures/whitequark/resbody_var.txt rename to test/prism/fixtures/whitequark/resbody_var.txt diff --git a/test/yarp/fixtures/whitequark/rescue.txt b/test/prism/fixtures/whitequark/rescue.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue.txt rename to test/prism/fixtures/whitequark/rescue.txt diff --git a/test/yarp/fixtures/whitequark/rescue_else.txt b/test/prism/fixtures/whitequark/rescue_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_else.txt rename to test/prism/fixtures/whitequark/rescue_else.txt diff --git a/test/yarp/fixtures/whitequark/rescue_else_ensure.txt b/test/prism/fixtures/whitequark/rescue_else_ensure.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_else_ensure.txt rename to test/prism/fixtures/whitequark/rescue_else_ensure.txt diff --git a/test/yarp/fixtures/whitequark/rescue_ensure.txt b/test/prism/fixtures/whitequark/rescue_ensure.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_ensure.txt rename to test/prism/fixtures/whitequark/rescue_ensure.txt diff --git a/test/yarp/fixtures/whitequark/rescue_in_lambda_block.txt b/test/prism/fixtures/whitequark/rescue_in_lambda_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_in_lambda_block.txt rename to test/prism/fixtures/whitequark/rescue_in_lambda_block.txt diff --git a/test/yarp/fixtures/whitequark/rescue_mod.txt b/test/prism/fixtures/whitequark/rescue_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_mod.txt rename to test/prism/fixtures/whitequark/rescue_mod.txt diff --git a/test/yarp/fixtures/whitequark/rescue_mod_asgn.txt b/test/prism/fixtures/whitequark/rescue_mod_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_mod_asgn.txt rename to test/prism/fixtures/whitequark/rescue_mod_asgn.txt diff --git a/test/yarp/fixtures/whitequark/rescue_mod_masgn.txt b/test/prism/fixtures/whitequark/rescue_mod_masgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_mod_masgn.txt rename to test/prism/fixtures/whitequark/rescue_mod_masgn.txt diff --git a/test/yarp/fixtures/whitequark/rescue_mod_op_assign.txt b/test/prism/fixtures/whitequark/rescue_mod_op_assign.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_mod_op_assign.txt rename to test/prism/fixtures/whitequark/rescue_mod_op_assign.txt diff --git a/test/yarp/fixtures/whitequark/rescue_without_begin_end.txt b/test/prism/fixtures/whitequark/rescue_without_begin_end.txt similarity index 100% rename from test/yarp/fixtures/whitequark/rescue_without_begin_end.txt rename to test/prism/fixtures/whitequark/rescue_without_begin_end.txt diff --git a/test/yarp/fixtures/whitequark/restarg_named.txt b/test/prism/fixtures/whitequark/restarg_named.txt similarity index 100% rename from test/yarp/fixtures/whitequark/restarg_named.txt rename to test/prism/fixtures/whitequark/restarg_named.txt diff --git a/test/yarp/fixtures/whitequark/restarg_unnamed.txt b/test/prism/fixtures/whitequark/restarg_unnamed.txt similarity index 100% rename from test/yarp/fixtures/whitequark/restarg_unnamed.txt rename to test/prism/fixtures/whitequark/restarg_unnamed.txt diff --git a/test/yarp/fixtures/whitequark/retry.txt b/test/prism/fixtures/whitequark/retry.txt similarity index 100% rename from test/yarp/fixtures/whitequark/retry.txt rename to test/prism/fixtures/whitequark/retry.txt diff --git a/test/yarp/fixtures/whitequark/return.txt b/test/prism/fixtures/whitequark/return.txt similarity index 100% rename from test/yarp/fixtures/whitequark/return.txt rename to test/prism/fixtures/whitequark/return.txt diff --git a/test/yarp/fixtures/whitequark/return_block.txt b/test/prism/fixtures/whitequark/return_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/return_block.txt rename to test/prism/fixtures/whitequark/return_block.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_10279.txt b/test/prism/fixtures/whitequark/ruby_bug_10279.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_10279.txt rename to test/prism/fixtures/whitequark/ruby_bug_10279.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_10653.txt b/test/prism/fixtures/whitequark/ruby_bug_10653.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_10653.txt rename to test/prism/fixtures/whitequark/ruby_bug_10653.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11107.txt b/test/prism/fixtures/whitequark/ruby_bug_11107.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11107.txt rename to test/prism/fixtures/whitequark/ruby_bug_11107.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11380.txt b/test/prism/fixtures/whitequark/ruby_bug_11380.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11380.txt rename to test/prism/fixtures/whitequark/ruby_bug_11380.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11873.txt b/test/prism/fixtures/whitequark/ruby_bug_11873.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11873.txt rename to test/prism/fixtures/whitequark/ruby_bug_11873.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11873_a.txt b/test/prism/fixtures/whitequark/ruby_bug_11873_a.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11873_a.txt rename to test/prism/fixtures/whitequark/ruby_bug_11873_a.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11873_b.txt b/test/prism/fixtures/whitequark/ruby_bug_11873_b.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11873_b.txt rename to test/prism/fixtures/whitequark/ruby_bug_11873_b.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11989.txt b/test/prism/fixtures/whitequark/ruby_bug_11989.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11989.txt rename to test/prism/fixtures/whitequark/ruby_bug_11989.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_11990.txt b/test/prism/fixtures/whitequark/ruby_bug_11990.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_11990.txt rename to test/prism/fixtures/whitequark/ruby_bug_11990.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_12073.txt b/test/prism/fixtures/whitequark/ruby_bug_12073.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_12073.txt rename to test/prism/fixtures/whitequark/ruby_bug_12073.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_12402.txt b/test/prism/fixtures/whitequark/ruby_bug_12402.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_12402.txt rename to test/prism/fixtures/whitequark/ruby_bug_12402.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_12669.txt b/test/prism/fixtures/whitequark/ruby_bug_12669.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_12669.txt rename to test/prism/fixtures/whitequark/ruby_bug_12669.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_12686.txt b/test/prism/fixtures/whitequark/ruby_bug_12686.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_12686.txt rename to test/prism/fixtures/whitequark/ruby_bug_12686.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_13547.txt b/test/prism/fixtures/whitequark/ruby_bug_13547.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_13547.txt rename to test/prism/fixtures/whitequark/ruby_bug_13547.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_14690.txt b/test/prism/fixtures/whitequark/ruby_bug_14690.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_14690.txt rename to test/prism/fixtures/whitequark/ruby_bug_14690.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_15789.txt b/test/prism/fixtures/whitequark/ruby_bug_15789.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_15789.txt rename to test/prism/fixtures/whitequark/ruby_bug_15789.txt diff --git a/test/yarp/fixtures/whitequark/ruby_bug_9669.txt b/test/prism/fixtures/whitequark/ruby_bug_9669.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ruby_bug_9669.txt rename to test/prism/fixtures/whitequark/ruby_bug_9669.txt diff --git a/test/yarp/fixtures/whitequark/sclass.txt b/test/prism/fixtures/whitequark/sclass.txt similarity index 100% rename from test/yarp/fixtures/whitequark/sclass.txt rename to test/prism/fixtures/whitequark/sclass.txt diff --git a/test/yarp/fixtures/whitequark/self.txt b/test/prism/fixtures/whitequark/self.txt similarity index 100% rename from test/yarp/fixtures/whitequark/self.txt rename to test/prism/fixtures/whitequark/self.txt diff --git a/test/yarp/fixtures/whitequark/send_attr_asgn.txt b/test/prism/fixtures/whitequark/send_attr_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_attr_asgn.txt rename to test/prism/fixtures/whitequark/send_attr_asgn.txt diff --git a/test/yarp/fixtures/whitequark/send_attr_asgn_conditional.txt b/test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_attr_asgn_conditional.txt rename to test/prism/fixtures/whitequark/send_attr_asgn_conditional.txt diff --git a/test/yarp/fixtures/whitequark/send_binary_op.txt b/test/prism/fixtures/whitequark/send_binary_op.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_binary_op.txt rename to test/prism/fixtures/whitequark/send_binary_op.txt diff --git a/test/yarp/fixtures/whitequark/send_block_chain_cmd.txt b/test/prism/fixtures/whitequark/send_block_chain_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_block_chain_cmd.txt rename to test/prism/fixtures/whitequark/send_block_chain_cmd.txt diff --git a/test/yarp/fixtures/whitequark/send_block_conditional.txt b/test/prism/fixtures/whitequark/send_block_conditional.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_block_conditional.txt rename to test/prism/fixtures/whitequark/send_block_conditional.txt diff --git a/test/yarp/fixtures/whitequark/send_call.txt b/test/prism/fixtures/whitequark/send_call.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_call.txt rename to test/prism/fixtures/whitequark/send_call.txt diff --git a/test/yarp/fixtures/whitequark/send_conditional.txt b/test/prism/fixtures/whitequark/send_conditional.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_conditional.txt rename to test/prism/fixtures/whitequark/send_conditional.txt diff --git a/test/yarp/fixtures/whitequark/send_index.txt b/test/prism/fixtures/whitequark/send_index.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_index.txt rename to test/prism/fixtures/whitequark/send_index.txt diff --git a/test/yarp/fixtures/whitequark/send_index_asgn.txt b/test/prism/fixtures/whitequark/send_index_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_index_asgn.txt rename to test/prism/fixtures/whitequark/send_index_asgn.txt diff --git a/test/yarp/fixtures/whitequark/send_index_asgn_legacy.txt b/test/prism/fixtures/whitequark/send_index_asgn_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_index_asgn_legacy.txt rename to test/prism/fixtures/whitequark/send_index_asgn_legacy.txt diff --git a/test/yarp/fixtures/whitequark/send_index_cmd.txt b/test/prism/fixtures/whitequark/send_index_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_index_cmd.txt rename to test/prism/fixtures/whitequark/send_index_cmd.txt diff --git a/test/yarp/fixtures/whitequark/send_index_legacy.txt b/test/prism/fixtures/whitequark/send_index_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_index_legacy.txt rename to test/prism/fixtures/whitequark/send_index_legacy.txt diff --git a/test/yarp/fixtures/whitequark/send_lambda.txt b/test/prism/fixtures/whitequark/send_lambda.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_lambda.txt rename to test/prism/fixtures/whitequark/send_lambda.txt diff --git a/test/yarp/fixtures/whitequark/send_lambda_args.txt b/test/prism/fixtures/whitequark/send_lambda_args.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_lambda_args.txt rename to test/prism/fixtures/whitequark/send_lambda_args.txt diff --git a/test/yarp/fixtures/whitequark/send_lambda_args_noparen.txt b/test/prism/fixtures/whitequark/send_lambda_args_noparen.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_lambda_args_noparen.txt rename to test/prism/fixtures/whitequark/send_lambda_args_noparen.txt diff --git a/test/yarp/fixtures/whitequark/send_lambda_args_shadow.txt b/test/prism/fixtures/whitequark/send_lambda_args_shadow.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_lambda_args_shadow.txt rename to test/prism/fixtures/whitequark/send_lambda_args_shadow.txt diff --git a/test/yarp/fixtures/whitequark/send_lambda_legacy.txt b/test/prism/fixtures/whitequark/send_lambda_legacy.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_lambda_legacy.txt rename to test/prism/fixtures/whitequark/send_lambda_legacy.txt diff --git a/test/yarp/fixtures/whitequark/send_op_asgn_conditional.txt b/test/prism/fixtures/whitequark/send_op_asgn_conditional.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_op_asgn_conditional.txt rename to test/prism/fixtures/whitequark/send_op_asgn_conditional.txt diff --git a/test/yarp/fixtures/whitequark/send_plain.txt b/test/prism/fixtures/whitequark/send_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_plain.txt rename to test/prism/fixtures/whitequark/send_plain.txt diff --git a/test/yarp/fixtures/whitequark/send_plain_cmd.txt b/test/prism/fixtures/whitequark/send_plain_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_plain_cmd.txt rename to test/prism/fixtures/whitequark/send_plain_cmd.txt diff --git a/test/yarp/fixtures/whitequark/send_self.txt b/test/prism/fixtures/whitequark/send_self.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_self.txt rename to test/prism/fixtures/whitequark/send_self.txt diff --git a/test/yarp/fixtures/whitequark/send_self_block.txt b/test/prism/fixtures/whitequark/send_self_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_self_block.txt rename to test/prism/fixtures/whitequark/send_self_block.txt diff --git a/test/yarp/fixtures/whitequark/send_unary_op.txt b/test/prism/fixtures/whitequark/send_unary_op.txt similarity index 100% rename from test/yarp/fixtures/whitequark/send_unary_op.txt rename to test/prism/fixtures/whitequark/send_unary_op.txt diff --git a/test/yarp/fixtures/whitequark/slash_newline_in_heredocs.txt b/test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt similarity index 100% rename from test/yarp/fixtures/whitequark/slash_newline_in_heredocs.txt rename to test/prism/fixtures/whitequark/slash_newline_in_heredocs.txt diff --git a/test/yarp/fixtures/whitequark/space_args_arg.txt b/test/prism/fixtures/whitequark/space_args_arg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_arg.txt rename to test/prism/fixtures/whitequark/space_args_arg.txt diff --git a/test/yarp/fixtures/whitequark/space_args_arg_block.txt b/test/prism/fixtures/whitequark/space_args_arg_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_arg_block.txt rename to test/prism/fixtures/whitequark/space_args_arg_block.txt diff --git a/test/yarp/fixtures/whitequark/space_args_arg_call.txt b/test/prism/fixtures/whitequark/space_args_arg_call.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_arg_call.txt rename to test/prism/fixtures/whitequark/space_args_arg_call.txt diff --git a/test/yarp/fixtures/whitequark/space_args_arg_newline.txt b/test/prism/fixtures/whitequark/space_args_arg_newline.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_arg_newline.txt rename to test/prism/fixtures/whitequark/space_args_arg_newline.txt diff --git a/test/yarp/fixtures/whitequark/space_args_block.txt b/test/prism/fixtures/whitequark/space_args_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_block.txt rename to test/prism/fixtures/whitequark/space_args_block.txt diff --git a/test/yarp/fixtures/whitequark/space_args_cmd.txt b/test/prism/fixtures/whitequark/space_args_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/space_args_cmd.txt rename to test/prism/fixtures/whitequark/space_args_cmd.txt diff --git a/test/yarp/fixtures/whitequark/string___FILE__.txt b/test/prism/fixtures/whitequark/string___FILE__.txt similarity index 100% rename from test/yarp/fixtures/whitequark/string___FILE__.txt rename to test/prism/fixtures/whitequark/string___FILE__.txt diff --git a/test/yarp/fixtures/whitequark/string_concat.txt b/test/prism/fixtures/whitequark/string_concat.txt similarity index 100% rename from test/yarp/fixtures/whitequark/string_concat.txt rename to test/prism/fixtures/whitequark/string_concat.txt diff --git a/test/yarp/fixtures/whitequark/string_dvar.txt b/test/prism/fixtures/whitequark/string_dvar.txt similarity index 100% rename from test/yarp/fixtures/whitequark/string_dvar.txt rename to test/prism/fixtures/whitequark/string_dvar.txt diff --git a/test/yarp/fixtures/whitequark/string_interp.txt b/test/prism/fixtures/whitequark/string_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/string_interp.txt rename to test/prism/fixtures/whitequark/string_interp.txt diff --git a/test/yarp/fixtures/whitequark/string_plain.txt b/test/prism/fixtures/whitequark/string_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/string_plain.txt rename to test/prism/fixtures/whitequark/string_plain.txt diff --git a/test/yarp/fixtures/whitequark/super.txt b/test/prism/fixtures/whitequark/super.txt similarity index 100% rename from test/yarp/fixtures/whitequark/super.txt rename to test/prism/fixtures/whitequark/super.txt diff --git a/test/yarp/fixtures/whitequark/super_block.txt b/test/prism/fixtures/whitequark/super_block.txt similarity index 100% rename from test/yarp/fixtures/whitequark/super_block.txt rename to test/prism/fixtures/whitequark/super_block.txt diff --git a/test/yarp/fixtures/whitequark/symbol_interp.txt b/test/prism/fixtures/whitequark/symbol_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/symbol_interp.txt rename to test/prism/fixtures/whitequark/symbol_interp.txt diff --git a/test/yarp/fixtures/whitequark/symbol_plain.txt b/test/prism/fixtures/whitequark/symbol_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/symbol_plain.txt rename to test/prism/fixtures/whitequark/symbol_plain.txt diff --git a/test/yarp/fixtures/whitequark/ternary.txt b/test/prism/fixtures/whitequark/ternary.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ternary.txt rename to test/prism/fixtures/whitequark/ternary.txt diff --git a/test/yarp/fixtures/whitequark/ternary_ambiguous_symbol.txt b/test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt similarity index 100% rename from test/yarp/fixtures/whitequark/ternary_ambiguous_symbol.txt rename to test/prism/fixtures/whitequark/ternary_ambiguous_symbol.txt diff --git a/test/yarp/fixtures/whitequark/trailing_forward_arg.txt b/test/prism/fixtures/whitequark/trailing_forward_arg.txt similarity index 100% rename from test/yarp/fixtures/whitequark/trailing_forward_arg.txt rename to test/prism/fixtures/whitequark/trailing_forward_arg.txt diff --git a/test/yarp/fixtures/whitequark/true.txt b/test/prism/fixtures/whitequark/true.txt similarity index 100% rename from test/yarp/fixtures/whitequark/true.txt rename to test/prism/fixtures/whitequark/true.txt diff --git a/test/yarp/fixtures/whitequark/unary_num_pow_precedence.txt b/test/prism/fixtures/whitequark/unary_num_pow_precedence.txt similarity index 100% rename from test/yarp/fixtures/whitequark/unary_num_pow_precedence.txt rename to test/prism/fixtures/whitequark/unary_num_pow_precedence.txt diff --git a/test/yarp/fixtures/whitequark/undef.txt b/test/prism/fixtures/whitequark/undef.txt similarity index 100% rename from test/yarp/fixtures/whitequark/undef.txt rename to test/prism/fixtures/whitequark/undef.txt diff --git a/test/yarp/fixtures/whitequark/unless.txt b/test/prism/fixtures/whitequark/unless.txt similarity index 100% rename from test/yarp/fixtures/whitequark/unless.txt rename to test/prism/fixtures/whitequark/unless.txt diff --git a/test/yarp/fixtures/whitequark/unless_else.txt b/test/prism/fixtures/whitequark/unless_else.txt similarity index 100% rename from test/yarp/fixtures/whitequark/unless_else.txt rename to test/prism/fixtures/whitequark/unless_else.txt diff --git a/test/yarp/fixtures/whitequark/unless_mod.txt b/test/prism/fixtures/whitequark/unless_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/unless_mod.txt rename to test/prism/fixtures/whitequark/unless_mod.txt diff --git a/test/yarp/fixtures/whitequark/until.txt b/test/prism/fixtures/whitequark/until.txt similarity index 100% rename from test/yarp/fixtures/whitequark/until.txt rename to test/prism/fixtures/whitequark/until.txt diff --git a/test/yarp/fixtures/whitequark/until_mod.txt b/test/prism/fixtures/whitequark/until_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/until_mod.txt rename to test/prism/fixtures/whitequark/until_mod.txt diff --git a/test/yarp/fixtures/whitequark/until_post.txt b/test/prism/fixtures/whitequark/until_post.txt similarity index 100% rename from test/yarp/fixtures/whitequark/until_post.txt rename to test/prism/fixtures/whitequark/until_post.txt diff --git a/test/yarp/fixtures/whitequark/var_and_asgn.txt b/test/prism/fixtures/whitequark/var_and_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/var_and_asgn.txt rename to test/prism/fixtures/whitequark/var_and_asgn.txt diff --git a/test/yarp/fixtures/whitequark/var_op_asgn.txt b/test/prism/fixtures/whitequark/var_op_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/var_op_asgn.txt rename to test/prism/fixtures/whitequark/var_op_asgn.txt diff --git a/test/yarp/fixtures/whitequark/var_op_asgn_cmd.txt b/test/prism/fixtures/whitequark/var_op_asgn_cmd.txt similarity index 100% rename from test/yarp/fixtures/whitequark/var_op_asgn_cmd.txt rename to test/prism/fixtures/whitequark/var_op_asgn_cmd.txt diff --git a/test/yarp/fixtures/whitequark/var_or_asgn.txt b/test/prism/fixtures/whitequark/var_or_asgn.txt similarity index 100% rename from test/yarp/fixtures/whitequark/var_or_asgn.txt rename to test/prism/fixtures/whitequark/var_or_asgn.txt diff --git a/test/yarp/fixtures/whitequark/when_multi.txt b/test/prism/fixtures/whitequark/when_multi.txt similarity index 100% rename from test/yarp/fixtures/whitequark/when_multi.txt rename to test/prism/fixtures/whitequark/when_multi.txt diff --git a/test/yarp/fixtures/whitequark/when_splat.txt b/test/prism/fixtures/whitequark/when_splat.txt similarity index 100% rename from test/yarp/fixtures/whitequark/when_splat.txt rename to test/prism/fixtures/whitequark/when_splat.txt diff --git a/test/yarp/fixtures/whitequark/when_then.txt b/test/prism/fixtures/whitequark/when_then.txt similarity index 100% rename from test/yarp/fixtures/whitequark/when_then.txt rename to test/prism/fixtures/whitequark/when_then.txt diff --git a/test/yarp/fixtures/whitequark/while.txt b/test/prism/fixtures/whitequark/while.txt similarity index 100% rename from test/yarp/fixtures/whitequark/while.txt rename to test/prism/fixtures/whitequark/while.txt diff --git a/test/yarp/fixtures/whitequark/while_mod.txt b/test/prism/fixtures/whitequark/while_mod.txt similarity index 100% rename from test/yarp/fixtures/whitequark/while_mod.txt rename to test/prism/fixtures/whitequark/while_mod.txt diff --git a/test/yarp/fixtures/whitequark/while_post.txt b/test/prism/fixtures/whitequark/while_post.txt similarity index 100% rename from test/yarp/fixtures/whitequark/while_post.txt rename to test/prism/fixtures/whitequark/while_post.txt diff --git a/test/yarp/fixtures/whitequark/xstring_interp.txt b/test/prism/fixtures/whitequark/xstring_interp.txt similarity index 100% rename from test/yarp/fixtures/whitequark/xstring_interp.txt rename to test/prism/fixtures/whitequark/xstring_interp.txt diff --git a/test/yarp/fixtures/whitequark/xstring_plain.txt b/test/prism/fixtures/whitequark/xstring_plain.txt similarity index 100% rename from test/yarp/fixtures/whitequark/xstring_plain.txt rename to test/prism/fixtures/whitequark/xstring_plain.txt diff --git a/test/yarp/fixtures/whitequark/yield.txt b/test/prism/fixtures/whitequark/yield.txt similarity index 100% rename from test/yarp/fixtures/whitequark/yield.txt rename to test/prism/fixtures/whitequark/yield.txt diff --git a/test/yarp/fixtures/whitequark/zsuper.txt b/test/prism/fixtures/whitequark/zsuper.txt similarity index 100% rename from test/yarp/fixtures/whitequark/zsuper.txt rename to test/prism/fixtures/whitequark/zsuper.txt diff --git a/test/yarp/fixtures/xstring.txt b/test/prism/fixtures/xstring.txt similarity index 100% rename from test/yarp/fixtures/xstring.txt rename to test/prism/fixtures/xstring.txt diff --git a/test/yarp/fixtures/yield.txt b/test/prism/fixtures/yield.txt similarity index 100% rename from test/yarp/fixtures/yield.txt rename to test/prism/fixtures/yield.txt diff --git a/test/yarp/fuzzer_test.rb b/test/prism/fuzzer_test.rb similarity index 96% rename from test/yarp/fuzzer_test.rb rename to test/prism/fuzzer_test.rb index f4abcd4ac8000f..04e45518b14f7a 100644 --- a/test/yarp/fuzzer_test.rb +++ b/test/prism/fuzzer_test.rb @@ -2,11 +2,11 @@ require_relative "test_helper" -module YARP +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}") { YARP.dump(source) } + define_method(:"test_fuzzer_#{name}") { Prism.dump(source) } end snippet "incomplete global variable", "$" diff --git a/test/prism/heredoc_dedent_test.rb b/test/prism/heredoc_dedent_test.rb new file mode 100644 index 00000000000000..1dd7e4d5115c69 --- /dev/null +++ b/test/prism/heredoc_dedent_test.rb @@ -0,0 +1,22 @@ +# 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| + 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/yarp/library_symbols_test.rb b/test/prism/library_symbols_test.rb similarity index 76% rename from test/yarp/library_symbols_test.rb rename to test/prism/library_symbols_test.rb index 53f56d9bfa6c73..c8eedb0674ee91 100644 --- a/test/yarp/library_symbols_test.rb +++ b/test/prism/library_symbols_test.rb @@ -4,9 +4,9 @@ return if RUBY_PLATFORM !~ /linux/ -module YARP +module Prism # - # examine a yarp dll or static archive for expected external symbols. + # examine a prism dll or static archive for expected external symbols. # these tests only work on a linux system right now. # class LibrarySymbolsTest < TestCase @@ -15,7 +15,7 @@ def setup @librubyparser_a = File.expand_path("../../build/librubyparser.a", __dir__) @librubyparser_so = File.expand_path("../../build/librubyparser.so", __dir__) - @yarp_so = File.expand_path("../../lib/yarp/yarp.so", __dir__) + @prism_so = File.expand_path("../../lib/prism/prism.so", __dir__) end # objdump runner and helpers @@ -64,12 +64,12 @@ def test_librubyparser_a_contains_nothing_globally_visible assert_empty(names(visible_global_objdump_symbols(@librubyparser_a))) end - def test_librubyparser_a_contains_hidden_yp_symbols + def test_librubyparser_a_contains_hidden_pm_symbols omit("librubyparser.a is not built") unless File.exist?(@librubyparser_a) names(hidden_global_objdump_symbols(@librubyparser_a)).tap do |symbols| - assert_includes(symbols, "yp_parse") - assert_includes(symbols, "yp_version") + assert_includes(symbols, "pm_parse") + assert_includes(symbols, "pm_version") end end @@ -80,23 +80,23 @@ def test_librubyparser_so_exports_only_the_necessary_functions omit("librubyparser.so is not built") unless File.exist?(@librubyparser_so) names(global_nm_symbols(@librubyparser_so)).tap do |symbols| - assert_includes(symbols, "yp_parse") - assert_includes(symbols, "yp_version") + assert_includes(symbols, "pm_parse") + assert_includes(symbols, "pm_version") end names(local_nm_symbols(@librubyparser_so)).tap do |symbols| - assert_includes(symbols, "yp_encoding_shift_jis_isupper_char") + assert_includes(symbols, "pm_encoding_shift_jis_isupper_char") end # TODO: someone who uses this library needs to finish this test end # - # shared object - yarp.so + # shared object - prism.so # - def test_yarp_so_exports_only_the_C_extension_init_function - omit("yarp.so is not built") unless File.exist?(@yarp_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(@yarp_so)).tap do |symbols| - assert_equal(["Init_yarp"], symbols) + names(global_nm_symbols(@prism_so)).tap do |symbols| + assert_equal(["Init_prism"], symbols) end end end diff --git a/test/yarp/locals_test.rb b/test/prism/locals_test.rb similarity index 98% rename from test/yarp/locals_test.rb rename to test/prism/locals_test.rb index 45aecdcaf7ef2e..06324f9d94deb9 100644 --- a/test/yarp/locals_test.rb +++ b/test/prism/locals_test.rb @@ -15,7 +15,7 @@ require_relative "test_helper" -module YARP +module Prism class LocalsTest < TestCase invalid = [] todos = [] @@ -93,7 +93,7 @@ def assert_locals(filepath) source = File.read(filepath) expected = Debug.cruby_locals(source) - actual = Debug.yarp_locals(source) + actual = Debug.prism_locals(source) assert_equal(expected, actual) end diff --git a/test/yarp/location_test.rb b/test/prism/location_test.rb similarity index 94% rename from test/yarp/location_test.rb rename to test/prism/location_test.rb index 6b219a0b3664c3..7242bdeca5b16e 100644 --- a/test/yarp/location_test.rb +++ b/test/prism/location_test.rb @@ -2,10 +2,14 @@ require_relative "test_helper" -module YARP +module Prism class LocationTest < TestCase - def test_AliasNode - assert_location(AliasNode, "alias foo bar") + def test_AliasGlobalVariableNode + assert_location(AliasGlobalVariableNode, "alias $foo $bar") + end + + def test_AliasMethodNode + assert_location(AliasMethodNode, "alias foo bar") end def test_AlternationPatternNode @@ -64,7 +68,7 @@ def test_BeginNode end def test_BlockArgumentNode - assert_location(BlockArgumentNode, "foo(&bar)", 4...8) { |node| node.arguments.arguments.last } + assert_location(BlockArgumentNode, "foo(&bar)", 4...8, &:block) end def test_BlockLocalVariableNode @@ -202,7 +206,7 @@ def test_CaseNode def test_ClassNode assert_location(ClassNode, "class Foo end") - assert_location(ClassNode, "class Foo < Bar end") + assert_location(ClassNode, "class Foo < Bar; end") end def test_ClassVariableAndWriteNode @@ -406,6 +410,20 @@ def test_ImaginaryNode 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_InNode assert_location(InNode, "case foo; in bar; end", 10...16) do |node| node.conditions.first @@ -450,13 +468,17 @@ def test_IntegerNode 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 world\nA", 0...4) + assert_location(InterpolatedStringNode, "<<~A\nhello \#{1} world\nA", 0...4) end def test_InterpolatedSymbolNode @@ -525,6 +547,10 @@ 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 @@ -533,6 +559,10 @@ def test_MatchRequiredNode assert_location(MatchRequiredNode, "foo => bar") end + def test_MatchWriteNode + assert_location(MatchWriteNode, "/(?)/ =~ foo") + end + def test_ModuleNode assert_location(ModuleNode, "module Foo end") end @@ -544,6 +574,8 @@ def test_MultiTargetNode 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 @@ -807,7 +839,7 @@ def test_YieldNode end def test_all_tested - expected = YARP.constants.grep(/.Node$/).sort - %i[MissingNode ProgramNode] + 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 @@ -815,7 +847,7 @@ def test_all_tested private def assert_location(kind, source, expected = 0...source.length) - result = YARP.parse(source) + result = Prism.parse(source) assert_equal [], result.comments assert_equal [], result.errors diff --git a/test/yarp/memsize_test.rb b/test/prism/memsize_test.rb similarity index 86% rename from test/yarp/memsize_test.rb rename to test/prism/memsize_test.rb index 07c85ce329504a..d7e1448dbc0ec3 100644 --- a/test/yarp/memsize_test.rb +++ b/test/prism/memsize_test.rb @@ -2,9 +2,9 @@ require_relative "test_helper" -return if YARP::BACKEND == :FFI +return if Prism::BACKEND == :FFI -module YARP +module Prism class MemsizeTest < TestCase def test_memsize result = Debug.memsize("2 + 3") diff --git a/test/yarp/newline_test.rb b/test/prism/newline_test.rb similarity index 83% rename from test/yarp/newline_test.rb rename to test/prism/newline_test.rb index ba82b5ef45dc8e..6fd0aee2d50f56 100644 --- a/test/yarp/newline_test.rb +++ b/test/prism/newline_test.rb @@ -4,22 +4,8 @@ return unless defined?(RubyVM::InstructionSequence) -module YARP +module Prism class NewlineTest < TestCase - class NewlineVisitor < Visitor - attr_reader :source, :newlines - - def initialize(source) - @source = source - @newlines = [] - end - - def visit(node) - newlines << source.line(node.location.start_offset) if node&.newline? - super(node) - end - end - base = File.dirname(__dir__) Dir["{lib,test}/**/*.rb", base: base].each do |relative| define_method("test_newline_flags_#{relative}") do @@ -34,14 +20,9 @@ def assert_newlines(base, relative) source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8) expected = rubyvm_lines(source) - result = YARP.parse_file(filepath) + result = Prism.parse_file(filepath) assert_empty result.errors - - result.mark_newlines! - visitor = NewlineVisitor.new(result.source) - - result.value.accept(visitor) - actual = visitor.newlines + 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 @@ -92,5 +73,19 @@ def rubyvm_lines(source) 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/yarp/parse_serialize_test.rb b/test/prism/parse_serialize_test.rb similarity index 81% rename from test/yarp/parse_serialize_test.rb rename to test/prism/parse_serialize_test.rb index d3474f7104d95f..001518c14d55dc 100644 --- a/test/yarp/parse_serialize_test.rb +++ b/test/prism/parse_serialize_test.rb @@ -2,13 +2,13 @@ require_relative "test_helper" -return if YARP::BACKEND == :FFI +return if Prism::BACKEND == :FFI -module YARP +module Prism class ParseSerializeTest < TestCase def test_parse_serialize dumped = Debug.parse_serialize_file(__FILE__) - result = YARP.load(File.read(__FILE__), dumped) + result = Prism.load(File.read(__FILE__), dumped) assert_kind_of ParseResult, result, "Expected the return value to be a ParseResult" assert_equal __FILE__, find_file_node(result)&.filepath, "Expected the filepath to be set correctly" @@ -19,7 +19,7 @@ def test_parse_serialize_with_locals metadata = [filepath.bytesize, filepath.b, 1, 1, 1, "foo".b].pack("LA*LLLA*") dumped = Debug.parse_serialize_file_metadata(filepath, metadata) - result = YARP.load(File.read(__FILE__), dumped) + result = Prism.load(File.read(__FILE__), dumped) assert_kind_of ParseResult, result, "Expected the return value to be a ParseResult" end @@ -31,7 +31,7 @@ def find_file_node(result) while (node = queue.shift) return node if node.is_a?(SourceFileNode) - queue.concat(node.child_nodes.compact) + queue.concat(node.compact_child_nodes) end end end diff --git a/test/yarp/parse_test.rb b/test/prism/parse_test.rb similarity index 81% rename from test/yarp/parse_test.rb rename to test/prism/parse_test.rb index 5299cfd7b11ed4..3c0d584a1271d4 100644 --- a/test/yarp/parse_test.rb +++ b/test/prism/parse_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class ParseTest < TestCase # 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 @@ -20,34 +20,34 @@ def teardown end def test_empty_string - result = YARP.parse("") + result = Prism.parse("") assert_equal [], result.value.statements.body end def test_parse_takes_file_path filepath = "filepath.rb" - result = YARP.parse("def foo; __FILE__; end", filepath) + result = Prism.parse("def foo; __FILE__; end", filepath) assert_equal filepath, find_source_file_node(result.value).filepath end def test_parse_lex - node, tokens = YARP.parse_lex("def foo; end").value + 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 = YARP.parse_lex_file(__FILE__).value + 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 Ruby 3.2+. - ripper_enabled = RUBY_VERSION >= "3.2.0" + # 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. @@ -85,12 +85,23 @@ def test_parse_lex_file # and explicitly set the external encoding to UTF-8 to override the binmode default. source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8) - # Make sure that 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(source), "Ripper failed to parse") if ripper_should_parse + if ripper_should_parse + src = source + + case relative + when /break|next|redo|if|unless|rescue|control|keywords|retry|yield|\/args_assocs/ + # Uncaught syntax errors: Invalid break, Invalid next + src = "->do\nrescue\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 = YARP.parse(source, relative) + result = Prism.parse(source, relative) assert_empty result.errors # Next, pretty print the source. @@ -117,7 +128,7 @@ def test_parse_lex_file # Next, assert that the value can be serialized and deserialized without # changing the shape of the tree. - assert_equal_nodes(result.value, YARP.load(source, YARP.dump(source, relative)).value) + assert_equal_nodes(result.value, Prism.load(source, Prism.dump(source, relative)).value) # Next, check that the location ranges of each node in the tree are a # superset of their respective child nodes. @@ -126,25 +137,18 @@ def test_parse_lex_file # Next, assert that the newlines are in the expected places. expected_newlines = [0] source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 } - - # If there's a __END__, then we should trip out those newlines because we - # don't actually scan them during parsing (because we don't need to). - if found = result.comments.find { |comment| comment.type == :__END__ } - expected_newlines = expected_newlines[...found.location.start_line] - end - 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 = YARP.lex_compat(source) + lex_result = Prism.lex_compat(source) assert_equal [], lex_result.errors tokens = lex_result.value begin - YARP.lex_ripper(source).zip(tokens).each do |(ripper, yarp)| - assert_equal ripper, yarp + 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}" @@ -167,10 +171,10 @@ def test_parse_lex_file file_contents.split(/(?<=\S)\n\n(?=\S)/).each do |snippet| snippet = snippet.rstrip - result = YARP.parse(snippet, relative) + result = Prism.parse(snippet, relative) assert_empty result.errors - assert_equal_nodes(result.value, YARP.load(snippet, YARP.dump(snippet, relative)).value) + assert_equal_nodes(result.value, Prism.load(snippet, Prism.dump(snippet, relative)).value) end end end @@ -186,7 +190,11 @@ def assert_non_overlapping_locations(node) # 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?(InterpolatedStringNode) || current.is_a?(InterpolatedXStringNode)) || !current.opening&.start_with?("<<") + 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. @@ -207,7 +215,7 @@ def find_source_file_node(program) queue = [program] while (node = queue.shift) return node if node.is_a?(SourceFileNode) - queue.concat(node.child_nodes.compact) + queue.concat(node.compact_child_nodes) end end diff --git a/test/yarp/pattern_test.rb b/test/prism/pattern_test.rb similarity index 92% rename from test/yarp/pattern_test.rb rename to test/prism/pattern_test.rb index d34fe84458f206..af1efa7560a6e1 100644 --- a/test/yarp/pattern_test.rb +++ b/test/prism/pattern_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class PatternTest < TestCase def test_invalid_syntax assert_raise(Pattern::CompilationError) { scan("", "<>") } @@ -69,7 +69,7 @@ def test_object_const end def test_constant_path - results = scan("Foo + Bar + Baz", "YARP::ConstantReadNode") + results = scan("Foo + Bar + Baz", "Prism::ConstantReadNode") assert_equal 3, results.length end @@ -84,7 +84,7 @@ def test_hash_pattern_regexp results = scan("Foo + Bar + Baz", "{ name: /^[[:punct:]]$/ }") assert_equal 2, results.length - assert_equal ["YARP::CallNode"], results.map { |node| node.class.name }.uniq + assert_equal ["Prism::CallNode"], results.map { |node| node.class.name }.uniq end def test_nil @@ -126,7 +126,7 @@ def test_symbol private def scan(source, query) - YARP::Pattern.new(query).scan(YARP.parse(source).value).to_a + Prism::Pattern.new(query).scan(Prism.parse(source).value).to_a end end end diff --git a/test/yarp/regexp_test.rb b/test/prism/regexp_test.rb similarity index 77% rename from test/yarp/regexp_test.rb rename to test/prism/regexp_test.rb index 9863a54758aa1f..67114c7bf3dd5f 100644 --- a/test/yarp/regexp_test.rb +++ b/test/prism/regexp_test.rb @@ -2,9 +2,9 @@ require_relative "test_helper" -return if YARP::BACKEND == :FFI +return if Prism::BACKEND == :FFI -module YARP +module Prism class RegexpTest < TestCase ############################################################################## # These tests test the actual use case of extracting named capture groups @@ -192,10 +192,60 @@ 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 + 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/yarp/ripper_compat_test.rb b/test/prism/ripper_compat_test.rb similarity index 96% rename from test/yarp/ripper_compat_test.rb rename to test/prism/ripper_compat_test.rb index 9fcdfe63c685ca..af38d1e9463298 100644 --- a/test/yarp/ripper_compat_test.rb +++ b/test/prism/ripper_compat_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class RipperCompatTest < TestCase def test_1_plus_2 assert_equivalent("1 + 2") diff --git a/test/yarp/ruby_api_test.rb b/test/prism/ruby_api_test.rb similarity index 79% rename from test/yarp/ruby_api_test.rb rename to test/prism/ruby_api_test.rb index dc12012f44abf2..a6ce976a85ed0b 100644 --- a/test/yarp/ruby_api_test.rb +++ b/test/prism/ruby_api_test.rb @@ -2,19 +2,19 @@ require_relative "test_helper" -module YARP +module Prism class RubyAPITest < TestCase def test_ruby_api filepath = __FILE__ source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8) - assert_equal YARP.lex(source, filepath).value, YARP.lex_file(filepath).value - assert_equal YARP.dump(source, filepath), YARP.dump_file(filepath) + assert_equal Prism.lex(source, filepath).value, Prism.lex_file(filepath).value + assert_equal Prism.dump(source, filepath), Prism.dump_file(filepath) - serialized = YARP.dump(source, filepath) - ast1 = YARP.load(source, serialized).value - ast2 = YARP.parse(source, filepath).value - ast3 = YARP.parse_file(filepath).value + serialized = Prism.dump(source, filepath) + ast1 = Prism.load(source, serialized).value + ast2 = Prism.parse(source, filepath).value + ast3 = Prism.parse_file(filepath).value assert_equal_nodes ast1, ast2 assert_equal_nodes ast2, ast3 @@ -58,7 +58,7 @@ def test_location_join private def parse_expression(source) - YARP.parse(source).value.statements.body.first + Prism.parse(source).value.statements.body.first end end end diff --git a/test/prism/snapshots/alias.txt b/test/prism/snapshots/alias.txt new file mode 100644 index 00000000000000..732c69b4d1b109 --- /dev/null +++ b/test/prism/snapshots/alias.txt @@ -0,0 +1,173 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ └── keyword_loc: (9,0)-(9,5) = "alias" + ├── @ AliasMethodNode (location: (11,0)-(11,13)) + │ ├── new_name: + │ │ @ SymbolNode (location: (11,6)-(11,9)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (11,6)-(11,9) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── old_name: + │ │ @ SymbolNode (location: (11,10)-(11,13)) + │ │ ├── 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)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (15,6)-(15,9) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── old_name: + │ │ @ SymbolNode (location: (15,10)-(15,12)) + │ │ ├── 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)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (17,6)-(17,9) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── old_name: + │ │ @ SymbolNode (location: (17,10)-(17,13)) + │ │ ├── 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)) + │ │ ├── opening_loc: (19,6)-(19,7) = ":" + │ │ ├── value_loc: (19,7)-(19,9) = "==" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "==" + │ ├── old_name: + │ │ @ SymbolNode (location: (19,10)-(19,15)) + │ │ ├── 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)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (21,6)-(21,7) = "A" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "A" + │ ├── old_name: + │ │ @ SymbolNode (location: (21,8)-(21,9)) + │ │ ├── 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)) + │ ├── 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)) + │ ├── opening_loc: (23,9)-(23,10) = ":" + │ ├── value_loc: (23,10)-(23,11) = "B" + │ ├── closing_loc: ∅ + │ └── unescaped: "B" + └── keyword_loc: (23,0)-(23,5) = "alias" diff --git a/test/prism/snapshots/arithmetic.txt b/test/prism/snapshots/arithmetic.txt new file mode 100644 index 00000000000000..5ff36ffe844a30 --- /dev/null +++ b/test/prism/snapshots/arithmetic.txt @@ -0,0 +1,245 @@ +@ ProgramNode (location: (1,0)-(13,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(13,8)) + └── body: (length: 7) + ├── @ CallNode (location: (1,0)-(1,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (1,5)-(1,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,5)-(1,8) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "!" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (3,0)-(3,8)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,4)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (3,1)-(3,4)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,1)-(3,4) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,1) = "-" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "-@" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,4)-(3,5) = "*" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,5)-(3,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,5)-(3,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,5)-(3,8) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "*" + ├── @ CallNode (location: (5,0)-(5,9)) + │ ├── receiver: + │ │ @ CallNode (location: (5,0)-(5,4)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (5,1)-(5,4)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,1)-(5,4) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,1) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+@" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,4)-(5,6) = "**" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,6)-(5,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (5,6)-(5,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,6)-(5,9) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "**" + ├── @ CallNode (location: (7,0)-(7,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,4)-(7,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (7,4)-(7,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (7,5)-(7,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,5)-(7,8) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,4)-(7,5) = "~" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "~" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (9,0)-(9,17)) + │ ├── receiver: + │ │ @ CallNode (location: (9,0)-(9,10)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (9,0)-(9,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,0)-(9,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,4)-(9,6) = "<<" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,7)-(9,10)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (9,7)-(9,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,7)-(9,10) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "<<" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,11)-(9,13) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,14)-(9,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (9,14)-(9,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,14)-(9,17) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ CallNode (location: (11,0)-(11,5)) + │ ├── receiver: + │ │ @ CallNode (location: (11,1)-(11,5)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (11,1)-(11,2)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,2)-(11,4) = "**" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (11,4)-(11,5)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (11,4)-(11,5)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "**" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,1) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-@" + └── @ CallNode (location: (13,0)-(13,8)) + ├── receiver: + │ @ IntegerNode (location: (13,0)-(13,2)) + │ └── flags: decimal + ├── call_operator_loc: (13,2)-(13,3) = "." + ├── message_loc: (13,3)-(13,8) = "zero?" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "zero?" diff --git a/test/prism/snapshots/arrays.txt b/test/prism/snapshots/arrays.txt new file mode 100644 index 00000000000000..8a7c98a839355f --- /dev/null +++ b/test/prism/snapshots/arrays.txt @@ -0,0 +1,873 @@ +@ ProgramNode (location: (1,0)-(82,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(82,7)) + └── body: (length: 30) + ├── @ ArrayNode (location: (1,0)-(1,4)) + │ ├── elements: (length: 1) + │ │ └── @ SplatNode (location: (1,1)-(1,3)) + │ │ ├── operator_loc: (1,1)-(1,2) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (1,2)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── opening_loc: (1,0)-(1,1) = "[" + │ └── closing_loc: (1,3)-(1,4) = "]" + ├── @ CallNode (location: (3,0)-(3,23)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,3)-(3,13) = "[bar, baz]" + │ ├── opening_loc: (3,3)-(3,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,4)-(3,23)) + │ │ └── arguments: (length: 3) + │ │ ├── @ CallNode (location: (3,4)-(3,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,4)-(3,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── @ CallNode (location: (3,9)-(3,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,9)-(3,12) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ ArrayNode (location: (3,16)-(3,23)) + │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ ArrayNode (location: (5,0)-(5,13)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (5,1)-(5,12)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (5,1)-(5,12)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (5,1)-(5,3)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (5,1)-(5,2) = "a" + │ │ │ ├── closing_loc: (5,2)-(5,3) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ ArrayNode (location: (5,4)-(5,12)) + │ │ │ ├── elements: (length: 2) + │ │ │ │ ├── @ SymbolNode (location: (5,5)-(5,7)) + │ │ │ │ │ ├── opening_loc: (5,5)-(5,6) = ":" + │ │ │ │ │ ├── value_loc: (5,6)-(5,7) = "b" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "b" + │ │ │ │ └── @ SymbolNode (location: (5,9)-(5,11)) + │ │ │ │ ├── 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)) + │ ├── elements: (length: 5) + │ │ ├── @ SymbolNode (location: (9,1)-(9,3)) + │ │ │ ├── opening_loc: (9,1)-(9,2) = ":" + │ │ │ ├── value_loc: (9,2)-(9,3) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ SymbolNode (location: (9,5)-(9,7)) + │ │ │ ├── opening_loc: (9,5)-(9,6) = ":" + │ │ │ ├── value_loc: (9,6)-(9,7) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ ├── @ SymbolNode (location: (10,0)-(10,2)) + │ │ │ ├── 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)) + │ │ ├── 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)) + │ ├── elements: (length: 5) + │ │ ├── @ SymbolNode (location: (18,1)-(18,3)) + │ │ │ ├── opening_loc: (18,1)-(18,2) = ":" + │ │ │ ├── value_loc: (18,2)-(18,3) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ SymbolNode (location: (18,5)-(18,7)) + │ │ │ ├── opening_loc: (18,5)-(18,6) = ":" + │ │ │ ├── value_loc: (18,6)-(18,7) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ ├── @ SymbolNode (location: (19,0)-(19,2)) + │ │ │ ├── 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)) + │ │ ├── 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)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (28,1)-(28,11)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (28,1)-(28,11)) + │ │ ├── key: + │ │ │ @ CallNode (location: (28,1)-(28,4)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (28,1)-(28,4) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── value: + │ │ │ @ CallNode (location: (28,8)-(28,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (28,8)-(28,11) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── operator_loc: (28,5)-(28,7) = "=>" + │ ├── opening_loc: (28,0)-(28,1) = "[" + │ └── closing_loc: (28,11)-(28,12) = "]" + ├── @ CallNode (location: (30,0)-(30,19)) + │ ├── receiver: + │ │ @ CallNode (location: (30,0)-(30,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (30,0)-(30,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (30,0)-(30,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,3)-(30,8) = "[bar]" + │ │ ├── opening_loc: (30,3)-(30,4) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (30,4)-(30,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (30,4)-(30,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (30,4)-(30,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (30,7)-(30,8) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (30,8)-(30,13) = "[baz]" + │ ├── opening_loc: (30,8)-(30,9) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (30,9)-(30,19)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (30,9)-(30,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (30,9)-(30,12) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ CallNode (location: (30,16)-(30,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,16)-(30,19) = "qux" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "qux" + │ ├── closing_loc: (30,12)-(30,13) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (32,0)-(32,13)) + │ ├── receiver: + │ │ @ CallNode (location: (32,0)-(32,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (32,0)-(32,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (32,0)-(32,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,3)-(32,8) = "[bar]" + │ │ ├── opening_loc: (32,3)-(32,4) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (32,4)-(32,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (32,4)-(32,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (32,4)-(32,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (32,7)-(32,8) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (32,8)-(32,13) = "[baz]" + │ ├── opening_loc: (32,8)-(32,9) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (32,9)-(32,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (32,9)-(32,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,9)-(32,12) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: (32,12)-(32,13) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ ArrayNode (location: (34,0)-(35,1)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (34,0)-(34,1) = "[" + │ └── closing_loc: (35,0)-(35,1) = "]" + ├── @ CallNode (location: (37,0)-(37,13)) + │ ├── receiver: + │ │ @ CallNode (location: (37,0)-(37,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,0)-(37,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,3)-(37,13) = "[bar, baz]" + │ ├── opening_loc: (37,3)-(37,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,4)-(37,12)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (37,4)-(37,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,4)-(37,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ CallNode (location: (37,9)-(37,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,9)-(37,12) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: (37,12)-(37,13) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (39,0)-(39,19)) + │ ├── receiver: + │ │ @ CallNode (location: (39,0)-(39,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,0)-(39,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (39,3)-(39,13) = "[bar, baz]" + │ ├── opening_loc: (39,3)-(39,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (39,4)-(39,19)) + │ │ └── arguments: (length: 3) + │ │ ├── @ CallNode (location: (39,4)-(39,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,4)-(39,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── @ CallNode (location: (39,9)-(39,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,9)-(39,12) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ CallNode (location: (39,16)-(39,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,16)-(39,19) = "qux" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "qux" + │ ├── closing_loc: (39,12)-(39,13) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ MultiWriteNode (location: (41,0)-(41,21)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (41,0)-(41,6)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (41,0)-(41,3)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (41,0)-(41,3) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (41,3)-(41,6) = "[0]" + │ │ │ ├── opening_loc: (41,3)-(41,4) = "[" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (41,4)-(41,5)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (41,4)-(41,5)) + │ │ │ │ └── flags: decimal + │ │ │ ├── closing_loc: (41,5)-(41,6) = "]" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "[]=" + │ │ └── @ CallNode (location: (41,8)-(41,14)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (41,8)-(41,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (41,8)-(41,11) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (41,11)-(41,14) = "[0]" + │ │ ├── opening_loc: (41,11)-(41,12) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (41,12)-(41,13)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (41,12)-(41,13)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (41,13)-(41,14) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]=" + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (41,15)-(41,16) = "=" + │ └── value: + │ @ ArrayNode (location: (41,17)-(41,21)) + │ ├── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (43,0)-(43,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (43,0)-(43,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (43,3)-(43,19) = "[bar[baz] = qux]" + │ ├── opening_loc: (43,3)-(43,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (43,4)-(43,18)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (43,4)-(43,18)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (43,4)-(43,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (43,4)-(43,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (43,7)-(43,12) = "[baz]" + │ │ ├── opening_loc: (43,7)-(43,8) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (43,8)-(43,18)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ CallNode (location: (43,8)-(43,11)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (43,8)-(43,11) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── @ CallNode (location: (43,15)-(43,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (43,15)-(43,18) = "qux" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "qux" + │ │ ├── closing_loc: (43,11)-(43,12) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]=" + │ ├── closing_loc: (43,18)-(43,19) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (45,0)-(45,8)) + │ ├── receiver: + │ │ @ CallNode (location: (45,0)-(45,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,0)-(45,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (45,3)-(45,8) = "[bar]" + │ ├── opening_loc: (45,3)-(45,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (45,4)-(45,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (45,4)-(45,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,4)-(45,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (45,7)-(45,8) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (47,0)-(47,14)) + │ ├── receiver: + │ │ @ CallNode (location: (47,0)-(47,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,0)-(47,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (47,3)-(47,8) = "[bar]" + │ ├── opening_loc: (47,3)-(47,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (47,4)-(47,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (47,4)-(47,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (47,4)-(47,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ CallNode (location: (47,11)-(47,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,11)-(47,14) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: (47,7)-(47,8) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ ArrayNode (location: (49,0)-(49,6)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (49,1)-(49,5)) + │ │ └── 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)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (51,1)-(51,5)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (51,1)-(51,5)) + │ │ ├── value: + │ │ │ @ CallNode (location: (51,3)-(51,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (51,3)-(51,5) = "kw" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "kw" + │ │ └── operator_loc: (51,1)-(51,3) = "**" + │ ├── opening_loc: (51,0)-(51,1) = "[" + │ └── closing_loc: (51,5)-(51,6) = "]" + ├── @ ArrayNode (location: (53,0)-(53,9)) + │ ├── elements: (length: 2) + │ │ ├── @ IntegerNode (location: (53,1)-(53,2)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordHashNode (location: (53,4)-(53,8)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (53,4)-(53,8)) + │ │ ├── value: + │ │ │ @ CallNode (location: (53,6)-(53,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (53,6)-(53,8) = "kw" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "kw" + │ │ └── operator_loc: (53,4)-(53,6) = "**" + │ ├── opening_loc: (53,0)-(53,1) = "[" + │ └── closing_loc: (53,8)-(53,9) = "]" + ├── @ ArrayNode (location: (55,0)-(55,21)) + │ ├── elements: (length: 2) + │ │ ├── @ IntegerNode (location: (55,1)-(55,2)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordHashNode (location: (55,4)-(55,20)) + │ │ └── elements: (length: 3) + │ │ ├── @ AssocSplatNode (location: (55,4)-(55,8)) + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (55,6)-(55,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (55,6)-(55,8) = "kw" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "kw" + │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (55,18)-(55,20) = "kw" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "kw" + │ │ └── operator_loc: (55,16)-(55,18) = "**" + │ ├── opening_loc: (55,0)-(55,1) = "[" + │ └── closing_loc: (55,20)-(55,21) = "]" + ├── @ ArrayNode (location: (57,0)-(59,1)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (58,2)-(58,12)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (58,2)-(58,12)) + │ │ ├── key: + │ │ │ @ CallNode (location: (58,2)-(58,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (58,2)-(58,5) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── value: + │ │ │ @ CallNode (location: (58,9)-(58,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (58,9)-(58,12) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── operator_loc: (58,6)-(58,8) = "=>" + │ ├── opening_loc: (57,0)-(57,1) = "[" + │ └── closing_loc: (59,0)-(59,1) = "]" + ├── @ ArrayNode (location: (62,0)-(62,17)) + │ ├── elements: (length: 3) + │ │ ├── @ SymbolNode (location: (62,3)-(62,6)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (62,3)-(62,6) = "one" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "one" + │ │ ├── @ SymbolNode (location: (62,7)-(62,10)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (62,7)-(62,10) = "two" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "two" + │ │ └── @ SymbolNode (location: (62,11)-(62,16)) + │ │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── elements: (length: 3) + │ │ ├── @ SymbolNode (location: (69,3)-(69,6)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (69,3)-(69,6) = "one" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "one" + │ │ ├── @ SymbolNode (location: (69,7)-(69,10)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (69,7)-(69,10) = "two" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "two" + │ │ └── @ SymbolNode (location: (69,11)-(69,16)) + │ │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── elements: (length: 3) + │ │ ├── @ SymbolNode (location: (76,3)-(76,6)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (76,3)-(76,6) = "one" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "one" + │ │ ├── @ SymbolNode (location: (76,7)-(76,10)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (76,7)-(76,10) = "two" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "two" + │ │ └── @ SymbolNode (location: (76,11)-(76,16)) + │ │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + ├── 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) = "]" diff --git a/test/prism/snapshots/begin_ensure.txt b/test/prism/snapshots/begin_ensure.txt new file mode 100644 index 00000000000000..42b97cd609e864 --- /dev/null +++ b/test/prism/snapshots/begin_ensure.txt @@ -0,0 +1,249 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,0)-(2,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,0)-(4,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,7)-(7,8) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,18)-(7,19) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,6)-(9,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (10,8)-(10,9) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,6)-(13,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,16)-(13,17) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: + │ │ │ @ SymbolNode (location: (15,11)-(15,13)) + │ │ │ ├── opening_loc: (15,11)-(15,12) = ":" + │ │ │ ├── value_loc: (15,12)-(15,13) = "s" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "s" + │ │ ├── call_operator_loc: (15,13)-(15,14) = "." + │ │ ├── message_loc: (15,14)-(15,15) = "l" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (15,16)-(21,7)) + │ │ │ └── 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)) + │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ @ ConstantReadNode (location: (15,29)-(15,35)) + │ │ │ │ │ │ └── name: :Module + │ │ │ │ │ ├── call_operator_loc: (15,35)-(15,36) = "." + │ │ │ │ │ ├── message_loc: (15,36)-(15,39) = "new" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (15,40)-(21,3)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: + │ │ │ │ │ │ │ @ StatementsNode (location: (16,2)-(20,5)) + │ │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ │ └── @ BeginNode (location: (16,2)-(20,5)) + │ │ │ │ │ │ │ ├── begin_keyword_loc: (16,2)-(16,7) = "begin" + │ │ │ │ │ │ │ ├── statements: + │ │ │ │ │ │ │ │ @ StatementsNode (location: (17,4)-(17,9)) + │ │ │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ │ │ └── @ BreakNode (location: (17,4)-(17,9)) + │ │ │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ │ │ └── keyword_loc: (17,4)-(17,9) = "break" + │ │ │ │ │ │ │ ├── rescue_clause: ∅ + │ │ │ │ │ │ │ ├── else_clause: ∅ + │ │ │ │ │ │ │ ├── ensure_clause: + │ │ │ │ │ │ │ │ @ EnsureNode (location: (18,4)-(20,5)) + │ │ │ │ │ │ │ │ ├── ensure_keyword_loc: (18,4)-(18,10) = "ensure" + │ │ │ │ │ │ │ │ ├── statements: + │ │ │ │ │ │ │ │ │ @ StatementsNode (location: (18,11)-(19,7)) + │ │ │ │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ │ │ │ └── @ CallNode (location: (18,11)-(19,7)) + │ │ │ │ │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ │ │ │ │ @ ConstantReadNode (location: (18,11)-(18,17)) + │ │ │ │ │ │ │ │ │ │ └── name: :Module + │ │ │ │ │ │ │ │ │ ├── call_operator_loc: (18,17)-(18,18) = "." + │ │ │ │ │ │ │ │ │ ├── message_loc: (18,18)-(18,21) = "new" + │ │ │ │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ │ │ │ ├── block: + │ │ │ │ │ │ │ │ │ │ @ BlockNode (location: (18,22)-(19,7)) + │ │ │ │ │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ │ │ │ │ ├── opening_loc: (18,22)-(18,24) = "do" + │ │ │ │ │ │ │ │ │ │ └── closing_loc: (19,4)-(19,7) = "end" + │ │ │ │ │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ │ │ │ │ └── name: "new" + │ │ │ │ │ │ │ │ └── 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" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "new" + │ │ │ │ └── end_keyword_loc: (21,4)-(21,7) = "end" + │ │ │ └── end_keyword_loc: (21,4)-(21,7) = "end" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "l" + │ ├── rescue_clause: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (21,8)-(21,11) = "end" + ├── rescue_clause: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (21,12)-(21,15) = "end" diff --git a/test/prism/snapshots/begin_rescue.txt b/test/prism/snapshots/begin_rescue.txt new file mode 100644 index 00000000000000..3812134fd1e43f --- /dev/null +++ b/test/prism/snapshots/begin_rescue.txt @@ -0,0 +1,699 @@ +@ ProgramNode (location: (1,0)-(78,3)) +├── locals: [:ex] +└── statements: + @ StatementsNode (location: (1,0)-(78,3)) + └── body: (length: 17) + ├── @ BeginNode (location: (1,0)-(1,33)) + │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + │ ├── statements: + │ │ @ StatementsNode (location: (1,7)-(1,8)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,7)-(1,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,8) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,18)-(1,19) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,27)-(1,28) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,7)-(3,8) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,18)-(3,19) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,27)-(3,28) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,38)-(3,39) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,0)-(6,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,7)-(9,8) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,6)-(11,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,6)-(14,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,0)-(17,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,0)-(19,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,0)-(21,1) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,0)-(23,1) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (27,2)-(27,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,2)-(29,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (31,2)-(31,3) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,2)-(35,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,2)-(37,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,2)-(39,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,0)-(45,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (47,0)-(47,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (50,6)-(50,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (50,15)-(50,16) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (53,0)-(53,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (54,0)-(54,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (57,0)-(57,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (59,0)-(59,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (63,0)-(63,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (65,0)-(65,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (69,2)-(69,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (71,2)-(71,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (75,2)-(75,3) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (77,2)-(77,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (78,0)-(78,3) = "end" diff --git a/test/prism/snapshots/blocks.txt b/test/prism/snapshots/blocks.txt new file mode 100644 index 00000000000000..9a6fbbb9252202 --- /dev/null +++ b/test/prism/snapshots/blocks.txt @@ -0,0 +1,750 @@ +@ ProgramNode (location: (1,0)-(54,17)) +├── locals: [:fork] +└── statements: + @ StatementsNode (location: (1,0)-(54,17)) + └── body: (length: 20) + ├── @ CallNode (location: (1,0)-(1,16)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,3)-(1,8) = "[bar]" + │ ├── opening_loc: (1,3)-(1,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (1,7)-(1,8) = "]" + │ ├── block: + │ │ @ BlockNode (location: (1,9)-(1,16)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,11)-(1,14)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (1,11)-(1,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,11)-(1,14) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── opening_loc: (1,9)-(1,10) = "{" + │ │ └── closing_loc: (1,15)-(1,16) = "}" + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (3,0)-(5,3)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,3)-(3,8) = "[bar]" + │ ├── opening_loc: (3,3)-(3,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,4)-(3,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,4)-(3,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,4)-(3,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (3,7)-(3,8) = "]" + │ ├── block: + │ │ @ BlockNode (location: (3,9)-(5,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (4,0)-(4,3)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (4,0)-(4,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,0)-(4,3) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── opening_loc: (3,9)-(3,11) = "do" + │ │ └── closing_loc: (5,0)-(5,3) = "end" + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (7,0)-(7,35)) + │ ├── receiver: + │ │ @ CallNode (location: (7,0)-(7,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,1) = "x" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "x" + │ ├── call_operator_loc: (7,1)-(7,2) = "." + │ ├── message_loc: (7,2)-(7,8) = "reduce" + │ ├── opening_loc: (7,8)-(7,9) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,9)-(7,10)) + │ │ └── 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] + │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "reduce" + ├── @ CallNode (location: (9,0)-(9,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,0)-(9,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (9,4)-(9,10)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (9,4)-(9,6) = "do" + │ │ └── closing_loc: (9,7)-(9,10) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (11,0)-(11,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,4)-(11,21)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (11,4)-(11,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,4)-(11,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ ParenthesesNode (location: (11,9)-(11,21)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (11,10)-(11,20)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (11,10)-(11,20)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,10)-(11,13) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (11,14)-(11,20)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (11,14)-(11,16) = "do" + │ │ │ │ └── closing_loc: (11,17)-(11,20) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ ├── opening_loc: (11,9)-(11,10) = "(" + │ │ └── closing_loc: (11,20)-(11,21) = ")" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (13,0)-(13,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,4)-(13,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (13,4)-(13,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,4)-(13,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,8)-(13,14)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (13,8)-(13,10) = "do" + │ │ └── closing_loc: (13,11)-(13,14) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (15,0)-(15,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,4)-(15,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (15,4)-(15,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,4)-(15,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (15,8)-(15,11)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (15,8)-(15,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,8)-(15,11) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (15,12)-(15,18)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (15,12)-(15,14) = "do" + │ │ └── closing_loc: (15,15)-(15,18) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (17,0)-(18,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (17,4)-(18,3)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (17,7)-(17,17)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (17,8)-(17,16)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (17,8)-(17,16)) + │ │ │ │ │ ├── name: :a + │ │ │ │ │ ├── name_loc: (17,8)-(17,9) = "a" + │ │ │ │ │ ├── operator_loc: (17,10)-(17,11) = "=" + │ │ │ │ │ └── value: + │ │ │ │ │ @ CallNode (location: (17,12)-(17,16)) + │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ @ CallNode (location: (17,12)-(17,13)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (17,12)-(17,13) = "b" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "b" + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (17,13)-(17,16) = "[1]" + │ │ │ │ │ ├── opening_loc: (17,13)-(17,14) = "[" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (17,14)-(17,15)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ IntegerNode (location: (17,14)-(17,15)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ ├── closing_loc: (17,15)-(17,16) = "]" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "[]" + │ │ │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (20,0)-(22,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (20,0)-(20,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (20,4)-(22,3)) + │ │ ├── locals: [] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (24,0)-(29,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (24,0)-(24,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (24,4)-(29,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (25,2)-(28,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (25,2)-(28,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (25,2)-(25,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (25,6)-(28,5)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (26,4)-(27,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (26,4)-(27,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (26,4)-(26,7) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (26,8)-(27,7)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (26,8)-(26,10) = "do" + │ │ │ │ │ │ └── closing_loc: (27,4)-(27,7) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "baz" + │ │ │ │ ├── opening_loc: (25,6)-(25,8) = "do" + │ │ │ │ └── closing_loc: (28,2)-(28,5) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── opening_loc: (24,4)-(24,6) = "do" + │ │ └── closing_loc: (29,0)-(29,3) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (31,0)-(31,16)) + │ ├── receiver: + │ │ @ CallNode (location: (31,0)-(31,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,0)-(31,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,3)-(31,8) = "[bar]" + │ ├── opening_loc: (31,3)-(31,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,4)-(31,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (31,4)-(31,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,4)-(31,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (31,7)-(31,8) = "]" + │ ├── block: + │ │ @ BlockNode (location: (31,9)-(31,16)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (31,11)-(31,14)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (31,11)-(31,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (31,11)-(31,14) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── opening_loc: (31,9)-(31,10) = "{" + │ │ └── closing_loc: (31,15)-(31,16) = "}" + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (33,0)-(33,24)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,0)-(33,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (33,4)-(33,24)) + │ │ ├── locals: [:x, :y, :z] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (33,6)-(33,20)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (33,7)-(33,19)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (33,7)-(33,8)) + │ │ │ │ │ └── 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) + │ │ │ │ │ └── @ KeywordParameterNode (location: (33,17)-(33,19)) + │ │ │ │ │ ├── name: :z + │ │ │ │ │ ├── name_loc: (33,17)-(33,19) = "z:" + │ │ │ │ │ └── value: ∅ + │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (35,0)-(35,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (35,4)-(35,11)) + │ │ ├── locals: [:x] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (35,6)-(35,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (35,7)-(35,8)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (35,7)-(35,8)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (38,0)-(38,4) = "fork" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (38,5)-(39,3)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (38,8)-(38,11)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (38,9)-(38,10)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (38,9)-(38,10)) + │ │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "fork" + ├── @ CallNode (location: (41,0)-(41,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,0)-(41,4) = "fork" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (41,5)-(41,12)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (41,7)-(41,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (41,8)-(41,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (41,8)-(41,9)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "fork" + ├── @ CallNode (location: (43,0)-(44,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (43,0)-(43,1) = "C" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (43,2)-(44,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (43,2)-(43,4) = "do" + │ │ └── closing_loc: (44,0)-(44,3) = "end" + │ ├── flags: ∅ + │ └── name: "C" + ├── @ CallNode (location: (46,0)-(46,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (46,0)-(46,1) = "C" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (46,2)-(46,4)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (46,2)-(46,3) = "{" + │ │ └── closing_loc: (46,3)-(46,4) = "}" + │ ├── flags: ∅ + │ └── name: "C" + ├── @ CallNode (location: (48,0)-(52,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (48,0)-(48,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (48,4)-(52,1)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (48,4)-(52,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (48,4)-(48,10) = "lambda" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (48,11)-(52,1)) + │ │ │ ├── locals: [:a, :b] + │ │ │ ├── parameters: + │ │ │ │ @ BlockParametersNode (location: (48,13)-(51,3)) + │ │ │ │ ├── parameters: + │ │ │ │ │ @ ParametersNode (location: (49,2)-(50,6)) + │ │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ │ ├── rest: ∅ + │ │ │ │ │ ├── posts: (length: 0) + │ │ │ │ │ ├── keywords: (length: 2) + │ │ │ │ │ │ ├── @ KeywordParameterNode (location: (49,2)-(49,6)) + │ │ │ │ │ │ │ ├── name: :a + │ │ │ │ │ │ │ ├── name_loc: (49,2)-(49,4) = "a:" + │ │ │ │ │ │ │ └── value: + │ │ │ │ │ │ │ @ IntegerNode (location: (49,5)-(49,6)) + │ │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ │ └── @ KeywordParameterNode (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) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "lambda" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + └── @ CallNode (location: (54,0)-(54,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (54,0)-(54,3) = "foo" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (54,4)-(54,17)) + │ ├── locals: [:bar] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (54,7)-(54,13)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (54,8)-(54,12)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (54,8)-(54,11)) + │ │ │ │ └── name: :bar + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (54,11)-(54,12)) + │ │ │ │ ├── name: nil + │ │ │ │ ├── name_loc: ∅ + │ │ │ │ └── operator_loc: (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" + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/boolean_operators.txt b/test/prism/snapshots/boolean_operators.txt new file mode 100644 index 00000000000000..4ed94c368d71ed --- /dev/null +++ b/test/prism/snapshots/boolean_operators.txt @@ -0,0 +1,54 @@ +@ ProgramNode (location: (1,0)-(5,7)) +├── locals: [:a] +└── statements: + @ StatementsNode (location: (1,0)-(5,7)) + └── body: (length: 3) + ├── @ LocalVariableAndWriteNode (location: (1,0)-(1,7)) + │ ├── name_loc: (1,0)-(1,1) = "a" + │ ├── operator_loc: (1,2)-(1,5) = "&&=" + │ ├── value: + │ │ @ CallNode (location: (1,6)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,5)-(3,6) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,6)-(5,7) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── name: :a + └── depth: 0 diff --git a/test/prism/snapshots/booleans.txt b/test/prism/snapshots/booleans.txt new file mode 100644 index 00000000000000..47319662439221 --- /dev/null +++ b/test/prism/snapshots/booleans.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 2) + ├── @ FalseNode (location: (1,0)-(1,5)) + └── @ TrueNode (location: (3,0)-(3,4)) diff --git a/test/prism/snapshots/break.txt b/test/prism/snapshots/break.txt new file mode 100644 index 00000000000000..49e74d0904ab9c --- /dev/null +++ b/test/prism/snapshots/break.txt @@ -0,0 +1,207 @@ +@ 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ ArrayNode (location: (12,6)-(12,15)) + │ │ ├── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (23,0)-(23,16)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,0)-(23,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (23,4)-(23,16)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (23,6)-(23,14)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ BreakNode (location: (23,6)-(23,14)) + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (23,12)-(23,14)) + │ │ │ │ │ └── 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) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,17)-(23,19) = "==" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (23,20)-(23,22)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (23,20)-(23,22)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "==" + └── @ CallNode (location: (25,0)-(25,23)) + ├── receiver: + │ @ CallNode (location: (25,0)-(25,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,0)-(25,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (25,4)-(25,17)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (25,6)-(25,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (25,7)-(25,8)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (25,7)-(25,8)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (25,18)-(25,20) = "==" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (25,21)-(25,23)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (25,21)-(25,23)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "==" diff --git a/test/prism/snapshots/case.txt b/test/prism/snapshots/case.txt new file mode 100644 index 00000000000000..15386a794f5668 --- /dev/null +++ b/test/prism/snapshots/case.txt @@ -0,0 +1,265 @@ +@ ProgramNode (location: (1,0)-(32,25)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(32,25)) + └── body: (length: 9) + ├── @ CaseNode (location: (1,0)-(3,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (1,5)-(1,8)) + │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,22)-(5,26) = "puts" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,27)-(5,30)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (5,27)-(5,30)) + │ │ │ │ ├── opening_loc: (5,27)-(5,28) = ":" + │ │ │ │ ├── value_loc: (5,28)-(5,30) = "hi" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "hi" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "puts" + │ │ └── @ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,44)-(5,48) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,49)-(5,53)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ SymbolNode (location: (5,49)-(5,53)) + │ │ │ ├── opening_loc: (5,49)-(5,50) = ":" + │ │ │ ├── value_loc: (5,50)-(5,53) = "bye" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bye" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,12)-(7,15) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── 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)) + │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,5)-(15,9) = "this" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "this" + │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (18,5)-(18,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,5)-(18,8) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (18,9)-(18,11) = "==" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (18,12)-(18,15)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (18,12)-(18,15)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,12)-(18,15) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "==" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (22,5)-(22,6) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (27,5)-(27,9) = "type" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "type" + │ ├── 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)) + │ │ │ ├── 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" diff --git a/test/prism/snapshots/classes.txt b/test/prism/snapshots/classes.txt new file mode 100644 index 00000000000000..e349da627d3419 --- /dev/null +++ b/test/prism/snapshots/classes.txt @@ -0,0 +1,355 @@ +@ 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (11,13)-(11,16)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,13)-(11,16) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,9)-(11,12) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (18,9)-(18,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (18,9)-(18,12) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: (18,12)-(18,13) = "." + │ │ ├── message_loc: (18,13)-(18,16) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (21,9)-(21,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,9)-(21,12) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: (21,12)-(21,13) = "." + │ │ ├── message_loc: (21,13)-(21,16) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (29,0)-(29,1)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (29,2)-(29,3) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (29,4)-(29,5)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (29,4)-(29,5)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (32,14)-(32,15)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,16)-(32,17) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (32,18)-(32,19)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (32,18)-(32,19)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ └── 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)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (34,10)-(34,11)) + │ │ └── name: :B + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (34,11)-(34,14) = "[1]" + │ ├── opening_loc: (34,11)-(34,12) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (34,12)-(34,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (34,12)-(34,13)) + │ │ └── flags: decimal + │ ├── closing_loc: (34,13)-(34,14) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── body: ∅ + ├── end_keyword_loc: (35,0)-(35,3) = "end" + └── name: :A diff --git a/test/prism/snapshots/comments.txt b/test/prism/snapshots/comments.txt new file mode 100644 index 00000000000000..84cd210bb9cc28 --- /dev/null +++ b/test/prism/snapshots/comments.txt @@ -0,0 +1,145 @@ +@ ProgramNode (location: (1,0)-(24,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(24,5)) + └── body: (length: 9) + ├── @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── @ CallNode (location: (3,0)-(3,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── @ CallNode (location: (5,0)-(5,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "c" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "c" + ├── @ CallNode (location: (6,0)-(6,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,0)-(6,1) = "d" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "d" + ├── @ CallNode (location: (8,0)-(10,4)) + │ ├── receiver: + │ │ @ CallNode (location: (8,0)-(8,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (8,0)-(8,1) = "e" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "e" + │ ├── call_operator_loc: (10,2)-(10,3) = "." + │ ├── message_loc: (10,3)-(10,4) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (12,0)-(14,2)) + │ ├── receiver: + │ │ @ CallNode (location: (12,0)-(12,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (12,0)-(12,1) = "g" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "g" + │ ├── call_operator_loc: (14,0)-(14,1) = "." + │ ├── message_loc: (14,1)-(14,2) = "h" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "h" + ├── @ CallNode (location: (16,0)-(17,2)) + │ ├── receiver: + │ │ @ CallNode (location: (16,0)-(16,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,0)-(16,1) = "i" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "i" + │ ├── call_operator_loc: (17,0)-(17,1) = "." + │ ├── message_loc: (17,1)-(17,2) = "j" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "j" + ├── @ CallNode (location: (19,0)-(20,4)) + │ ├── receiver: + │ │ @ CallNode (location: (19,0)-(19,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,0)-(19,1) = "k" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "k" + │ ├── call_operator_loc: (20,2)-(20,3) = "." + │ ├── message_loc: (20,3)-(20,4) = "l" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "l" + └── @ CallNode (location: (22,0)-(24,5)) + ├── receiver: + │ @ CallNode (location: (22,0)-(22,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (22,0)-(22,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "m" + ├── call_operator_loc: (24,2)-(24,4) = "&." + ├── message_loc: (24,4)-(24,5) = "n" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: safe_navigation + └── name: "n" diff --git a/test/prism/snapshots/constants.txt b/test/prism/snapshots/constants.txt new file mode 100644 index 00000000000000..9b3105880be2f4 --- /dev/null +++ b/test/prism/snapshots/constants.txt @@ -0,0 +1,1225 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,3) = "Foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,4)-(13,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (13,4)-(13,5)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Foo" + ├── @ CallNode (location: (15,0)-(15,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,3) = "Foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,4)-(15,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (15,4)-(15,8)) + │ │ ├── operator_loc: (15,4)-(15,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (15,5)-(15,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,5)-(15,8) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Foo" + ├── @ CallNode (location: (17,0)-(17,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,3) = "Foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,4)-(17,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (17,4)-(17,9)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (17,4)-(17,9)) + │ │ ├── value: + │ │ │ @ CallNode (location: (17,6)-(17,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (17,6)-(17,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── operator_loc: (17,4)-(17,6) = "**" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Foo" + ├── @ CallNode (location: (19,0)-(19,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,5)-(19,8) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── operator_loc: (19,4)-(19,5) = "&" + │ ├── flags: ∅ + │ └── name: "Foo" + ├── @ CallNode (location: (21,0)-(21,13)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (21,0)-(21,3)) + │ │ └── name: :Foo + │ ├── call_operator_loc: (21,3)-(21,5) = "::" + │ ├── message_loc: (21,5)-(21,8) = "Bar" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,9)-(21,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (21,9)-(21,13)) + │ │ ├── operator_loc: (21,9)-(21,10) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (21,10)-(21,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,10)-(21,13) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Bar" + ├── @ CallNode (location: (23,0)-(23,14)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (23,0)-(23,3)) + │ │ └── name: :Foo + │ ├── call_operator_loc: (23,3)-(23,5) = "::" + │ ├── message_loc: (23,5)-(23,8) = "Bar" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (23,9)-(23,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (23,9)-(23,14)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (23,9)-(23,14)) + │ │ ├── value: + │ │ │ @ CallNode (location: (23,11)-(23,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,11)-(23,14) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── operator_loc: (23,9)-(23,11) = "**" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Bar" + ├── @ CallNode (location: (25,0)-(25,13)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (25,0)-(25,3)) + │ │ └── name: :Foo + │ ├── call_operator_loc: (25,3)-(25,5) = "::" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (25,10)-(25,13) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── operator_loc: (25,9)-(25,10) = "&" + │ ├── flags: ∅ + │ └── name: "Bar" + ├── @ CallNode (location: (27,0)-(27,8)) + │ ├── 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) = "::" + │ ├── message_loc: (27,5)-(27,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ 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)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (37,0)-(37,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (37,1)-(37,3) = "::" + │ ├── message_loc: (37,3)-(37,8) = "false" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "false" + ├── @ CallNode (location: (39,0)-(39,10)) + │ ├── 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) = "::" + │ ├── message_loc: (39,6)-(39,10) = "true" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "true" + ├── @ CallNode (location: (41,0)-(41,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (41,0)-(41,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (41,1)-(41,3) = "::" + │ ├── message_loc: (41,3)-(41,4) = "&" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "&" + ├── @ CallNode (location: (43,0)-(43,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (43,0)-(43,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (43,1)-(43,3) = "::" + │ ├── message_loc: (43,3)-(43,4) = "`" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "`" + ├── @ CallNode (location: (45,0)-(45,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (45,0)-(45,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (45,1)-(45,3) = "::" + │ ├── message_loc: (45,3)-(45,4) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (47,0)-(47,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (47,0)-(47,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (47,1)-(47,3) = "::" + │ ├── message_loc: (47,3)-(47,5) = "!=" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!=" + ├── @ CallNode (location: (49,0)-(49,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (49,0)-(49,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (49,1)-(49,3) = "::" + │ ├── message_loc: (49,3)-(49,4) = "^" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "^" + ├── @ CallNode (location: (51,0)-(51,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (51,0)-(51,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (51,1)-(51,3) = "::" + │ ├── message_loc: (51,3)-(51,5) = "==" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "==" + ├── @ CallNode (location: (53,0)-(53,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (53,0)-(53,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (53,1)-(53,3) = "::" + │ ├── message_loc: (53,3)-(53,6) = "===" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "===" + ├── @ CallNode (location: (55,0)-(55,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (55,0)-(55,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (55,1)-(55,3) = "::" + │ ├── message_loc: (55,3)-(55,5) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ CallNode (location: (57,0)-(57,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (57,0)-(57,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (57,1)-(57,3) = "::" + │ ├── message_loc: (57,3)-(57,4) = ">" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">" + ├── @ CallNode (location: (59,0)-(59,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (59,0)-(59,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (59,1)-(59,3) = "::" + │ ├── message_loc: (59,3)-(59,5) = ">=" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">=" + ├── @ CallNode (location: (61,0)-(61,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (61,0)-(61,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (61,1)-(61,3) = "::" + │ ├── message_loc: (61,3)-(61,5) = ">>" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">>" + ├── @ CallNode (location: (63,0)-(63,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (63,0)-(63,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (63,1)-(63,3) = "::" + │ ├── message_loc: (63,3)-(63,5) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ 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)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (69,0)-(69,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (69,1)-(69,3) = "::" + │ ├── message_loc: (69,3)-(69,8) = "alias" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "alias" + ├── @ CallNode (location: (71,0)-(71,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (71,0)-(71,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (71,1)-(71,3) = "::" + │ ├── message_loc: (71,3)-(71,6) = "and" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "and" + ├── @ CallNode (location: (73,0)-(73,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (73,0)-(73,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (73,1)-(73,3) = "::" + │ ├── message_loc: (73,3)-(73,8) = "begin" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "begin" + ├── @ 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)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (77,0)-(77,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (77,1)-(77,3) = "::" + │ ├── message_loc: (77,3)-(77,8) = "break" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "break" + ├── @ CallNode (location: (79,0)-(79,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (79,0)-(79,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (79,1)-(79,3) = "::" + │ ├── message_loc: (79,3)-(79,8) = "class" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "class" + ├── @ CallNode (location: (81,0)-(81,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (81,0)-(81,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (81,1)-(81,3) = "::" + │ ├── message_loc: (81,3)-(81,6) = "def" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "def" + ├── @ CallNode (location: (83,0)-(83,10)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (83,0)-(83,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (83,1)-(83,3) = "::" + │ ├── message_loc: (83,3)-(83,10) = "defined" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "defined" + ├── @ CallNode (location: (85,0)-(85,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (85,0)-(85,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (85,1)-(85,3) = "::" + │ ├── message_loc: (85,3)-(85,5) = "do" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "do" + ├── @ CallNode (location: (87,0)-(87,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (87,0)-(87,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (87,1)-(87,3) = "::" + │ ├── message_loc: (87,3)-(87,7) = "else" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "else" + ├── @ CallNode (location: (89,0)-(89,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (89,0)-(89,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (89,1)-(89,3) = "::" + │ ├── message_loc: (89,3)-(89,8) = "elsif" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "elsif" + ├── @ CallNode (location: (91,0)-(91,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (91,0)-(91,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (91,1)-(91,3) = "::" + │ ├── message_loc: (91,3)-(91,6) = "end" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "end" + ├── @ 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)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (95,0)-(95,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (95,1)-(95,3) = "::" + │ ├── message_loc: (95,3)-(95,9) = "ensure" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "ensure" + ├── @ CallNode (location: (97,0)-(97,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (97,0)-(97,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (97,1)-(97,3) = "::" + │ ├── message_loc: (97,3)-(97,8) = "false" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "false" + ├── @ CallNode (location: (99,0)-(99,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (99,0)-(99,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (99,1)-(99,3) = "::" + │ ├── message_loc: (99,3)-(99,6) = "for" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "for" + ├── @ CallNode (location: (101,0)-(101,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (101,0)-(101,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (101,1)-(101,3) = "::" + │ ├── message_loc: (101,3)-(101,5) = "if" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "if" + ├── @ CallNode (location: (103,0)-(103,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (103,0)-(103,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (103,1)-(103,3) = "::" + │ ├── message_loc: (103,3)-(103,5) = "in" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "in" + ├── @ CallNode (location: (105,0)-(105,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (105,0)-(105,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (105,1)-(105,3) = "::" + │ ├── message_loc: (105,3)-(105,7) = "next" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "next" + ├── @ CallNode (location: (107,0)-(107,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (107,0)-(107,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (107,1)-(107,3) = "::" + │ ├── message_loc: (107,3)-(107,6) = "nil" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "nil" + ├── @ CallNode (location: (109,0)-(109,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (109,0)-(109,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (109,1)-(109,3) = "::" + │ ├── message_loc: (109,3)-(109,6) = "not" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "not" + ├── @ CallNode (location: (111,0)-(111,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (111,0)-(111,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (111,1)-(111,3) = "::" + │ ├── message_loc: (111,3)-(111,5) = "or" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "or" + ├── @ CallNode (location: (113,0)-(113,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (113,0)-(113,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (113,1)-(113,3) = "::" + │ ├── message_loc: (113,3)-(113,7) = "redo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "redo" + ├── @ CallNode (location: (115,0)-(115,9)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (115,0)-(115,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (115,1)-(115,3) = "::" + │ ├── message_loc: (115,3)-(115,9) = "rescue" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "rescue" + ├── @ CallNode (location: (117,0)-(117,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (117,0)-(117,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (117,1)-(117,3) = "::" + │ ├── message_loc: (117,3)-(117,8) = "retry" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "retry" + ├── @ CallNode (location: (119,0)-(119,9)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (119,0)-(119,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (119,1)-(119,3) = "::" + │ ├── message_loc: (119,3)-(119,9) = "return" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "return" + ├── @ CallNode (location: (121,0)-(121,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (121,0)-(121,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (121,1)-(121,3) = "::" + │ ├── message_loc: (121,3)-(121,7) = "self" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "self" + ├── @ CallNode (location: (123,0)-(123,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (123,0)-(123,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (123,1)-(123,3) = "::" + │ ├── message_loc: (123,3)-(123,8) = "super" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "super" + ├── @ CallNode (location: (125,0)-(125,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (125,0)-(125,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (125,1)-(125,3) = "::" + │ ├── message_loc: (125,3)-(125,7) = "then" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "then" + ├── @ CallNode (location: (127,0)-(127,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (127,0)-(127,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (127,1)-(127,3) = "::" + │ ├── message_loc: (127,3)-(127,7) = "true" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "true" + ├── @ CallNode (location: (129,0)-(129,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (129,0)-(129,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (129,1)-(129,3) = "::" + │ ├── message_loc: (129,3)-(129,8) = "undef" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "undef" + ├── @ CallNode (location: (131,0)-(131,9)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (131,0)-(131,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (131,1)-(131,3) = "::" + │ ├── message_loc: (131,3)-(131,9) = "unless" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "unless" + ├── @ CallNode (location: (133,0)-(133,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (133,0)-(133,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (133,1)-(133,3) = "::" + │ ├── message_loc: (133,3)-(133,8) = "until" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "until" + ├── @ CallNode (location: (135,0)-(135,7)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (135,0)-(135,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (135,1)-(135,3) = "::" + │ ├── message_loc: (135,3)-(135,7) = "when" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "when" + ├── @ CallNode (location: (137,0)-(137,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (137,0)-(137,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (137,1)-(137,3) = "::" + │ ├── message_loc: (137,3)-(137,8) = "while" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "while" + ├── @ CallNode (location: (139,0)-(139,8)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (139,0)-(139,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (139,1)-(139,3) = "::" + │ ├── message_loc: (139,3)-(139,8) = "yield" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "yield" + ├── @ CallNode (location: (141,0)-(141,15)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (141,0)-(141,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (141,1)-(141,3) = "::" + │ ├── message_loc: (141,3)-(141,15) = "__ENCODING__" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "__ENCODING__" + ├── @ CallNode (location: (143,0)-(143,11)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (143,0)-(143,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (143,1)-(143,3) = "::" + │ ├── message_loc: (143,3)-(143,11) = "__FILE__" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "__FILE__" + ├── @ CallNode (location: (145,0)-(145,11)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (145,0)-(145,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (145,1)-(145,3) = "::" + │ ├── message_loc: (145,3)-(145,11) = "__LINE__" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "__LINE__" + ├── @ CallNode (location: (147,0)-(147,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (147,0)-(147,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (147,1)-(147,3) = "::" + │ ├── message_loc: (147,3)-(147,4) = "<" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<" + ├── @ CallNode (location: (149,0)-(149,6)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (149,0)-(149,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (149,1)-(149,3) = "::" + │ ├── message_loc: (149,3)-(149,6) = "<=>" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<=>" + ├── @ CallNode (location: (151,0)-(151,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (151,0)-(151,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (151,1)-(151,3) = "::" + │ ├── message_loc: (151,3)-(151,5) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ CallNode (location: (153,0)-(153,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (153,0)-(153,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (153,1)-(153,3) = "::" + │ ├── message_loc: (153,3)-(153,4) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-" + ├── @ CallNode (location: (155,0)-(155,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (155,0)-(155,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (155,1)-(155,3) = "::" + │ ├── message_loc: (155,3)-(155,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (157,0)-(157,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (157,0)-(157,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (157,1)-(157,3) = "::" + │ ├── message_loc: (157,3)-(157,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (157,4)-(157,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (157,4)-(157,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (157,4)-(157,5) = "i" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "i" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (159,0)-(159,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (159,0)-(159,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (159,1)-(159,3) = "::" + │ ├── message_loc: (159,3)-(159,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (159,4)-(159,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (159,4)-(159,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (159,4)-(159,5) = "w" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "w" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (161,0)-(161,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (161,0)-(161,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (161,1)-(161,3) = "::" + │ ├── message_loc: (161,3)-(161,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (161,4)-(161,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (161,4)-(161,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (161,4)-(161,5) = "x" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "x" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (163,0)-(163,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (163,0)-(163,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (163,1)-(163,3) = "::" + │ ├── message_loc: (163,3)-(163,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (163,4)-(163,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ ConstantReadNode (location: (163,4)-(163,5)) + │ │ └── name: :I + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (165,0)-(165,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (165,0)-(165,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (165,1)-(165,3) = "::" + │ ├── message_loc: (165,3)-(165,4) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (165,4)-(165,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ ConstantReadNode (location: (165,4)-(165,5)) + │ │ └── name: :W + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (167,0)-(167,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (167,0)-(167,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (167,1)-(167,3) = "::" + │ ├── message_loc: (167,3)-(167,4) = "|" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "|" + ├── @ CallNode (location: (169,0)-(169,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (169,0)-(169,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (169,1)-(169,3) = "::" + │ ├── message_loc: (169,3)-(169,4) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (171,0)-(171,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (171,0)-(171,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (171,1)-(171,3) = "::" + │ ├── message_loc: (171,3)-(171,4) = "/" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "/" + ├── @ CallNode (location: (173,0)-(173,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (173,0)-(173,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (173,1)-(173,3) = "::" + │ ├── message_loc: (173,3)-(173,4) = "*" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "*" + ├── @ CallNode (location: (175,0)-(175,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (175,0)-(175,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (175,1)-(175,3) = "::" + │ ├── message_loc: (175,3)-(175,5) = "**" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "**" + ├── @ CallNode (location: (177,0)-(177,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (177,0)-(177,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (177,1)-(177,3) = "::" + │ ├── message_loc: (177,3)-(177,4) = "~" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "~" + ├── @ ConstantPathNode (location: (179,0)-(180,1)) + │ ├── parent: + │ │ @ CallNode (location: (179,0)-(179,4)) + │ │ ├── receiver: + │ │ │ @ ConstantReadNode (location: (179,0)-(179,1)) + │ │ │ └── name: :A + │ │ ├── call_operator_loc: (179,1)-(179,3) = "::" + │ │ ├── message_loc: (179,3)-(179,4) = "_" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "_" + │ ├── child: + │ │ @ ConstantReadNode (location: (180,0)-(180,1)) + │ │ └── name: :C + │ └── delimiter_loc: (179,4)-(179,6) = "::" + └── @ RangeNode (location: (182,0)-(184,10)) + ├── left: + │ @ CallNode (location: (182,0)-(182,4)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (182,0)-(182,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (182,1)-(182,3) = "::" + │ ├── message_loc: (182,3)-(182,4) = "_" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "_" + ├── right: + │ @ CallNode (location: (184,0)-(184,10)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (184,0)-(184,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (184,1)-(184,3) = "::" + │ ├── message_loc: (184,3)-(184,10) = "__END__" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "__END__" + ├── operator_loc: (182,4)-(182,6) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/dash_heredocs.txt b/test/prism/snapshots/dash_heredocs.txt new file mode 100644 index 00000000000000..929aa6c0675af3 --- /dev/null +++ b/test/prism/snapshots/dash_heredocs.txt @@ -0,0 +1,251 @@ +@ 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)-(2,0) = " a\n" + │ ├── closing_loc: (3,0)-(3,0) = "EOF\n" + │ └── unescaped: " a\n" + ├── @ CallNode (location: (5,0)-(5,20)) + │ ├── receiver: + │ │ @ StringNode (location: (5,0)-(5,8)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (5,0)-(5,8) = "<<-FIRST" + │ │ ├── content_loc: (6,0)-(6,0) = " a\n" + │ │ ├── closing_loc: (7,0)-(7,0) = "FIRST\n" + │ │ └── unescaped: " a\n" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,9)-(5,10) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,11)-(5,20)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (5,11)-(5,20)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (5,11)-(5,20) = "<<-SECOND" + │ │ ├── content_loc: (8,0)-(8,0) = " b\n" + │ │ ├── closing_loc: (9,0)-(9,0) = "SECOND\n" + │ │ └── unescaped: " b\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ InterpolatedXStringNode (location: (11,0)-(11,8)) + │ ├── opening_loc: (11,0)-(11,8) = "<<-`EOF`" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (12,0)-(12,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (12,0)-(12,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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (13,2)-(13,3) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── closing_loc: (13,3)-(13,4) = "}" + │ │ └── @ StringNode (location: (13,4)-(13,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (13,4)-(13,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (14,0)-(14,0) = "EOF\n" + ├── @ StringNode (location: (16,0)-(16,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (16,0)-(16,6) = "<<-EOF" + │ ├── content_loc: (17,0)-(17,0) = " a\n" + │ ├── closing_loc: (18,0)-(18,0) = "EOF\n" + │ └── unescaped: " a\n" + ├── @ StringNode (location: (20,0)-(20,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (20,0)-(20,6) = "<<-EOF" + │ ├── content_loc: (21,0)-(22,0) = " a\n b\n" + │ ├── closing_loc: (23,0)-(23,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)-(26,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (26,0)-(26,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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (27,2)-(27,3) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── closing_loc: (27,3)-(27,4) = "}" + │ │ └── @ StringNode (location: (27,4)-(27,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (27,4)-(27,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (28,0)-(28,0) = "EOF\n" + ├── @ InterpolatedStringNode (location: (30,0)-(30,6)) + │ ├── opening_loc: (30,0)-(30,6) = "<<-EOF" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (31,0)-(31,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (31,0)-(31,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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (32,2)-(32,3) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── closing_loc: (32,3)-(32,4) = "}" + │ │ └── @ StringNode (location: (32,4)-(32,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (32,4)-(32,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (33,0)-(33,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)-(39,0) = " a\n b\n" + │ ├── closing_loc: (40,0)-(40,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)-(42,0) = "" + │ ├── closing_loc: (43,0)-(43,0) = "\n" + │ └── unescaped: "" + ├── @ StringNode (location: (45,0)-(45,8)) + │ ├── flags: ∅ + │ ├── opening_loc: (45,0)-(45,8) = "<<-'EOF'" + │ ├── content_loc: (46,0)-(46,0) = " a \#{1}\n" + │ ├── closing_loc: (47,0)-(47,0) = "EOF\n" + │ └── unescaped: " a \#{1}\n" + ├── @ CallNode (location: (49,0)-(49,11)) + │ ├── receiver: + │ │ @ StringNode (location: (49,0)-(49,4)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (49,0)-(49,4) = "<<-A" + │ │ ├── content_loc: (50,0)-(50,0) = " a\n" + │ │ ├── closing_loc: (51,0)-(51,0) = "A\n" + │ │ └── unescaped: " a\n" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (49,5)-(49,6) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (49,7)-(49,11)) + │ │ └── 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)-(54,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (54,3)-(54,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (55,0)-(55,0) = "B\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + └── @ CallNode (location: (57,0)-(57,11)) + ├── receiver: + │ @ StringNode (location: (57,0)-(57,4)) + │ ├── flags: ∅ + │ ├── opening_loc: (57,0)-(57,4) = "<<-A" + │ ├── content_loc: (58,0)-(58,0) = " a\n" + │ ├── closing_loc: (59,0)-(59,0) = "A\n" + │ └── unescaped: " a\n" + ├── call_operator_loc: ∅ + ├── message_loc: (57,5)-(57,6) = "+" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (57,7)-(57,11)) + │ └── 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)-(62,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (62,4)-(62,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (63,0)-(63,0) = "B\n" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "+" diff --git a/test/prism/snapshots/defined.txt b/test/prism/snapshots/defined.txt new file mode 100644 index 00000000000000..c6537b860cf03a --- /dev/null +++ b/test/prism/snapshots/defined.txt @@ -0,0 +1,73 @@ +@ ProgramNode (location: (1,0)-(7,10)) +├── locals: [:x] +└── statements: + @ StatementsNode (location: (1,0)-(7,10)) + └── body: (length: 4) + ├── @ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,9)-(5,12) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── right: + │ │ │ @ CallNode (location: (5,17)-(5,20)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,17)-(5,20) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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?" diff --git a/test/prism/snapshots/dos_endings.txt b/test/prism/snapshots/dos_endings.txt new file mode 100644 index 00000000000000..fd9bc956095ad0 --- /dev/null +++ b/test/prism/snapshots/dos_endings.txt @@ -0,0 +1,93 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "puts" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,5)-(2,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringConcatNode (location: (1,5)-(2,12)) + │ │ ├── left: + │ │ │ @ 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" + │ │ └── right: + │ │ @ 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: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "puts" + ├── @ ArrayNode (location: (4,0)-(5,2)) + │ ├── elements: (length: 1) + │ │ └── @ SymbolNode (location: (4,3)-(5,1)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (4,3)-(5,1) = "a\\\r\nb" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "ab" + │ ├── 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)-(10,0) = " 1 \\\r\n 2\r\n 3\r\n" + │ ├── closing_loc: (11,0)-(11,0) = "E\r\n" + │ └── unescaped: " 1 2\r\n 3\r\n" + ├── @ LocalVariableWriteNode (location: (13,0)-(14,0)) + │ ├── name: :x + │ ├── depth: 0 + │ ├── name_loc: (13,0)-(13,1) = "x" + │ ├── value: + │ │ @ StringNode (location: (13,4)-(14,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (13,4)-(13,0) = "%\r\n" + │ │ ├── content_loc: (14,0)-(13,0) = "" + │ │ ├── closing_loc: (14,0)-(14,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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,4)-(17,7) = "foo" + │ ├── opening_loc: (17,7)-(17,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,8)-(17,19)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (17,8)-(17,19)) + │ │ ├── receiver: + │ │ │ @ StringNode (location: (17,8)-(17,14)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (17,8)-(17,14) = "<<~EOF" + │ │ │ ├── content_loc: (18,0)-(19,0) = "\r\n baz\r\n" + │ │ │ ├── closing_loc: (20,0)-(20,0) = " EOF\r\n" + │ │ │ └── unescaped: "\nbaz\r\n" + │ │ ├── call_operator_loc: (17,14)-(17,15) = "." + │ │ ├── message_loc: (17,15)-(17,19) = "chop" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "chop" + │ ├── closing_loc: (17,19)-(17,20) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + └── 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 new file mode 100644 index 00000000000000..870bdb6ad54607 --- /dev/null +++ b/test/prism/snapshots/embdoc_no_newline_at_end.txt @@ -0,0 +1,5 @@ +@ ProgramNode (location: (1,0)-(0,0)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(0,0)) + └── body: (length: 0) diff --git a/test/prism/snapshots/endless_methods.txt b/test/prism/snapshots/endless_methods.txt new file mode 100644 index 00000000000000..36d52673a83fa5 --- /dev/null +++ b/test/prism/snapshots/endless_methods.txt @@ -0,0 +1,100 @@ +@ 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: [] + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,10)-(3,11) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,12)-(3,14)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── locals: [] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (3,8)-(3,9) = "=" + │ └── end_keyword_loc: ∅ + └── @ DefNode (location: (5,0)-(5,22)) + ├── name: :method + ├── name_loc: (5,4)-(5,10) = "method" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (5,13)-(5,22)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (5,13)-(5,22)) + │ ├── receiver: + │ │ @ CallNode (location: (5,13)-(5,18)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (5,13)-(5,14)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,15)-(5,16) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,17)-(5,18)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (5,17)-(5,18)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,19)-(5,20) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,21)-(5,22)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (5,21)-(5,22)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── locals: [] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (5,11)-(5,12) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/endless_range_in_conditional.txt b/test/prism/snapshots/endless_range_in_conditional.txt new file mode 100644 index 00000000000000..27447e9522f869 --- /dev/null +++ b/test/prism/snapshots/endless_range_in_conditional.txt @@ -0,0 +1,46 @@ +@ 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (1,3)-(1,4)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (1,6)-(1,7)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (1,4)-(1,6) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── left: ∅ + │ │ ├── right: + │ │ │ @ IntegerNode (location: (2,5)-(2,6)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (2,3)-(2,5) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ ├── left: + │ │ @ IntegerNode (location: (3,3)-(3,4)) + │ │ └── flags: decimal + │ ├── right: ∅ + │ ├── operator_loc: (3,4)-(3,6) = ".." + │ └── flags: ∅ + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (3,9)-(3,12) = "end" diff --git a/test/prism/snapshots/for.txt b/test/prism/snapshots/for.txt new file mode 100644 index 00000000000000..a0485a57ff0f9a --- /dev/null +++ b/test/prism/snapshots/for.txt @@ -0,0 +1,172 @@ +@ 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (1,9)-(1,10)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (1,12)-(1,14)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (1,10)-(1,12) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (5,9)-(5,10)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (5,12)-(5,14)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (5,10)-(5,12) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (7,4)-(7,5)) + │ │ │ │ ├── name: :i + │ │ │ │ └── depth: 0 + │ │ │ └── @ LocalVariableTargetNode (location: (7,6)-(7,7)) + │ │ │ ├── name: :j + │ │ │ └── depth: 0 + │ │ ├── lparen_loc: ∅ + │ │ └── rparen_loc: ∅ + │ ├── collection: + │ │ @ RangeNode (location: (7,11)-(7,16)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (7,11)-(7,12)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (7,14)-(7,16)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (7,12)-(7,14) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── targets: (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 + │ │ ├── lparen_loc: ∅ + │ │ └── rparen_loc: ∅ + │ ├── collection: + │ │ @ RangeNode (location: (11,13)-(11,18)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (11,13)-(11,14)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (11,16)-(11,18)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (11,14)-(11,16) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (15,9)-(15,10)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (15,12)-(15,14)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (15,10)-(15,12) = ".." + │ │ └── flags: ∅ + │ ├── 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)) + │ ├── left: + │ │ @ IntegerNode (location: (19,9)-(19,10)) + │ │ └── flags: decimal + │ ├── right: + │ │ @ IntegerNode (location: (19,12)-(19,14)) + │ │ └── flags: decimal + │ ├── operator_loc: (19,10)-(19,12) = ".." + │ └── flags: ∅ + ├── statements: + │ @ StatementsNode (location: (19,16)-(19,17)) + │ └── body: (length: 1) + │ └── @ LocalVariableReadNode (location: (19,16)-(19,17)) + │ ├── name: :i + │ └── depth: 0 + ├── for_keyword_loc: (19,0)-(19,3) = "for" + ├── in_keyword_loc: (19,6)-(19,8) = "in" + ├── do_keyword_loc: ∅ + └── end_keyword_loc: (19,19)-(19,22) = "end" diff --git a/test/prism/snapshots/global_variables.txt b/test/prism/snapshots/global_variables.txt new file mode 100644 index 00000000000000..bb2e7d53b9d841 --- /dev/null +++ b/test/prism/snapshots/global_variables.txt @@ -0,0 +1,164 @@ +@ 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)) + ├── @ BackReferenceReadNode (location: (23,0)-(23,2)) + ├── @ BackReferenceReadNode (location: (25,0)-(25,2)) + ├── @ BackReferenceReadNode (location: (27,0)-(27,2)) + ├── @ 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)) + │ ├── 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)) + │ ├── opening_loc: (51,0)-(51,1) = ":" + │ ├── value_loc: (51,1)-(51,3) = "$_" + │ ├── closing_loc: ∅ + │ └── unescaped: "$_" + ├── @ SymbolNode (location: (53,0)-(53,4)) + │ ├── opening_loc: (53,0)-(53,1) = ":" + │ ├── value_loc: (53,1)-(53,4) = "$-w" + │ ├── closing_loc: ∅ + │ └── unescaped: "$-w" + ├── @ SymbolNode (location: (55,0)-(55,11)) + │ ├── 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)) + │ ├── opening_loc: (57,0)-(57,1) = ":" + │ ├── value_loc: (57,1)-(57,7) = "$stdin" + │ ├── closing_loc: ∅ + │ └── unescaped: "$stdin" + ├── @ SymbolNode (location: (59,0)-(59,8)) + │ ├── opening_loc: (59,0)-(59,1) = ":" + │ ├── value_loc: (59,1)-(59,8) = "$stdout" + │ ├── closing_loc: ∅ + │ └── unescaped: "$stdout" + ├── @ SymbolNode (location: (61,0)-(61,8)) + │ ├── opening_loc: (61,0)-(61,1) = ":" + │ ├── value_loc: (61,1)-(61,8) = "$stderr" + │ ├── closing_loc: ∅ + │ └── unescaped: "$stderr" + ├── @ SymbolNode (location: (63,0)-(63,3)) + │ ├── opening_loc: (63,0)-(63,1) = ":" + │ ├── value_loc: (63,1)-(63,3) = "$!" + │ ├── closing_loc: ∅ + │ └── unescaped: "$!" + ├── @ SymbolNode (location: (65,0)-(65,3)) + │ ├── opening_loc: (65,0)-(65,1) = ":" + │ ├── value_loc: (65,1)-(65,3) = "$?" + │ ├── closing_loc: ∅ + │ └── unescaped: "$?" + ├── @ SymbolNode (location: (67,0)-(67,3)) + │ ├── opening_loc: (67,0)-(67,1) = ":" + │ ├── value_loc: (67,1)-(67,3) = "$~" + │ ├── closing_loc: ∅ + │ └── unescaped: "$~" + ├── @ SymbolNode (location: (69,0)-(69,3)) + │ ├── opening_loc: (69,0)-(69,1) = ":" + │ ├── value_loc: (69,1)-(69,3) = "$&" + │ ├── closing_loc: ∅ + │ └── unescaped: "$&" + ├── @ SymbolNode (location: (71,0)-(71,3)) + │ ├── opening_loc: (71,0)-(71,1) = ":" + │ ├── value_loc: (71,1)-(71,3) = "$`" + │ ├── closing_loc: ∅ + │ └── unescaped: "$`" + ├── @ SymbolNode (location: (73,0)-(73,3)) + │ ├── opening_loc: (73,0)-(73,1) = ":" + │ ├── value_loc: (73,1)-(73,3) = "$'" + │ ├── closing_loc: ∅ + │ └── unescaped: "$'" + ├── @ SymbolNode (location: (75,0)-(75,3)) + │ ├── opening_loc: (75,0)-(75,1) = ":" + │ ├── value_loc: (75,1)-(75,3) = "$+" + │ ├── closing_loc: ∅ + │ └── unescaped: "$+" + ├── @ SymbolNode (location: (77,0)-(77,3)) + │ ├── opening_loc: (77,0)-(77,1) = ":" + │ ├── value_loc: (77,1)-(77,3) = "$:" + │ ├── closing_loc: ∅ + │ └── unescaped: "$:" + ├── @ SymbolNode (location: (79,0)-(79,3)) + │ ├── opening_loc: (79,0)-(79,1) = ":" + │ ├── value_loc: (79,1)-(79,3) = "$;" + │ ├── closing_loc: ∅ + │ └── unescaped: "$;" + ├── @ SymbolNode (location: (81,0)-(81,7)) + │ ├── opening_loc: (81,0)-(81,1) = ":" + │ ├── value_loc: (81,1)-(81,7) = "$DEBUG" + │ ├── closing_loc: ∅ + │ └── unescaped: "$DEBUG" + ├── @ SymbolNode (location: (83,0)-(83,10)) + │ ├── opening_loc: (83,0)-(83,1) = ":" + │ ├── value_loc: (83,1)-(83,10) = "$FILENAME" + │ ├── closing_loc: ∅ + │ └── unescaped: "$FILENAME" + ├── @ SymbolNode (location: (85,0)-(85,3)) + │ ├── opening_loc: (85,0)-(85,1) = ":" + │ ├── value_loc: (85,1)-(85,3) = "$0" + │ ├── closing_loc: ∅ + │ └── unescaped: "$0" + ├── @ SymbolNode (location: (87,0)-(87,4)) + │ ├── opening_loc: (87,0)-(87,1) = ":" + │ ├── value_loc: (87,1)-(87,4) = "$-0" + │ ├── closing_loc: ∅ + │ └── unescaped: "$-0" + ├── @ SymbolNode (location: (89,0)-(89,17)) + │ ├── 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)) + │ ├── opening_loc: (91,0)-(91,1) = ":" + │ ├── value_loc: (91,1)-(91,9) = "$VERBOSE" + │ ├── closing_loc: ∅ + │ └── unescaped: "$VERBOSE" + └── @ SymbolNode (location: (93,0)-(93,4)) + ├── opening_loc: (93,0)-(93,1) = ":" + ├── value_loc: (93,1)-(93,4) = "$-K" + ├── closing_loc: ∅ + └── unescaped: "$-K" diff --git a/test/prism/snapshots/hashes.txt b/test/prism/snapshots/hashes.txt new file mode 100644 index 00000000000000..ea8400635bdfa9 --- /dev/null +++ b/test/prism/snapshots/hashes.txt @@ -0,0 +1,355 @@ +@ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (6,2)-(6,3) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (6,7)-(6,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (6,7)-(6,8) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: (6,4)-(6,6) = "=>" + │ │ └── @ AssocNode (location: (6,10)-(6,16)) + │ │ ├── key: + │ │ │ @ CallNode (location: (6,10)-(6,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (6,10)-(6,11) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── value: + │ │ │ @ CallNode (location: (6,15)-(6,16)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (6,15)-(6,16) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,2)-(8,3) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (8,7)-(8,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,7)-(8,8) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: (8,4)-(8,6) = "=>" + │ │ └── @ AssocSplatNode (location: (8,10)-(8,13)) + │ │ ├── value: + │ │ │ @ CallNode (location: (8,12)-(8,13)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (8,12)-(8,13) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (11,6)-(11,7) = "a" + │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (11,9)-(11,10)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (11,9)-(11,10) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: ∅ + │ │ └── @ AssocNode (location: (12,6)-(12,10)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (12,6)-(12,8)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (12,6)-(12,7) = "c" + │ │ │ ├── closing_loc: (12,7)-(12,8) = ":" + │ │ │ └── unescaped: "c" + │ │ ├── value: + │ │ │ @ CallNode (location: (12,9)-(12,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (12,9)-(12,10) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ └── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (18,2)-(18,3) = "a" + │ │ │ │ ├── closing_loc: (18,3)-(18,4) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (18,5)-(18,6)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,5)-(18,6) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: ∅ + │ │ ├── @ AssocNode (location: (18,8)-(18,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (18,8)-(18,10)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (18,8)-(18,9) = "c" + │ │ │ │ ├── closing_loc: (18,9)-(18,10) = ":" + │ │ │ │ └── unescaped: "c" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (18,11)-(18,12)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,11)-(18,12) = "d" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "d" + │ │ │ └── operator_loc: ∅ + │ │ ├── @ AssocSplatNode (location: (18,14)-(18,17)) + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (18,16)-(18,17)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,16)-(18,17) = "e" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "e" + │ │ │ └── operator_loc: (18,14)-(18,16) = "**" + │ │ └── @ AssocNode (location: (18,19)-(18,23)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (18,19)-(18,21)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (18,19)-(18,20) = "f" + │ │ │ ├── closing_loc: (18,20)-(18,21) = ":" + │ │ │ └── unescaped: "f" + │ │ ├── value: + │ │ │ @ CallNode (location: (18,22)-(18,23)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (18,22)-(18,23) = "g" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "g" + │ │ └── 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)) + │ │ │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (20,8)-(20,10)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (20,8)-(20,10) = "b?" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "b?" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (20,7)-(20,8) = "!" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "!" + │ │ └── 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (23,0)-(23,3) = "tap" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (23,4)-(26,3)) + │ ├── locals: [:b] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (24,2)-(25,20)) + │ │ └── body: (length: 2) + │ │ ├── @ LocalVariableWriteNode (location: (24,2)-(24,7)) + │ │ │ ├── name: :b + │ │ │ ├── depth: 0 + │ │ │ ├── name_loc: (24,2)-(24,3) = "b" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (24,6)-(24,7)) + │ │ │ │ └── flags: decimal + │ │ │ └── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (25,12)-(25,13) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ └── operator_loc: ∅ + │ │ │ └── @ AssocNode (location: (25,16)-(25,18)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (25,16)-(25,18)) + │ │ │ │ ├── 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" + ├── flags: ∅ + └── name: "tap" diff --git a/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt b/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt new file mode 100644 index 00000000000000..c4ec0d86ce83aa --- /dev/null +++ b/test/prism/snapshots/heredoc_with_escaped_newline_at_start.txt @@ -0,0 +1,65 @@ +@ ProgramNode (location: (1,0)-(5,25)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,25)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,25)) + │ ├── receiver: + │ │ @ StringNode (location: (1,0)-(1,9)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,0)-(1,9) = "<<-TARGET" + │ │ ├── content_loc: (2,0)-(1,0) = "" + │ │ ├── closing_loc: (2,0)-(2,0) = "TARGET\n" + │ │ └── unescaped: "" + │ ├── call_operator_loc: (1,9)-(1,10) = "." + │ ├── message_loc: (1,10)-(1,14) = "gsub" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,15)-(1,25)) + │ │ └── arguments: (length: 2) + │ │ ├── @ RegularExpressionNode (location: (1,15)-(1,21)) + │ │ │ ├── opening_loc: (1,15)-(1,16) = "/" + │ │ │ ├── content_loc: (1,16)-(1,20) = "^\\s{" + │ │ │ ├── closing_loc: (1,20)-(1,21) = "/" + │ │ │ ├── unescaped: "^ {" + │ │ │ └── flags: ∅ + │ │ └── @ 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: ∅ + │ ├── flags: ∅ + │ └── name: "gsub" + └── @ CallNode (location: (5,0)-(5,25)) + ├── receiver: + │ @ StringNode (location: (5,0)-(5,9)) + │ ├── flags: ∅ + │ ├── opening_loc: (5,0)-(5,9) = "<<-TARGET" + │ ├── content_loc: (6,0)-(5,0) = "" + │ ├── closing_loc: (6,0)-(6,0) = "TARGET\r\n" + │ └── unescaped: "" + ├── call_operator_loc: (5,9)-(5,10) = "." + ├── message_loc: (5,10)-(5,14) = "gsub" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (5,15)-(5,25)) + │ └── arguments: (length: 2) + │ ├── @ RegularExpressionNode (location: (5,15)-(5,21)) + │ │ ├── opening_loc: (5,15)-(5,16) = "/" + │ │ ├── content_loc: (5,16)-(5,20) = "^\\s{" + │ │ ├── closing_loc: (5,20)-(5,21) = "/" + │ │ ├── unescaped: "^ {" + │ │ └── flags: ∅ + │ └── @ 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: ∅ + ├── flags: ∅ + └── name: "gsub" diff --git a/test/prism/snapshots/heredoc_with_trailing_newline.txt b/test/prism/snapshots/heredoc_with_trailing_newline.txt new file mode 100644 index 00000000000000..01178042d6b5bd --- /dev/null +++ b/test/prism/snapshots/heredoc_with_trailing_newline.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,6)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,6) = "<<-END" + ├── content_loc: (2,0)-(1,0) = "" + ├── closing_loc: (2,0)-(2,3) = "END" + └── unescaped: "" diff --git a/test/prism/snapshots/heredocs_nested.txt b/test/prism/snapshots/heredocs_nested.txt new file mode 100644 index 00000000000000..8680dd23461a41 --- /dev/null +++ b/test/prism/snapshots/heredocs_nested.txt @@ -0,0 +1,33 @@ +@ 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) = "<<~RUBY" + ├── parts: (length: 3) + │ ├── @ StringNode (location: (2,0)-(2,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (2,0)-(2,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) = "<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,6)-(31,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (31,6)-(31,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<=>" + ├── @ CallNode (location: (33,0)-(33,6)) + │ ├── receiver: + │ │ @ IntegerNode (location: (33,0)-(33,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,2)-(33,4) = "==" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (33,5)-(33,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (33,5)-(33,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "==" + ├── @ CallNode (location: (35,0)-(35,7)) + │ ├── receiver: + │ │ @ IntegerNode (location: (35,0)-(35,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,2)-(35,5) = "===" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,6)-(35,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (35,6)-(35,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "===" + ├── @ CallNode (location: (37,0)-(37,6)) + │ ├── receiver: + │ │ @ IntegerNode (location: (37,0)-(37,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,2)-(37,4) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,5)-(37,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (37,5)-(37,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ CallNode (location: (39,0)-(39,5)) + │ ├── receiver: + │ │ @ IntegerNode (location: (39,0)-(39,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (39,2)-(39,3) = ">" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (39,4)-(39,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (39,4)-(39,5)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">" + ├── @ CallNode (location: (41,0)-(41,6)) + │ ├── receiver: + │ │ @ IntegerNode (location: (41,0)-(41,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,2)-(41,4) = ">=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (41,5)-(41,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (41,5)-(41,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">=" + ├── @ CallNode (location: (43,0)-(43,6)) + │ ├── receiver: + │ │ @ IntegerNode (location: (43,0)-(43,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (43,2)-(43,4) = ">>" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (43,5)-(43,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (43,5)-(43,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">>" + ├── @ CallNode (location: (45,0)-(45,5)) + │ ├── receiver: + │ │ @ IntegerNode (location: (45,0)-(45,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (45,2)-(45,3) = "^" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (45,4)-(45,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (45,4)-(45,5)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "^" + ├── @ CallNode (location: (47,0)-(47,5)) + │ ├── receiver: + │ │ @ IntegerNode (location: (47,0)-(47,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (47,2)-(47,3) = "|" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (47,4)-(47,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (47,4)-(47,5)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "|" + ├── @ 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)) + │ ├── receiver: + │ │ @ IntegerNode (location: (53,0)-(53,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (53,2)-(53,3) = "*" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (53,4)-(53,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (53,4)-(53,10)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (53,4)-(53,5)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (53,6)-(53,8) = "**" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (53,9)-(53,10)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (53,9)-(53,10)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "**" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "*" + ├── @ CallNode (location: (55,0)-(55,9)) + │ ├── receiver: + │ │ @ CallNode (location: (55,0)-(55,5)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (55,0)-(55,1)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (55,2)-(55,3) = "*" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (55,4)-(55,5)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (55,4)-(55,5)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "*" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (55,6)-(55,7) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (55,8)-(55,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (55,8)-(55,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ 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)) + │ ├── receiver: + │ │ @ IntegerNode (location: (61,0)-(61,1)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (61,2)-(61,3) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (61,4)-(61,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (61,4)-(61,9)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (61,4)-(61,5)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (61,6)-(61,7) = "*" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (61,8)-(61,9)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (61,8)-(61,9)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "*" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + └── @ ParenthesesNode (location: (63,0)-(63,7)) + ├── body: + │ @ StatementsNode (location: (63,1)-(63,6)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (63,1)-(63,6)) + │ ├── receiver: + │ │ @ IntegerNode (location: (63,1)-(63,2)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (63,3)-(63,4) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (63,5)-(63,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (63,5)-(63,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── opening_loc: (63,0)-(63,1) = "(" + └── closing_loc: (63,6)-(63,7) = ")" diff --git a/test/prism/snapshots/keyword_method_names.txt b/test/prism/snapshots/keyword_method_names.txt new file mode 100644 index 00000000000000..9ecd52585a6a8a --- /dev/null +++ b/test/prism/snapshots/keyword_method_names.txt @@ -0,0 +1,170 @@ +@ ProgramNode (location: (1,0)-(29,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(29,3)) + └── body: (length: 10) + ├── @ DefNode (location: (1,0)-(2,3)) + │ ├── name: :def + │ ├── name_loc: (1,4)-(1,7) = "def" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (2,0)-(2,3) = "end" + ├── @ DefNode (location: (4,0)-(5,3)) + │ ├── name: :ensure + │ ├── name_loc: (4,9)-(4,15) = "ensure" + │ ├── receiver: + │ │ @ SelfNode (location: (4,4)-(4,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (4,0)-(4,3) = "def" + │ ├── operator_loc: (4,8)-(4,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,0)-(5,3) = "end" + ├── @ CallNode (location: (7,0)-(10,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,7) = "private" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,8)-(10,3)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (8,2)-(8,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (8,6)-(9,5)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (8,6)-(8,8) = "do" + │ │ │ │ └── closing_loc: (9,2)-(9,5) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── locals: [] + │ │ ├── def_keyword_loc: (7,8)-(7,11) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (10,0)-(10,3) = "end" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "private" + ├── @ 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] + │ ├── def_keyword_loc: (12,0)-(12,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (12,5)-(12,6) = "(" + │ ├── rparen_loc: (12,14)-(12,15) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (13,0)-(13,3) = "end" + ├── @ DefNode (location: (15,0)-(16,3)) + │ ├── name: :a + │ ├── name_loc: (15,17)-(15,18) = "a" + │ ├── receiver: + │ │ @ SourceEncodingNode (location: (15,4)-(15,16)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (15,0)-(15,3) = "def" + │ ├── operator_loc: (15,16)-(15,17) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (16,0)-(16,3) = "end" + ├── @ StringNode (location: (18,0)-(18,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (18,0)-(18,2) = "%{" + │ ├── content_loc: (18,2)-(18,5) = "abc" + │ ├── closing_loc: (18,5)-(18,6) = "}" + │ └── unescaped: "abc" + ├── @ StringNode (location: (20,0)-(20,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (20,0)-(20,2) = "%\"" + │ ├── content_loc: (20,2)-(20,5) = "abc" + │ ├── closing_loc: (20,5)-(20,6) = "\"" + │ └── unescaped: "abc" + ├── @ DefNode (location: (22,0)-(23,3)) + │ ├── name: :a + │ ├── name_loc: (22,13)-(22,14) = "a" + │ ├── receiver: + │ │ @ SourceFileNode (location: (22,4)-(22,12)) + │ │ └── filepath: "keyword_method_names.txt" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (22,0)-(22,3) = "def" + │ ├── operator_loc: (22,12)-(22,13) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (23,0)-(23,3) = "end" + ├── @ DefNode (location: (25,0)-(26,3)) + │ ├── name: :a + │ ├── name_loc: (25,13)-(25,14) = "a" + │ ├── receiver: + │ │ @ SourceLineNode (location: (25,4)-(25,12)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (25,0)-(25,3) = "def" + │ ├── operator_loc: (25,12)-(25,13) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (26,0)-(26,3) = "end" + └── @ DefNode (location: (28,0)-(29,3)) + ├── name: :a + ├── name_loc: (28,9)-(28,10) = "a" + ├── receiver: + │ @ NilNode (location: (28,4)-(28,7)) + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (28,0)-(28,3) = "def" + ├── operator_loc: (28,7)-(28,9) = "::" + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (29,0)-(29,3) = "end" diff --git a/test/prism/snapshots/keywords.txt b/test/prism/snapshots/keywords.txt new file mode 100644 index 00000000000000..6df11487d70f15 --- /dev/null +++ b/test/prism/snapshots/keywords.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..ed622f6739c225 --- /dev/null +++ b/test/prism/snapshots/lambda.txt @@ -0,0 +1,194 @@ +@ ProgramNode (location: (1,0)-(11,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(11,18)) + └── body: (length: 5) + ├── @ LambdaNode (location: (1,0)-(3,4)) + │ ├── locals: [:foo] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (3,2)-(3,3) = "{" + │ ├── closing_loc: (3,3)-(3,4) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,2)-(3,1)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (2,2)-(2,5)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (2,2)-(2,5)) + │ │ │ │ └── name: :foo + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,2)-(1,3) = "(" + │ │ └── closing_loc: (3,0)-(3,1) = ")" + │ └── body: ∅ + ├── @ LambdaNode (location: (5,0)-(5,18)) + │ ├── locals: [:x] + │ ├── operator_loc: (5,0)-(5,2) = "->" + │ ├── opening_loc: (5,15)-(5,16) = "{" + │ ├── closing_loc: (5,17)-(5,18) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (5,2)-(5,14)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (5,3)-(5,13)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (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)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (5,10)-(5,11) = "a" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "a" + │ │ │ │ │ └── closing_loc: (5,11)-(5,12) = "}" + │ │ │ │ └── closing_loc: (5,12)-(5,13) = "\"" + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (5,2)-(5,3) = "(" + │ │ └── closing_loc: (5,13)-(5,14) = ")" + │ └── body: ∅ + ├── @ LambdaNode (location: (7,0)-(7,15)) + │ ├── locals: [:a] + │ ├── operator_loc: (7,0)-(7,2) = "->" + │ ├── opening_loc: (7,13)-(7,14) = "{" + │ ├── closing_loc: (7,14)-(7,15) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (7,2)-(7,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (7,3)-(7,11)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (location: (7,3)-(7,11)) + │ │ │ │ ├── name: :a + │ │ │ │ ├── name_loc: (7,3)-(7,5) = "a:" + │ │ │ │ └── value: + │ │ │ │ @ CallNode (location: (7,6)-(7,11)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ CallNode (location: (7,6)-(7,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "b" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "b" + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (7,8)-(7,9) = "*" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (7,10)-(7,11)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ IntegerNode (location: (7,10)-(7,11)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "*" + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (7,2)-(7,3) = "(" + │ │ └── closing_loc: (7,11)-(7,12) = ")" + │ └── body: ∅ + ├── @ LambdaNode (location: (9,0)-(9,19)) + │ ├── locals: [:foo] + │ ├── operator_loc: (9,0)-(9,2) = "->" + │ ├── opening_loc: (9,13)-(9,15) = "do" + │ ├── closing_loc: (9,16)-(9,19) = "end" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (9,3)-(9,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (9,3)-(9,12)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (9,3)-(9,12)) + │ │ │ │ ├── name: :foo + │ │ │ │ ├── name_loc: (9,3)-(9,6) = "foo" + │ │ │ │ ├── operator_loc: (9,7)-(9,8) = "=" + │ │ │ │ └── value: + │ │ │ │ @ CallNode (location: (9,9)-(9,12)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,9)-(9,12) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── body: ∅ + └── @ LambdaNode (location: (11,0)-(11,18)) + ├── locals: [:foo] + ├── operator_loc: (11,0)-(11,2) = "->" + ├── opening_loc: (11,12)-(11,14) = "do" + ├── closing_loc: (11,15)-(11,18) = "end" + ├── parameters: + │ @ BlockParametersNode (location: (11,3)-(11,11)) + │ ├── parameters: + │ │ @ ParametersNode (location: (11,3)-(11,11)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (location: (11,3)-(11,11)) + │ │ │ ├── name: :foo + │ │ │ ├── name_loc: (11,3)-(11,7) = "foo:" + │ │ │ └── value: + │ │ │ @ CallNode (location: (11,8)-(11,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,8)-(11,11) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + └── body: ∅ diff --git a/test/prism/snapshots/method_calls.txt b/test/prism/snapshots/method_calls.txt new file mode 100644 index 00000000000000..9019ef1798c1f3 --- /dev/null +++ b/test/prism/snapshots/method_calls.txt @@ -0,0 +1,2171 @@ +@ ProgramNode (location: (1,0)-(147,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(147,8)) + └── body: (length: 62) + ├── @ CallNode (location: (1,0)-(1,14)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,14)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (3,0)-(3,9)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (3,1)-(3,2) = "." + │ ├── message_loc: (3,2)-(3,3) = "b" + │ ├── opening_loc: (3,3)-(3,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,4)-(3,8)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (3,4)-(3,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,4)-(3,5) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── @ CallNode (location: (3,7)-(3,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,7)-(3,8) = "d" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "d" + │ ├── closing_loc: (3,8)-(3,9) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── @ CallNode (location: (5,0)-(5,5)) + │ ├── receiver: + │ │ @ CallNode (location: (5,0)-(5,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (5,1)-(5,2) = "." + │ ├── message_loc: (5,2)-(5,3) = "b" + │ ├── opening_loc: (5,3)-(5,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (5,4)-(5,5) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── @ CallNode (location: (7,0)-(9,7)) + │ ├── receiver: + │ │ @ CallNode (location: (7,0)-(8,6)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (7,0)-(7,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,0)-(7,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: (8,2)-(8,3) = "." + │ │ ├── message_loc: (8,3)-(8,6) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── call_operator_loc: (9,2)-(9,4) = "&." + │ ├── message_loc: (9,4)-(9,7) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "baz" + ├── @ CallNode (location: (11,0)-(11,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,2) = "a!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a!" + ├── @ CallNode (location: (13,0)-(13,4)) + │ ├── receiver: + │ │ @ CallNode (location: (13,0)-(13,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,0)-(13,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (13,1)-(13,2) = "." + │ ├── message_loc: ∅ + │ ├── opening_loc: (13,2)-(13,3) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (13,3)-(13,4) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "call" + ├── @ CallNode (location: (15,0)-(15,11)) + │ ├── receiver: + │ │ @ CallNode (location: (15,0)-(15,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,0)-(15,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (15,1)-(15,2) = "." + │ ├── message_loc: ∅ + │ ├── opening_loc: (15,2)-(15,3) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,3)-(15,10)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "call" + ├── @ CallNode (location: (17,0)-(17,4)) + │ ├── receiver: + │ │ @ CallNode (location: (17,0)-(17,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,0)-(17,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (17,1)-(17,3) = "::" + │ ├── message_loc: (17,3)-(17,4) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── @ CallNode (location: (19,0)-(19,6)) + │ ├── receiver: + │ │ @ CallNode (location: (19,0)-(19,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,0)-(19,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (19,1)-(19,3) = "::" + │ ├── message_loc: (19,3)-(19,4) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (19,5)-(19,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (19,5)-(19,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,5)-(19,6) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── @ CallNode (location: (21,0)-(21,11)) + │ ├── receiver: + │ │ @ CallNode (location: (21,0)-(21,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,0)-(21,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (21,3)-(21,4) = "." + │ ├── message_loc: (21,4)-(21,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,10)-(21,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (21,10)-(21,11)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar=" + ├── @ CallNode (location: (23,0)-(23,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,0)-(23,2) = "a?" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a?" + ├── @ CallNode (location: (25,0)-(25,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (25,3)-(25,8) = "block" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "block" + │ │ └── operator_loc: (25,2)-(25,3) = "&" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (27,0)-(27,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,0)-(27,1) = "a" + │ ├── opening_loc: (27,1)-(27,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,2)-(27,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (27,2)-(27,10)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (27,2)-(27,10)) + │ │ ├── value: + │ │ │ @ CallNode (location: (27,4)-(27,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (27,4)-(27,10) = "kwargs" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "kwargs" + │ │ └── operator_loc: (27,2)-(27,4) = "**" + │ ├── closing_loc: (27,10)-(27,11) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (29,0)-(29,5)) + │ ├── receiver: + │ │ @ CallNode (location: (29,0)-(29,3)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (29,0)-(29,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,0)-(29,1) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── call_operator_loc: (29,1)-(29,2) = "." + │ │ ├── message_loc: (29,2)-(29,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── call_operator_loc: (29,3)-(29,4) = "." + │ ├── message_loc: (29,4)-(29,5) = "c" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "c" + ├── @ CallNode (location: (31,0)-(31,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,0)-(31,1) = "a" + │ ├── opening_loc: (31,1)-(31,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,2)-(31,6)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (31,2)-(31,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (31,2)-(31,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── @ CallNode (location: (31,5)-(31,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,5)-(31,6) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: (31,6)-(31,7) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (33,0)-(33,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,0)-(33,1) = "a" + │ ├── opening_loc: (33,1)-(33,2) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (33,2)-(33,3) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (35,0)-(35,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,1) = "a" + │ ├── opening_loc: (35,1)-(35,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,2)-(35,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (35,2)-(35,7)) + │ │ ├── operator_loc: (35,2)-(35,3) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (35,3)-(35,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,3)-(35,7) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (35,7)-(35,8) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (37,0)-(37,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,0)-(37,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,2)-(37,6)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (37,2)-(37,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,2)-(37,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── @ CallNode (location: (37,5)-(37,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,5)-(37,6) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (39,0)-(39,8)) + │ ├── receiver: + │ │ @ CallNode (location: (39,0)-(39,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,0)-(39,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (39,1)-(39,2) = "." + │ ├── message_loc: (39,2)-(39,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (39,4)-(39,8)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (39,4)-(39,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,4)-(39,5) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── @ CallNode (location: (39,7)-(39,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,7)-(39,8) = "d" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "d" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── @ MultiWriteNode (location: (41,0)-(41,23)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (41,0)-(41,7)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (41,0)-(41,3)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (41,0)-(41,3) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── call_operator_loc: (41,3)-(41,4) = "." + │ │ │ ├── message_loc: (41,4)-(41,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "foo=" + │ │ └── @ CallNode (location: (41,9)-(41,16)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (41,9)-(41,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (41,9)-(41,12) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: (41,12)-(41,13) = "." + │ │ ├── message_loc: (41,13)-(41,16) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar=" + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (41,17)-(41,18) = "=" + │ └── value: + │ @ ArrayNode (location: (41,19)-(41,23)) + │ ├── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (43,0)-(43,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (43,0)-(43,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (43,1)-(43,3) = "&." + │ ├── message_loc: (43,3)-(43,4) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + ├── @ CallNode (location: (45,0)-(45,5)) + │ ├── receiver: + │ │ @ CallNode (location: (45,0)-(45,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,0)-(45,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (45,1)-(45,3) = "&." + │ ├── message_loc: ∅ + │ ├── opening_loc: (45,3)-(45,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (45,4)-(45,5) = ")" + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "call" + ├── @ CallNode (location: (47,0)-(47,7)) + │ ├── receiver: + │ │ @ CallNode (location: (47,0)-(47,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,0)-(47,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (47,1)-(47,3) = "&." + │ ├── message_loc: (47,3)-(47,4) = "b" + │ ├── opening_loc: (47,4)-(47,5) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (47,5)-(47,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (47,5)-(47,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,5)-(47,6) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: (47,6)-(47,7) = ")" + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + ├── @ CallNode (location: (49,0)-(49,6)) + │ ├── receiver: + │ │ @ CallNode (location: (49,0)-(49,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (49,0)-(49,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (49,1)-(49,3) = "&." + │ ├── message_loc: (49,3)-(49,4) = "b" + │ ├── opening_loc: (49,4)-(49,5) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (49,5)-(49,6) = ")" + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + ├── @ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (51,14)-(51,18) = "bar?" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "bar?" + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (51,22)-(51,25)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (51,22)-(51,25) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── operator_loc: (51,19)-(51,21) = "or" + │ │ ├── right: + │ │ │ @ CallNode (location: (51,30)-(51,33)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (51,30)-(51,33) = "qux" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "qux" + │ │ └── operator_loc: (51,26)-(51,29) = "and" + │ ├── statements: + │ │ @ StatementsNode (location: (51,0)-(51,10)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (51,0)-(51,10)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (51,0)-(51,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (51,4)-(51,10)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ SymbolNode (location: (51,4)-(51,6)) + │ │ │ │ ├── opening_loc: (51,4)-(51,5) = ":" + │ │ │ │ ├── value_loc: (51,5)-(51,6) = "a" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "a" + │ │ │ └── @ SymbolNode (location: (51,8)-(51,10)) + │ │ │ ├── opening_loc: (51,8)-(51,9) = ":" + │ │ │ ├── value_loc: (51,9)-(51,10) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "foo" + │ ├── consequent: ∅ + │ └── end_keyword_loc: ∅ + ├── @ CallNode (location: (53,0)-(56,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (53,0)-(53,3) = "foo" + │ ├── opening_loc: (53,3)-(53,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (53,4)-(55,4)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (53,4)-(53,6)) + │ │ │ ├── opening_loc: (53,4)-(53,5) = ":" + │ │ │ ├── value_loc: (53,5)-(53,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (55,2)-(55,4)) + │ │ ├── opening_loc: (55,2)-(55,3) = ":" + │ │ ├── value_loc: (55,3)-(55,4) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: (56,0)-(56,1) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (58,0)-(58,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (58,0)-(58,3) = "foo" + │ ├── opening_loc: (58,3)-(58,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (58,4)-(58,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (58,4)-(58,9)) + │ │ ├── operator_loc: (58,4)-(58,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (58,5)-(58,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (58,5)-(58,9) = "rest" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "rest" + │ ├── closing_loc: (58,9)-(58,10) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (60,0)-(60,39)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (60,0)-(60,3) = "foo" + │ ├── opening_loc: (60,3)-(60,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (60,4)-(60,32)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (60,4)-(60,6)) + │ │ │ ├── opening_loc: (60,4)-(60,5) = ":" + │ │ │ ├── value_loc: (60,5)-(60,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ KeywordHashNode (location: (60,8)-(60,32)) + │ │ └── elements: (length: 2) + │ │ ├── @ AssocNode (location: (60,8)-(60,22)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (60,8)-(60,10)) + │ │ │ │ ├── opening_loc: (60,8)-(60,9) = ":" + │ │ │ │ ├── value_loc: (60,9)-(60,10) = "h" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "h" + │ │ │ ├── value: + │ │ │ │ @ ArrayNode (location: (60,14)-(60,22)) + │ │ │ │ ├── elements: (length: 2) + │ │ │ │ │ ├── @ SymbolNode (location: (60,15)-(60,17)) + │ │ │ │ │ │ ├── opening_loc: (60,15)-(60,16) = ":" + │ │ │ │ │ │ ├── value_loc: (60,16)-(60,17) = "x" + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ └── unescaped: "x" + │ │ │ │ │ └── @ SymbolNode (location: (60,19)-(60,21)) + │ │ │ │ │ ├── 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)) + │ │ │ ├── opening_loc: (60,24)-(60,25) = ":" + │ │ │ ├── value_loc: (60,25)-(60,26) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (60,30)-(60,32)) + │ │ │ ├── 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)) + │ │ │ ├── opening_loc: (60,35)-(60,36) = ":" + │ │ │ ├── value_loc: (60,36)-(60,39) = "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bar" + │ │ └── operator_loc: (60,34)-(60,35) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (62,0)-(62,49)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (62,0)-(62,2) = "hi" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (62,3)-(62,49)) + │ │ └── 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)) + │ │ │ │ │ ├── opening_loc: (62,10)-(62,11) = ":" + │ │ │ │ │ ├── value_loc: (62,11)-(62,16) = "there" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "there" + │ │ │ │ ├── value: + │ │ │ │ │ @ SymbolNode (location: (62,20)-(62,27)) + │ │ │ │ │ ├── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (62,35)-(62,41) = "whatup" + │ │ │ │ ├── closing_loc: (62,41)-(62,42) = ":" + │ │ │ │ └── unescaped: "whatup" + │ │ │ ├── value: + │ │ │ │ @ SymbolNode (location: (62,43)-(62,47)) + │ │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "hi" + ├── @ CallNode (location: (64,0)-(64,36)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (64,0)-(64,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (64,4)-(64,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (64,4)-(64,6)) + │ │ │ ├── opening_loc: (64,4)-(64,5) = ":" + │ │ │ ├── value_loc: (64,5)-(64,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ KeywordHashNode (location: (64,8)-(64,15)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (64,8)-(64,15)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (64,8)-(64,10)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (64,8)-(64,9) = "b" + │ │ │ ├── closing_loc: (64,9)-(64,10) = ":" + │ │ │ └── unescaped: "b" + │ │ ├── value: + │ │ │ @ TrueNode (location: (64,11)-(64,15)) + │ │ └── operator_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (64,16)-(64,36)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (64,19)-(64,25)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (64,20)-(64,24)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (64,20)-(64,21)) + │ │ │ │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (64,26)-(64,30) = "puts" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (64,31)-(64,32)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (64,31)-(64,32)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "puts" + │ │ ├── opening_loc: (64,16)-(64,18) = "do" + │ │ └── closing_loc: (64,33)-(64,36) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (66,0)-(66,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (66,0)-(66,2) = "hi" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (66,3)-(66,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (66,3)-(66,17)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (66,3)-(66,17)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (66,3)-(66,9)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (66,3)-(66,8) = "there" + │ │ │ ├── closing_loc: (66,8)-(66,9) = ":" + │ │ │ └── unescaped: "there" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (66,10)-(66,17)) + │ │ │ ├── opening_loc: (66,10)-(66,11) = ":" + │ │ │ ├── value_loc: (66,11)-(66,17) = "friend" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "friend" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "hi" + ├── @ CallNode (location: (68,0)-(68,40)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (68,0)-(68,2) = "hi" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (68,3)-(68,40)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (68,3)-(68,40)) + │ │ └── elements: (length: 3) + │ │ ├── @ AssocNode (location: (68,3)-(68,20)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (68,3)-(68,9)) + │ │ │ │ ├── opening_loc: (68,3)-(68,4) = ":" + │ │ │ │ ├── value_loc: (68,4)-(68,9) = "there" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "there" + │ │ │ ├── value: + │ │ │ │ @ SymbolNode (location: (68,13)-(68,20)) + │ │ │ │ ├── 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (68,28)-(68,34) = "whatup" + │ │ │ ├── closing_loc: (68,34)-(68,35) = ":" + │ │ │ └── unescaped: "whatup" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (68,36)-(68,40)) + │ │ │ ├── opening_loc: (68,36)-(68,37) = ":" + │ │ │ ├── value_loc: (68,37)-(68,40) = "dog" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "dog" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "hi" + ├── @ CallNode (location: (70,0)-(70,41)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (70,0)-(70,2) = "hi" + │ ├── opening_loc: (70,2)-(70,3) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (70,3)-(70,40)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (70,3)-(70,40)) + │ │ └── elements: (length: 3) + │ │ ├── @ AssocNode (location: (70,3)-(70,20)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (70,3)-(70,9)) + │ │ │ │ ├── opening_loc: (70,3)-(70,4) = ":" + │ │ │ │ ├── value_loc: (70,4)-(70,9) = "there" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "there" + │ │ │ ├── value: + │ │ │ │ @ SymbolNode (location: (70,13)-(70,20)) + │ │ │ │ ├── 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (70,28)-(70,34) = "whatup" + │ │ │ ├── closing_loc: (70,34)-(70,35) = ":" + │ │ │ └── unescaped: "whatup" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (70,36)-(70,40)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "hi" + ├── @ CallNode (location: (72,0)-(72,35)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (72,0)-(72,3) = "foo" + │ ├── opening_loc: (72,3)-(72,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (72,4)-(72,26)) + │ │ └── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ ├── 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)) + │ │ │ ├── opening_loc: (72,29)-(72,30) = ":" + │ │ │ ├── value_loc: (72,30)-(72,35) = "block" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "block" + │ │ └── operator_loc: (72,28)-(72,29) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (74,0)-(74,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (74,0)-(74,2) = "hi" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (74,3)-(74,20)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (74,3)-(74,20)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (74,3)-(74,20)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (74,3)-(74,9)) + │ │ │ ├── opening_loc: (74,3)-(74,4) = ":" + │ │ │ ├── value_loc: (74,4)-(74,9) = "there" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "there" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (74,13)-(74,20)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "hi" + ├── @ CallNode (location: (76,0)-(78,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (76,0)-(76,3) = "foo" + │ ├── opening_loc: (76,3)-(76,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (76,4)-(77,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (76,4)-(76,6)) + │ │ │ ├── opening_loc: (76,4)-(76,5) = ":" + │ │ │ ├── value_loc: (76,5)-(76,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (77,0)-(77,2)) + │ │ ├── opening_loc: (77,0)-(77,1) = ":" + │ │ ├── value_loc: (77,1)-(77,2) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: (78,0)-(78,1) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (80,0)-(83,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (80,0)-(80,3) = "foo" + │ ├── opening_loc: (80,3)-(80,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (81,0)-(82,5)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (81,0)-(81,2)) + │ │ │ ├── opening_loc: (81,0)-(81,1) = ":" + │ │ │ ├── value_loc: (81,1)-(81,2) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ KeywordHashNode (location: (82,0)-(82,5)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (82,0)-(82,5)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (82,0)-(82,2)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (82,0)-(82,1) = "b" + │ │ │ ├── closing_loc: (82,1)-(82,2) = ":" + │ │ │ └── unescaped: "b" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (82,3)-(82,5)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (85,0)-(85,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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)) + │ │ │ ├── opening_loc: (85,5)-(85,6) = ":" + │ │ │ ├── value_loc: (85,6)-(85,11) = "block" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "block" + │ │ └── operator_loc: (85,4)-(85,5) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (87,0)-(87,30)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (87,0)-(87,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (87,4)-(87,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (87,4)-(87,21)) + │ │ └── elements: (length: 2) + │ │ ├── @ AssocNode (location: (87,4)-(87,11)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (87,4)-(87,6)) + │ │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── opening_loc: (87,24)-(87,25) = ":" + │ │ │ ├── value_loc: (87,25)-(87,30) = "block" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "block" + │ │ └── operator_loc: (87,23)-(87,24) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (89,0)-(89,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (89,0)-(89,9) = "some_func" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (89,10)-(89,21)) + │ │ └── arguments: (length: 2) + │ │ ├── @ IntegerNode (location: (89,10)-(89,11)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordHashNode (location: (89,13)-(89,21)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (89,13)-(89,21)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (89,13)-(89,19)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "some_func" + ├── @ CallNode (location: (91,0)-(91,18)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (91,0)-(91,6)) + │ │ └── name: :Kernel + │ ├── call_operator_loc: (91,6)-(91,7) = "." + │ ├── message_loc: (91,7)-(91,14) = "Integer" + │ ├── opening_loc: (91,14)-(91,15) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (91,15)-(91,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (91,15)-(91,17)) + │ │ └── flags: decimal + │ ├── closing_loc: (91,17)-(91,18) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Integer" + ├── @ CallNode (location: (93,0)-(93,10)) + │ ├── receiver: + │ │ @ CallNode (location: (93,0)-(93,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (93,0)-(93,1) = "x" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "x" + │ ├── call_operator_loc: (93,1)-(93,2) = "." + │ ├── message_loc: (93,2)-(93,6) = "each" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (93,7)-(93,10)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (93,7)-(93,8) = "{" + │ │ └── closing_loc: (93,9)-(93,10) = "}" + │ ├── flags: ∅ + │ └── name: "each" + ├── @ CallNode (location: (95,0)-(95,14)) + │ ├── receiver: + │ │ @ CallNode (location: (95,0)-(95,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (95,0)-(95,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (95,3)-(95,4) = "." + │ ├── message_loc: (95,4)-(95,7) = "map" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (95,8)-(95,14)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (95,10)-(95,12)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ BackReferenceReadNode (location: (95,10)-(95,12)) + │ │ ├── opening_loc: (95,8)-(95,9) = "{" + │ │ └── closing_loc: (95,13)-(95,14) = "}" + │ ├── flags: ∅ + │ └── name: "map" + ├── @ CallNode (location: (97,0)-(97,12)) + │ ├── 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) = "::" + │ ├── message_loc: (97,6)-(97,7) = "C" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (97,8)-(97,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (97,8)-(97,12)) + │ │ ├── opening_loc: (97,8)-(97,9) = ":" + │ │ ├── value_loc: (97,9)-(97,12) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "C" + ├── @ CallNode (location: (99,0)-(99,13)) + │ ├── 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) = "::" + │ ├── message_loc: (99,6)-(99,7) = "C" + │ ├── opening_loc: (99,7)-(99,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (99,8)-(99,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (99,8)-(99,12)) + │ │ ├── opening_loc: (99,8)-(99,9) = ":" + │ │ ├── value_loc: (99,9)-(99,12) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── closing_loc: (99,12)-(99,13) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "C" + ├── @ CallNode (location: (101,0)-(101,17)) + │ ├── 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) = "::" + │ ├── message_loc: (101,6)-(101,7) = "C" + │ ├── opening_loc: (101,7)-(101,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (101,8)-(101,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (101,8)-(101,12)) + │ │ ├── opening_loc: (101,8)-(101,9) = ":" + │ │ ├── value_loc: (101,9)-(101,12) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── closing_loc: (101,12)-(101,13) = ")" + │ ├── block: + │ │ @ BlockNode (location: (101,14)-(101,17)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (101,14)-(101,15) = "{" + │ │ └── closing_loc: (101,16)-(101,17) = "}" + │ ├── flags: ∅ + │ └── name: "C" + ├── @ CallNode (location: (103,0)-(103,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (103,0)-(103,3) = "foo" + │ ├── opening_loc: (103,3)-(103,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (103,4)-(103,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (103,4)-(103,11)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (103,4)-(103,11)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (103,4)-(103,8)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (105,0)-(105,28)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (105,0)-(105,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (105,4)-(105,28)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (105,4)-(105,28)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (105,4)-(105,28)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (105,4)-(105,8)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (105,11)-(105,14) = "baz" + │ │ │ │ │ ├── closing_loc: (105,14)-(105,15) = ":" + │ │ │ │ │ └── unescaped: "baz" + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (105,16)-(105,26)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (105,16)-(105,19) = "qux" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (105,20)-(105,26)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (105,20)-(105,22) = "do" + │ │ │ │ │ │ └── closing_loc: (105,23)-(105,26) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "qux" + │ │ │ │ └── operator_loc: ∅ + │ │ │ └── closing_loc: (105,27)-(105,28) = "}" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (107,0)-(107,24)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (107,0)-(107,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (107,4)-(107,24)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (107,4)-(107,24)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (107,4)-(107,24)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (107,4)-(107,8)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (107,13)-(107,15) = "kw" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (107,16)-(107,22)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (107,16)-(107,18) = "do" + │ │ │ │ │ │ └── closing_loc: (107,19)-(107,22) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "kw" + │ │ │ │ └── operator_loc: (107,11)-(107,13) = "**" + │ │ │ └── closing_loc: (107,23)-(107,24) = "}" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (109,0)-(109,36)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (109,0)-(109,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (109,4)-(109,29)) + │ │ └── 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)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ CallNode (location: (109,7)-(109,10)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (109,7)-(109,10) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ ├── call_operator_loc: (109,10)-(109,11) = "." + │ │ │ │ ├── message_loc: (109,11)-(109,14) = "map" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (109,15)-(109,27)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: + │ │ │ │ │ │ @ StatementsNode (location: (109,18)-(109,23)) + │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ └── @ StringNode (location: (109,18)-(109,23)) + │ │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ │ ├── opening_loc: (109,18)-(109,19) = "\"" + │ │ │ │ │ │ ├── content_loc: (109,19)-(109,22) = "baz" + │ │ │ │ │ │ ├── closing_loc: (109,22)-(109,23) = "\"" + │ │ │ │ │ │ └── unescaped: "baz" + │ │ │ │ │ ├── opening_loc: (109,15)-(109,17) = "do" + │ │ │ │ │ └── closing_loc: (109,24)-(109,27) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "map" + │ │ │ └── closing_loc: (109,27)-(109,28) = "}" + │ │ └── closing_loc: (109,28)-(109,29) = "\"" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (109,30)-(109,36)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (109,30)-(109,32) = "do" + │ │ └── closing_loc: (109,33)-(109,36) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (111,0)-(111,28)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (111,0)-(111,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (111,4)-(111,28)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (111,14)-(111,17) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (111,18)-(111,24)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (111,18)-(111,20) = "do" + │ │ │ │ └── closing_loc: (111,21)-(111,24) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ ├── end_keyword_loc: (111,25)-(111,28) = "end" + │ │ └── name: :Bar + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (113,0)-(113,29)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (113,0)-(113,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (113,4)-(113,29)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (113,15)-(113,18) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (113,19)-(113,25)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (113,19)-(113,21) = "do" + │ │ │ │ └── closing_loc: (113,22)-(113,25) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ ├── end_keyword_loc: (113,26)-(113,29) = "end" + │ │ └── name: :Bar + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (115,0)-(115,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (115,0)-(115,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (115,4)-(115,16)) + │ │ └── arguments: (length: 1) + │ │ └── @ ArrayNode (location: (115,4)-(115,16)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ CallNode (location: (115,5)-(115,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (115,5)-(115,8) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (115,9)-(115,15)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (115,9)-(115,11) = "do" + │ │ │ │ └── closing_loc: (115,12)-(115,15) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ ├── opening_loc: (115,4)-(115,5) = "[" + │ │ └── closing_loc: (115,15)-(115,16) = "]" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (117,0)-(117,28)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (117,0)-(117,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (117,2)-(117,28)) + │ │ └── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ IntegerNode (location: (117,8)-(117,9)) + │ │ │ │ └── flags: decimal + │ │ │ ├── call_operator_loc: (117,9)-(117,10) = "." + │ │ │ ├── message_loc: (117,10)-(117,15) = "times" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (117,16)-(117,24)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (117,19)-(117,20)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ IntegerNode (location: (117,19)-(117,20)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── opening_loc: (117,16)-(117,18) = "do" + │ │ │ │ └── closing_loc: (117,21)-(117,24) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "times" + │ │ ├── rescue_clause: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (117,25)-(117,28) = "end" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (119,0)-(124,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (119,0)-(119,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (119,4)-(124,5)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (119,4)-(119,6)) + │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (120,5)-(120,6) = "x" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "x" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (121,4)-(123,7)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (121,4)-(123,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (121,4)-(121,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (121,8)-(123,7)) + │ │ │ │ ├── locals: [:a] + │ │ │ │ ├── parameters: + │ │ │ │ │ @ BlockParametersNode (location: (121,11)-(121,14)) + │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ @ ParametersNode (location: (121,12)-(121,13)) + │ │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (121,12)-(121,13)) + │ │ │ │ │ │ │ └── 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" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── consequent: ∅ + │ │ └── end_keyword_loc: (124,2)-(124,5) = "end" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (126,0)-(135,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (126,0)-(126,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (126,4)-(135,5)) + │ │ └── arguments: (length: 3) + │ │ ├── @ SymbolNode (location: (126,4)-(126,6)) + │ │ │ ├── opening_loc: (126,4)-(126,5) = ":" + │ │ │ ├── value_loc: (126,5)-(126,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ WhileNode (location: (127,2)-(131,5)) + │ │ │ ├── keyword_loc: (127,2)-(127,7) = "while" + │ │ │ ├── closing_loc: (131,2)-(131,5) = "end" + │ │ │ ├── predicate: + │ │ │ │ @ CallNode (location: (127,8)-(127,9)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (127,8)-(127,9) = "x" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "x" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (128,4)-(130,7)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (128,4)-(130,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (128,4)-(128,7) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (128,8)-(130,7)) + │ │ │ │ │ ├── locals: [:a] + │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ @ BlockParametersNode (location: (128,11)-(128,14)) + │ │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ │ @ ParametersNode (location: (128,12)-(128,13)) + │ │ │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (128,12)-(128,13)) + │ │ │ │ │ │ │ │ └── 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" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "bar" + │ │ │ └── flags: ∅ + │ │ └── @ UntilNode (location: (132,2)-(135,5)) + │ │ ├── keyword_loc: (132,2)-(132,7) = "until" + │ │ ├── closing_loc: (135,2)-(135,5) = "end" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (132,8)-(132,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (132,8)-(132,9) = "x" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "x" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (133,4)-(134,7)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (133,4)-(134,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (133,4)-(133,7) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (133,8)-(134,7)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (133,8)-(133,10) = "do" + │ │ │ │ └── closing_loc: (134,4)-(134,7) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (137,0)-(137,9)) + │ ├── 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: ∅ + │ ├── message_loc: (137,3)-(137,4) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (137,5)-(137,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (137,5)-(137,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (137,5)-(137,6) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (137,7)-(137,9)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (137,7)-(137,8) = "{" + │ │ │ └── closing_loc: (137,8)-(137,9) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (139,0)-(139,16)) + │ ├── 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: ∅ + │ ├── message_loc: (139,3)-(139,4) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (139,5)-(139,16)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (139,5)-(139,16)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (139,5)-(139,6) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (139,7)-(139,16)) + │ │ │ ├── locals: [:a] + │ │ │ ├── parameters: + │ │ │ │ @ BlockParametersNode (location: (139,9)-(139,12)) + │ │ │ │ ├── parameters: + │ │ │ │ │ @ ParametersNode (location: (139,10)-(139,11)) + │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (139,10)-(139,11)) + │ │ │ │ │ │ └── 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) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (141,0)-(141,11)) + │ ├── receiver: + │ │ @ CallNode (location: (141,0)-(141,4)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (141,0)-(141,1) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (141,2)-(141,4)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (141,2)-(141,3) = "{" + │ │ │ └── closing_loc: (141,3)-(141,4) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (141,5)-(141,6) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (141,7)-(141,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (141,7)-(141,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (141,7)-(141,8) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (141,9)-(141,11)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (141,9)-(141,10) = "{" + │ │ │ └── closing_loc: (141,10)-(141,11) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (143,0)-(143,11)) + │ ├── receiver: + │ │ @ CallNode (location: (143,0)-(143,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (143,0)-(143,3) = "lst" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "lst" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (143,4)-(143,6) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (143,7)-(143,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (143,7)-(143,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (143,7)-(143,8) = "A" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (143,9)-(143,11)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (143,9)-(143,10) = "{" + │ │ │ └── closing_loc: (143,10)-(143,11) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "A" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (145,4)-(145,8) = "join" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (145,9)-(145,14)) + │ │ │ │ └── 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: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "join" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (147,4)-(147,5) = "v" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "v" + │ │ ├── opening_loc: (147,3)-(147,4) = "(" + │ │ └── closing_loc: (147,5)-(147,6) = ")" + │ └── closing_loc: (147,6)-(147,7) = "}" + └── closing_loc: (147,7)-(147,8) = "\"" diff --git a/test/prism/snapshots/methods.txt b/test/prism/snapshots/methods.txt new file mode 100644 index 00000000000000..7e8091b4d53d6c --- /dev/null +++ b/test/prism/snapshots/methods.txt @@ -0,0 +1,1642 @@ +@ ProgramNode (location: (1,0)-(168,16)) +├── locals: [:a, :c, :foo] +└── statements: + @ StatementsNode (location: (1,0)-(168,16)) + └── body: (length: 62) + ├── @ 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) + │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,18)) + │ │ │ ├── parameters: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,12)) + │ │ │ │ │ └── name: :bar + │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,17)) + │ │ │ │ └── name: :baz + │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ └── closing_loc: (1,17)-(1,18) = ")" + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar, :baz] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ ├── rparen_loc: (1,18)-(1,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (2,0)-(2,3) = "end" + ├── @ DefNode (location: (4,0)-(5,3)) + │ ├── name: :foo + │ ├── name_loc: (4,4)-(4,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (4,8)-(4,44)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredDestructuredParameterNode (location: (4,8)-(4,18)) + │ │ │ ├── parameters: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (4,9)-(4,12)) + │ │ │ │ │ └── name: :bar + │ │ │ │ └── @ RequiredParameterNode (location: (4,14)-(4,17)) + │ │ │ │ └── name: :baz + │ │ │ ├── opening_loc: (4,8)-(4,9) = "(" + │ │ │ └── closing_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) + │ │ │ └── @ RequiredDestructuredParameterNode (location: (4,34)-(4,44)) + │ │ │ ├── parameters: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (4,35)-(4,38)) + │ │ │ │ │ └── name: :bin + │ │ │ │ └── @ RequiredParameterNode (location: (4,40)-(4,43)) + │ │ │ │ └── name: :bag + │ │ │ ├── opening_loc: (4,34)-(4,35) = "(" + │ │ │ └── closing_loc: (4,43)-(4,44) = ")" + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar, :baz, :optional, :bin, :bag] + │ ├── def_keyword_loc: (4,0)-(4,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (4,7)-(4,8) = "(" + │ ├── rparen_loc: (4,44)-(4,45) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,0)-(5,3) = "end" + ├── @ DefNode (location: (8,0)-(8,18)) + │ ├── name: :a + │ ├── name_loc: (8,4)-(8,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (8,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: [] + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (10,5)-(10,6) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── opening_loc: (10,4)-(10,5) = "(" + │ │ └── closing_loc: (10,6)-(10,7) = ")" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (10,0)-(10,3) = "def" + │ ├── operator_loc: (10,7)-(10,8) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (11,0)-(11,3) = "end" + ├── @ DefNode (location: (13,0)-(14,3)) + │ ├── name: :b + │ ├── name_loc: (13,9)-(13,10) = "b" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (13,4)-(13,7)) + │ │ ├── body: + │ │ │ @ CallNode (location: (13,5)-(13,6)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,5)-(13,6) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── opening_loc: (13,4)-(13,5) = "(" + │ │ └── closing_loc: (13,6)-(13,7) = ")" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (13,0)-(13,3) = "def" + │ ├── operator_loc: (13,7)-(13,9) = "::" + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (14,0)-(14,3) = "end" + ├── @ DefNode (location: (16,0)-(17,3)) + │ ├── name: :a + │ ├── name_loc: (16,10)-(16,11) = "a" + │ ├── receiver: + │ │ @ FalseNode (location: (16,4)-(16,9)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (16,0)-(16,3) = "def" + │ ├── operator_loc: (16,9)-(16,10) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (17,0)-(17,3) = "end" + ├── @ DefNode (location: (19,0)-(20,3)) + │ ├── name: :a + │ ├── name_loc: (19,4)-(19,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (19,6)-(19,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (19,6)-(19,9)) + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (19,0)-(19,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (19,5)-(19,6) = "(" + │ ├── rparen_loc: (19,9)-(19,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (20,0)-(20,3) = "end" + ├── @ DefNode (location: (22,0)-(23,3)) + │ ├── name: :a + │ ├── name_loc: (22,9)-(22,10) = "a" + │ ├── receiver: + │ │ @ GlobalVariableReadNode (location: (22,4)-(22,8)) + │ │ └── name: :$var + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (22,0)-(22,3) = "def" + │ ├── operator_loc: (22,8)-(22,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (23,0)-(23,3) = "end" + ├── @ DefNode (location: (25,0)-(26,3)) + │ ├── name: :b + │ ├── name_loc: (25,6)-(25,7) = "b" + │ ├── receiver: + │ │ @ CallNode (location: (25,4)-(25,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,4)-(25,5) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (25,0)-(25,3) = "def" + │ ├── operator_loc: (25,5)-(25,6) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (26,0)-(26,3) = "end" + ├── @ DefNode (location: (28,0)-(29,3)) + │ ├── name: :a + │ ├── name_loc: (28,9)-(28,10) = "a" + │ ├── receiver: + │ │ @ InstanceVariableReadNode (location: (28,4)-(28,8)) + │ │ └── name: :@var + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (28,0)-(28,3) = "def" + │ ├── operator_loc: (28,8)-(28,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (29,0)-(29,3) = "end" + ├── @ DefNode (location: (31,0)-(31,13)) + │ ├── name: :a + │ ├── name_loc: (31,4)-(31,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (31,6)-(31,8)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (location: (31,6)-(31,8)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (31,6)-(31,8) = "b:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (31,0)-(31,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (31,10)-(31,13) = "end" + ├── @ StringNode (location: (33,0)-(33,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (33,0)-(33,2) = "%," + │ ├── content_loc: (33,2)-(33,5) = "abc" + │ ├── closing_loc: (33,5)-(33,6) = "," + │ └── unescaped: "abc" + ├── @ DefNode (location: (35,0)-(36,3)) + │ ├── name: :a + │ ├── name_loc: (35,4)-(35,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (35,6)-(35,8)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (location: (35,6)-(35,8)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (35,6)-(35,8) = "b:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (35,0)-(35,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (35,5)-(35,6) = "(" + │ ├── rparen_loc: (35,8)-(35,9) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (36,0)-(36,3) = "end" + ├── @ DefNode (location: (38,0)-(39,3)) + │ ├── name: :a + │ ├── name_loc: (38,4)-(38,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (38,6)-(38,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ KeywordRestParameterNode (location: (38,6)-(38,9)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (38,8)-(38,9) = "b" + │ │ │ └── operator_loc: (38,6)-(38,8) = "**" + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (38,0)-(38,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (38,5)-(38,6) = "(" + │ ├── rparen_loc: (38,9)-(38,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (39,0)-(39,3) = "end" + ├── @ DefNode (location: (41,0)-(42,3)) + │ ├── name: :a + │ ├── name_loc: (41,4)-(41,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (41,6)-(41,8)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ KeywordRestParameterNode (location: (41,6)-(41,8)) + │ │ │ ├── name: nil + │ │ │ ├── name_loc: ∅ + │ │ │ └── operator_loc: (41,6)-(41,8) = "**" + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:**] + │ ├── def_keyword_loc: (41,0)-(41,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (41,5)-(41,6) = "(" + │ ├── rparen_loc: (41,8)-(41,9) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (42,0)-(42,3) = "end" + ├── @ LocalVariableWriteNode (location: (44,0)-(44,5)) + │ ├── name: :a + │ ├── depth: 0 + │ ├── name_loc: (44,0)-(44,1) = "a" + │ ├── value: + │ │ @ IntegerNode (location: (44,4)-(44,5)) + │ │ └── flags: decimal + │ └── operator_loc: (44,2)-(44,3) = "=" + ├── @ DefNode (location: (44,7)-(45,3)) + │ ├── name: :a + │ ├── name_loc: (44,11)-(44,12) = "a" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (44,7)-(44,10) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (45,0)-(45,3) = "end" + ├── @ DefNode (location: (47,0)-(48,3)) + │ ├── name: :a + │ ├── name_loc: (47,4)-(47,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (47,6)-(47,13)) + │ │ ├── requireds: (length: 3) + │ │ │ ├── @ RequiredParameterNode (location: (47,6)-(47,7)) + │ │ │ │ └── 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] + │ ├── def_keyword_loc: (47,0)-(47,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (48,0)-(48,3) = "end" + ├── @ DefNode (location: (50,0)-(51,3)) + │ ├── name: :a + │ ├── name_loc: (50,8)-(50,9) = "a" + │ ├── receiver: + │ │ @ NilNode (location: (50,4)-(50,7)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (50,0)-(50,3) = "def" + │ ├── operator_loc: (50,7)-(50,8) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (51,0)-(51,3) = "end" + ├── @ DefNode (location: (53,0)-(54,3)) + │ ├── name: :a + │ ├── name_loc: (53,4)-(53,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (53,6)-(53,14)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 2) + │ │ │ ├── @ KeywordParameterNode (location: (53,6)-(53,8)) + │ │ │ │ ├── name: :b + │ │ │ │ ├── name_loc: (53,6)-(53,8) = "b:" + │ │ │ │ └── value: ∅ + │ │ │ └── @ KeywordParameterNode (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] + │ ├── 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) + │ │ │ ├── @ KeywordParameterNode (location: (56,6)-(56,8)) + │ │ │ │ ├── name: :b + │ │ │ │ ├── name_loc: (56,6)-(56,8) = "b:" + │ │ │ │ └── value: ∅ + │ │ │ └── @ KeywordParameterNode (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] + │ ├── 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) + │ │ │ ├── @ KeywordParameterNode (location: (59,6)-(60,3)) + │ │ │ │ ├── name: :b + │ │ │ │ ├── name_loc: (59,6)-(59,8) = "b:" + │ │ │ │ └── value: + │ │ │ │ @ IntegerNode (location: (60,2)-(60,3)) + │ │ │ │ └── flags: decimal + │ │ │ └── @ KeywordParameterNode (location: (60,5)-(60,7)) + │ │ │ ├── name: :c + │ │ │ ├── name_loc: (60,5)-(60,7) = "c:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b, :c] + │ ├── def_keyword_loc: (59,0)-(59,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (59,5)-(59,6) = "(" + │ ├── rparen_loc: (60,7)-(60,8) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (61,0)-(61,3) = "end" + ├── @ StringNode (location: (63,0)-(63,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (63,0)-(63,2) = "%." + │ ├── content_loc: (63,2)-(63,5) = "abc" + │ ├── closing_loc: (63,5)-(63,6) = "." + │ └── unescaped: "abc" + ├── @ DefNode (location: (65,0)-(66,3)) + │ ├── name: :a + │ ├── name_loc: (65,4)-(65,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (65,6)-(65,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 2) + │ │ │ ├── @ OptionalParameterNode (location: (65,6)-(65,11)) + │ │ │ │ ├── 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] + │ ├── def_keyword_loc: (65,0)-(65,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (66,0)-(66,3) = "end" + ├── @ DefNode (location: (68,0)-(69,3)) + │ ├── name: :a + │ ├── name_loc: (68,4)-(68,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (68,0)-(68,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (68,5)-(68,6) = "(" + │ ├── rparen_loc: (68,6)-(68,7) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (69,0)-(69,3) = "end" + ├── @ DefNode (location: (71,0)-(72,3)) + │ ├── name: :a + │ ├── name_loc: (71,4)-(71,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (71,6)-(71,14)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (71,6)-(71,7)) + │ │ │ └── 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] + │ ├── 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] + │ ├── 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: [] + │ ├── 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] + │ ├── 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: nil + │ │ │ ├── name_loc: ∅ + │ │ │ └── operator_loc: (82,6)-(82,7) = "*" + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:*] + │ ├── def_keyword_loc: (82,0)-(82,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (82,5)-(82,6) = "(" + │ ├── rparen_loc: (82,7)-(82,8) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (83,0)-(83,3) = "end" + ├── @ DefNode (location: (85,0)-(87,3)) + │ ├── name: :a + │ ├── name_loc: (85,4)-(85,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (86,0)-(86,5)) + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableWriteNode (location: (86,0)-(86,5)) + │ │ ├── name: :b + │ │ ├── depth: 0 + │ │ ├── name_loc: (86,0)-(86,1) = "b" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (86,4)-(86,5)) + │ │ │ └── flags: decimal + │ │ └── operator_loc: (86,2)-(86,3) = "=" + │ ├── locals: [:b] + │ ├── def_keyword_loc: (85,0)-(85,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (87,0)-(87,3) = "end" + ├── @ DefNode (location: (89,0)-(90,3)) + │ ├── name: :a + │ ├── name_loc: (89,9)-(89,10) = "a" + │ ├── receiver: + │ │ @ SelfNode (location: (89,4)-(89,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (89,0)-(89,3) = "def" + │ ├── operator_loc: (89,8)-(89,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (90,0)-(90,3) = "end" + ├── @ DefNode (location: (92,0)-(93,3)) + │ ├── name: :a + │ ├── name_loc: (92,9)-(92,10) = "a" + │ ├── receiver: + │ │ @ TrueNode (location: (92,4)-(92,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (92,0)-(92,3) = "def" + │ ├── operator_loc: (92,8)-(92,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (93,0)-(93,3) = "end" + ├── @ DefNode (location: (95,0)-(96,3)) + │ ├── name: :a + │ ├── name_loc: (95,4)-(95,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (95,0)-(95,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (96,0)-(96,3) = "end" + ├── @ DefNode (location: (98,0)-(101,3)) + │ ├── name: :hi + │ ├── name_loc: (98,4)-(98,6) = "hi" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (99,0)-(100,4)) + │ │ └── body: (length: 2) + │ │ ├── @ IfNode (location: (99,0)-(99,18)) + │ │ │ ├── if_keyword_loc: (99,11)-(99,13) = "if" + │ │ │ ├── predicate: + │ │ │ │ @ TrueNode (location: (99,14)-(99,18)) + │ │ │ ├── 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)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (99,7)-(99,10)) + │ │ │ │ ├── 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)) + │ │ ├── opening_loc: (100,0)-(100,1) = ":" + │ │ ├── value_loc: (100,1)-(100,4) = "bye" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bye" + │ ├── locals: [] + │ ├── def_keyword_loc: (98,0)-(98,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (101,0)-(101,3) = "end" + ├── @ DefNode (location: (103,0)-(103,11)) + │ ├── name: :foo + │ ├── name_loc: (103,4)-(103,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (103,10)-(103,11)) + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (103,10)-(103,11)) + │ │ └── flags: decimal + │ ├── locals: [] + │ ├── def_keyword_loc: (103,0)-(103,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (103,8)-(103,9) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (104,0)-(104,11)) + │ ├── name: :bar + │ ├── name_loc: (104,4)-(104,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (104,10)-(104,11)) + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (104,10)-(104,11)) + │ │ └── flags: decimal + │ ├── locals: [] + │ ├── def_keyword_loc: (104,0)-(104,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (104,8)-(104,9) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (106,0)-(106,18)) + │ ├── name: :foo + │ ├── name_loc: (106,4)-(106,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (106,8)-(106,11)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (106,8)-(106,11)) + │ │ │ └── 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] + │ ├── 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: [] + │ ├── 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: nil + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (110,10)-(110,11) = "b" + │ │ ├── opening_loc: (110,11)-(110,12) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (110,12)-(110,13)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ SplatNode (location: (110,12)-(110,13)) + │ │ │ ├── operator_loc: (110,12)-(110,13) = "*" + │ │ │ └── expression: ∅ + │ │ ├── closing_loc: (110,13)-(110,14) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── locals: [:*] + │ ├── def_keyword_loc: (110,0)-(110,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (110,5)-(110,6) = "(" + │ ├── rparen_loc: (110,7)-(110,8) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (110,16)-(110,19) = "end" + ├── @ DefNode (location: (112,0)-(112,23)) + │ ├── name: :a + │ ├── name_loc: (112,4)-(112,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (112,6)-(112,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (112,6)-(112,9)) + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (112,12)-(112,18)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (112,12)-(112,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (112,12)-(112,13) = "b" + │ │ ├── opening_loc: (112,13)-(112,14) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (112,14)-(112,17)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (112,14)-(112,17)) + │ │ ├── closing_loc: (112,17)-(112,18) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (112,0)-(112,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (112,5)-(112,6) = "(" + │ ├── rparen_loc: (112,9)-(112,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (112,20)-(112,23) = "end" + ├── @ DefNode (location: (114,0)-(114,29)) + │ ├── name: :a + │ ├── name_loc: (114,4)-(114,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (114,6)-(114,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (114,6)-(114,9)) + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (114,12)-(114,24)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (114,12)-(114,24)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (114,12)-(114,13) = "b" + │ │ ├── opening_loc: (114,13)-(114,14) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (114,14)-(114,23)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (114,0)-(114,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (114,5)-(114,6) = "(" + │ ├── rparen_loc: (114,9)-(114,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (114,26)-(114,29) = "end" + ├── @ DefNode (location: (116,0)-(117,3)) + │ ├── name: :a + │ ├── name_loc: (116,12)-(116,13) = "a" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (116,4)-(116,11)) + │ │ ├── body: + │ │ │ @ LocalVariableWriteNode (location: (116,5)-(116,10)) + │ │ │ ├── name: :c + │ │ │ ├── depth: 0 + │ │ │ ├── name_loc: (116,5)-(116,6) = "c" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (116,9)-(116,10)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (116,9)-(116,10) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: (116,7)-(116,8) = "=" + │ │ ├── opening_loc: (116,4)-(116,5) = "(" + │ │ └── closing_loc: (116,10)-(116,11) = ")" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (116,0)-(116,3) = "def" + │ ├── operator_loc: (116,11)-(116,12) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (117,0)-(117,3) = "end" + ├── @ DefNode (location: (119,0)-(120,3)) + │ ├── name: :a + │ ├── name_loc: (119,4)-(119,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (119,6)-(119,8)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: + │ │ @ BlockParameterNode (location: (119,6)-(119,8)) + │ │ ├── name: :b + │ │ ├── name_loc: (119,7)-(119,8) = "b" + │ │ └── operator_loc: (119,6)-(119,7) = "&" + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (119,0)-(119,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (120,0)-(120,3) = "end" + ├── @ DefNode (location: (122,0)-(123,3)) + │ ├── name: :a + │ ├── name_loc: (122,4)-(122,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (122,6)-(122,7)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: + │ │ @ BlockParameterNode (location: (122,6)-(122,7)) + │ │ ├── name: nil + │ │ ├── name_loc: ∅ + │ │ └── operator_loc: (122,6)-(122,7) = "&" + │ ├── body: ∅ + │ ├── locals: [:&] + │ ├── def_keyword_loc: (122,0)-(122,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (122,5)-(122,6) = "(" + │ ├── rparen_loc: (122,7)-(122,8) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (123,0)-(123,3) = "end" + ├── @ DefNode (location: (125,0)-(126,3)) + │ ├── name: :a + │ ├── name_loc: (125,10)-(125,11) = "a" + │ ├── receiver: + │ │ @ ClassVariableReadNode (location: (125,4)-(125,9)) + │ │ └── name: :@@var + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (125,0)-(125,3) = "def" + │ ├── operator_loc: (125,9)-(125,10) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (126,0)-(126,3) = "end" + ├── @ DefNode (location: (128,0)-(129,3)) + │ ├── name: :C + │ ├── name_loc: (128,12)-(128,13) = "C" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (128,4)-(128,11)) + │ │ ├── body: + │ │ │ @ LocalVariableWriteNode (location: (128,5)-(128,10)) + │ │ │ ├── name: :a + │ │ │ ├── depth: 0 + │ │ │ ├── name_loc: (128,5)-(128,6) = "a" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (128,9)-(128,10)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (128,9)-(128,10) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: (128,7)-(128,8) = "=" + │ │ ├── opening_loc: (128,4)-(128,5) = "(" + │ │ └── closing_loc: (128,10)-(128,11) = ")" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (128,0)-(128,3) = "def" + │ ├── operator_loc: (128,11)-(128,12) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (129,0)-(129,3) = "end" + ├── @ DefNode (location: (131,0)-(131,28)) + │ ├── name: :Array_function + │ ├── name_loc: (131,9)-(131,23) = "Array_function" + │ ├── receiver: + │ │ @ SelfNode (location: (131,4)-(131,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (131,0)-(131,3) = "def" + │ ├── operator_loc: (131,8)-(131,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (131,25)-(131,28) = "end" + ├── @ ConstantWriteNode (location: (133,0)-(133,9)) + │ ├── name: :Const + │ ├── name_loc: (133,0)-(133,5) = "Const" + │ ├── value: + │ │ @ IntegerNode (location: (133,8)-(133,9)) + │ │ └── flags: decimal + │ └── operator_loc: (133,6)-(133,7) = "=" + ├── @ DefNode (location: (133,11)-(134,3)) + │ ├── name: :a + │ ├── name_loc: (133,21)-(133,22) = "a" + │ ├── receiver: + │ │ @ ConstantReadNode (location: (133,15)-(133,20)) + │ │ └── name: :Const + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (133,11)-(133,14) = "def" + │ ├── operator_loc: (133,20)-(133,21) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (134,0)-(134,3) = "end" + ├── @ DefNode (location: (136,0)-(136,31)) + │ ├── name: :a + │ ├── name_loc: (136,4)-(136,5) = "a" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (136,6)-(136,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (136,6)-(136,9)) + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (136,12)-(136,26)) + │ │ └── body: (length: 1) + │ │ └── @ InterpolatedStringNode (location: (136,12)-(136,26)) + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (136,18)-(136,19) = "b" + │ │ │ │ ├── opening_loc: (136,19)-(136,20) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (136,20)-(136,23)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ ForwardingArgumentsNode (location: (136,20)-(136,23)) + │ │ │ │ ├── closing_loc: (136,23)-(136,24) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "b" + │ │ │ └── closing_loc: (136,24)-(136,25) = "}" + │ │ └── closing_loc: (136,25)-(136,26) = "\"" + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (136,0)-(136,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (136,5)-(136,6) = "(" + │ ├── rparen_loc: (136,9)-(136,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (136,28)-(136,31) = "end" + ├── @ DefNode (location: (138,0)-(140,3)) + │ ├── name: :foo + │ ├── name_loc: (138,4)-(138,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (139,2)-(139,30)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (139,2)-(139,30)) + │ │ ├── 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) = "." + │ │ ├── message_loc: (139,5)-(139,10) = "merge" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (139,11)-(139,30)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ KeywordHashNode (location: (139,11)-(139,30)) + │ │ │ └── elements: (length: 3) + │ │ │ ├── @ AssocSplatNode (location: (139,11)-(139,16)) + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (139,13)-(139,16)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (139,13)-(139,16) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ └── operator_loc: (139,11)-(139,13) = "**" + │ │ │ ├── @ AssocSplatNode (location: (139,18)-(139,23)) + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (139,20)-(139,23)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (139,20)-(139,23) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── operator_loc: (139,18)-(139,20) = "**" + │ │ │ └── @ AssocSplatNode (location: (139,25)-(139,30)) + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (139,27)-(139,30)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (139,27)-(139,30) = "qux" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "qux" + │ │ │ └── operator_loc: (139,25)-(139,27) = "**" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "merge" + │ ├── locals: [] + │ ├── def_keyword_loc: (138,0)-(138,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (140,0)-(140,3) = "end" + ├── @ DefNode (location: (142,0)-(143,3)) + │ ├── name: :bar + │ ├── name_loc: (142,4)-(142,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (142,8)-(142,19)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (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)) + │ │ │ │ ├── left: + │ │ │ │ │ @ IntegerNode (location: (142,12)-(142,13)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── right: + │ │ │ │ │ @ IntegerNode (location: (142,16)-(142,18)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── operator_loc: (142,13)-(142,16) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (142,11)-(142,12) = "(" + │ │ │ └── closing_loc: (142,18)-(142,19) = ")" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (142,0)-(142,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (142,7)-(142,8) = "(" + │ ├── rparen_loc: (142,19)-(142,20) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (143,0)-(143,3) = "end" + ├── @ DefNode (location: (145,0)-(146,3)) + │ ├── name: :bar + │ ├── name_loc: (145,4)-(145,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (145,8)-(145,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (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)) + │ │ │ │ ├── left: ∅ + │ │ │ │ ├── right: + │ │ │ │ │ @ IntegerNode (location: (145,15)-(145,17)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── operator_loc: (145,12)-(145,15) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (145,11)-(145,12) = "(" + │ │ │ └── closing_loc: (145,17)-(145,18) = ")" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (145,0)-(145,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (145,7)-(145,8) = "(" + │ ├── rparen_loc: (145,18)-(145,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (146,0)-(146,3) = "end" + ├── @ DefNode (location: (148,0)-(149,3)) + │ ├── name: :bar + │ ├── name_loc: (148,4)-(148,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (148,8)-(148,17)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (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)) + │ │ │ │ ├── left: + │ │ │ │ │ @ IntegerNode (location: (148,12)-(148,13)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── right: ∅ + │ │ │ │ ├── operator_loc: (148,13)-(148,16) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (148,11)-(148,12) = "(" + │ │ │ └── closing_loc: (148,16)-(148,17) = ")" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (148,0)-(148,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (148,7)-(148,8) = "(" + │ ├── rparen_loc: (148,17)-(148,18) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (149,0)-(149,3) = "end" + ├── @ DefNode (location: (151,0)-(152,3)) + │ ├── name: :bar + │ ├── name_loc: (151,4)-(151,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (151,8)-(151,20)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (151,8)-(151,20)) + │ │ │ ├── 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)) + │ │ │ │ ├── left: + │ │ │ │ │ @ IntegerNode (location: (151,13)-(151,14)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── right: + │ │ │ │ │ @ IntegerNode (location: (151,17)-(151,19)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── operator_loc: (151,14)-(151,17) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (151,12)-(151,13) = "(" + │ │ │ └── closing_loc: (151,19)-(151,20) = ")" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (151,0)-(151,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (151,7)-(151,8) = "(" + │ ├── rparen_loc: (151,20)-(151,21) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (152,0)-(152,3) = "end" + ├── @ DefNode (location: (154,0)-(155,3)) + │ ├── name: :bar + │ ├── name_loc: (154,4)-(154,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (154,8)-(154,19)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (154,8)-(154,19)) + │ │ │ ├── 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)) + │ │ │ │ ├── left: ∅ + │ │ │ │ ├── right: + │ │ │ │ │ @ IntegerNode (location: (154,16)-(154,18)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── operator_loc: (154,13)-(154,16) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (154,12)-(154,13) = "(" + │ │ │ └── closing_loc: (154,18)-(154,19) = ")" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (154,0)-(154,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (154,7)-(154,8) = "(" + │ ├── rparen_loc: (154,19)-(154,20) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (155,0)-(155,3) = "end" + ├── @ DefNode (location: (157,0)-(158,3)) + │ ├── name: :bar + │ ├── name_loc: (157,4)-(157,7) = "bar" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (157,8)-(157,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (157,8)-(157,18)) + │ │ │ ├── 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)) + │ │ │ │ ├── left: + │ │ │ │ │ @ IntegerNode (location: (157,13)-(157,14)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── right: ∅ + │ │ │ │ ├── operator_loc: (157,14)-(157,17) = "..." + │ │ │ │ └── flags: exclude_end + │ │ │ ├── opening_loc: (157,12)-(157,13) = "(" + │ │ │ └── closing_loc: (157,17)-(157,18) = ")" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (157,0)-(157,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (157,7)-(157,8) = "(" + │ ├── rparen_loc: (157,18)-(157,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (158,0)-(158,3) = "end" + ├── @ DefNode (location: (160,0)-(162,3)) + │ ├── name: :method + │ ├── name_loc: (160,4)-(160,10) = "method" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (160,11)-(160,12)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (160,11)-(160,12)) + │ │ │ └── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (161,2)-(161,6)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (161,2)-(161,6) = "item" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "item" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (161,7)-(161,9) = ">>" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (161,10)-(161,14)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (161,10)-(161,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (161,10)-(161,11) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (161,12)-(161,14)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (161,12)-(161,13) = "{" + │ │ │ │ └── closing_loc: (161,13)-(161,14) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "a" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: ">>" + │ ├── locals: [:a] + │ ├── def_keyword_loc: (160,0)-(160,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (160,10)-(160,11) = "(" + │ ├── rparen_loc: (160,12)-(160,13) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (162,0)-(162,3) = "end" + ├── @ 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] + │ ├── 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: [] + ├── 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" diff --git a/test/prism/snapshots/modules.txt b/test/prism/snapshots/modules.txt new file mode 100644 index 00000000000000..94f4bdb8ebd1df --- /dev/null +++ b/test/prism/snapshots/modules.txt @@ -0,0 +1,179 @@ +@ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,9)-(3,12) = "bbb" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bbb" + │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,7)-(5,8) = "m" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "m" + │ │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ ConstantReadNode (location: (14,7)-(14,8)) + │ │ │ │ └── name: :A + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (14,8)-(14,10) = "[]" + │ │ │ ├── opening_loc: (14,8)-(14,9) = "[" + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: (14,9)-(14,10) = "]" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "[]" + │ │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ ConstantReadNode (location: (17,7)-(17,8)) + │ │ │ └── name: :A + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,8)-(17,11) = "[1]" + │ │ ├── opening_loc: (17,8)-(17,9) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (17,9)-(17,10)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (17,9)-(17,10)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (17,10)-(17,11) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]" + │ ├── 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 new file mode 100644 index 00000000000000..bf752571043965 --- /dev/null +++ b/test/prism/snapshots/newline_terminated.txt @@ -0,0 +1,107 @@ +@ ProgramNode (location: (3,0)-(40,0)) +├── locals: [] +└── statements: + @ StatementsNode (location: (3,0)-(40,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)-(8,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (7,0)-(7,0) = "%\n" + │ ├── content_loc: (8,0)-(8,3) = "abc" + │ ├── closing_loc: (8,3)-(8,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)-(12,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (11,0)-(11,0) = "%\n" + │ ├── content_loc: (12,0)-(12,3) = "abc" + │ ├── closing_loc: (12,3)-(12,0) = "\n" + │ └── unescaped: "abc" + ├── @ StringNode (location: (14,0)-(15,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (14,0)-(14,0) = "%\n" + │ ├── content_loc: (15,0)-(15,4) = "\rabc" + │ ├── closing_loc: (15,4)-(15,0) = "\n" + │ └── unescaped: "\rabc" + ├── @ StringNode (location: (17,0)-(18,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (17,0)-(17,0) = "%\n" + │ ├── content_loc: (18,0)-(18,4) = "\rabc" + │ ├── closing_loc: (18,4)-(18,0) = "\n" + │ └── unescaped: "\rabc" + ├── @ StringNode (location: (20,0)-(21,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (20,0)-(20,0) = "%\n" + │ ├── content_loc: (21,0)-(21,3) = "abc" + │ ├── closing_loc: (21,3)-(21,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)-(25,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (24,0)-(24,0) = "%\n" + │ ├── content_loc: (25,0)-(25,3) = "abc" + │ ├── closing_loc: (25,3)-(25,0) = "\n" + │ └── unescaped: "abc" + ├── @ StringNode (location: (27,0)-(28,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (27,0)-(27,0) = "%\n" + │ ├── content_loc: (28,0)-(28,3) = "abc" + │ ├── closing_loc: (28,3)-(28,0) = "\n" + │ └── unescaped: "abc" + ├── @ StringNode (location: (30,0)-(31,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (30,0)-(30,0) = "%\n" + │ ├── content_loc: (31,0)-(31,3) = "foo" + │ ├── closing_loc: (31,3)-(31,0) = "\n" + │ └── unescaped: "foo" + ├── @ StringNode (location: (33,0)-(34,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (33,0)-(33,0) = "%q\n" + │ ├── content_loc: (34,0)-(34,3) = "foo" + │ ├── closing_loc: (34,3)-(34,0) = "\n" + │ └── unescaped: "foo" + ├── @ StringNode (location: (36,0)-(37,0)) + │ ├── flags: ∅ + │ ├── opening_loc: (36,0)-(36,0) = "%Q\n" + │ ├── content_loc: (37,0)-(37,3) = "foo" + │ ├── closing_loc: (37,3)-(37,0) = "\n" + │ └── unescaped: "foo" + └── @ RegularExpressionNode (location: (39,0)-(40,0)) + ├── opening_loc: (39,0)-(39,0) = "%r\n" + ├── content_loc: (40,0)-(40,3) = "foo" + ├── closing_loc: (40,3)-(40,0) = "\n" + ├── unescaped: "foo" + └── flags: ∅ diff --git a/test/prism/snapshots/next.txt b/test/prism/snapshots/next.txt new file mode 100644 index 00000000000000..508cb1e5397662 --- /dev/null +++ b/test/prism/snapshots/next.txt @@ -0,0 +1,123 @@ +@ 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ ArrayNode (location: (12,5)-(12,14)) + │ │ ├── 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)) + │ │ └── 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)) + │ │ └── 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)) + │ └── 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 new file mode 100644 index 00000000000000..cbadbcf911784f --- /dev/null +++ b/test/prism/snapshots/nils.txt @@ -0,0 +1,32 @@ +@ 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 new file mode 100644 index 00000000000000..725b94c4e556b8 --- /dev/null +++ b/test/prism/snapshots/non_alphanumeric_methods.txt @@ -0,0 +1,501 @@ +@ ProgramNode (location: (1,0)-(105,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(105,3)) + └── body: (length: 36) + ├── @ DefNode (location: (1,0)-(2,3)) + │ ├── name: :! + │ ├── name_loc: (1,4)-(1,5) = "!" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (2,0)-(2,3) = "end" + ├── @ DefNode (location: (4,0)-(5,3)) + │ ├── name: :!= + │ ├── name_loc: (4,4)-(4,6) = "!=" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (4,0)-(4,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,0)-(5,3) = "end" + ├── @ DefNode (location: (7,0)-(8,3)) + │ ├── name: :!~ + │ ├── name_loc: (7,4)-(7,6) = "!~" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (8,0)-(8,3) = "end" + ├── @ DefNode (location: (10,0)-(11,3)) + │ ├── name: :% + │ ├── name_loc: (10,4)-(10,5) = "%" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (10,0)-(10,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (11,0)-(11,3) = "end" + ├── @ DefNode (location: (13,0)-(14,3)) + │ ├── name: :+ + │ ├── name_loc: (13,9)-(13,10) = "+" + │ ├── receiver: + │ │ @ SelfNode (location: (13,4)-(13,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (13,0)-(13,3) = "def" + │ ├── operator_loc: (13,8)-(13,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (14,0)-(14,3) = "end" + ├── @ DefNode (location: (16,0)-(17,3)) + │ ├── name: :& + │ ├── name_loc: (16,4)-(16,5) = "&" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (16,0)-(16,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (17,0)-(17,3) = "end" + ├── @ DefNode (location: (19,0)-(20,3)) + │ ├── name: :* + │ ├── name_loc: (19,4)-(19,5) = "*" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (19,0)-(19,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (20,0)-(20,3) = "end" + ├── @ DefNode (location: (22,0)-(23,3)) + │ ├── name: :** + │ ├── name_loc: (22,4)-(22,6) = "**" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (22,0)-(22,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (23,0)-(23,3) = "end" + ├── @ StringNode (location: (25,0)-(25,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (25,0)-(25,2) = "%|" + │ ├── content_loc: (25,2)-(25,5) = "abc" + │ ├── closing_loc: (25,5)-(25,6) = "|" + │ └── unescaped: "abc" + ├── @ DefNode (location: (27,0)-(28,3)) + │ ├── name: :+ + │ ├── name_loc: (27,4)-(27,5) = "+" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (27,6)-(27,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ KeywordRestParameterNode (location: (27,6)-(27,9)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (27,8)-(27,9) = "b" + │ │ │ └── operator_loc: (27,6)-(27,8) = "**" + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (27,0)-(27,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (28,0)-(28,3) = "end" + ├── @ DefNode (location: (30,0)-(31,3)) + │ ├── name: :+ + │ ├── name_loc: (30,4)-(30,5) = "+" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (30,0)-(30,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (30,5)-(30,6) = "(" + │ ├── rparen_loc: (30,6)-(30,7) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (31,0)-(31,3) = "end" + ├── @ DefNode (location: (33,0)-(34,3)) + │ ├── name: :+ + │ ├── name_loc: (33,4)-(33,5) = "+" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (33,6)-(33,7)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (33,6)-(33,7)) + │ │ │ └── name: :b + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (33,0)-(33,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (34,0)-(34,3) = "end" + ├── @ DefNode (location: (36,0)-(37,3)) + │ ├── name: :+ + │ ├── name_loc: (36,9)-(36,10) = "+" + │ ├── receiver: + │ │ @ SelfNode (location: (36,4)-(36,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (36,0)-(36,3) = "def" + │ ├── operator_loc: (36,8)-(36,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (37,0)-(37,3) = "end" + ├── @ DefNode (location: (39,0)-(40,3)) + │ ├── name: :+ + │ ├── name_loc: (39,4)-(39,5) = "+" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (39,0)-(39,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (40,0)-(40,3) = "end" + ├── @ DefNode (location: (42,0)-(43,3)) + │ ├── name: :+@ + │ ├── name_loc: (42,4)-(42,6) = "+@" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (42,0)-(42,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (43,0)-(43,3) = "end" + ├── @ DefNode (location: (45,0)-(46,3)) + │ ├── name: :- + │ ├── name_loc: (45,4)-(45,5) = "-" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (45,0)-(45,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (46,0)-(46,3) = "end" + ├── @ DefNode (location: (48,0)-(48,11)) + │ ├── name: :- + │ ├── name_loc: (48,6)-(48,7) = "-" + │ ├── receiver: + │ │ @ CallNode (location: (48,4)-(48,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (48,4)-(48,5) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (48,0)-(48,3) = "def" + │ ├── operator_loc: (48,5)-(48,6) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (48,8)-(48,11) = "end" + ├── @ DefNode (location: (50,0)-(51,3)) + │ ├── name: :-@ + │ ├── name_loc: (50,4)-(50,6) = "-@" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (50,0)-(50,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (51,0)-(51,3) = "end" + ├── @ DefNode (location: (53,0)-(54,3)) + │ ├── name: :/ + │ ├── name_loc: (53,4)-(53,5) = "/" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (53,0)-(53,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (54,0)-(54,3) = "end" + ├── @ DefNode (location: (56,0)-(57,3)) + │ ├── name: :< + │ ├── name_loc: (56,4)-(56,5) = "<" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (56,0)-(56,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (57,0)-(57,3) = "end" + ├── @ DefNode (location: (59,0)-(60,3)) + │ ├── name: :<< + │ ├── name_loc: (59,4)-(59,6) = "<<" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (59,0)-(59,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (60,0)-(60,3) = "end" + ├── @ DefNode (location: (62,0)-(63,3)) + │ ├── name: :<= + │ ├── name_loc: (62,4)-(62,6) = "<=" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (62,0)-(62,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (63,0)-(63,3) = "end" + ├── @ DefNode (location: (65,0)-(66,3)) + │ ├── name: :<=> + │ ├── name_loc: (65,4)-(65,7) = "<=>" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (65,0)-(65,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (66,0)-(66,3) = "end" + ├── @ DefNode (location: (68,0)-(69,3)) + │ ├── name: :== + │ ├── name_loc: (68,4)-(68,6) = "==" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (68,0)-(68,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (69,0)-(69,3) = "end" + ├── @ DefNode (location: (71,0)-(72,3)) + │ ├── name: :=== + │ ├── name_loc: (71,4)-(71,7) = "===" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (71,0)-(71,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (72,0)-(72,3) = "end" + ├── @ DefNode (location: (74,0)-(75,3)) + │ ├── name: :=~ + │ ├── name_loc: (74,4)-(74,6) = "=~" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (74,0)-(74,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (75,0)-(75,3) = "end" + ├── @ DefNode (location: (77,0)-(78,3)) + │ ├── name: :> + │ ├── name_loc: (77,4)-(77,5) = ">" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (77,0)-(77,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (78,0)-(78,3) = "end" + ├── @ DefNode (location: (80,0)-(81,3)) + │ ├── name: :>= + │ ├── name_loc: (80,4)-(80,6) = ">=" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (80,0)-(80,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (81,0)-(81,3) = "end" + ├── @ DefNode (location: (83,0)-(84,3)) + │ ├── name: :>> + │ ├── name_loc: (83,4)-(83,6) = ">>" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (83,0)-(83,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (84,0)-(84,3) = "end" + ├── @ DefNode (location: (86,0)-(87,3)) + │ ├── name: :[] + │ ├── name_loc: (86,4)-(86,6) = "[]" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (86,0)-(86,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (87,0)-(87,3) = "end" + ├── @ DefNode (location: (89,0)-(90,3)) + │ ├── name: :[]= + │ ├── name_loc: (89,4)-(89,7) = "[]=" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (89,0)-(89,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (90,0)-(90,3) = "end" + ├── @ DefNode (location: (92,0)-(93,3)) + │ ├── name: :^ + │ ├── name_loc: (92,4)-(92,5) = "^" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (92,0)-(92,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (93,0)-(93,3) = "end" + ├── @ DefNode (location: (95,0)-(96,3)) + │ ├── name: :` + │ ├── name_loc: (95,4)-(95,5) = "`" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (95,0)-(95,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (96,0)-(96,3) = "end" + ├── @ DefNode (location: (98,0)-(99,3)) + │ ├── name: :` + │ ├── name_loc: (98,9)-(98,10) = "`" + │ ├── receiver: + │ │ @ SelfNode (location: (98,4)-(98,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (98,0)-(98,3) = "def" + │ ├── operator_loc: (98,8)-(98,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (99,0)-(99,3) = "end" + ├── @ DefNode (location: (101,0)-(102,3)) + │ ├── name: :| + │ ├── name_loc: (101,4)-(101,5) = "|" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (101,0)-(101,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (102,0)-(102,3) = "end" + └── @ DefNode (location: (104,0)-(105,3)) + ├── name: :~ + ├── name_loc: (104,4)-(104,5) = "~" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (104,0)-(104,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (105,0)-(105,3) = "end" diff --git a/test/prism/snapshots/not.txt b/test/prism/snapshots/not.txt new file mode 100644 index 00000000000000..6f4255b48a568b --- /dev/null +++ b/test/prism/snapshots/not.txt @@ -0,0 +1,351 @@ +@ ProgramNode (location: (1,0)-(37,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(37,16)) + └── body: (length: 10) + ├── @ AndNode (location: (1,0)-(1,19)) + │ ├── left: + │ │ @ CallNode (location: (1,0)-(1,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (1,4)-(1,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,4)-(1,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── right: + │ │ @ CallNode (location: (1,12)-(1,19)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (1,16)-(1,19)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,16)-(1,19) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,12)-(1,15) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ └── operator_loc: (1,8)-(1,11) = "and" + ├── @ CallNode (location: (3,0)-(3,16)) + │ ├── receiver: + │ │ @ AndNode (location: (3,4)-(3,15)) + │ │ ├── left: + │ │ │ @ CallNode (location: (3,4)-(3,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,4)-(3,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── right: + │ │ │ @ CallNode (location: (3,12)-(3,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,12)-(3,15) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── operator_loc: (3,8)-(3,11) = "and" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "not" + │ ├── opening_loc: (3,3)-(3,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (3,15)-(3,16) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (5,0)-(5,7)) + │ ├── receiver: + │ │ @ CallNode (location: (5,4)-(5,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,4)-(5,7) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "not" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ AndNode (location: (7,0)-(8,5)) + │ ├── left: + │ │ @ CallNode (location: (7,0)-(7,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (7,4)-(7,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,4)-(7,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,3) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── right: + │ │ @ CallNode (location: (7,12)-(8,5)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (8,2)-(8,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (8,2)-(8,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,12)-(7,15) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ └── operator_loc: (7,8)-(7,11) = "and" + ├── @ AndNode (location: (11,0)-(13,5)) + │ ├── left: + │ │ @ CallNode (location: (11,0)-(11,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (11,4)-(11,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,4)-(11,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,3) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── right: + │ │ @ CallNode (location: (12,4)-(13,5)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (13,2)-(13,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,2)-(13,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (12,4)-(12,7) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ └── operator_loc: (11,8)-(11,11) = "and" + ├── @ AndNode (location: (16,0)-(20,5)) + │ ├── left: + │ │ @ CallNode (location: (16,0)-(16,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (16,4)-(16,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (16,4)-(16,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,0)-(16,3) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ ├── right: + │ │ @ CallNode (location: (17,2)-(20,5)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (20,2)-(20,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (20,2)-(20,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,2)-(17,5) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ └── operator_loc: (16,8)-(16,11) = "and" + ├── @ CallNode (location: (22,0)-(25,1)) + │ ├── receiver: + │ │ @ CallNode (location: (22,4)-(22,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (22,4)-(22,7) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (22,0)-(22,3) = "not" + │ ├── opening_loc: (22,3)-(22,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (25,0)-(25,1) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (27,0)-(33,3)) + │ ├── receiver: + │ │ @ CallNode (location: (30,0)-(30,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,0)-(30,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,0)-(27,3) = "not" + │ ├── opening_loc: (27,3)-(27,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (33,2)-(33,3) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (35,0)-(35,14)) + │ ├── receiver: + │ │ @ FlipFlopNode (location: (35,4)-(35,14)) + │ │ ├── left: + │ │ │ @ CallNode (location: (35,4)-(35,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (35,4)-(35,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── right: + │ │ │ @ CallNode (location: (35,11)-(35,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (35,11)-(35,14) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── operator_loc: (35,8)-(35,10) = ".." + │ │ └── flags: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,3) = "not" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + └── @ CallNode (location: (37,0)-(37,16)) + ├── receiver: + │ @ ParenthesesNode (location: (37,4)-(37,16)) + │ ├── body: + │ │ @ StatementsNode (location: (37,5)-(37,15)) + │ │ └── body: (length: 1) + │ │ └── @ FlipFlopNode (location: (37,5)-(37,15)) + │ │ ├── left: + │ │ │ @ CallNode (location: (37,5)-(37,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,5)-(37,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── right: + │ │ │ @ CallNode (location: (37,12)-(37,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,12)-(37,15) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── operator_loc: (37,9)-(37,11) = ".." + │ │ └── flags: ∅ + │ ├── opening_loc: (37,4)-(37,5) = "(" + │ └── closing_loc: (37,15)-(37,16) = ")" + ├── call_operator_loc: ∅ + ├── message_loc: (37,0)-(37,3) = "not" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/numbers.txt b/test/prism/snapshots/numbers.txt new file mode 100644 index 00000000000000..ca31480f67bea2 --- /dev/null +++ b/test/prism/snapshots/numbers.txt @@ -0,0 +1,102 @@ +@ ProgramNode (location: (1,0)-(63,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(63,5)) + └── body: (length: 32) + ├── @ 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 + ├── @ ImaginaryNode (location: (47,0)-(47,5)) + │ └── numeric: + │ @ RationalNode (location: (47,0)-(47,4)) + │ └── numeric: + │ @ FloatNode (location: (47,0)-(47,3)) + ├── @ ImaginaryNode (location: (49,0)-(49,4)) + │ └── numeric: + │ @ RationalNode (location: (49,0)-(49,3)) + │ └── numeric: + │ @ IntegerNode (location: (49,0)-(49,2)) + │ └── flags: decimal + ├── @ ImaginaryNode (location: (51,0)-(51,6)) + │ └── numeric: + │ @ RationalNode (location: (51,0)-(51,5)) + │ └── numeric: + │ @ FloatNode (location: (51,0)-(51,4)) + ├── @ RationalNode (location: (53,0)-(53,4)) + │ └── numeric: + │ @ IntegerNode (location: (53,0)-(53,3)) + │ └── flags: octal + ├── @ ImaginaryNode (location: (55,0)-(55,4)) + │ └── numeric: + │ @ IntegerNode (location: (55,0)-(55,3)) + │ └── flags: octal + ├── @ ImaginaryNode (location: (57,0)-(57,5)) + │ └── numeric: + │ @ RationalNode (location: (57,0)-(57,4)) + │ └── numeric: + │ @ IntegerNode (location: (57,0)-(57,3)) + │ └── flags: octal + ├── @ RationalNode (location: (59,0)-(59,4)) + │ └── numeric: + │ @ IntegerNode (location: (59,0)-(59,3)) + │ └── flags: decimal + ├── @ ImaginaryNode (location: (61,0)-(61,4)) + │ └── numeric: + │ @ IntegerNode (location: (61,0)-(61,3)) + │ └── flags: decimal + └── @ ImaginaryNode (location: (63,0)-(63,5)) + └── numeric: + @ RationalNode (location: (63,0)-(63,4)) + └── numeric: + @ IntegerNode (location: (63,0)-(63,3)) + └── flags: binary diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt new file mode 100644 index 00000000000000..2cb524e1e05cbf --- /dev/null +++ b/test/prism/snapshots/patterns.txt @@ -0,0 +1,4501 @@ +@ ProgramNode (location: (1,0)-(192,1)) +├── locals: [:bar, :baz, :qux, :b, :a] +└── statements: + @ StatementsNode (location: (1,0)-(192,1)) + └── body: (length: 170) + ├── @ MatchRequiredNode (location: (1,0)-(1,10)) + │ ├── value: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,0)-(2,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (4,0)-(4,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,0)-(6,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (6,7)-(6,11)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (7,7)-(7,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (8,0)-(8,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (8,7)-(8,13)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,0)-(9,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RegularExpressionNode (location: (9,7)-(9,12)) + │ │ ├── opening_loc: (9,7)-(9,8) = "/" + │ │ ├── content_loc: (9,8)-(9,11) = "foo" + │ │ ├── closing_loc: (9,11)-(9,12) = "/" + │ │ ├── unescaped: "foo" + │ │ └── flags: ∅ + │ └── operator_loc: (9,4)-(9,6) = "=>" + ├── @ MatchRequiredNode (location: (10,0)-(10,12)) + │ ├── value: + │ │ @ CallNode (location: (10,0)-(10,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,0)-(10,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ XStringNode (location: (10,7)-(10,12)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ XStringNode (location: (11,7)-(11,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (12,0)-(12,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (12,7)-(12,14)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ SymbolNode (location: (12,10)-(12,13)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,0)-(13,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (13,7)-(13,14)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ SymbolNode (location: (13,10)-(13,13)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,0)-(14,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (14,7)-(14,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,0)-(15,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (15,7)-(15,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,0)-(16,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,0)-(17,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (18,0)-(18,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,0)-(19,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (20,0)-(20,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,0)-(21,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (22,0)-(22,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,0)-(23,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (24,0)-(24,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,0)-(25,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (26,0)-(26,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ LambdaNode (location: (26,7)-(26,17)) + │ │ ├── locals: [] + │ │ ├── operator_loc: (26,7)-(26,9) = "->" + │ │ ├── opening_loc: (26,10)-(26,11) = "{" + │ │ ├── closing_loc: (26,16)-(26,17) = "}" + │ │ ├── parameters: ∅ + │ │ └── body: + │ │ @ StatementsNode (location: (26,12)-(26,15)) + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (26,12)-(26,15)) + │ │ ├── name: :bar + │ │ └── depth: 1 + │ └── operator_loc: (26,4)-(26,6) = "=>" + ├── @ MatchRequiredNode (location: (28,0)-(28,13)) + │ ├── value: + │ │ @ CallNode (location: (28,0)-(28,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,0)-(28,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (28,7)-(28,13)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (28,7)-(28,8)) + │ │ │ └── flags: decimal + │ │ ├── right: + │ │ │ @ IntegerNode (location: (28,12)-(28,13)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (28,9)-(28,11) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (28,4)-(28,6) = "=>" + ├── @ MatchRequiredNode (location: (29,0)-(29,17)) + │ ├── value: + │ │ @ CallNode (location: (29,0)-(29,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (29,0)-(29,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (29,7)-(29,17)) + │ │ ├── left: + │ │ │ @ FloatNode (location: (29,7)-(29,10)) + │ │ ├── right: + │ │ │ @ FloatNode (location: (29,14)-(29,17)) + │ │ ├── operator_loc: (29,11)-(29,13) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (29,4)-(29,6) = "=>" + ├── @ MatchRequiredNode (location: (30,0)-(30,15)) + │ ├── value: + │ │ @ CallNode (location: (30,0)-(30,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,0)-(30,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (30,7)-(30,15)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (30,4)-(30,6) = "=>" + ├── @ MatchRequiredNode (location: (31,0)-(31,15)) + │ ├── value: + │ │ @ CallNode (location: (31,0)-(31,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,0)-(31,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (31,7)-(31,15)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (31,4)-(31,6) = "=>" + ├── @ MatchRequiredNode (location: (32,0)-(32,19)) + │ ├── value: + │ │ @ CallNode (location: (32,0)-(32,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,0)-(32,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (32,7)-(32,19)) + │ │ ├── left: + │ │ │ @ SymbolNode (location: (32,7)-(32,11)) + │ │ │ ├── opening_loc: (32,7)-(32,8) = ":" + │ │ │ ├── value_loc: (32,8)-(32,11) = "foo" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo" + │ │ ├── right: + │ │ │ @ SymbolNode (location: (32,15)-(32,19)) + │ │ │ ├── opening_loc: (32,15)-(32,16) = ":" + │ │ │ ├── value_loc: (32,16)-(32,19) = "foo" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo" + │ │ ├── operator_loc: (32,12)-(32,14) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (32,4)-(32,6) = "=>" + ├── @ MatchRequiredNode (location: (33,0)-(33,25)) + │ ├── value: + │ │ @ CallNode (location: (33,0)-(33,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (33,0)-(33,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (33,7)-(33,25)) + │ │ ├── left: + │ │ │ @ SymbolNode (location: (33,7)-(33,14)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (33,4)-(33,6) = "=>" + ├── @ MatchRequiredNode (location: (34,0)-(34,23)) + │ ├── value: + │ │ @ CallNode (location: (34,0)-(34,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (34,0)-(34,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (34,7)-(34,23)) + │ │ ├── left: + │ │ │ @ SymbolNode (location: (34,7)-(34,13)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (34,4)-(34,6) = "=>" + ├── @ MatchRequiredNode (location: (35,0)-(35,21)) + │ ├── value: + │ │ @ CallNode (location: (35,0)-(35,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,0)-(35,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (35,7)-(35,21)) + │ │ ├── left: + │ │ │ @ RegularExpressionNode (location: (35,7)-(35,12)) + │ │ │ ├── opening_loc: (35,7)-(35,8) = "/" + │ │ │ ├── content_loc: (35,8)-(35,11) = "foo" + │ │ │ ├── closing_loc: (35,11)-(35,12) = "/" + │ │ │ ├── unescaped: "foo" + │ │ │ └── flags: ∅ + │ │ ├── right: + │ │ │ @ RegularExpressionNode (location: (35,16)-(35,21)) + │ │ │ ├── opening_loc: (35,16)-(35,17) = "/" + │ │ │ ├── content_loc: (35,17)-(35,20) = "foo" + │ │ │ ├── closing_loc: (35,20)-(35,21) = "/" + │ │ │ ├── unescaped: "foo" + │ │ │ └── flags: ∅ + │ │ ├── operator_loc: (35,13)-(35,15) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (35,4)-(35,6) = "=>" + ├── @ MatchRequiredNode (location: (36,0)-(36,21)) + │ ├── value: + │ │ @ CallNode (location: (36,0)-(36,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (36,0)-(36,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (36,7)-(36,21)) + │ │ ├── left: + │ │ │ @ XStringNode (location: (36,7)-(36,12)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (36,4)-(36,6) = "=>" + ├── @ MatchRequiredNode (location: (37,0)-(37,25)) + │ ├── value: + │ │ @ CallNode (location: (37,0)-(37,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,0)-(37,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (37,7)-(37,25)) + │ │ ├── left: + │ │ │ @ XStringNode (location: (37,7)-(37,14)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (37,4)-(37,6) = "=>" + ├── @ MatchRequiredNode (location: (38,0)-(38,25)) + │ ├── value: + │ │ @ CallNode (location: (38,0)-(38,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (38,0)-(38,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (38,7)-(38,25)) + │ │ ├── left: + │ │ │ @ ArrayNode (location: (38,7)-(38,14)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (38,10)-(38,13)) + │ │ │ │ ├── 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)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (38,21)-(38,24)) + │ │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (38,4)-(38,6) = "=>" + ├── @ MatchRequiredNode (location: (39,0)-(39,25)) + │ ├── value: + │ │ @ CallNode (location: (39,0)-(39,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,0)-(39,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (39,7)-(39,25)) + │ │ ├── left: + │ │ │ @ ArrayNode (location: (39,7)-(39,14)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (39,10)-(39,13)) + │ │ │ │ ├── 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)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (39,21)-(39,24)) + │ │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (39,4)-(39,6) = "=>" + ├── @ MatchRequiredNode (location: (40,0)-(40,25)) + │ ├── value: + │ │ @ CallNode (location: (40,0)-(40,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (40,0)-(40,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (40,7)-(40,25)) + │ │ ├── left: + │ │ │ @ ArrayNode (location: (40,7)-(40,14)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (40,4)-(40,6) = "=>" + ├── @ MatchRequiredNode (location: (41,0)-(41,25)) + │ ├── value: + │ │ @ CallNode (location: (41,0)-(41,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (41,0)-(41,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (41,7)-(41,25)) + │ │ ├── left: + │ │ │ @ ArrayNode (location: (41,7)-(41,14)) + │ │ │ ├── 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)) + │ │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (41,4)-(41,6) = "=>" + ├── @ MatchRequiredNode (location: (42,0)-(42,25)) + │ ├── value: + │ │ @ CallNode (location: (42,0)-(42,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (42,0)-(42,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (42,7)-(42,25)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (42,4)-(42,6) = "=>" + ├── @ MatchRequiredNode (location: (43,0)-(43,25)) + │ ├── value: + │ │ @ CallNode (location: (43,0)-(43,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (43,0)-(43,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (43,7)-(43,25)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (43,4)-(43,6) = "=>" + ├── @ MatchRequiredNode (location: (44,0)-(44,21)) + │ ├── value: + │ │ @ CallNode (location: (44,0)-(44,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (44,0)-(44,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (44,7)-(44,21)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (44,4)-(44,6) = "=>" + ├── @ MatchRequiredNode (location: (45,0)-(45,17)) + │ ├── value: + │ │ @ CallNode (location: (45,0)-(45,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,0)-(45,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (45,7)-(45,17)) + │ │ ├── left: + │ │ │ @ NilNode (location: (45,7)-(45,10)) + │ │ ├── right: + │ │ │ @ NilNode (location: (45,14)-(45,17)) + │ │ ├── operator_loc: (45,11)-(45,13) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (45,4)-(45,6) = "=>" + ├── @ MatchRequiredNode (location: (46,0)-(46,19)) + │ ├── value: + │ │ @ CallNode (location: (46,0)-(46,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (46,0)-(46,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (46,7)-(46,19)) + │ │ ├── left: + │ │ │ @ SelfNode (location: (46,7)-(46,11)) + │ │ ├── right: + │ │ │ @ SelfNode (location: (46,15)-(46,19)) + │ │ ├── operator_loc: (46,12)-(46,14) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (46,4)-(46,6) = "=>" + ├── @ MatchRequiredNode (location: (47,0)-(47,19)) + │ ├── value: + │ │ @ CallNode (location: (47,0)-(47,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,0)-(47,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (47,7)-(47,19)) + │ │ ├── left: + │ │ │ @ TrueNode (location: (47,7)-(47,11)) + │ │ ├── right: + │ │ │ @ TrueNode (location: (47,15)-(47,19)) + │ │ ├── operator_loc: (47,12)-(47,14) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (47,4)-(47,6) = "=>" + ├── @ MatchRequiredNode (location: (48,0)-(48,21)) + │ ├── value: + │ │ @ CallNode (location: (48,0)-(48,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (48,0)-(48,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (48,7)-(48,21)) + │ │ ├── left: + │ │ │ @ FalseNode (location: (48,7)-(48,12)) + │ │ ├── right: + │ │ │ @ FalseNode (location: (48,16)-(48,21)) + │ │ ├── operator_loc: (48,13)-(48,15) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (48,4)-(48,6) = "=>" + ├── @ MatchRequiredNode (location: (49,0)-(49,27)) + │ ├── value: + │ │ @ CallNode (location: (49,0)-(49,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (49,0)-(49,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (49,7)-(49,27)) + │ │ ├── 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) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (49,4)-(49,6) = "=>" + ├── @ MatchRequiredNode (location: (50,0)-(50,27)) + │ ├── value: + │ │ @ CallNode (location: (50,0)-(50,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (50,0)-(50,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (50,7)-(50,27)) + │ │ ├── left: + │ │ │ @ SourceLineNode (location: (50,7)-(50,15)) + │ │ ├── right: + │ │ │ @ SourceLineNode (location: (50,19)-(50,27)) + │ │ ├── operator_loc: (50,16)-(50,18) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (50,4)-(50,6) = "=>" + ├── @ MatchRequiredNode (location: (51,0)-(51,35)) + │ ├── value: + │ │ @ CallNode (location: (51,0)-(51,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (51,0)-(51,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (51,7)-(51,35)) + │ │ ├── left: + │ │ │ @ SourceEncodingNode (location: (51,7)-(51,19)) + │ │ ├── right: + │ │ │ @ SourceEncodingNode (location: (51,23)-(51,35)) + │ │ ├── operator_loc: (51,20)-(51,22) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (51,4)-(51,6) = "=>" + ├── @ MatchRequiredNode (location: (52,0)-(52,31)) + │ ├── value: + │ │ @ CallNode (location: (52,0)-(52,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (52,0)-(52,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RangeNode (location: (52,7)-(52,31)) + │ │ ├── left: + │ │ │ @ LambdaNode (location: (52,7)-(52,17)) + │ │ │ ├── locals: [] + │ │ │ ├── operator_loc: (52,7)-(52,9) = "->" + │ │ │ ├── opening_loc: (52,10)-(52,11) = "{" + │ │ │ ├── closing_loc: (52,16)-(52,17) = "}" + │ │ │ ├── parameters: ∅ + │ │ │ └── body: + │ │ │ @ StatementsNode (location: (52,12)-(52,15)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (52,12)-(52,15)) + │ │ │ ├── name: :bar + │ │ │ └── depth: 1 + │ │ ├── right: + │ │ │ @ LambdaNode (location: (52,21)-(52,31)) + │ │ │ ├── locals: [] + │ │ │ ├── operator_loc: (52,21)-(52,23) = "->" + │ │ │ ├── opening_loc: (52,24)-(52,25) = "{" + │ │ │ ├── closing_loc: (52,30)-(52,31) = "}" + │ │ │ ├── parameters: ∅ + │ │ │ └── body: + │ │ │ @ StatementsNode (location: (52,26)-(52,29)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (52,26)-(52,29)) + │ │ │ ├── name: :bar + │ │ │ └── depth: 1 + │ │ ├── operator_loc: (52,18)-(52,20) = ".." + │ │ └── flags: ∅ + │ └── operator_loc: (52,4)-(52,6) = "=>" + ├── @ MatchRequiredNode (location: (54,0)-(54,11)) + │ ├── value: + │ │ @ CallNode (location: (54,0)-(54,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (54,0)-(54,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (55,0)-(55,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (56,0)-(56,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (57,0)-(57,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (59,0)-(59,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (60,0)-(60,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (61,0)-(61,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ PinnedExpressionNode (location: (61,7)-(61,23)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (61,9)-(61,22)) + │ │ │ ├── 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: ∅ + │ │ │ ├── message_loc: (61,15)-(61,16) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (61,17)-(61,22)) + │ │ │ │ └── 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: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (63,0)-(63,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (64,0)-(64,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (65,0)-(65,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (66,0)-(66,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (68,0)-(68,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (69,0)-(69,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (70,0)-(70,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (71,0)-(71,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (72,0)-(72,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (73,0)-(73,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (74,0)-(74,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (76,0)-(76,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (77,0)-(77,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (78,0)-(78,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (79,0)-(79,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (80,0)-(80,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (81,0)-(81,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (82,0)-(82,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (83,0)-(83,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (85,0)-(85,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (86,0)-(86,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (87,0)-(87,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (88,0)-(88,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (89,0)-(89,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (91,0)-(91,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (92,0)-(92,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (94,0)-(94,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (95,0)-(95,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (96,0)-(96,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (97,0)-(97,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (98,0)-(98,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (100,0)-(100,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (101,0)-(101,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (102,0)-(102,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (103,0)-(103,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (104,0)-(104,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (105,0)-(105,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (105,7)-(105,11)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (106,0)-(106,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (106,7)-(106,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (107,0)-(107,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ SymbolNode (location: (107,7)-(107,13)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (108,0)-(108,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ RegularExpressionNode (location: (108,7)-(108,12)) + │ │ ├── opening_loc: (108,7)-(108,8) = "/" + │ │ ├── content_loc: (108,8)-(108,11) = "foo" + │ │ ├── closing_loc: (108,11)-(108,12) = "/" + │ │ ├── unescaped: "foo" + │ │ └── flags: ∅ + │ └── operator_loc: (108,4)-(108,6) = "in" + ├── @ MatchPredicateNode (location: (109,0)-(109,12)) + │ ├── value: + │ │ @ CallNode (location: (109,0)-(109,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (109,0)-(109,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ XStringNode (location: (109,7)-(109,12)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (110,0)-(110,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ XStringNode (location: (110,7)-(110,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (111,0)-(111,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (111,7)-(111,14)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ SymbolNode (location: (111,10)-(111,13)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (112,0)-(112,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (112,7)-(112,14)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ SymbolNode (location: (112,10)-(112,13)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (113,0)-(113,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (113,7)-(113,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (114,0)-(114,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ ArrayNode (location: (114,7)-(114,14)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (115,0)-(115,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (116,0)-(116,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (117,0)-(117,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (118,0)-(118,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (119,0)-(119,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (120,0)-(120,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (121,0)-(121,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (122,0)-(122,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (123,0)-(123,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (124,0)-(124,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (125,0)-(125,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── pattern: + │ │ @ LambdaNode (location: (125,7)-(125,17)) + │ │ ├── locals: [] + │ │ ├── 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" + ├── @ CaseNode (location: (127,0)-(127,25)) + │ ├── predicate: + │ │ @ CallNode (location: (127,5)-(127,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (127,5)-(127,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (128,0)-(128,23)) + │ ├── predicate: + │ │ @ CallNode (location: (128,5)-(128,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (128,5)-(128,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (129,0)-(129,25)) + │ ├── predicate: + │ │ @ CallNode (location: (129,5)-(129,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (129,5)-(129,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (130,0)-(130,24)) + │ ├── predicate: + │ │ @ CallNode (location: (130,5)-(130,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (130,5)-(130,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (131,0)-(131,24)) + │ ├── predicate: + │ │ @ CallNode (location: (131,5)-(131,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (131,5)-(131,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (132,0)-(132,26)) + │ ├── predicate: + │ │ @ CallNode (location: (132,5)-(132,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (132,5)-(132,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (132,10)-(132,22)) + │ │ ├── pattern: + │ │ │ @ SymbolNode (location: (132,13)-(132,17)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (133,0)-(133,29)) + │ ├── predicate: + │ │ @ CallNode (location: (133,5)-(133,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (133,5)-(133,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (133,10)-(133,25)) + │ │ ├── pattern: + │ │ │ @ SymbolNode (location: (133,13)-(133,20)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (134,0)-(134,28)) + │ ├── predicate: + │ │ @ CallNode (location: (134,5)-(134,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (134,5)-(134,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (134,10)-(134,24)) + │ │ ├── pattern: + │ │ │ @ SymbolNode (location: (134,13)-(134,19)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (135,0)-(135,27)) + │ ├── predicate: + │ │ @ CallNode (location: (135,5)-(135,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (135,5)-(135,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (135,10)-(135,23)) + │ │ ├── pattern: + │ │ │ @ RegularExpressionNode (location: (135,13)-(135,18)) + │ │ │ ├── opening_loc: (135,13)-(135,14) = "/" + │ │ │ ├── content_loc: (135,14)-(135,17) = "foo" + │ │ │ ├── closing_loc: (135,17)-(135,18) = "/" + │ │ │ ├── unescaped: "foo" + │ │ │ └── flags: ∅ + │ │ ├── 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" + ├── @ CaseNode (location: (136,0)-(136,27)) + │ ├── predicate: + │ │ @ CallNode (location: (136,5)-(136,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (136,5)-(136,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (136,10)-(136,23)) + │ │ ├── pattern: + │ │ │ @ XStringNode (location: (136,13)-(136,18)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (137,0)-(137,29)) + │ ├── predicate: + │ │ @ CallNode (location: (137,5)-(137,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (137,5)-(137,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (137,10)-(137,25)) + │ │ ├── pattern: + │ │ │ @ XStringNode (location: (137,13)-(137,20)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (138,0)-(138,29)) + │ ├── predicate: + │ │ @ CallNode (location: (138,5)-(138,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (138,5)-(138,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (138,10)-(138,25)) + │ │ ├── pattern: + │ │ │ @ ArrayNode (location: (138,13)-(138,20)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (138,16)-(138,19)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (139,0)-(139,29)) + │ ├── predicate: + │ │ @ CallNode (location: (139,5)-(139,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (139,5)-(139,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (139,10)-(139,25)) + │ │ ├── pattern: + │ │ │ @ ArrayNode (location: (139,13)-(139,20)) + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (139,16)-(139,19)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (140,0)-(140,29)) + │ ├── predicate: + │ │ @ CallNode (location: (140,5)-(140,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (140,5)-(140,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (140,10)-(140,25)) + │ │ ├── pattern: + │ │ │ @ ArrayNode (location: (140,13)-(140,20)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (141,0)-(141,29)) + │ ├── predicate: + │ │ @ CallNode (location: (141,5)-(141,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (141,5)-(141,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (141,10)-(141,25)) + │ │ ├── pattern: + │ │ │ @ ArrayNode (location: (141,13)-(141,20)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (142,0)-(142,29)) + │ ├── predicate: + │ │ @ CallNode (location: (142,5)-(142,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (142,5)-(142,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (143,0)-(143,29)) + │ ├── predicate: + │ │ @ CallNode (location: (143,5)-(143,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (143,5)-(143,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (144,0)-(144,27)) + │ ├── predicate: + │ │ @ CallNode (location: (144,5)-(144,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (144,5)-(144,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (145,0)-(145,25)) + │ ├── predicate: + │ │ @ CallNode (location: (145,5)-(145,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (145,5)-(145,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (146,0)-(146,26)) + │ ├── predicate: + │ │ @ CallNode (location: (146,5)-(146,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (146,5)-(146,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (147,0)-(147,26)) + │ ├── predicate: + │ │ @ CallNode (location: (147,5)-(147,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (147,5)-(147,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (148,0)-(148,27)) + │ ├── predicate: + │ │ @ CallNode (location: (148,5)-(148,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (148,5)-(148,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (149,0)-(149,30)) + │ ├── predicate: + │ │ @ CallNode (location: (149,5)-(149,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (149,5)-(149,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (150,0)-(150,30)) + │ ├── predicate: + │ │ @ CallNode (location: (150,5)-(150,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (150,5)-(150,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (151,0)-(151,34)) + │ ├── predicate: + │ │ @ CallNode (location: (151,5)-(151,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (151,5)-(151,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (152,0)-(152,32)) + │ ├── predicate: + │ │ @ CallNode (location: (152,5)-(152,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (152,5)-(152,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (152,10)-(152,28)) + │ │ ├── pattern: + │ │ │ @ LambdaNode (location: (152,13)-(152,23)) + │ │ │ ├── locals: [] + │ │ │ ├── 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" + ├── @ CaseNode (location: (154,0)-(154,32)) + │ ├── predicate: + │ │ @ CallNode (location: (154,5)-(154,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (154,5)-(154,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (155,0)-(155,30)) + │ ├── predicate: + │ │ @ CallNode (location: (155,5)-(155,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (155,5)-(155,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (156,0)-(156,32)) + │ ├── predicate: + │ │ @ CallNode (location: (156,5)-(156,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (156,5)-(156,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (157,0)-(157,31)) + │ ├── predicate: + │ │ @ CallNode (location: (157,5)-(157,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (157,5)-(157,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (158,0)-(158,31)) + │ ├── predicate: + │ │ @ CallNode (location: (158,5)-(158,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (158,5)-(158,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (159,0)-(159,33)) + │ ├── predicate: + │ │ @ CallNode (location: (159,5)-(159,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (159,5)-(159,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (159,13)-(159,17)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (159,13)-(159,17)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (160,0)-(160,36)) + │ ├── predicate: + │ │ @ CallNode (location: (160,5)-(160,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (160,5)-(160,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (160,13)-(160,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (160,13)-(160,20)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (161,0)-(161,35)) + │ ├── predicate: + │ │ @ CallNode (location: (161,5)-(161,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (161,5)-(161,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (161,13)-(161,19)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (161,13)-(161,19)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (162,0)-(162,34)) + │ ├── predicate: + │ │ @ CallNode (location: (162,5)-(162,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (162,5)-(162,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (162,13)-(162,18)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ RegularExpressionNode (location: (162,13)-(162,18)) + │ │ │ │ ├── opening_loc: (162,13)-(162,14) = "/" + │ │ │ │ ├── content_loc: (162,14)-(162,17) = "foo" + │ │ │ │ ├── closing_loc: (162,17)-(162,18) = "/" + │ │ │ │ ├── unescaped: "foo" + │ │ │ │ └── flags: ∅ + │ │ │ ├── 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" + ├── @ CaseNode (location: (163,0)-(163,34)) + │ ├── predicate: + │ │ @ CallNode (location: (163,5)-(163,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (163,5)-(163,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (163,13)-(163,18)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ XStringNode (location: (163,13)-(163,18)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (164,0)-(164,36)) + │ ├── predicate: + │ │ @ CallNode (location: (164,5)-(164,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (164,5)-(164,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (164,13)-(164,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ XStringNode (location: (164,13)-(164,20)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (165,0)-(165,36)) + │ ├── predicate: + │ │ @ CallNode (location: (165,5)-(165,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (165,5)-(165,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (165,13)-(165,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ ArrayNode (location: (165,13)-(165,20)) + │ │ │ │ ├── elements: (length: 1) + │ │ │ │ │ └── @ SymbolNode (location: (165,16)-(165,19)) + │ │ │ │ │ ├── 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" + ├── @ CaseNode (location: (166,0)-(166,36)) + │ ├── predicate: + │ │ @ CallNode (location: (166,5)-(166,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (166,5)-(166,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (166,13)-(166,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ ArrayNode (location: (166,13)-(166,20)) + │ │ │ │ ├── elements: (length: 1) + │ │ │ │ │ └── @ SymbolNode (location: (166,16)-(166,19)) + │ │ │ │ │ ├── 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" + ├── @ CaseNode (location: (167,0)-(167,36)) + │ ├── predicate: + │ │ @ CallNode (location: (167,5)-(167,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (167,5)-(167,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (167,13)-(167,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ ArrayNode (location: (167,13)-(167,20)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (168,0)-(168,36)) + │ ├── predicate: + │ │ @ CallNode (location: (168,5)-(168,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (168,5)-(168,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (168,13)-(168,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ ArrayNode (location: (168,13)-(168,20)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (169,0)-(169,36)) + │ ├── predicate: + │ │ @ CallNode (location: (169,5)-(169,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (169,5)-(169,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (170,0)-(170,36)) + │ ├── predicate: + │ │ @ CallNode (location: (170,5)-(170,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (170,5)-(170,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (171,0)-(171,34)) + │ ├── predicate: + │ │ @ CallNode (location: (171,5)-(171,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (171,5)-(171,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (172,0)-(172,32)) + │ ├── predicate: + │ │ @ CallNode (location: (172,5)-(172,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (172,5)-(172,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (173,0)-(173,33)) + │ ├── predicate: + │ │ @ CallNode (location: (173,5)-(173,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (173,5)-(173,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (174,0)-(174,33)) + │ ├── predicate: + │ │ @ CallNode (location: (174,5)-(174,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (174,5)-(174,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (175,0)-(175,34)) + │ ├── predicate: + │ │ @ CallNode (location: (175,5)-(175,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (175,5)-(175,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (176,0)-(176,37)) + │ ├── predicate: + │ │ @ CallNode (location: (176,5)-(176,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (176,5)-(176,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (177,0)-(177,37)) + │ ├── predicate: + │ │ @ CallNode (location: (177,5)-(177,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (177,5)-(177,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (178,0)-(178,41)) + │ ├── predicate: + │ │ @ CallNode (location: (178,5)-(178,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (178,5)-(178,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── 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" + ├── @ CaseNode (location: (179,0)-(179,39)) + │ ├── predicate: + │ │ @ CallNode (location: (179,5)-(179,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (179,5)-(179,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (179,13)-(179,23)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ LambdaNode (location: (179,13)-(179,23)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (181,3)-(181,4) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── 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" + │ ├── statements: ∅ + │ ├── consequent: ∅ + │ └── end_keyword_loc: (182,0)-(182,3) = "end" + ├── @ MatchRequiredNode (location: (184,0)-(186,1)) + │ ├── value: + │ │ @ CallNode (location: (184,0)-(184,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (184,0)-(184,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (188,0)-(188,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── pattern: + │ @ HashPatternNode (location: (188,7)-(192,1)) + │ ├── constant: + │ │ @ ConstantReadNode (location: (188,7)-(188,8)) + │ │ └── name: :A + │ ├── assocs: (length: 1) + │ │ └── @ AssocNode (location: (189,2)-(191,3)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (189,2)-(189,6)) + │ │ │ ├── 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 + │ │ │ ├── assocs: (length: 1) + │ │ │ │ └── @ AssocNode (location: (190,4)-(190,12)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (190,4)-(190,10)) + │ │ │ │ │ ├── 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: ∅ + │ │ │ ├── kwrest: ∅ + │ │ │ ├── opening_loc: (189,8)-(189,9) = "[" + │ │ │ └── closing_loc: (191,2)-(191,3) = "]" + │ │ └── operator_loc: ∅ + │ ├── kwrest: ∅ + │ ├── opening_loc: (188,8)-(188,9) = "[" + │ └── closing_loc: (192,0)-(192,1) = "]" + └── operator_loc: (188,4)-(188,6) = "in" diff --git a/test/prism/snapshots/procs.txt b/test/prism/snapshots/procs.txt new file mode 100644 index 00000000000000..8203cc08c8b9bd --- /dev/null +++ b/test/prism/snapshots/procs.txt @@ -0,0 +1,375 @@ +@ ProgramNode (location: (1,0)-(27,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(27,19)) + └── body: (length: 10) + ├── @ LambdaNode (location: (1,0)-(1,21)) + │ ├── locals: [:a, :b, :c, :d] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,16)-(1,17) = "{" + │ ├── closing_loc: (1,20)-(1,21) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,3)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,4)-(1,5)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5)) + │ │ │ │ └── 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: [] + │ ├── 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: [] + │ ├── 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: [] + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,5)-(13,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── @ LambdaNode (location: (15,0)-(15,15)) + │ ├── locals: [] + │ ├── operator_loc: (15,0)-(15,2) = "->" + │ ├── opening_loc: (15,3)-(15,5) = "do" + │ ├── closing_loc: (15,12)-(15,15) = "end" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (15,7)-(15,10)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (15,7)-(15,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,7)-(15,10) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── @ LambdaNode (location: (17,0)-(17,29)) + │ ├── locals: [:a, :b, :c, :d, :e] + │ ├── operator_loc: (17,0)-(17,2) = "->" + │ ├── opening_loc: (17,24)-(17,25) = "{" + │ ├── closing_loc: (17,28)-(17,29) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (17,3)-(17,23)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (17,3)-(17,23)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (17,3)-(17,4)) + │ │ │ │ └── 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) + │ │ │ │ ├── @ KeywordParameterNode (location: (17,13)-(17,15)) + │ │ │ │ │ ├── name: :c + │ │ │ │ │ ├── name_loc: (17,13)-(17,15) = "c:" + │ │ │ │ │ └── value: ∅ + │ │ │ │ └── @ KeywordParameterNode (location: (17,17)-(17,19)) + │ │ │ │ ├── name: :d + │ │ │ │ ├── name_loc: (17,17)-(17,19) = "d:" + │ │ │ │ └── value: ∅ + │ │ │ ├── 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] + │ ├── 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) + │ │ │ │ ├── @ KeywordParameterNode (location: (19,18)-(19,20)) + │ │ │ │ │ ├── name: :d + │ │ │ │ │ ├── name_loc: (19,18)-(19,20) = "d:" + │ │ │ │ │ └── value: ∅ + │ │ │ │ └── @ KeywordParameterNode (location: (19,22)-(19,24)) + │ │ │ │ ├── name: :e + │ │ │ │ ├── name_loc: (19,22)-(19,24) = "e:" + │ │ │ │ └── value: ∅ + │ │ │ ├── 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] + │ ├── 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) + │ │ │ │ ├── @ KeywordParameterNode (location: (21,18)-(21,20)) + │ │ │ │ │ ├── name: :d + │ │ │ │ │ ├── name_loc: (21,18)-(21,20) = "d:" + │ │ │ │ │ └── value: ∅ + │ │ │ │ └── @ KeywordParameterNode (location: (21,22)-(21,24)) + │ │ │ │ ├── name: :e + │ │ │ │ ├── name_loc: (21,22)-(21,24) = "e:" + │ │ │ │ └── value: ∅ + │ │ │ ├── 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] + │ ├── 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] + │ ├── 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)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (25,16)-(25,17)) + │ │ ├── name: :a + │ │ └── depth: 1 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,18)-(25,19) = "*" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (25,20)-(25,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (25,20)-(25,21)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "*" + └── @ LambdaNode (location: (27,0)-(27,19)) + ├── locals: [:a, :b, :c] + ├── operator_loc: (27,0)-(27,2) = "->" + ├── opening_loc: (27,16)-(27,17) = "{" + ├── closing_loc: (27,18)-(27,19) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (27,3)-(27,15)) + │ ├── parameters: + │ │ @ ParametersNode (location: (27,4)-(27,14)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredDestructuredParameterNode (location: (27,4)-(27,10)) + │ │ │ ├── parameters: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (27,5)-(27,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredParameterNode (location: (27,8)-(27,9)) + │ │ │ │ └── name: :b + │ │ │ ├── opening_loc: (27,4)-(27,5) = "(" + │ │ │ └── closing_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 new file mode 100644 index 00000000000000..e4842729f1fa92 --- /dev/null +++ b/test/prism/snapshots/range_begin_open_exclusive.txt @@ -0,0 +1,12 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,4)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (1,3)-(1,4)) + │ └── flags: decimal + ├── operator_loc: (1,0)-(1,3) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/range_begin_open_inclusive.txt b/test/prism/snapshots/range_begin_open_inclusive.txt new file mode 100644 index 00000000000000..1d9c64ec97b512 --- /dev/null +++ b/test/prism/snapshots/range_begin_open_inclusive.txt @@ -0,0 +1,12 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,3)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (1,2)-(1,3)) + │ └── flags: decimal + ├── operator_loc: (1,0)-(1,2) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/range_end_open_exclusive.txt b/test/prism/snapshots/range_end_open_exclusive.txt new file mode 100644 index 00000000000000..defd76783efab8 --- /dev/null +++ b/test/prism/snapshots/range_end_open_exclusive.txt @@ -0,0 +1,12 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,4)) + ├── left: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── right: ∅ + ├── operator_loc: (1,1)-(1,4) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/range_end_open_inclusive.txt b/test/prism/snapshots/range_end_open_inclusive.txt new file mode 100644 index 00000000000000..ee51b81e51f3b4 --- /dev/null +++ b/test/prism/snapshots/range_end_open_inclusive.txt @@ -0,0 +1,12 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,3)) + ├── left: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── right: ∅ + ├── operator_loc: (1,1)-(1,3) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/ranges.txt b/test/prism/snapshots/ranges.txt new file mode 100644 index 00000000000000..65192ecc4bbdaa --- /dev/null +++ b/test/prism/snapshots/ranges.txt @@ -0,0 +1,160 @@ +@ ProgramNode (location: (1,0)-(17,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(17,5)) + └── body: (length: 9) + ├── @ ParenthesesNode (location: (1,0)-(1,6)) + │ ├── body: + │ │ @ StatementsNode (location: (1,1)-(1,5)) + │ │ └── body: (length: 1) + │ │ └── @ RangeNode (location: (1,1)-(1,5)) + │ │ ├── left: ∅ + │ │ ├── right: + │ │ │ @ IntegerNode (location: (1,4)-(1,5)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (1,1)-(1,4) = "..." + │ │ └── flags: exclude_end + │ ├── 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)) + │ │ ├── left: ∅ + │ │ ├── right: + │ │ │ @ IntegerNode (location: (3,3)-(3,4)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (3,1)-(3,3) = ".." + │ │ └── flags: ∅ + │ ├── opening_loc: (3,0)-(3,1) = "(" + │ └── closing_loc: (3,4)-(3,5) = ")" + ├── @ RangeNode (location: (5,0)-(5,5)) + │ ├── left: + │ │ @ IntegerNode (location: (5,0)-(5,1)) + │ │ └── flags: decimal + │ ├── right: + │ │ @ IntegerNode (location: (5,4)-(5,5)) + │ │ └── flags: decimal + │ ├── operator_loc: (5,1)-(5,4) = "..." + │ └── flags: exclude_end + ├── @ CallNode (location: (7,0)-(7,9)) + │ ├── receiver: + │ │ @ CallNode (location: (7,0)-(7,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,3)-(7,9) = "[...2]" + │ ├── opening_loc: (7,3)-(7,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,4)-(7,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ RangeNode (location: (7,4)-(7,8)) + │ │ ├── left: ∅ + │ │ ├── right: + │ │ │ @ IntegerNode (location: (7,7)-(7,8)) + │ │ │ └── flags: decimal + │ │ ├── operator_loc: (7,4)-(7,7) = "..." + │ │ └── flags: exclude_end + │ ├── closing_loc: (7,8)-(7,9) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (9,2)-(9,5) = "foo" + │ │ │ ├── closing_loc: (9,5)-(9,6) = ":" + │ │ │ └── unescaped: "foo" + │ │ ├── value: + │ │ │ @ RangeNode (location: (9,7)-(9,13)) + │ │ │ ├── left: ∅ + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (9,10)-(9,13)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,10)-(9,13) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── operator_loc: (9,7)-(9,10) = "..." + │ │ │ └── flags: exclude_end + │ │ └── 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (11,1)-(11,2)) + │ │ │ └── flags: decimal + │ │ ├── right: ∅ + │ │ ├── operator_loc: (11,2)-(11,5) = "..." + │ │ └── flags: exclude_end + │ ├── opening_loc: (11,0)-(11,1) = "(" + │ └── closing_loc: (11,5)-(11,6) = ")" + ├── @ RangeNode (location: (13,0)-(13,4)) + │ ├── left: + │ │ @ IntegerNode (location: (13,0)-(13,1)) + │ │ └── flags: decimal + │ ├── right: + │ │ @ IntegerNode (location: (13,3)-(13,4)) + │ │ └── flags: decimal + │ ├── operator_loc: (13,1)-(13,3) = ".." + │ └── flags: ∅ + ├── @ 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (15,2)-(15,5) = "foo" + │ │ │ ├── closing_loc: (15,5)-(15,6) = ":" + │ │ │ └── unescaped: "foo" + │ │ ├── value: + │ │ │ @ RangeNode (location: (15,7)-(15,12)) + │ │ │ ├── left: ∅ + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (15,9)-(15,12)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (15,9)-(15,12) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── operator_loc: (15,7)-(15,9) = ".." + │ │ │ └── flags: ∅ + │ │ └── 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)) + │ ├── left: + │ │ @ IntegerNode (location: (17,1)-(17,2)) + │ │ └── flags: decimal + │ ├── right: ∅ + │ ├── operator_loc: (17,2)-(17,4) = ".." + │ └── flags: ∅ + ├── opening_loc: (17,0)-(17,1) = "(" + └── closing_loc: (17,4)-(17,5) = ")" diff --git a/test/prism/snapshots/regex.txt b/test/prism/snapshots/regex.txt new file mode 100644 index 00000000000000..a20a97c5eb7437 --- /dev/null +++ b/test/prism/snapshots/regex.txt @@ -0,0 +1,209 @@ +@ ProgramNode (location: (1,0)-(30,13)) +├── locals: [:foo] +└── statements: + @ StatementsNode (location: (1,0)-(30,13)) + └── body: (length: 14) + ├── @ CallNode (location: (1,0)-(1,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ RegularExpressionNode (location: (1,4)-(1,9)) + │ │ ├── opening_loc: (1,4)-(1,5) = "/" + │ │ ├── content_loc: (1,5)-(1,8) = "bar" + │ │ ├── closing_loc: (1,8)-(1,9) = "/" + │ │ ├── unescaped: "bar" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ RegularExpressionNode (location: (3,0)-(3,8)) + │ ├── opening_loc: (3,0)-(3,3) = "%r{" + │ ├── content_loc: (3,3)-(3,6) = "abc" + │ ├── closing_loc: (3,6)-(3,8) = "}i" + │ ├── unescaped: "abc" + │ └── flags: ignore_case + ├── @ RegularExpressionNode (location: (5,0)-(5,5)) + │ ├── opening_loc: (5,0)-(5,1) = "/" + │ ├── content_loc: (5,1)-(5,4) = "a\\b" + │ ├── closing_loc: (5,4)-(5,5) = "/" + │ ├── unescaped: "a\b" + │ └── flags: ∅ + ├── @ InterpolatedRegularExpressionNode (location: (7,0)-(7,11)) + │ ├── 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) = "/" + │ └── flags: ∅ + ├── @ InterpolatedRegularExpressionNode (location: (9,0)-(9,16)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,7)-(9,10) = "bbb" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bbb" + │ │ │ └── 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) = "/" + │ └── flags: ∅ + ├── @ ArrayNode (location: (11,0)-(11,27)) + │ ├── elements: (length: 2) + │ │ ├── @ MatchWriteNode (location: (11,1)-(11,21)) + │ │ │ ├── call: + │ │ │ │ @ CallNode (location: (11,1)-(11,21)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ RegularExpressionNode (location: (11,1)-(11,14)) + │ │ │ │ │ ├── opening_loc: (11,1)-(11,2) = "/" + │ │ │ │ │ ├── content_loc: (11,2)-(11,13) = "(?bar)" + │ │ │ │ │ ├── closing_loc: (11,13)-(11,14) = "/" + │ │ │ │ │ ├── unescaped: "(?bar)" + │ │ │ │ │ └── flags: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (11,15)-(11,17) = "=~" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (11,18)-(11,21)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (11,18)-(11,21)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (11,18)-(11,21) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "=~" + │ │ │ └── locals: [:foo] + │ │ └── @ 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)) + │ ├── opening_loc: (13,0)-(13,1) = "/" + │ ├── content_loc: (13,1)-(13,4) = "abc" + │ ├── closing_loc: (13,4)-(13,6) = "/i" + │ ├── unescaped: "abc" + │ └── flags: ignore_case + ├── @ RegularExpressionNode (location: (15,0)-(15,26)) + │ ├── 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$.?\#@~]*:" + │ └── flags: ignore_case + ├── @ RegularExpressionNode (location: (17,0)-(17,37)) + │ ├── 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$.?\#@~]*)( +)(equ)" + │ └── flags: ignore_case + ├── @ RegularExpressionNode (location: (19,0)-(19,25)) + │ ├── 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$.?\#@~]*" + │ └── flags: ignore_case + ├── @ RegularExpressionNode (location: (21,0)-(24,1)) + │ ├── opening_loc: (21,0)-(21,3) = "%r(" + │ ├── content_loc: (21,3)-(23,0) = "\n(?:[\\w\#$%_']|\\(\\)|\\(,\\)|\\[\\]|[0-9])*\n (?:[\\w\#$%_']+)\n" + │ ├── closing_loc: (24,0)-(24,1) = ")" + │ ├── unescaped: "\n(?:[w\#$%_']|()|(,)|[]|[0-9])*\n (?:[w\#$%_']+)\n" + │ └── flags: ∅ + ├── @ CallNode (location: (26,0)-(26,16)) + │ ├── receiver: + │ │ @ RegularExpressionNode (location: (26,0)-(26,8)) + │ │ ├── opening_loc: (26,0)-(26,1) = "/" + │ │ ├── content_loc: (26,1)-(26,7) = "(?#\\))" + │ │ ├── closing_loc: (26,7)-(26,8) = "/" + │ │ ├── unescaped: "(?#))" + │ │ └── flags: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (26,9)-(26,11) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (26,12)-(26,16)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ RegularExpressionNode (location: (28,0)-(28,9)) + │ ├── opening_loc: (28,0)-(28,3) = "%r#" + │ ├── content_loc: (28,3)-(28,8) = "pound" + │ ├── closing_loc: (28,8)-(28,9) = "#" + │ ├── unescaped: "pound" + │ └── flags: ∅ + └── @ InterpolatedRegularExpressionNode (location: (30,0)-(30,13)) + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,7)-(30,10) = "bbb" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bbb" + │ └── closing_loc: (30,10)-(30,11) = "}" + ├── closing_loc: (30,11)-(30,13) = "/o" + └── flags: once diff --git a/test/prism/snapshots/rescue.txt b/test/prism/snapshots/rescue.txt new file mode 100644 index 00000000000000..b57f5de7a7cbb2 --- /dev/null +++ b/test/prism/snapshots/rescue.txt @@ -0,0 +1,378 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (12,0)-(12,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,0)-(14,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,7)-(16,8) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (16,18)-(16,19) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── operator_loc: ∅ + │ │ ├── reference: ∅ + │ │ ├── statements: ∅ + │ │ └── consequent: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (16,21)-(16,24) = "end" + ├── @ CallNode (location: (18,0)-(20,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (18,0)-(18,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (18,4)-(20,3)) + │ │ ├── locals: [:x] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (18,7)-(18,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (18,8)-(18,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (18,8)-(18,9)) + │ │ │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (19,2)-(19,5) = "bar" + │ │ │ │ ├── opening_loc: (19,5)-(19,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "y" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "y" + │ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "bar" + │ │ │ ├── keyword_loc: (19,9)-(19,15) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ CallNode (location: (19,16)-(19,40)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,16)-(19,29) = "ArgumentError" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (19,30)-(19,40)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (19,30)-(19,40)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (19,30)-(19,34) = "fail" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (19,35)-(19,40)) + │ │ │ │ │ └── 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: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "fail" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "ArgumentError" + │ │ ├── opening_loc: (18,4)-(18,6) = "do" + │ │ └── closing_loc: (20,0)-(20,3) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (22,7)-(22,10) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── keyword_loc: (22,11)-(22,17) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ NilNode (location: (22,18)-(22,21)) + │ │ └── operator_loc: (22,5)-(22,6) = "=" + │ ├── statements: + │ │ @ StatementsNode (location: (23,2)-(23,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (23,2)-(23,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,2)-(23,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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) + │ │ └── @ CallNode (location: (26,18)-(26,44)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (26,18)-(26,30) = "other_method" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (26,31)-(26,44)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ RescueModifierNode (location: (26,31)-(26,44)) + │ │ │ ├── expression: + │ │ │ │ @ IntegerNode (location: (26,31)-(26,33)) + │ │ │ │ └── flags: decimal + │ │ │ ├── keyword_loc: (26,34)-(26,40) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ NilNode (location: (26,41)-(26,44)) + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "other_method" + │ ├── locals: [] + │ ├── def_keyword_loc: (26,0)-(26,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (26,16)-(26,17) = "=" + │ └── end_keyword_loc: ∅ + └── @ DefNode (location: (28,0)-(31,3)) + ├── name: :a + ├── name_loc: (28,4)-(28,5) = "a" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ BeginNode (location: (29,2)-(31,3)) + │ ├── begin_keyword_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (29,2)-(29,6)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (29,2)-(29,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (29,2)-(29,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (29,4)-(29,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ KeywordHashNode (location: (29,4)-(29,6)) + │ │ │ └── elements: (length: 1) + │ │ │ └── @ AssocNode (location: (29,4)-(29,6)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (29,4)-(29,6)) + │ │ │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (29,4)-(29,5) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "b" + │ │ │ └── operator_loc: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "a" + │ ├── rescue_clause: + │ │ @ RescueNode (location: (30,0)-(30,6)) + │ │ ├── keyword_loc: (30,0)-(30,6) = "rescue" + │ │ ├── exceptions: (length: 0) + │ │ ├── operator_loc: ∅ + │ │ ├── reference: ∅ + │ │ ├── statements: ∅ + │ │ └── consequent: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (31,0)-(31,3) = "end" + ├── locals: [] + ├── def_keyword_loc: (28,0)-(28,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (31,0)-(31,3) = "end" diff --git a/test/prism/snapshots/return.txt b/test/prism/snapshots/return.txt new file mode 100644 index 00000000000000..66e462526209bd --- /dev/null +++ b/test/prism/snapshots/return.txt @@ -0,0 +1,128 @@ +@ 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)) + │ └── 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)) + │ └── 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)) + │ └── 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)) + │ └── 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)) + │ └── 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)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (14,7)-(14,16)) + │ ├── 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)) + │ └── 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)) + │ └── 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)) + └── 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 new file mode 100644 index 00000000000000..3595e2a05c82a9 --- /dev/null +++ b/test/prism/snapshots/seattlerb/BEGIN.txt @@ -0,0 +1,14 @@ +@ 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 new file mode 100644 index 00000000000000..deb317781a0518 --- /dev/null +++ b/test/prism/snapshots/seattlerb/TestRubyParserShared.txt @@ -0,0 +1,332 @@ +@ ProgramNode (location: (1,0)-(92,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(92,1)) + └── body: (length: 16) + ├── @ ArrayNode (location: (1,0)-(4,1)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (1,0)-(1,3) = "%I[" + │ └── closing_loc: (4,0)-(4,1) = "]" + ├── @ ArrayNode (location: (6,0)-(9,1)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (7,0)-(7,5)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (7,0)-(7,5) = "line2" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "line2" + │ │ └── @ SymbolNode (location: (8,0)-(8,5)) + │ │ ├── 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)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (11,0)-(11,3) = "%W[" + │ └── closing_loc: (14,0)-(14,1) = "]" + ├── @ ArrayNode (location: (16,0)-(19,1)) + │ ├── 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)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (21,0)-(21,3) = "%i[" + │ └── closing_loc: (24,0)-(24,1) = "]" + ├── @ ArrayNode (location: (26,0)-(29,1)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (27,0)-(27,5)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (27,0)-(27,5) = "line2" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "line2" + │ │ └── @ SymbolNode (location: (28,0)-(28,5)) + │ │ ├── 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)) + │ ├── opening_loc: (31,0)-(31,3) = "%r[" + │ ├── content_loc: (31,3)-(33,0) = "\n\n\n" + │ ├── closing_loc: (34,0)-(34,1) = "]" + │ ├── unescaped: "\n\n\n" + │ └── flags: ∅ + ├── @ ArrayNode (location: (36,0)-(39,1)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (36,0)-(36,3) = "%w[" + │ └── closing_loc: (39,0)-(39,1) = "]" + ├── @ ArrayNode (location: (41,0)-(44,1)) + │ ├── 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)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (47,0)-(47,6)) + │ │ │ ├── opening_loc: (47,0)-(47,1) = ":" + │ │ │ ├── value_loc: (47,1)-(47,6) = "line2" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "line2" + │ │ └── @ SymbolNode (location: (48,0)-(48,6)) + │ │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (54,4)-(54,5)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (54,6)-(54,7) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (54,8)-(54,9)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (54,8)-(54,9)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── locals: [:a, :b] + │ │ ├── def_keyword_loc: (52,2)-(52,5) = "def" + │ │ ├── operator_loc: (52,10)-(52,11) = "." + │ │ ├── lparen_loc: (52,12)-(52,13) = "(" + │ │ ├── rparen_loc: (53,9)-(53,10) = ")" + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (55,2)-(55,5) = "end" + │ ├── end_keyword_loc: (56,0)-(56,3) = "end" + │ └── name: :X + ├── @ ClassNode (location: (59,0)-(63,3)) + │ ├── locals: [] + │ ├── class_keyword_loc: (59,0)-(59,5) = "class" + │ ├── constant_path: + │ │ @ ConstantReadNode (location: (59,6)-(59,7)) + │ │ └── name: :X + │ ├── inheritance_operator_loc: ∅ + │ ├── superclass: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (60,2)-(62,5)) + │ │ └── body: (length: 1) + │ │ └── @ ClassNode (location: (60,2)-(62,5)) + │ │ ├── locals: [] + │ │ ├── class_keyword_loc: (60,2)-(60,7) = "class" + │ │ ├── constant_path: + │ │ │ @ ConstantReadNode (location: (60,8)-(60,9)) + │ │ │ └── name: :Y + │ │ ├── inheritance_operator_loc: ∅ + │ │ ├── superclass: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (61,4)-(61,10)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ ConstantWriteNode (location: (61,4)-(61,10)) + │ │ │ ├── name: :Z + │ │ │ ├── name_loc: (61,4)-(61,5) = "Z" + │ │ │ ├── value: + │ │ │ │ @ IntegerNode (location: (61,8)-(61,10)) + │ │ │ │ └── flags: decimal + │ │ │ └── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (69,4)-(69,5)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (69,6)-(69,7) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (69,8)-(69,9)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (69,8)-(69,9)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── locals: [:a, :b] + │ │ ├── def_keyword_loc: (67,2)-(67,5) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: (67,7)-(67,8) = "(" + │ │ ├── rparen_loc: (68,9)-(68,10) = ")" + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (70,2)-(70,5) = "end" + │ ├── end_keyword_loc: (71,0)-(71,3) = "end" + │ └── name: :X + ├── @ ModuleNode (location: (74,0)-(79,3)) + │ ├── locals: [] + │ ├── module_keyword_loc: (74,0)-(74,6) = "module" + │ ├── constant_path: + │ │ @ ConstantReadNode (location: (74,7)-(74,8)) + │ │ └── name: :X + │ ├── body: + │ │ @ StatementsNode (location: (75,2)-(78,3)) + │ │ └── body: (length: 1) + │ │ └── @ ConstantWriteNode (location: (75,2)-(78,3)) + │ │ ├── name: :X + │ │ ├── name_loc: (75,2)-(75,3) = "X" + │ │ ├── value: + │ │ │ @ ArrayNode (location: (75,6)-(78,3)) + │ │ │ ├── elements: (length: 2) + │ │ │ │ ├── @ SymbolNode (location: (76,4)-(76,10)) + │ │ │ │ │ ├── opening_loc: (76,4)-(76,5) = ":" + │ │ │ │ │ ├── value_loc: (76,5)-(76,10) = "line3" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "line3" + │ │ │ │ └── @ SymbolNode (location: (77,4)-(77,10)) + │ │ │ │ ├── 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (89,0)-(89,1) = "x" + ├── opening_loc: (89,1)-(89,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (90,0)-(91,6)) + │ └── arguments: (length: 2) + │ ├── @ SymbolNode (location: (90,0)-(90,6)) + │ │ ├── opening_loc: (90,0)-(90,1) = ":" + │ │ ├── value_loc: (90,1)-(90,6) = "line2" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "line2" + │ └── @ SymbolNode (location: (91,0)-(91,6)) + │ ├── opening_loc: (91,0)-(91,1) = ":" + │ ├── value_loc: (91,1)-(91,6) = "line3" + │ ├── closing_loc: ∅ + │ └── unescaped: "line3" + ├── closing_loc: (92,0)-(92,1) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/__ENCODING__.txt b/test/prism/snapshots/seattlerb/__ENCODING__.txt new file mode 100644 index 00000000000000..1b223bd8fe78dd --- /dev/null +++ b/test/prism/snapshots/seattlerb/__ENCODING__.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ SourceEncodingNode (location: (1,0)-(1,12)) diff --git a/test/prism/snapshots/seattlerb/alias_gvar_backref.txt b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt new file mode 100644 index 00000000000000..4ba046913228b5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/alias_gvar_backref.txt @@ -0,0 +1,12 @@ +@ 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)) + └── keyword_loc: (1,0)-(1,5) = "alias" diff --git a/test/prism/snapshots/seattlerb/alias_resword.txt b/test/prism/snapshots/seattlerb/alias_resword.txt new file mode 100644 index 00000000000000..089819b528d10d --- /dev/null +++ b/test/prism/snapshots/seattlerb/alias_resword.txt @@ -0,0 +1,19 @@ +@ 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)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (1,6)-(1,8) = "in" + │ ├── closing_loc: ∅ + │ └── unescaped: "in" + ├── old_name: + │ @ SymbolNode (location: (1,9)-(1,12)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (1,9)-(1,12) = "out" + │ ├── closing_loc: ∅ + │ └── unescaped: "out" + └── keyword_loc: (1,0)-(1,5) = "alias" diff --git a/test/prism/snapshots/seattlerb/and_multi.txt b/test/prism/snapshots/seattlerb/and_multi.txt new file mode 100644 index 00000000000000..575f75fe307889 --- /dev/null +++ b/test/prism/snapshots/seattlerb/and_multi.txt @@ -0,0 +1,26 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 1) + └── @ AndNode (location: (1,0)-(3,4)) + ├── left: + │ @ AndNode (location: (1,0)-(2,9)) + │ ├── left: + │ │ @ TrueNode (location: (1,0)-(1,4)) + │ ├── right: + │ │ @ CallNode (location: (2,0)-(2,9)) + │ │ ├── receiver: + │ │ │ @ FalseNode (location: (2,4)-(2,9)) + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,0)-(2,3) = "not" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "!" + │ └── operator_loc: (1,5)-(1,8) = "and" + ├── right: + │ @ TrueNode (location: (3,0)-(3,4)) + └── operator_loc: (2,10)-(2,13) = "and" diff --git a/test/prism/snapshots/seattlerb/aref_args_assocs.txt b/test/prism/snapshots/seattlerb/aref_args_assocs.txt new file mode 100644 index 00000000000000..02bfd74b502115 --- /dev/null +++ b/test/prism/snapshots/seattlerb/aref_args_assocs.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,8)) + ├── elements: (length: 1) + │ └── @ KeywordHashNode (location: (1,1)-(1,7)) + │ └── 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 new file mode 100644 index 00000000000000..bbe45dfc0e5344 --- /dev/null +++ b/test/prism/snapshots/seattlerb/aref_args_lit_assocs.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,11)) + ├── elements: (length: 2) + │ ├── @ IntegerNode (location: (1,1)-(1,2)) + │ │ └── flags: decimal + │ └── @ KeywordHashNode (location: (1,4)-(1,10)) + │ └── 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 new file mode 100644 index 00000000000000..3cbd2c1705d057 --- /dev/null +++ b/test/prism/snapshots/seattlerb/args_kw_block.txt @@ -0,0 +1,36 @@ +@ 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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,14)-(1,15) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,17)-(1,20) = "end" diff --git a/test/prism/snapshots/seattlerb/array_line_breaks.txt b/test/prism/snapshots/seattlerb/array_line_breaks.txt new file mode 100644 index 00000000000000..b6ebac16883897 --- /dev/null +++ b/test/prism/snapshots/seattlerb/array_line_breaks.txt @@ -0,0 +1,23 @@ +@ ProgramNode (location: (1,0)-(4,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,1)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(3,4)) + │ ├── 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 new file mode 100644 index 00000000000000..ef31ed8bbc72d0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/array_lits_trailing_calls.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,6)) + │ ├── receiver: + │ │ @ ArrayNode (location: (1,0)-(1,4)) + │ │ ├── elements: (length: 0) + │ │ ├── opening_loc: (1,0)-(1,3) = "%w[" + │ │ └── closing_loc: (1,3)-(1,4) = "]" + │ ├── call_operator_loc: (1,4)-(1,5) = "." + │ ├── message_loc: (1,5)-(1,6) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + └── @ CallNode (location: (3,0)-(3,4)) + ├── receiver: + │ @ ArrayNode (location: (3,0)-(3,2)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (3,0)-(3,1) = "[" + │ └── closing_loc: (3,1)-(3,2) = "]" + ├── call_operator_loc: (3,2)-(3,3) = "." + ├── message_loc: (3,3)-(3,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/assoc__bare.txt b/test/prism/snapshots/seattlerb/assoc__bare.txt new file mode 100644 index 00000000000000..1de54f236d0c24 --- /dev/null +++ b/test/prism/snapshots/seattlerb/assoc__bare.txt @@ -0,0 +1,30 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "y" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "y" + │ └── operator_loc: ∅ + └── closing_loc: (1,5)-(1,6) = "}" diff --git a/test/prism/snapshots/seattlerb/assoc_label.txt b/test/prism/snapshots/seattlerb/assoc_label.txt new file mode 100644 index 00000000000000..2e20f9fc293d70 --- /dev/null +++ b/test/prism/snapshots/seattlerb/assoc_label.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(1,5)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,2)-(1,5)) + │ ├── key: + │ │ @ SymbolNode (location: (1,2)-(1,4)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt b/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt new file mode 100644 index 00000000000000..52327382670702 --- /dev/null +++ b/test/prism/snapshots/seattlerb/attr_asgn_colon_id.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: + │ @ ConstantReadNode (location: (1,0)-(1,1)) + │ └── name: :A + ├── call_operator_loc: (1,1)-(1,3) = "::" + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,7)-(1,8)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,7)-(1,8)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "b=" diff --git a/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt b/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt new file mode 100644 index 00000000000000..5d30d718c92b6f --- /dev/null +++ b/test/prism/snapshots/seattlerb/attrasgn_array_arg.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,1)-(1,9) = "[[1, 2]]" + ├── opening_loc: (1,1)-(1,2) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,13)) + │ └── arguments: (length: 2) + │ ├── @ ArrayNode (location: (1,2)-(1,8)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "[]=" diff --git a/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt b/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt new file mode 100644 index 00000000000000..741e1cba091793 --- /dev/null +++ b/test/prism/snapshots/seattlerb/attrasgn_array_lhs.txt @@ -0,0 +1,76 @@ +@ ProgramNode (location: (1,0)-(1,42)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,42)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,42)) + ├── receiver: + │ @ ArrayNode (location: (1,0)-(1,12)) + │ ├── 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: ∅ + ├── message_loc: (1,12)-(1,24) = "[from .. to]" + ├── opening_loc: (1,12)-(1,13) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,13)-(1,42)) + │ └── arguments: (length: 2) + │ ├── @ RangeNode (location: (1,13)-(1,23)) + │ │ ├── left: + │ │ │ @ CallNode (location: (1,13)-(1,17)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,13)-(1,17) = "from" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "from" + │ │ ├── right: + │ │ │ @ CallNode (location: (1,21)-(1,23)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,21)-(1,23) = "to" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "to" + │ │ ├── operator_loc: (1,18)-(1,20) = ".." + │ │ └── flags: ∅ + │ └── @ ArrayNode (location: (1,27)-(1,42)) + │ ├── 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: ∅ + ├── flags: ∅ + └── name: "[]=" diff --git a/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt b/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt new file mode 100644 index 00000000000000..73b65fc6364160 --- /dev/null +++ b/test/prism/snapshots/seattlerb/attrasgn_primary_dot_constant.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,2) = "." + ├── message_loc: (1,2)-(1,3) = "B" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,6)-(1,7)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "B=" diff --git a/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt b/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt new file mode 100644 index 00000000000000..d56a532bc42d45 --- /dev/null +++ b/test/prism/snapshots/seattlerb/backticks_interpolation_line.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,8)) + │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,5)-(1,6) = "y" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "y" + │ │ └── closing_loc: (1,6)-(1,7) = "}" + │ └── closing_loc: (1,7)-(1,8) = "`" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/bang_eq.txt b/test/prism/snapshots/seattlerb/bang_eq.txt new file mode 100644 index 00000000000000..b2fc7b7bb7bf5f --- /dev/null +++ b/test/prism/snapshots/seattlerb/bang_eq.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = "!=" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!=" diff --git a/test/prism/snapshots/seattlerb/bdot2.txt b/test/prism/snapshots/seattlerb/bdot2.txt new file mode 100644 index 00000000000000..2fc74e52a72657 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bdot2.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 3) + ├── @ RangeNode (location: (1,0)-(1,4)) + │ ├── left: ∅ + │ ├── right: + │ │ @ IntegerNode (location: (1,2)-(1,4)) + │ │ └── flags: decimal + │ ├── operator_loc: (1,0)-(1,2) = ".." + │ └── flags: ∅ + ├── @ RangeNode (location: (2,2)-(2,5)) + │ ├── left: ∅ + │ ├── right: + │ │ @ CallNode (location: (2,4)-(2,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,4)-(2,5) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── operator_loc: (2,2)-(2,4) = ".." + │ └── flags: ∅ + └── @ CallNode (location: (3,2)-(3,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,2)-(3,3) = "c" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/bdot3.txt b/test/prism/snapshots/seattlerb/bdot3.txt new file mode 100644 index 00000000000000..f282688f85c248 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bdot3.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 3) + ├── @ RangeNode (location: (1,0)-(1,5)) + │ ├── left: ∅ + │ ├── right: + │ │ @ IntegerNode (location: (1,3)-(1,5)) + │ │ └── flags: decimal + │ ├── operator_loc: (1,0)-(1,3) = "..." + │ └── flags: exclude_end + ├── @ RangeNode (location: (2,2)-(2,6)) + │ ├── left: ∅ + │ ├── right: + │ │ @ CallNode (location: (2,5)-(2,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,5)-(2,6) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── operator_loc: (2,2)-(2,5) = "..." + │ └── flags: exclude_end + └── @ CallNode (location: (3,2)-(3,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,2)-(3,3) = "c" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt b/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt new file mode 100644 index 00000000000000..e1698d0baefcc0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/begin_ensure_no_bodies.txt @@ -0,0 +1,16 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(3,3)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: ∅ + ├── else_clause: ∅ + ├── ensure_clause: + │ @ EnsureNode (location: (2,0)-(3,3)) + │ ├── ensure_keyword_loc: (2,0)-(2,6) = "ensure" + │ ├── statements: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt new file mode 100644 index 00000000000000..686fa100f1b48d --- /dev/null +++ b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt @@ -0,0 +1,43 @@ +@ 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 new file mode 100644 index 00000000000000..02e1f097ac4eab --- /dev/null +++ b/test/prism/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(9,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(9,3)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(9,3)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: + │ @ RescueNode (location: (3,0)-(3,6)) + │ ├── keyword_loc: (3,0)-(3,6) = "rescue" + │ ├── exceptions: (length: 0) + │ ├── operator_loc: ∅ + │ ├── reference: ∅ + │ ├── statements: ∅ + │ └── consequent: ∅ + ├── else_clause: + │ @ ElseNode (location: (5,0)-(7,6)) + │ ├── else_keyword_loc: (5,0)-(5,4) = "else" + │ ├── statements: ∅ + │ └── end_keyword_loc: (7,0)-(7,6) = "ensure" + ├── ensure_clause: + │ @ EnsureNode (location: (7,0)-(9,3)) + │ ├── ensure_keyword_loc: (7,0)-(7,6) = "ensure" + │ ├── statements: ∅ + │ └── end_keyword_loc: (9,0)-(9,3) = "end" + └── end_keyword_loc: (9,0)-(9,3) = "end" diff --git a/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt b/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt new file mode 100644 index 00000000000000..b36fe5c1fef513 --- /dev/null +++ b/test/prism/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt @@ -0,0 +1,23 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(4,3)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: + │ @ RescueNode (location: (2,0)-(2,6)) + │ ├── keyword_loc: (2,0)-(2,6) = "rescue" + │ ├── exceptions: (length: 0) + │ ├── operator_loc: ∅ + │ ├── reference: ∅ + │ ├── statements: ∅ + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: + │ @ EnsureNode (location: (3,0)-(4,3)) + │ ├── ensure_keyword_loc: (3,0)-(3,6) = "ensure" + │ ├── statements: ∅ + │ └── end_keyword_loc: (4,0)-(4,3) = "end" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/block_arg__bare.txt b/test/prism/snapshots/seattlerb/block_arg__bare.txt new file mode 100644 index 00000000000000..fb9b0bdd0da4fa --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg__bare.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,13)) + ├── name: :x + ├── name_loc: (1,4)-(1,5) = "x" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (1,6)-(1,7)) + │ ├── requireds: (length: 0) + │ ├── optionals: (length: 0) + │ ├── rest: ∅ + │ ├── posts: (length: 0) + │ ├── keywords: (length: 0) + │ ├── keyword_rest: ∅ + │ └── block: + │ @ BlockParameterNode (location: (1,6)-(1,7)) + │ ├── name: nil + │ ├── name_loc: ∅ + │ └── operator_loc: (1,6)-(1,7) = "&" + ├── body: ∅ + ├── locals: [:&] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,7)-(1,8) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,10)-(1,13) = "end" diff --git a/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt new file mode 100644 index 00000000000000..c3041819bfc4f7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_kwsplat.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,11)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,11)) + │ ├── locals: [:b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,9)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,8)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: + │ │ │ │ @ KeywordRestParameterNode (location: (1,5)-(1,8)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt b/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt new file mode 100644 index 00000000000000..d1382f9a53f91f --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_opt_arg_block.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(1,21)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,21)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,21)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,21)) + │ ├── locals: [:b, :c, :d, :e] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,19)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,18)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt b/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt new file mode 100644 index 00000000000000..1119f827dd92ff --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_opt_splat.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,20)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,20)) + │ ├── locals: [:b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,18)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,17)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt new file mode 100644 index 00000000000000..5bb2de2a16cb63 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(1,25)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,25)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,25)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,25)) + │ ├── locals: [:b, :c, :d, :e, :f] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,23)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,22)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_optional.txt b/test/prism/snapshots/seattlerb/block_arg_optional.txt new file mode 100644 index 00000000000000..8b29ce6e9fec69 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_optional.txt @@ -0,0 +1,41 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,13)) + │ ├── locals: [:b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,11)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,10)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,10)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_scope.txt b/test/prism/snapshots/seattlerb/block_arg_scope.txt new file mode 100644 index 00000000000000..e70f2f4ce7d3b7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_scope.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,12)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,10)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,6)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_scope2.txt b/test/prism/snapshots/seattlerb/block_arg_scope2.txt new file mode 100644 index 00000000000000..99af39a10975ed --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_scope2.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,3)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,4)-(1,5)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt b/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt new file mode 100644 index 00000000000000..a3a194f30b044c --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_arg_splat_arg.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,16)) + │ ├── locals: [:b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,14)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,13)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_args_kwargs.txt b/test/prism/snapshots/seattlerb/block_args_kwargs.txt new file mode 100644 index 00000000000000..4d2255fd661910 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_kwargs.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,23)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,23)) + │ ├── locals: [:kwargs] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,14)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,13)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: + │ │ │ │ @ KeywordRestParameterNode (location: (1,5)-(1,13)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt b/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt new file mode 100644 index 00000000000000..b8542f2ab7be5f --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_no_kwargs.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,13)) + │ ├── locals: [] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,11)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,10)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: + │ │ │ │ @ NoKeywordsParameterNode (location: (1,5)-(1,10)) + │ │ │ │ ├── operator_loc: (1,5)-(1,7) = "**" + │ │ │ │ └── keyword_loc: (1,7)-(1,10) = "nil" + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,4)-(1,5) = "|" + │ │ └── closing_loc: (1,10)-(1,11) = "|" + │ ├── body: ∅ + │ ├── opening_loc: (1,2)-(1,3) = "{" + │ └── closing_loc: (1,12)-(1,13) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_args_opt1.txt b/test/prism/snapshots/seattlerb/block_args_opt1.txt new file mode 100644 index 00000000000000..7e022ab1eac9ad --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_opt1.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(1,24)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,24)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,24)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,24)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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)) + │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_args_opt2.txt b/test/prism/snapshots/seattlerb/block_args_opt2.txt new file mode 100644 index 00000000000000..4a5b0ef03d730b --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_opt2.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,18)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,18)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,6)-(1,14)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 2) + │ │ │ │ ├── @ OptionalParameterNode (location: (1,6)-(1,9)) + │ │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_args_opt2_2.txt b/test/prism/snapshots/seattlerb/block_args_opt2_2.txt new file mode 100644 index 00000000000000..da706e2306df96 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_opt2_2.txt @@ -0,0 +1,65 @@ +@ ProgramNode (location: (1,0)-(1,35)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,35)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,35)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,35)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,23)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,22)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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)) + │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_args_opt3.txt b/test/prism/snapshots/seattlerb/block_args_opt3.txt new file mode 100644 index 00000000000000..5f187e20cf56fe --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_args_opt3.txt @@ -0,0 +1,72 @@ +@ ProgramNode (location: (1,0)-(1,42)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,42)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,42)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,42)) + │ ├── locals: [:a, :b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,27)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,26)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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)) + │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_break.txt b/test/prism/snapshots/seattlerb/block_break.txt new file mode 100644 index 00000000000000..ce4f94f1c98a56 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_break.txt @@ -0,0 +1,53 @@ +@ 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,6)-(1,26)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,6)-(1,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,10)-(1,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,10)-(1,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,10)-(1,13) = "arg" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "arg" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,14)-(1,26)) + │ │ ├── locals: [:bar] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "foo" + └── 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 new file mode 100644 index 00000000000000..49ddad48b2a22c --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_defn_call_block_call.txt @@ -0,0 +1,78 @@ +@ ProgramNode (location: (1,0)-(4,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,11)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(3,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(3,4)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,1)-(2,2) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── locals: [:c] + │ │ ├── def_keyword_loc: (1,2)-(1,5) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ │ ├── rparen_loc: (1,9)-(1,10) = ")" + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (3,1)-(3,4) = "end" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (4,1)-(4,11)) + ├── receiver: + │ @ CallNode (location: (4,1)-(4,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,1)-(4,2) = "e" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "e" + ├── call_operator_loc: (4,2)-(4,3) = "." + ├── message_loc: (4,3)-(4,4) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (4,5)-(4,11)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (4,5)-(4,7) = "do" + │ └── closing_loc: (4,8)-(4,11) = "end" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt b/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt new file mode 100644 index 00000000000000..812b7ab1516997 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_dot_op2_brace_block.txt @@ -0,0 +1,98 @@ +@ ProgramNode (location: (1,0)-(1,31)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,31)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,31)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,16)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: (1,2)-(1,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: (1,6)-(1,7) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,8)-(1,16)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,11)-(1,12)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (1,11)-(1,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,11)-(1,12) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (1,8)-(1,10) = "do" + │ │ └── closing_loc: (1,13)-(1,16) = "end" + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (1,16)-(1,17) = "." + ├── message_loc: (1,17)-(1,18) = "e" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,19)-(1,31)) + │ ├── locals: [:f] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,22)-(1,25)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,23)-(1,24)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,23)-(1,24)) + │ │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,26)-(1,27) = "g" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "g" + │ ├── opening_loc: (1,19)-(1,21) = "do" + │ └── closing_loc: (1,28)-(1,31) = "end" + ├── flags: ∅ + └── name: "e" diff --git a/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt b/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt new file mode 100644 index 00000000000000..2262a7cc883acd --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt @@ -0,0 +1,110 @@ +@ ProgramNode (location: (1,0)-(1,33)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,33)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,33)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,16)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: (1,2)-(1,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: (1,6)-(1,7) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,8)-(1,16)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,11)-(1,12)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (1,11)-(1,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,11)-(1,12) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (1,8)-(1,10) = "do" + │ │ └── closing_loc: (1,13)-(1,16) = "end" + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (1,16)-(1,17) = "." + ├── message_loc: (1,17)-(1,18) = "e" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,19)-(1,20)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,19)-(1,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,19)-(1,20) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "f" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,21)-(1,33)) + │ ├── locals: [:g] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,24)-(1,27)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,25)-(1,26)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,25)-(1,26)) + │ │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,28)-(1,29) = "h" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "h" + │ ├── opening_loc: (1,21)-(1,23) = "do" + │ └── closing_loc: (1,30)-(1,33) = "end" + ├── flags: ∅ + └── name: "e" diff --git a/test/prism/snapshots/seattlerb/block_call_operation_colon.txt b/test/prism/snapshots/seattlerb/block_call_operation_colon.txt new file mode 100644 index 00000000000000..3bcc89b50a36a6 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_operation_colon.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,12)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: (1,2)-(1,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,6)-(1,12)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,6)-(1,8) = "do" + │ │ └── closing_loc: (1,9)-(1,12) = "end" + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (1,12)-(1,14) = "::" + ├── message_loc: (1,14)-(1,15) = "d" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "d" diff --git a/test/prism/snapshots/seattlerb/block_call_operation_dot.txt b/test/prism/snapshots/seattlerb/block_call_operation_dot.txt new file mode 100644 index 00000000000000..93116aed589a22 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_operation_dot.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,12)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: (1,2)-(1,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,6)-(1,12)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,6)-(1,8) = "do" + │ │ └── closing_loc: (1,9)-(1,12) = "end" + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (1,12)-(1,13) = "." + ├── message_loc: (1,13)-(1,14) = "d" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "d" diff --git a/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt b/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt new file mode 100644 index 00000000000000..ec75ca056ad31b --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_call_paren_call_block_call.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(2,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,10)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,5)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,3)-(1,4) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── opening_loc: (1,2)-(1,3) = "(" + │ │ └── closing_loc: (1,4)-(1,5) = ")" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (2,0)-(2,10)) + ├── receiver: + │ @ CallNode (location: (2,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,0)-(2,1) = "c" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "c" + ├── call_operator_loc: (2,1)-(2,2) = "." + ├── message_loc: (2,2)-(2,3) = "d" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (2,4)-(2,10)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (2,4)-(2,6) = "do" + │ └── closing_loc: (2,7)-(2,10) = "end" + ├── flags: ∅ + └── name: "d" diff --git a/test/prism/snapshots/seattlerb/block_command_operation_colon.txt b/test/prism/snapshots/seattlerb/block_command_operation_colon.txt new file mode 100644 index 00000000000000..90bb7ad6d052ad --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_command_operation_colon.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,4)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (1,2)-(1,4)) + │ │ ├── opening_loc: (1,2)-(1,3) = ":" + │ │ ├── value_loc: (1,3)-(1,4) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,5)-(1,11)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,5)-(1,7) = "do" + │ │ └── closing_loc: (1,8)-(1,11) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── call_operator_loc: (1,11)-(1,13) = "::" + ├── message_loc: (1,13)-(1,14) = "c" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,15)-(1,17)) + │ └── arguments: (length: 1) + │ └── @ SymbolNode (location: (1,15)-(1,17)) + │ ├── opening_loc: (1,15)-(1,16) = ":" + │ ├── value_loc: (1,16)-(1,17) = "d" + │ ├── closing_loc: ∅ + │ └── unescaped: "d" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/block_command_operation_dot.txt b/test/prism/snapshots/seattlerb/block_command_operation_dot.txt new file mode 100644 index 00000000000000..94be9641fb41c1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_command_operation_dot.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,4)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (1,2)-(1,4)) + │ │ ├── opening_loc: (1,2)-(1,3) = ":" + │ │ ├── value_loc: (1,3)-(1,4) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,5)-(1,11)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,5)-(1,7) = "do" + │ │ └── closing_loc: (1,8)-(1,11) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── call_operator_loc: (1,11)-(1,12) = "." + ├── message_loc: (1,12)-(1,13) = "c" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,14)-(1,16)) + │ └── arguments: (length: 1) + │ └── @ SymbolNode (location: (1,14)-(1,16)) + │ ├── opening_loc: (1,14)-(1,15) = ":" + │ ├── value_loc: (1,15)-(1,16) = "d" + │ ├── closing_loc: ∅ + │ └── unescaped: "d" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt b/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt new file mode 100644 index 00000000000000..76c3b8c413dd51 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_decomp_anon_splat_arg.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:a] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,11)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ SplatNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ ├── operator_loc: (1,6)-(1,7) = "*" + │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt b/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt new file mode 100644 index 00000000000000..3eebb50b72301f --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_decomp_arg_splat.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,11)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ SplatNode (location: (1,9)-(1,10)) + │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ └── expression: ∅ + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt b/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt new file mode 100644 index 00000000000000..4ee66e215bb89d --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_decomp_arg_splat_arg.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,18)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,18)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,15)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,15)) + │ │ │ │ ├── parameters: (length: 3) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ └── name: :a + │ │ │ │ │ ├── @ SplatNode (location: (1,9)-(1,11)) + │ │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ │ └── expression: + │ │ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_decomp_splat.txt b/test/prism/snapshots/seattlerb/block_decomp_splat.txt new file mode 100644 index 00000000000000..698dba24db3d8e --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_decomp_splat.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,12)) + │ ├── locals: [:a] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,10)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,9)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,9)) + │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ └── @ SplatNode (location: (1,6)-(1,8)) + │ │ │ │ │ ├── operator_loc: (1,6)-(1,7) = "*" + │ │ │ │ │ └── expression: + │ │ │ │ │ @ RequiredParameterNode (location: (1,7)-(1,8)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/block_kw.txt b/test/prism/snapshots/seattlerb/block_kw.txt new file mode 100644 index 00000000000000..f7060638845222 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_kw.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,4) = "blah" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,5)-(1,15)) + │ ├── locals: [:k] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,7)-(1,13)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,8)-(1,12)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (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) = "}" + ├── flags: ∅ + └── name: "blah" diff --git a/test/prism/snapshots/seattlerb/block_kw__required.txt b/test/prism/snapshots/seattlerb/block_kw__required.txt new file mode 100644 index 00000000000000..d46bfcf21a65d0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_kw__required.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,4) = "blah" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,5)-(1,16)) + │ ├── locals: [:k] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,8)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,9)-(1,11)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (location: (1,9)-(1,11)) + │ │ │ │ ├── name: :k + │ │ │ │ ├── name_loc: (1,9)-(1,11) = "k:" + │ │ │ │ └── value: ∅ + │ │ │ ├── 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" + ├── flags: ∅ + └── name: "blah" diff --git a/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt b/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt new file mode 100644 index 00000000000000..f268418a5f4521 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_kwarg_lvar.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,20)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,2) = "bl" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,3)-(1,20)) + │ ├── locals: [:kw] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,5)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,6)-(1,14)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (location: (1,6)-(1,14)) + │ │ │ │ ├── name: :kw + │ │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:" + │ │ │ │ └── value: + │ │ │ │ @ SymbolNode (location: (1,10)-(1,14)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "bl" diff --git a/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt b/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt new file mode 100644 index 00000000000000..f062044909c143 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_kwarg_lvar_multiple.txt @@ -0,0 +1,57 @@ +@ ProgramNode (location: (1,0)-(1,33)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,33)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,33)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,2) = "bl" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,3)-(1,33)) + │ ├── locals: [:kw, :kw2] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,5)-(1,28)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,6)-(1,26)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 2) + │ │ │ │ ├── @ KeywordParameterNode (location: (1,6)-(1,14)) + │ │ │ │ │ ├── name: :kw + │ │ │ │ │ ├── name_loc: (1,6)-(1,9) = "kw:" + │ │ │ │ │ └── value: + │ │ │ │ │ @ SymbolNode (location: (1,10)-(1,14)) + │ │ │ │ │ ├── opening_loc: (1,10)-(1,11) = ":" + │ │ │ │ │ ├── value_loc: (1,11)-(1,14) = "val" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "val" + │ │ │ │ └── @ KeywordParameterNode (location: (1,16)-(1,26)) + │ │ │ │ ├── name: :kw2 + │ │ │ │ ├── name_loc: (1,16)-(1,20) = "kw2:" + │ │ │ │ └── value: + │ │ │ │ @ SymbolNode (location: (1,21)-(1,26)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "bl" diff --git a/test/prism/snapshots/seattlerb/block_next.txt b/test/prism/snapshots/seattlerb/block_next.txt new file mode 100644 index 00000000000000..5c1b27d8f3fa46 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_next.txt @@ -0,0 +1,53 @@ +@ 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,5)-(1,25)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,9)-(1,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,9)-(1,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,12) = "arg" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "arg" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,13)-(1,25)) + │ │ ├── locals: [:bar] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "foo" + └── 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 new file mode 100644 index 00000000000000..32d5738df328fe --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_opt_arg.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,8)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_opt_splat.txt b/test/prism/snapshots/seattlerb/block_opt_splat.txt new file mode 100644 index 00000000000000..9a8a4938fe8120 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_opt_splat.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,10)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt new file mode 100644 index 00000000000000..e3fc3287375b6c --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt @@ -0,0 +1,51 @@ +@ ProgramNode (location: (1,0)-(1,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,22)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,22)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,22)) + │ ├── locals: [:b, :c, :d, :e] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,20)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,19)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,8)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_optarg.txt b/test/prism/snapshots/seattlerb/block_optarg.txt new file mode 100644 index 00000000000000..b930687f3b0538 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_optarg.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 1) + │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,11)) + │ │ │ │ ├── name: :b + │ │ │ │ ├── name_loc: (1,5)-(1,6) = "b" + │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "=" + │ │ │ │ └── value: + │ │ │ │ @ SymbolNode (location: (1,9)-(1,11)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_paren_splat.txt b/test/prism/snapshots/seattlerb/block_paren_splat.txt new file mode 100644 index 00000000000000..f7592497f1043f --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_paren_splat.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,15)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,13)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,12)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,12)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ SplatNode (location: (1,9)-(1,11)) + │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ └── expression: + │ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_reg_optarg.txt b/test/prism/snapshots/seattlerb/block_reg_optarg.txt new file mode 100644 index 00000000000000..2d6d50122c5a3a --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_reg_optarg.txt @@ -0,0 +1,46 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ └── 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)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_return.txt b/test/prism/snapshots/seattlerb/block_return.txt new file mode 100644 index 00000000000000..8c391abd5306d8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_return.txt @@ -0,0 +1,53 @@ +@ 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)) + └── arguments: (length: 1) + └── @ CallNode (location: (1,7)-(1,27)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,7)-(1,10) = "foo" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,11)-(1,14)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,11)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "arg" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "arg" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,15)-(1,27)) + │ ├── locals: [:bar] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,18)-(1,23)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,19)-(1,22)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,19)-(1,22)) + │ │ │ │ └── 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" + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/seattlerb/block_scope.txt b/test/prism/snapshots/seattlerb/block_scope.txt new file mode 100644 index 00000000000000..14263c5623847e --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_scope.txt @@ -0,0 +1,28 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,10)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,10)) + │ ├── locals: [:b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,8)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 1) + │ │ │ └── @ BlockLocalVariableNode (location: (1,6)-(1,7)) + │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/block_splat_reg.txt b/test/prism/snapshots/seattlerb/block_splat_reg.txt new file mode 100644 index 00000000000000..4b12ce34a8382c --- /dev/null +++ b/test/prism/snapshots/seattlerb/block_splat_reg.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,13)) + │ ├── locals: [:b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,11)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,10)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (1,5)-(1,7)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/bug169.txt b/test/prism/snapshots/seattlerb/bug169.txt new file mode 100644 index 00000000000000..94c2597316acf8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug169.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,4)) + │ └── arguments: (length: 1) + │ └── @ ParenthesesNode (location: (1,2)-(1,4)) + │ ├── body: ∅ + │ ├── opening_loc: (1,2)-(1,3) = "(" + │ └── closing_loc: (1,3)-(1,4) = ")" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,5)-(1,7)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,5)-(1,6) = "{" + │ └── closing_loc: (1,6)-(1,7) = "}" + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/seattlerb/bug179.txt b/test/prism/snapshots/seattlerb/bug179.txt new file mode 100644 index 00000000000000..233a4767e002e1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug179.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,9)) + │ └── arguments: (length: 1) + │ └── @ RangeNode (location: (1,2)-(1,9)) + │ ├── 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) = ".." + │ └── flags: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/seattlerb/bug190.txt b/test/prism/snapshots/seattlerb/bug190.txt new file mode 100644 index 00000000000000..527304835a7f06 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug190.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ RegularExpressionNode (location: (1,0)-(1,6)) + ├── opening_loc: (1,0)-(1,3) = "%r'" + ├── content_loc: (1,3)-(1,5) = "\\'" + ├── closing_loc: (1,5)-(1,6) = "'" + ├── unescaped: "'" + └── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/bug191.txt b/test/prism/snapshots/seattlerb/bug191.txt new file mode 100644 index 00000000000000..313e892629e570 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug191.txt @@ -0,0 +1,85 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,8)-(1,9) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + └── @ IfNode (location: (3,0)-(3,9)) + ├── if_keyword_loc: ∅ + ├── predicate: + │ @ CallNode (location: (3,0)-(3,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,8)-(3,9) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── end_keyword_loc: ∅ + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/bug202.txt b/test/prism/snapshots/seattlerb/bug202.txt new file mode 100644 index 00000000000000..3faff193dcf078 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug202.txt @@ -0,0 +1,20 @@ +@ 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 new file mode 100644 index 00000000000000..c53055bae0c552 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug236.txt @@ -0,0 +1,71 @@ +@ ProgramNode (location: (1,0)-(3,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,6)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,1)-(1,7)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (1,2)-(1,6)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (1,3)-(1,5)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (1,4)-(1,5)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── name_loc: ∅ + │ │ │ │ │ └── operator_loc: (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) = "}" + │ ├── flags: ∅ + │ └── name: "x" + └── @ CallNode (location: (3,0)-(3,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,0)-(3,1) = "x" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (3,1)-(3,6)) + │ ├── locals: [:a] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (3,2)-(3,5)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (3,3)-(3,4)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (3,3)-(3,4)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/bug290.txt b/test/prism/snapshots/seattlerb/bug290.txt new file mode 100644 index 00000000000000..dbe69a5a1542b0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug290.txt @@ -0,0 +1,24 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(3,3)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (2,2)-(2,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (2,2)-(2,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,2)-(2,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── rescue_clause: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/bug_187.txt b/test/prism/snapshots/seattlerb/bug_187.txt new file mode 100644 index 00000000000000..0f55dc049c604d --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_187.txt @@ -0,0 +1,58 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,7) = "private" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,8)-(3,3)) + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (2,0)-(2,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,0)-(2,1) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── call_operator_loc: (2,1)-(2,2) = "." + │ │ ├── message_loc: (2,2)-(2,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (2,4)-(2,10)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (2,4)-(2,6) = "do" + │ │ │ └── closing_loc: (2,7)-(2,10) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,8)-(1,11) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "private" diff --git a/test/prism/snapshots/seattlerb/bug_215.txt b/test/prism/snapshots/seattlerb/bug_215.txt new file mode 100644 index 00000000000000..0ce43b58dee5f7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_215.txt @@ -0,0 +1,13 @@ +@ 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)) + │ ├── opening_loc: (1,6)-(1,9) = "%s(" + │ ├── value_loc: (1,9)-(1,12) = "foo" + │ ├── closing_loc: (1,12)-(1,13) = ")" + │ └── unescaped: "foo" + └── keyword_loc: (1,0)-(1,5) = "undef" diff --git a/test/prism/snapshots/seattlerb/bug_249.txt b/test/prism/snapshots/seattlerb/bug_249.txt new file mode 100644 index 00000000000000..3fd204a71b1da4 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_249.txt @@ -0,0 +1,83 @@ +@ ProgramNode (location: (1,0)-(4,28)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,28)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(4,28)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,5) = "mount" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,6)-(4,28)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (1,6)-(4,9)) + │ │ ├── receiver: + │ │ │ @ ParenthesesNode (location: (1,6)-(4,5)) + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (1,7)-(4,4)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (1,7)-(4,4)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ ConstantReadNode (location: (1,7)-(1,12)) + │ │ │ │ │ └── name: :Class + │ │ │ │ ├── call_operator_loc: (1,12)-(1,13) = "." + │ │ │ │ ├── message_loc: (1,13)-(1,16) = "new" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (1,17)-(4,4)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: + │ │ │ │ │ │ @ StatementsNode (location: (2,0)-(3,3)) + │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ └── @ DefNode (location: (2,0)-(3,3)) + │ │ │ │ │ │ ├── name: :initialize + │ │ │ │ │ │ ├── name_loc: (2,4)-(2,14) = "initialize" + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── def_keyword_loc: (2,0)-(2,3) = "def" + │ │ │ │ │ │ ├── operator_loc: ∅ + │ │ │ │ │ │ ├── lparen_loc: ∅ + │ │ │ │ │ │ ├── rparen_loc: ∅ + │ │ │ │ │ │ ├── equal_loc: ∅ + │ │ │ │ │ │ └── end_keyword_loc: (3,0)-(3,3) = "end" + │ │ │ │ │ ├── opening_loc: (1,17)-(1,19) = "do" + │ │ │ │ │ └── closing_loc: (4,1)-(4,4) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "new" + │ │ │ ├── opening_loc: (1,6)-(1,7) = "(" + │ │ │ └── closing_loc: (4,4)-(4,5) = ")" + │ │ ├── call_operator_loc: (4,5)-(4,6) = "." + │ │ ├── message_loc: (4,6)-(4,9) = "new" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "new" + │ └── @ KeywordHashNode (location: (4,11)-(4,28)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (4,11)-(4,28)) + │ ├── key: + │ │ @ SymbolNode (location: (4,11)-(4,14)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "mount" diff --git a/test/prism/snapshots/seattlerb/bug_and.txt b/test/prism/snapshots/seattlerb/bug_and.txt new file mode 100644 index 00000000000000..49c387a72d0705 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_and.txt @@ -0,0 +1,20 @@ +@ 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)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (4,9)-(4,10) = "[" + │ └── closing_loc: (4,10)-(4,11) = "]" + └── operator_loc: (4,5)-(4,8) = "and" diff --git a/test/prism/snapshots/seattlerb/bug_args__19.txt b/test/prism/snapshots/seattlerb/bug_args__19.txt new file mode 100644 index 00000000000000..45abd4c0e4bc76 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_args__19.txt @@ -0,0 +1,54 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,16)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,11)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ └── name: :a + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ └── name: :b + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,13)-(1,14) = "d" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "d" + │ ├── opening_loc: (1,2)-(1,3) = "{" + │ └── closing_loc: (1,15)-(1,16) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn.txt b/test/prism/snapshots/seattlerb/bug_args_masgn.txt new file mode 100644 index 00000000000000..748eb80f26b4ca --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_args_masgn.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredDestructuredParameterNode (location: (1,5)-(1,11)) + │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ │ └── name: :a + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn2.txt b/test/prism/snapshots/seattlerb/bug_args_masgn2.txt new file mode 100644 index 00000000000000..b4e786c7c2f04a --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_args_masgn2.txt @@ -0,0 +1,50 @@ +@ ProgramNode (location: (1,0)-(1,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,22)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,22)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,22)) + │ ├── locals: [:a, :b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,20)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,19)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredDestructuredParameterNode (location: (1,5)-(1,16)) + │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ ├── @ RequiredDestructuredParameterNode (location: (1,6)-(1,12)) + │ │ │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,7)-(1,8)) + │ │ │ │ │ │ │ │ │ └── name: :a + │ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ │ │ └── name: :b + │ │ │ │ │ │ │ ├── opening_loc: (1,6)-(1,7) = "(" + │ │ │ │ │ │ │ └── closing_loc: (1,11)-(1,12) = ")" + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15)) + │ │ │ │ │ │ └── name: :c + │ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt b/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt new file mode 100644 index 00000000000000..61eacf4421f373 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,19)) + │ ├── locals: [:k, :v, :i] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,17)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,16)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,16)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredDestructuredParameterNode (location: (1,6)-(1,12)) + │ │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,7)-(1,8)) + │ │ │ │ │ │ │ │ └── name: :k + │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ │ └── name: :v + │ │ │ │ │ │ ├── opening_loc: (1,6)-(1,7) = "(" + │ │ │ │ │ │ └── closing_loc: (1,11)-(1,12) = ")" + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,14)-(1,15)) + │ │ │ │ │ └── name: :i + │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt b/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt new file mode 100644 index 00000000000000..3a7d53323836d7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_call_arglist_parens.txt @@ -0,0 +1,101 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,8)-(2,9) = "g" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (2,10)-(2,17)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "g" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,6)-(1,9) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,6)-(3,9) = "end" + ├── @ DefNode (location: (6,6)-(8,9)) + │ ├── name: :f + │ ├── name_loc: (6,10)-(6,11) = "f" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (7,8)-(7,16)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (7,8)-(7,16)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,8)-(7,9) = "g" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,10)-(7,16)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "g" + │ ├── locals: [] + │ ├── def_keyword_loc: (6,6)-(6,9) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (6,11)-(6,12) = "(" + │ ├── rparen_loc: (6,12)-(6,13) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (8,6)-(8,9) = "end" + └── @ CallNode (location: (11,0)-(11,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (11,0)-(11,1) = "g" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (11,2)-(11,9)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "g" diff --git a/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt b/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt new file mode 100644 index 00000000000000..ac948bc6c9b8b7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_case_when_regexp.txt @@ -0,0 +1,26 @@ +@ 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)) + │ ├── 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)) + │ │ ├── opening_loc: (1,14)-(1,15) = "/" + │ │ ├── content_loc: (1,15)-(1,16) = "x" + │ │ ├── closing_loc: (1,16)-(1,17) = "/" + │ │ ├── unescaped: "x" + │ │ └── flags: ∅ + │ └── statements: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,23)-(1,26) = "end" diff --git a/test/prism/snapshots/seattlerb/bug_comma.txt b/test/prism/snapshots/seattlerb/bug_comma.txt new file mode 100644 index 00000000000000..07ec02b23257ef --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_comma.txt @@ -0,0 +1,39 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,3)-(1,7) = "test" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,15)) + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,12)-(1,15) = "dir" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "dir" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "test" + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (1,21)-(1,24) = "end" diff --git a/test/prism/snapshots/seattlerb/bug_cond_pct.txt b/test/prism/snapshots/seattlerb/bug_cond_pct.txt new file mode 100644 index 00000000000000..bb07f009aa41cf --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_cond_pct.txt @@ -0,0 +1,21 @@ +@ 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)) + │ │ ├── opening_loc: (1,11)-(1,14) = "%r%" + │ │ ├── content_loc: (1,14)-(1,22) = "blahblah" + │ │ ├── closing_loc: (1,22)-(1,23) = "%" + │ │ ├── unescaped: "blahblah" + │ │ └── flags: ∅ + │ └── statements: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,25)-(1,28) = "end" diff --git a/test/prism/snapshots/seattlerb/bug_hash_args.txt b/test/prism/snapshots/seattlerb/bug_hash_args.txt new file mode 100644 index 00000000000000..3a204fb4b84ac4 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_hash_args.txt @@ -0,0 +1,34 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "foo" + ├── opening_loc: (1,3)-(1,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,18)) + │ └── arguments: (length: 2) + │ ├── @ SymbolNode (location: (1,4)-(1,8)) + │ │ ├── opening_loc: (1,4)-(1,5) = ":" + │ │ ├── value_loc: (1,5)-(1,8) = "bar" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bar" + │ └── @ KeywordHashNode (location: (1,10)-(1,18)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,10)-(1,18)) + │ ├── key: + │ │ @ SymbolNode (location: (1,10)-(1,14)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt new file mode 100644 index 00000000000000..73bc04243d025e --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_hash_args_trailing_comma.txt @@ -0,0 +1,34 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,20)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "foo" + ├── opening_loc: (1,3)-(1,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,18)) + │ └── arguments: (length: 2) + │ ├── @ SymbolNode (location: (1,4)-(1,8)) + │ │ ├── opening_loc: (1,4)-(1,5) = ":" + │ │ ├── value_loc: (1,5)-(1,8) = "bar" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bar" + │ └── @ KeywordHashNode (location: (1,10)-(1,18)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,10)-(1,18)) + │ ├── key: + │ │ @ SymbolNode (location: (1,10)-(1,14)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt b/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt new file mode 100644 index 00000000000000..e4b9536b87a8f1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_hash_interp_array.txt @@ -0,0 +1,25 @@ +@ 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)) + │ │ ├── elements: (length: 0) + │ │ ├── opening_loc: (1,9)-(1,10) = "[" + │ │ └── closing_loc: (1,10)-(1,11) = "]" + │ └── operator_loc: ∅ + └── closing_loc: (1,12)-(1,13) = "}" diff --git a/test/prism/snapshots/seattlerb/bug_masgn_right.txt b/test/prism/snapshots/seattlerb/bug_masgn_right.txt new file mode 100644 index 00000000000000..c19931cdd12ac2 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_masgn_right.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,14)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/bug_not_parens.txt b/test/prism/snapshots/seattlerb/bug_not_parens.txt new file mode 100644 index 00000000000000..8b937728d0257a --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_not_parens.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ CallNode (location: (1,4)-(1,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "not" + ├── opening_loc: (1,3)-(1,4) = "(" + ├── arguments: ∅ + ├── closing_loc: (1,5)-(1,6) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt b/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt new file mode 100644 index 00000000000000..c3df9b1be979a8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/bug_op_asgn_rescue.txt @@ -0,0 +1,26 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [:a] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ LocalVariableOrWriteNode (location: (1,0)-(1,18)) + ├── name_loc: (1,0)-(1,1) = "a" + ├── operator_loc: (1,2)-(1,5) = "||=" + ├── value: + │ @ RescueModifierNode (location: (1,6)-(1,18)) + │ ├── expression: + │ │ @ CallNode (location: (1,6)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── keyword_loc: (1,8)-(1,14) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (1,15)-(1,18)) + ├── name: :a + └── depth: 0 diff --git a/test/prism/snapshots/seattlerb/call_and.txt b/test/prism/snapshots/seattlerb/call_and.txt new file mode 100644 index 00000000000000..009eb877d05782 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_and.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "&" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "&" diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc.txt b/test/prism/snapshots/seattlerb/call_arg_assoc.txt new file mode 100644 index 00000000000000..2f7f20b2d94e59 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_arg_assoc.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,10)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,9)) + │ └── arguments: (length: 2) + │ ├── @ IntegerNode (location: (1,2)-(1,3)) + │ │ └── flags: decimal + │ └── @ KeywordHashNode (location: (1,5)-(1,9)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt new file mode 100644 index 00000000000000..f477f046ac3336 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_arg_assoc_kwsplat.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,15)) + │ └── arguments: (length: 2) + │ ├── @ IntegerNode (location: (1,2)-(1,3)) + │ │ └── flags: decimal + │ └── @ KeywordHashNode (location: (1,5)-(1,15)) + │ └── elements: (length: 2) + │ ├── @ AssocNode (location: (1,5)-(1,10)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,5)-(1,8)) + │ │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt new file mode 100644 index 00000000000000..6ebfe62964eff0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_arg_kwsplat.txt @@ -0,0 +1,34 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,8)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (1,2)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── @ KeywordHashNode (location: (1,5)-(1,8)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt new file mode 100644 index 00000000000000..095bab4ce17915 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_args_assoc_quoted.txt @@ -0,0 +1,95 @@ +@ ProgramNode (location: (1,0)-(5,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,8)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,2)-(1,11)) + │ │ └── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,5)-(1,6) = "k" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "k" + │ │ │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "x" + ├── @ CallNode (location: (3,0)-(3,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,2)-(3,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (3,2)-(3,8)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (3,2)-(3,8)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (3,2)-(3,6)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "x" + └── @ CallNode (location: (5,0)-(5,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,1) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (5,2)-(5,8)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (5,2)-(5,8)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (5,2)-(5,8)) + │ ├── key: + │ │ @ SymbolNode (location: (5,2)-(5,6)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt new file mode 100644 index 00000000000000..7af70d5832d896 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_args_assoc_trailing_comma.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,11)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,9)) + │ └── arguments: (length: 2) + │ ├── @ IntegerNode (location: (1,2)-(1,3)) + │ │ └── flags: decimal + │ └── @ KeywordHashNode (location: (1,5)-(1,9)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_args_command.txt b/test/prism/snapshots/seattlerb/call_args_command.txt new file mode 100644 index 00000000000000..dfd0e60fbd6aed --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_args_command.txt @@ -0,0 +1,51 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,2) = "." + ├── message_loc: (1,2)-(1,3) = "b" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,9)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,4)-(1,9)) + │ ├── receiver: + │ │ @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── call_operator_loc: (1,5)-(1,6) = "." + │ ├── message_loc: (1,6)-(1,7) = "d" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,8)-(1,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "d" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/call_array_arg.txt b/test/prism/snapshots/seattlerb/call_array_arg.txt new file mode 100644 index 00000000000000..f0bc196cf35db8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_array_arg.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = "==" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,13)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (1,5)-(1,13)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (1,6)-(1,8)) + │ │ │ ├── opening_loc: (1,6)-(1,7) = ":" + │ │ │ ├── value_loc: (1,7)-(1,8) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ └── @ SymbolNode (location: (1,10)-(1,12)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "==" diff --git a/test/prism/snapshots/seattlerb/call_array_block_call.txt b/test/prism/snapshots/seattlerb/call_array_block_call.txt new file mode 100644 index 00000000000000..6c78b7f52c94f2 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_array_block_call.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,19)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (1,2)-(1,19)) + │ ├── elements: (length: 2) + │ │ ├── @ NilNode (location: (1,4)-(1,7)) + │ │ └── @ CallNode (location: (1,9)-(1,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,10) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,11)-(1,17)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,11)-(1,13) = "do" + │ │ │ └── closing_loc: (1,14)-(1,17) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── opening_loc: (1,2)-(1,3) = "[" + │ └── closing_loc: (1,18)-(1,19) = "]" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt b/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt new file mode 100644 index 00000000000000..7b25a644198b01 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_array_lambda_block_call.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(2,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,11)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (1,2)-(1,11)) + │ ├── elements: (length: 1) + │ │ └── @ LambdaNode (location: (1,3)-(1,10)) + │ │ ├── locals: [] + │ │ ├── operator_loc: (1,3)-(1,5) = "->" + │ │ ├── opening_loc: (1,8)-(1,9) = "{" + │ │ ├── closing_loc: (1,9)-(1,10) = "}" + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (1,5)-(1,7)) + │ │ │ ├── parameters: ∅ + │ │ │ ├── locals: (length: 0) + │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ └── closing_loc: (1,6)-(1,7) = ")" + │ │ └── body: ∅ + │ ├── opening_loc: (1,2)-(1,3) = "[" + │ └── closing_loc: (1,10)-(1,11) = "]" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,12)-(2,3)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,12)-(1,14) = "do" + │ └── closing_loc: (2,0)-(2,3) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt b/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt new file mode 100644 index 00000000000000..6ce4c98d5fa08b --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_array_lit_inline_hash.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,15)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (1,2)-(1,15)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (1,3)-(1,5)) + │ │ │ ├── opening_loc: (1,3)-(1,4) = ":" + │ │ │ ├── value_loc: (1,4)-(1,5) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ └── @ KeywordHashNode (location: (1,7)-(1,14)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,7)-(1,14)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,7)-(1,9)) + │ │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_assoc.txt b/test/prism/snapshots/seattlerb/call_assoc.txt new file mode 100644 index 00000000000000..59ede3254ea2e4 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_assoc.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(1,6)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_assoc_new.txt b/test/prism/snapshots/seattlerb/call_assoc_new.txt new file mode 100644 index 00000000000000..d1121c377ff42c --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_assoc_new.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(1,5)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,2)-(1,5)) + │ ├── key: + │ │ @ SymbolNode (location: (1,2)-(1,4)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt new file mode 100644 index 00000000000000..c7ea9767c74a0e --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_assoc_new_if_multiline.txt @@ -0,0 +1,51 @@ +@ ProgramNode (location: (1,0)-(5,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,4)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(5,4)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(5,3)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(5,3)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,2)-(5,3)) + │ ├── key: + │ │ @ SymbolNode (location: (1,2)-(1,4)) + │ │ ├── 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)) + │ │ │ ├── opening_loc: (1,8)-(1,9) = ":" + │ │ │ ├── value_loc: (1,9)-(1,10) = "c" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "c" + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt new file mode 100644 index 00000000000000..bf0cce69561351 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_assoc_trailing_comma.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(1,6)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_bang_command_call.txt b/test/prism/snapshots/seattlerb/call_bang_command_call.txt new file mode 100644 index 00000000000000..b38ffe085bd1a8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_bang_command_call.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ CallNode (location: (1,2)-(1,7)) + │ ├── receiver: + │ │ @ CallNode (location: (1,2)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,5) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,6)-(1,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/seattlerb/call_bang_squiggle.txt b/test/prism/snapshots/seattlerb/call_bang_squiggle.txt new file mode 100644 index 00000000000000..2bc2d0a9bdd7be --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_bang_squiggle.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = "!~" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!~" diff --git a/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt b/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt new file mode 100644 index 00000000000000..f43f9a0bd949cc --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_begin_call_block_call.txt @@ -0,0 +1,52 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(3,3)) + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (2,0)-(2,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,0)-(2,1) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── call_operator_loc: (2,1)-(2,2) = "." + │ │ ├── message_loc: (2,2)-(2,3) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (2,4)-(2,10)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (2,4)-(2,6) = "do" + │ │ │ └── closing_loc: (2,7)-(2,10) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "c" + │ ├── rescue_clause: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_block_arg_named.txt b/test/prism/snapshots/seattlerb/call_block_arg_named.txt new file mode 100644 index 00000000000000..deb1433cabcffe --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_block_arg_named.txt @@ -0,0 +1,28 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,3)-(1,6) = "blk" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "blk" + │ └── operator_loc: (1,2)-(1,3) = "&" + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/call_carat.txt b/test/prism/snapshots/seattlerb/call_carat.txt new file mode 100644 index 00000000000000..6bf95e2a5a2c53 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_carat.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "^" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "^" diff --git a/test/prism/snapshots/seattlerb/call_colon2.txt b/test/prism/snapshots/seattlerb/call_colon2.txt new file mode 100644 index 00000000000000..42206b4f0859ac --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_colon2.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,4)) + ├── receiver: + │ @ ConstantReadNode (location: (1,0)-(1,1)) + │ └── name: :A + ├── call_operator_loc: (1,1)-(1,3) = "::" + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/call_colon_parens.txt b/test/prism/snapshots/seattlerb/call_colon_parens.txt new file mode 100644 index 00000000000000..f1327adac3bd85 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_colon_parens.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: (1,1)-(1,3) = "::" + ├── message_loc: ∅ + ├── opening_loc: (1,3)-(1,4) = "(" + ├── arguments: ∅ + ├── closing_loc: (1,4)-(1,5) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "call" diff --git a/test/prism/snapshots/seattlerb/call_div.txt b/test/prism/snapshots/seattlerb/call_div.txt new file mode 100644 index 00000000000000..4a9961847bfb68 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_div.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "/" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "/" diff --git a/test/prism/snapshots/seattlerb/call_dot_parens.txt b/test/prism/snapshots/seattlerb/call_dot_parens.txt new file mode 100644 index 00000000000000..a473a2258ab15c --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_dot_parens.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,4)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: (1,1)-(1,2) = "." + ├── message_loc: ∅ + ├── opening_loc: (1,2)-(1,3) = "(" + ├── arguments: ∅ + ├── closing_loc: (1,3)-(1,4) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "call" diff --git a/test/prism/snapshots/seattlerb/call_env.txt b/test/prism/snapshots/seattlerb/call_env.txt new file mode 100644 index 00000000000000..f2996f3a219e05 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_env.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,2) = "." + ├── message_loc: (1,2)-(1,7) = "happy" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "happy" diff --git a/test/prism/snapshots/seattlerb/call_eq3.txt b/test/prism/snapshots/seattlerb/call_eq3.txt new file mode 100644 index 00000000000000..146aa7993a0980 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_eq3.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,5) = "===" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,6)-(1,7)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "===" diff --git a/test/prism/snapshots/seattlerb/call_gt.txt b/test/prism/snapshots/seattlerb/call_gt.txt new file mode 100644 index 00000000000000..8cb2772a90d31f --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_gt.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = ">" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: ">" diff --git a/test/prism/snapshots/seattlerb/call_kwsplat.txt b/test/prism/snapshots/seattlerb/call_kwsplat.txt new file mode 100644 index 00000000000000..d750ea21e974a5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_kwsplat.txt @@ -0,0 +1,24 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,2)-(1,5)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_leading_dots.txt b/test/prism/snapshots/seattlerb/call_leading_dots.txt new file mode 100644 index 00000000000000..a8fad7a4aa30f6 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_leading_dots.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(3,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,2)) + ├── receiver: + │ @ CallNode (location: (1,0)-(2,2)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (2,0)-(2,1) = "." + │ ├── message_loc: (2,1)-(2,2) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (3,0)-(3,1) = "." + ├── message_loc: (3,1)-(3,2) = "c" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt b/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt new file mode 100644 index 00000000000000..b21a68b5426fb7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_leading_dots_comment.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(4,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(4,2)) + ├── receiver: + │ @ CallNode (location: (1,0)-(2,2)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (2,0)-(2,1) = "." + │ ├── message_loc: (2,1)-(2,2) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (4,0)-(4,1) = "." + ├── message_loc: (4,1)-(4,2) = "d" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "d" diff --git a/test/prism/snapshots/seattlerb/call_lt.txt b/test/prism/snapshots/seattlerb/call_lt.txt new file mode 100644 index 00000000000000..dcdfbb3420c39e --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_lt.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "<" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "<" diff --git a/test/prism/snapshots/seattlerb/call_lte.txt b/test/prism/snapshots/seattlerb/call_lte.txt new file mode 100644 index 00000000000000..32f886fa3c1a29 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_lte.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = "<=" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "<=" diff --git a/test/prism/snapshots/seattlerb/call_not.txt b/test/prism/snapshots/seattlerb/call_not.txt new file mode 100644 index 00000000000000..6c2f2d5f52c142 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_not.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,4)-(1,6)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "not" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/seattlerb/call_pipe.txt b/test/prism/snapshots/seattlerb/call_pipe.txt new file mode 100644 index 00000000000000..4981718ce9df16 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_pipe.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "|" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "|" diff --git a/test/prism/snapshots/seattlerb/call_rshift.txt b/test/prism/snapshots/seattlerb/call_rshift.txt new file mode 100644 index 00000000000000..dd50e3e3366384 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_rshift.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = ">>" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: ">>" diff --git a/test/prism/snapshots/seattlerb/call_self_brackets.txt b/test/prism/snapshots/seattlerb/call_self_brackets.txt new file mode 100644 index 00000000000000..0fb7d677d84d2b --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_self_brackets.txt @@ -0,0 +1,20 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ SelfNode (location: (1,0)-(1,4)) + ├── call_operator_loc: ∅ + ├── message_loc: (1,4)-(1,7) = "[1]" + ├── opening_loc: (1,4)-(1,5) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: (1,6)-(1,7) = "]" + ├── block: ∅ + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/seattlerb/call_spaceship.txt b/test/prism/snapshots/seattlerb/call_spaceship.txt new file mode 100644 index 00000000000000..388b8dc4274374 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_spaceship.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,5) = "<=>" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,6)-(1,7)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "<=>" diff --git a/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt b/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt new file mode 100644 index 00000000000000..576e1a49b05205 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_stabby_do_end_with_block.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,22)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,22)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,13)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(1,13)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,5)-(1,7) = "do" + │ ├── closing_loc: (1,10)-(1,13) = "end" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (1,8)-(1,9)) + │ └── body: (length: 1) + │ └── @ IntegerNode (location: (1,8)-(1,9)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,14)-(1,22)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,17)-(1,18)) + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (1,17)-(1,18)) + │ │ └── flags: decimal + │ ├── opening_loc: (1,14)-(1,16) = "do" + │ └── closing_loc: (1,19)-(1,22) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt b/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt new file mode 100644 index 00000000000000..0dc00fd90db255 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_stabby_with_braces_block.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,10)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(1,10)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,5)-(1,6) = "{" + │ ├── closing_loc: (1,9)-(1,10) = "}" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (1,7)-(1,8)) + │ └── body: (length: 1) + │ └── @ IntegerNode (location: (1,7)-(1,8)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,11)-(1,19)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,14)-(1,15)) + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (1,14)-(1,15)) + │ │ └── flags: decimal + │ ├── opening_loc: (1,11)-(1,13) = "do" + │ └── closing_loc: (1,16)-(1,19) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/call_star.txt b/test/prism/snapshots/seattlerb/call_star.txt new file mode 100644 index 00000000000000..bf3fa53b4402cc --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_star.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,3) = "*" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "*" diff --git a/test/prism/snapshots/seattlerb/call_star2.txt b/test/prism/snapshots/seattlerb/call_star2.txt new file mode 100644 index 00000000000000..960f676135932a --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_star2.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,2)-(1,4) = "**" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "**" diff --git a/test/prism/snapshots/seattlerb/call_trailing_comma.txt b/test/prism/snapshots/seattlerb/call_trailing_comma.txt new file mode 100644 index 00000000000000..91ffc098bf7ea1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_trailing_comma.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: (1,1)-(1,2) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,3)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,2)-(1,3)) + │ └── flags: decimal + ├── closing_loc: (1,4)-(1,5) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/call_trailing_dots.txt b/test/prism/snapshots/seattlerb/call_trailing_dots.txt new file mode 100644 index 00000000000000..828db0ce3bdf99 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_trailing_dots.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(3,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,1)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,1)) + ├── receiver: + │ @ CallNode (location: (1,0)-(2,1)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: (2,0)-(2,1) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── call_operator_loc: (2,1)-(2,2) = "." + ├── message_loc: (3,0)-(3,1) = "c" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/call_unary_bang.txt b/test/prism/snapshots/seattlerb/call_unary_bang.txt new file mode 100644 index 00000000000000..a3dc0368a54373 --- /dev/null +++ b/test/prism/snapshots/seattlerb/call_unary_bang.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,2)) + ├── receiver: + │ @ IntegerNode (location: (1,1)-(1,2)) + │ └── flags: decimal + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/seattlerb/case_in.txt b/test/prism/snapshots/seattlerb/case_in.txt new file mode 100644 index 00000000000000..94556ddecb728c --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in.txt @@ -0,0 +1,892 @@ +@ ProgramNode (location: (1,0)-(111,3)) +├── locals: [:b, :_, :lhs, :x, :rhs, :c, :e] +└── statements: + @ StatementsNode (location: (1,0)-(111,3)) + └── body: (length: 28) + ├── @ CaseNode (location: (1,0)-(3,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (1,5)-(1,7)) + │ │ ├── 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: ∅ + │ │ │ ├── assocs: (length: 1) + │ │ │ │ └── @ AssocNode (location: (2,4)-(2,8)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (2,4)-(2,8)) + │ │ │ │ │ ├── opening_loc: (2,4)-(2,5) = "\"" + │ │ │ │ │ ├── value_loc: (2,5)-(2,6) = "b" + │ │ │ │ │ ├── closing_loc: (2,6)-(2,8) = "\":" + │ │ │ │ │ └── unescaped: "b" + │ │ │ │ ├── value: ∅ + │ │ │ │ └── operator_loc: ∅ + │ │ │ ├── kwrest: ∅ + │ │ │ ├── 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" + ├── @ CaseNode (location: (5,0)-(7,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (5,5)-(5,7)) + │ │ ├── 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)) + │ │ │ ├── elements: (length: 2) + │ │ │ │ ├── @ SymbolNode (location: (6,6)-(6,7)) + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (6,6)-(6,7) = "a" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "a" + │ │ │ │ └── @ SymbolNode (location: (6,8)-(6,9)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (9,0)-(11,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (9,5)-(9,7)) + │ │ ├── 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)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (13,0)-(15,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (13,5)-(13,7)) + │ │ ├── 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)) + │ │ │ ├── elements: (length: 2) + │ │ │ │ ├── @ SymbolNode (location: (14,6)-(14,7)) + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (14,6)-(14,7) = "a" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "a" + │ │ │ │ └── @ SymbolNode (location: (14,8)-(14,9)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (17,0)-(19,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (17,5)-(17,7)) + │ │ ├── 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)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (21,0)-(23,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (21,5)-(21,7)) + │ │ ├── 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)) + │ │ │ ├── left: ∅ + │ │ │ ├── right: + │ │ │ │ @ IntegerNode (location: (22,7)-(22,9)) + │ │ │ │ └── flags: decimal + │ │ │ ├── operator_loc: (22,4)-(22,7) = "..." + │ │ │ └── flags: exclude_end + │ │ ├── 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" + ├── @ CaseNode (location: (25,0)-(27,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (25,5)-(25,7)) + │ │ ├── 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)) + │ │ │ ├── left: ∅ + │ │ │ ├── right: + │ │ │ │ @ IntegerNode (location: (26,6)-(26,8)) + │ │ │ │ └── flags: decimal + │ │ │ ├── operator_loc: (26,4)-(26,6) = ".." + │ │ │ └── flags: ∅ + │ │ ├── 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" + ├── @ CaseNode (location: (29,0)-(31,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (29,5)-(29,7)) + │ │ ├── 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)) + │ │ │ ├── left: + │ │ │ │ @ IntegerNode (location: (30,4)-(30,5)) + │ │ │ │ └── flags: decimal + │ │ │ ├── right: ∅ + │ │ │ ├── operator_loc: (30,5)-(30,8) = "..." + │ │ │ └── flags: exclude_end + │ │ ├── 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" + ├── @ CaseNode (location: (33,0)-(35,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (33,5)-(33,7)) + │ │ ├── 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)) + │ │ │ ├── left: + │ │ │ │ @ IntegerNode (location: (34,4)-(34,5)) + │ │ │ │ └── flags: decimal + │ │ │ ├── right: + │ │ │ │ @ IntegerNode (location: (34,8)-(34,9)) + │ │ │ │ └── flags: decimal + │ │ │ ├── operator_loc: (34,5)-(34,8) = "..." + │ │ │ └── flags: exclude_end + │ │ ├── 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" + ├── @ CaseNode (location: (37,0)-(39,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (37,5)-(37,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (41,0)-(43,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (41,5)-(41,7)) + │ │ ├── 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: ∅ + │ │ │ ├── assocs: (length: 1) + │ │ │ │ └── @ NoKeywordsParameterNode (location: (42,3)-(42,8)) + │ │ │ │ ├── operator_loc: (42,3)-(42,5) = "**" + │ │ │ │ └── keyword_loc: (42,5)-(42,8) = "nil" + │ │ │ ├── kwrest: ∅ + │ │ │ ├── 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" + ├── @ CaseNode (location: (45,0)-(47,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (45,5)-(45,7)) + │ │ ├── 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)) + │ │ │ ├── opening_loc: (46,3)-(46,4) = "/" + │ │ │ ├── content_loc: (46,4)-(46,10) = "regexp" + │ │ │ ├── closing_loc: (46,10)-(46,11) = "/" + │ │ │ ├── unescaped: "regexp" + │ │ │ └── flags: ∅ + │ │ ├── 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" + ├── @ CaseNode (location: (49,0)-(51,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (49,5)-(49,7)) + │ │ ├── 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)) + │ │ │ │ ├── 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)) + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (53,0)-(55,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (53,5)-(53,7)) + │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── 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" + ├── @ CaseNode (location: (57,0)-(59,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (57,5)-(57,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (61,0)-(63,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (61,5)-(61,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (65,0)-(67,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (65,5)-(65,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (69,0)-(71,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (69,5)-(69,7)) + │ │ ├── opening_loc: (69,5)-(69,6) = ":" + │ │ ├── value_loc: (69,6)-(69,7) = "a" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "a" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (70,0)-(70,22)) + │ │ ├── pattern: + │ │ │ @ ArrayPatternNode (location: (70,3)-(70,22)) + │ │ │ ├── constant: ∅ + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ LambdaNode (location: (70,4)-(70,18)) + │ │ │ │ │ ├── locals: [:b] + │ │ │ │ │ ├── operator_loc: (70,4)-(70,6) = "->" + │ │ │ │ │ ├── opening_loc: (70,10)-(70,11) = "{" + │ │ │ │ │ ├── closing_loc: (70,17)-(70,18) = "}" + │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ @ BlockParametersNode (location: (70,6)-(70,9)) + │ │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ │ @ ParametersNode (location: (70,7)-(70,8)) + │ │ │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (70,7)-(70,8)) + │ │ │ │ │ │ │ │ └── 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" + ├── @ CaseNode (location: (73,0)-(75,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (73,5)-(73,7)) + │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── 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" + ├── @ CaseNode (location: (77,0)-(79,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (77,5)-(77,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (81,0)-(83,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (81,5)-(81,7)) + │ │ ├── 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)) + │ │ │ │ │ │ │ ├── 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)) + │ │ │ │ │ │ ├── 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" + ├── @ CaseNode (location: (85,0)-(87,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (85,5)-(85,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (89,0)-(91,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (89,5)-(89,7)) + │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (90,6)-(90,7) = "a" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "a" + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (93,0)-(95,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (93,5)-(93,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (97,0)-(99,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (97,5)-(97,7)) + │ │ ├── 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)) + │ │ │ ├── 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" + ├── @ CaseNode (location: (101,0)-(103,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (101,5)-(101,7)) + │ │ ├── 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" + ├── @ CaseNode (location: (105,0)-(107,3)) + │ ├── predicate: + │ │ @ SymbolNode (location: (105,5)-(105,7)) + │ │ ├── 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: ∅ + │ │ │ ├── assocs: (length: 1) + │ │ │ │ └── @ AssocNode (location: (106,5)-(106,9)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (106,5)-(106,9)) + │ │ │ │ │ ├── opening_loc: (106,5)-(106,6) = "\"" + │ │ │ │ │ ├── value_loc: (106,6)-(106,7) = "b" + │ │ │ │ │ ├── closing_loc: (106,7)-(106,9) = "\":" + │ │ │ │ │ └── unescaped: "b" + │ │ │ │ ├── value: ∅ + │ │ │ │ └── operator_loc: ∅ + │ │ │ ├── kwrest: ∅ + │ │ │ ├── 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" + └── @ CaseNode (location: (109,0)-(111,3)) + ├── predicate: + │ @ SymbolNode (location: (109,5)-(109,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 0) + │ │ ├── kwrest: ∅ + │ │ ├── opening_loc: (110,3)-(110,4) = "{" + │ │ └── closing_loc: (110,4)-(110,5) = "}" + │ ├── statements: ∅ + │ ├── in_loc: (110,0)-(110,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (109,0)-(109,4) = "case" + └── end_keyword_loc: (111,0)-(111,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_31.txt b/test/prism/snapshots/seattlerb/case_in_31.txt new file mode 100644 index 00000000000000..e753c3ccff40a5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_31.txt @@ -0,0 +1,46 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [:c] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_37.txt b/test/prism/snapshots/seattlerb/case_in_37.txt new file mode 100644 index 00000000000000..46bdcf40b62819 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_37.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (2,5)-(2,17)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (2,5)-(2,7)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "c" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "c" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_42.txt b/test/prism/snapshots/seattlerb/case_in_42.txt new file mode 100644 index 00000000000000..fe69a9e3d3c71f --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_42.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:_] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ ├── opening_loc: (2,3)-(2,4) = ":" + │ │ │ ├── value_loc: (2,4)-(2,5) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ ├── rest: + │ │ │ @ SplatNode (location: (2,7)-(2,9)) + │ │ │ ├── operator_loc: (2,7)-(2,8) = "*" + │ │ │ └── expression: + │ │ │ @ LocalVariableTargetNode (location: (2,8)-(2,9)) + │ │ │ ├── name: :_ + │ │ │ └── depth: 0 + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,15)-(2,18)) + │ │ └── body: (length: 1) + │ │ └── @ NilNode (location: (2,15)-(2,18)) + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,10)-(2,14) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_42_2.txt b/test/prism/snapshots/seattlerb/case_in_42_2.txt new file mode 100644 index 00000000000000..f4e6806d35a66d --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_42_2.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:list] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── opening_loc: (1,5)-(1,6) = ":" + │ ├── value_loc: (1,6)-(1,7) = "a" + │ ├── closing_loc: ∅ + │ └── unescaped: "a" + ├── conditions: (length: 1) + │ └── @ InNode (location: (2,0)-(2,20)) + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (2,3)-(2,11)) + │ │ ├── constant: + │ │ │ @ ConstantReadNode (location: (2,3)-(2,4)) + │ │ │ └── name: :A + │ │ ├── requireds: (length: 0) + │ │ ├── rest: + │ │ │ @ SplatNode (location: (2,5)-(2,10)) + │ │ │ ├── operator_loc: (2,5)-(2,6) = "*" + │ │ │ └── expression: + │ │ │ @ LocalVariableTargetNode (location: (2,6)-(2,10)) + │ │ │ ├── name: :list + │ │ │ └── depth: 0 + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: (2,4)-(2,5) = "(" + │ │ └── closing_loc: (2,10)-(2,11) = ")" + │ ├── statements: + │ │ @ StatementsNode (location: (2,17)-(2,20)) + │ │ └── body: (length: 1) + │ │ └── @ NilNode (location: (2,17)-(2,20)) + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,12)-(2,16) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_47.txt b/test/prism/snapshots/seattlerb/case_in_47.txt new file mode 100644 index 00000000000000..32b24fc98d307b --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_47.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ │ ├── opening_loc: (2,7)-(2,8) = ":" + │ │ │ │ ├── value_loc: (2,8)-(2,9) = "b" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "b" + │ │ │ └── @ SymbolNode (location: (2,11)-(2,13)) + │ │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_67.txt b/test/prism/snapshots/seattlerb/case_in_67.txt new file mode 100644 index 00000000000000..73649059f0762f --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_67.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (2,3)-(2,4)) + │ │ │ └── flags: decimal + │ │ ├── right: ∅ + │ │ ├── operator_loc: (2,4)-(2,6) = ".." + │ │ └── flags: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,12)-(2,15)) + │ │ └── body: (length: 1) + │ │ └── @ NilNode (location: (2,12)-(2,15)) + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,7)-(2,11) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_86.txt b/test/prism/snapshots/seattlerb/case_in_86.txt new file mode 100644 index 00000000000000..7197e77bc0c973 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_86.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ ArrayNode (location: (1,5)-(1,13)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (1,6)-(1,8)) + │ │ │ ├── opening_loc: (1,6)-(1,7) = ":" + │ │ │ ├── value_loc: (1,7)-(1,8) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (1,10)-(1,12)) + │ │ ├── opening_loc: (1,10)-(1,11) = ":" + │ │ ├── value_loc: (1,11)-(1,12) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── opening_loc: (1,5)-(1,6) = "[" + │ └── closing_loc: (1,12)-(1,13) = "]" + ├── conditions: (length: 1) + │ └── @ InNode (location: (2,0)-(2,25)) + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (2,3)-(2,16)) + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 1) + │ │ │ └── @ ConstantPathNode (location: (2,3)-(2,13)) + │ │ │ ├── parent: ∅ + │ │ │ ├── child: + │ │ │ │ @ ConstantReadNode (location: (2,5)-(2,13)) + │ │ │ │ └── name: :NilClass + │ │ │ └── delimiter_loc: (2,3)-(2,5) = "::" + │ │ ├── rest: + │ │ │ @ SplatNode (location: (2,15)-(2,16)) + │ │ │ ├── operator_loc: (2,15)-(2,16) = "*" + │ │ │ └── expression: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,22)-(2,25)) + │ │ └── body: (length: 1) + │ │ └── @ NilNode (location: (2,22)-(2,25)) + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,17)-(2,21) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_86_2.txt b/test/prism/snapshots/seattlerb/case_in_86_2.txt new file mode 100644 index 00000000000000..9d3abbb31d16c6 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_86_2.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ ArrayNode (location: (1,5)-(1,13)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (1,6)-(1,8)) + │ │ │ ├── opening_loc: (1,6)-(1,7) = ":" + │ │ │ ├── value_loc: (1,7)-(1,8) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (1,10)-(1,12)) + │ │ ├── opening_loc: (1,10)-(1,11) = ":" + │ │ ├── value_loc: (1,11)-(1,12) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── opening_loc: (1,5)-(1,6) = "[" + │ └── closing_loc: (1,12)-(1,13) = "]" + ├── conditions: (length: 1) + │ └── @ InNode (location: (2,0)-(2,25)) + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (2,3)-(2,16)) + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 0) + │ │ ├── rest: + │ │ │ @ SplatNode (location: (2,3)-(2,4)) + │ │ │ ├── operator_loc: (2,3)-(2,4) = "*" + │ │ │ └── expression: ∅ + │ │ ├── posts: (length: 1) + │ │ │ └── @ ConstantPathNode (location: (2,6)-(2,16)) + │ │ │ ├── parent: ∅ + │ │ │ ├── child: + │ │ │ │ @ ConstantReadNode (location: (2,8)-(2,16)) + │ │ │ │ └── name: :NilClass + │ │ │ └── delimiter_loc: (2,6)-(2,8) = "::" + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,22)-(2,25)) + │ │ └── body: (length: 1) + │ │ └── @ NilNode (location: (2,22)-(2,25)) + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,17)-(2,21) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt new file mode 100644 index 00000000000000..8316c51f2e0a2d --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [:c] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt new file mode 100644 index 00000000000000..9f54b921acff61 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_array_pat_const2.txt @@ -0,0 +1,46 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [:d] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "e" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "e" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt b/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt new file mode 100644 index 00000000000000..0b903e8d914e8d --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_array_pat_paren_assign.txt @@ -0,0 +1,46 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [:d] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_const.txt b/test/prism/snapshots/seattlerb/case_in_const.txt new file mode 100644 index 00000000000000..59880bc2a7f3c0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_const.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_else.txt b/test/prism/snapshots/seattlerb/case_in_else.txt new file mode 100644 index 00000000000000..c132443cc8ed1f --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_else.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(6,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(6,3)) + └── body: (length: 1) + └── @ CaseNode (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)) + │ │ ├── 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)) + │ │ ├── opening_loc: (5,2)-(5,3) = ":" + │ │ ├── value_loc: (5,3)-(5,4) = "c" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "c" + │ └── end_keyword_loc: (6,0)-(6,3) = "end" + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (6,0)-(6,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_find.txt b/test/prism/snapshots/seattlerb/case_in_find.txt new file mode 100644 index 00000000000000..191dee3a047b46 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_find.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:a, :b] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ ├── opening_loc: (2,9)-(2,10) = ":" + │ │ │ ├── value_loc: (2,10)-(2,11) = "+" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "+" + │ │ ├── right: + │ │ │ @ SplatNode (location: (2,13)-(2,15)) + │ │ │ ├── operator_loc: (2,13)-(2,14) = "*" + │ │ │ └── expression: + │ │ │ @ LocalVariableTargetNode (location: (2,14)-(2,15)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: ∅ + │ ├── in_loc: (2,2)-(2,4) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_find_array.txt b/test/prism/snapshots/seattlerb/case_in_find_array.txt new file mode 100644 index 00000000000000..df764a4b079369 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_find_array.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:c] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ │ ├── opening_loc: (2,7)-(2,8) = ":" + │ │ │ │ ├── value_loc: (2,8)-(2,9) = "b" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "b" + │ │ │ └── @ LocalVariableTargetNode (location: (2,11)-(2,12)) + │ │ │ ├── name: :c + │ │ │ └── depth: 0 + │ │ ├── right: + │ │ │ @ SplatNode (location: (2,14)-(2,15)) + │ │ │ ├── operator_loc: (2,14)-(2,15) = "*" + │ │ │ └── expression: ∅ + │ │ ├── opening_loc: (2,3)-(2,4) = "[" + │ │ └── closing_loc: (2,15)-(2,16) = "]" + │ ├── statements: ∅ + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat.txt new file mode 100644 index 00000000000000..e0391402414863 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat.txt @@ -0,0 +1,64 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 2) + │ │ │ ├── @ AssocNode (location: (2,5)-(2,11)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7)) + │ │ │ │ │ ├── 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "f" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "f" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,22)-(2,26) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt new file mode 100644 index 00000000000000..b24718b1ee95a8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_assign.txt @@ -0,0 +1,76 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [:x, :f] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 3) + │ │ │ ├── @ AssocNode (location: (2,5)-(2,20)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (2,5)-(2,7)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (2,30)-(2,31) = "f" + │ │ │ │ ├── closing_loc: (2,31)-(2,32) = ":" + │ │ │ │ └── unescaped: "f" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "g" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "g" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,35)-(2,39) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt new file mode 100644 index 00000000000000..802c09438ee9b6 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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 + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (2,5)-(2,10)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (2,5)-(2,7)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt new file mode 100644 index 00000000000000..ca7fbcfd92c1e9 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_paren_true.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (2,3)-(2,10)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (2,3)-(2,5)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (3,2)-(3,4)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (3,2)-(3,4)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "c" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "c" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,11)-(2,15) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt new file mode 100644 index 00000000000000..bbd49630086ab9 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest.txt @@ -0,0 +1,52 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:c, :rest] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 2) + │ │ │ ├── @ AssocNode (location: (2,3)-(2,7)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (2,3)-(2,5)) + │ │ │ │ │ ├── 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: ∅ + │ │ │ └── @ AssocSplatNode (location: (2,9)-(2,15)) + │ │ │ ├── value: + │ │ │ │ @ LocalVariableTargetNode (location: (2,11)-(2,15)) + │ │ │ │ ├── name: :rest + │ │ │ │ └── depth: 0 + │ │ │ └── operator_loc: (2,9)-(2,11) = "**" + │ │ ├── kwrest: ∅ + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,21)-(2,23)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (2,21)-(2,23)) + │ │ ├── opening_loc: (2,21)-(2,22) = ":" + │ │ ├── value_loc: (2,22)-(2,23) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,16)-(2,20) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt new file mode 100644 index 00000000000000..4a189bb5904998 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [:rest] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(3,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocSplatNode (location: (2,3)-(2,9)) + │ │ │ ├── value: + │ │ │ │ @ LocalVariableTargetNode (location: (2,5)-(2,9)) + │ │ │ │ ├── name: :rest + │ │ │ │ └── depth: 0 + │ │ │ └── operator_loc: (2,3)-(2,5) = "**" + │ │ ├── kwrest: ∅ + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,15)-(2,17)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (2,15)-(2,17)) + │ │ ├── opening_loc: (2,15)-(2,16) = ":" + │ │ ├── value_loc: (2,16)-(2,17) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: (2,10)-(2,14) = "then" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt b/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt new file mode 100644 index 00000000000000..b058ee028510e9 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_if_unless_post_mod.txt @@ -0,0 +1,62 @@ +@ ProgramNode (location: (1,0)-(6,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(6,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(6,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── opening_loc: (5,2)-(5,3) = ":" + │ │ ├── value_loc: (5,3)-(5,4) = "E" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "E" + │ ├── in_loc: (4,0)-(4,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (6,0)-(6,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_multiple.txt b/test/prism/snapshots/seattlerb/case_in_multiple.txt new file mode 100644 index 00000000000000..046cb618387ab4 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_multiple.txt @@ -0,0 +1,56 @@ +@ ProgramNode (location: (1,0)-(6,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(6,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(6,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── opening_loc: (5,2)-(5,3) = ":" + │ │ ├── value_loc: (5,3)-(5,4) = "F" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "F" + │ ├── in_loc: (4,0)-(4,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (6,0)-(6,3) = "end" diff --git a/test/prism/snapshots/seattlerb/case_in_or.txt b/test/prism/snapshots/seattlerb/case_in_or.txt new file mode 100644 index 00000000000000..059ddcd32c2a53 --- /dev/null +++ b/test/prism/snapshots/seattlerb/case_in_or.txt @@ -0,0 +1,36 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(4,3)) + ├── predicate: + │ @ SymbolNode (location: (1,5)-(1,7)) + │ ├── 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)) + │ │ ├── opening_loc: (3,2)-(3,3) = ":" + │ │ ├── value_loc: (3,3)-(3,4) = "d" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "d" + │ ├── in_loc: (2,0)-(2,2) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/seattlerb/class_comments.txt b/test/prism/snapshots/seattlerb/class_comments.txt new file mode 100644 index 00000000000000..5ac05b6be686e3 --- /dev/null +++ b/test/prism/snapshots/seattlerb/class_comments.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (4,0)-(9,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (4,0)-(9,3)) + └── body: (length: 1) + └── @ ClassNode (location: (4,0)-(9,3)) + ├── locals: [] + ├── class_keyword_loc: (4,0)-(4,5) = "class" + ├── constant_path: + │ @ ConstantReadNode (location: (4,6)-(4,7)) + │ └── name: :X + ├── inheritance_operator_loc: ∅ + ├── superclass: ∅ + ├── body: + │ @ StatementsNode (location: (6,2)-(8,5)) + │ └── body: (length: 1) + │ └── @ DefNode (location: (6,2)-(8,5)) + │ ├── name: :blah + │ ├── name_loc: (6,6)-(6,10) = "blah" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (6,2)-(6,5) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (8,2)-(8,5) = "end" + ├── end_keyword_loc: (9,0)-(9,3) = "end" + └── name: :X diff --git a/test/prism/snapshots/seattlerb/cond_unary_minus.txt b/test/prism/snapshots/seattlerb/cond_unary_minus.txt new file mode 100644 index 00000000000000..28c354b85d2adc --- /dev/null +++ b/test/prism/snapshots/seattlerb/cond_unary_minus.txt @@ -0,0 +1,13 @@ +@ 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 + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (1,7)-(1,10) = "end" diff --git a/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt new file mode 100644 index 00000000000000..332c7ff302e1ee --- /dev/null +++ b/test/prism/snapshots/seattlerb/const_2_op_asgn_or2.txt @@ -0,0 +1,23 @@ +@ 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 new file mode 100644 index 00000000000000..e7130cc1b389ff --- /dev/null +++ b/test/prism/snapshots/seattlerb/const_3_op_asgn_or.txt @@ -0,0 +1,17 @@ +@ 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 new file mode 100644 index 00000000000000..c4c5534f9297df --- /dev/null +++ b/test/prism/snapshots/seattlerb/const_op_asgn_and1.txt @@ -0,0 +1,18 @@ +@ 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 new file mode 100644 index 00000000000000..ef9ee358b991dd --- /dev/null +++ b/test/prism/snapshots/seattlerb/const_op_asgn_and2.txt @@ -0,0 +1,17 @@ +@ 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 new file mode 100644 index 00000000000000..7afc8882e99f14 --- /dev/null +++ b/test/prism/snapshots/seattlerb/const_op_asgn_or.txt @@ -0,0 +1,19 @@ +@ 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 new file mode 100644 index 00000000000000..16864d1e33a51d --- /dev/null +++ b/test/prism/snapshots/seattlerb/dasgn_icky2.txt @@ -0,0 +1,61 @@ +@ ProgramNode (location: (1,0)-(8,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(8,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(8,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(8,3)) + │ ├── locals: [:v] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (2,2)-(7,5)) + │ │ └── body: (length: 2) + │ │ ├── @ LocalVariableWriteNode (location: (2,2)-(2,9)) + │ │ │ ├── name: :v + │ │ │ ├── depth: 0 + │ │ │ ├── name_loc: (2,2)-(2,3) = "v" + │ │ │ ├── value: + │ │ │ │ @ NilNode (location: (2,6)-(2,9)) + │ │ │ └── operator_loc: (2,4)-(2,5) = "=" + │ │ └── @ BeginNode (location: (3,2)-(7,5)) + │ │ ├── begin_keyword_loc: (3,2)-(3,7) = "begin" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (4,4)-(4,9)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ YieldNode (location: (4,4)-(4,9)) + │ │ │ ├── keyword_loc: (4,4)-(4,9) = "yield" + │ │ │ ├── lparen_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ └── rparen_loc: ∅ + │ │ ├── rescue_clause: + │ │ │ @ RescueNode (location: (5,2)-(6,9)) + │ │ │ ├── keyword_loc: (5,2)-(5,8) = "rescue" + │ │ │ ├── exceptions: (length: 1) + │ │ │ │ └── @ ConstantReadNode (location: (5,9)-(5,18)) + │ │ │ │ └── name: :Exception + │ │ │ ├── operator_loc: (5,19)-(5,21) = "=>" + │ │ │ ├── reference: + │ │ │ │ @ LocalVariableTargetNode (location: (5,22)-(5,23)) + │ │ │ │ ├── name: :v + │ │ │ │ └── depth: 0 + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (6,4)-(6,9)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ BreakNode (location: (6,4)-(6,9)) + │ │ │ │ ├── arguments: ∅ + │ │ │ │ └── keyword_loc: (6,4)-(6,9) = "break" + │ │ │ └── consequent: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (7,2)-(7,5) = "end" + │ ├── opening_loc: (1,2)-(1,4) = "do" + │ └── closing_loc: (8,0)-(8,3) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/defined_eh_parens.txt b/test/prism/snapshots/seattlerb/defined_eh_parens.txt new file mode 100644 index 00000000000000..b03666c7e4a4be --- /dev/null +++ b/test/prism/snapshots/seattlerb/defined_eh_parens.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..c5c169fc0ed6ec --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_arg_asplat_arg.txt @@ -0,0 +1,34 @@ +@ 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: nil + │ │ ├── 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,8)-(1,9) = "(" + ├── rparen_loc: (1,24)-(1,25) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,26)-(1,29) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt b/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt new file mode 100644 index 00000000000000..8b85009de044b2 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_arg_forward_args.txt @@ -0,0 +1,47 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,15)-(1,16) = "b" + │ ├── opening_loc: (1,16)-(1,17) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,17)-(1,23)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── locals: [:x, :"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,12)-(1,13) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,26)-(1,29) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_args_forward_args.txt b/test/prism/snapshots/seattlerb/defn_args_forward_args.txt new file mode 100644 index 00000000000000..2d033dd1f2302b --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_args_forward_args.txt @@ -0,0 +1,56 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,21)-(1,22) = "b" + │ ├── opening_loc: (1,22)-(1,23) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,23)-(1,35)) + │ │ └── arguments: (length: 3) + │ │ ├── @ SymbolNode (location: (1,23)-(1,27)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── locals: [:x, :y, :z, :"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,18)-(1,19) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,38)-(1,41) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_comments.txt b/test/prism/snapshots/seattlerb/defn_comments.txt new file mode 100644 index 00000000000000..585aa65c9a6df2 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_comments.txt @@ -0,0 +1,18 @@ +@ ProgramNode (location: (4,0)-(5,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (4,0)-(5,3)) + └── body: (length: 1) + └── @ DefNode (location: (4,0)-(5,3)) + ├── name: :blah + ├── name_loc: (4,4)-(4,8) = "blah" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (4,0)-(4,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (5,0)-(5,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_endless_command.txt b/test/prism/snapshots/seattlerb/defn_endless_command.txt new file mode 100644 index 00000000000000..90cfd1c888f771 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_endless_command.txt @@ -0,0 +1,34 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,18)-(1,30) = "other_method" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,31)-(1,33)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,31)-(1,33)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "other_method" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (1,16)-(1,17) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt b/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt new file mode 100644 index 00000000000000..18e019d4f41f18 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_endless_command_rescue.txt @@ -0,0 +1,40 @@ +@ 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) + │ └── @ CallNode (location: (1,18)-(1,43)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,18)-(1,30) = "other_method" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,31)-(1,43)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (1,31)-(1,43)) + │ │ ├── expression: + │ │ │ @ IntegerNode (location: (1,31)-(1,33)) + │ │ │ └── flags: decimal + │ │ ├── keyword_loc: (1,34)-(1,40) = "rescue" + │ │ └── rescue_expression: + │ │ @ IntegerNode (location: (1,41)-(1,43)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "other_method" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (1,16)-(1,17) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_forward_args.txt b/test/prism/snapshots/seattlerb/defn_forward_args.txt new file mode 100644 index 00000000000000..5eb2cf1d189db7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_forward_args.txt @@ -0,0 +1,42 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,12)-(1,13) = "b" + │ ├── opening_loc: (1,13)-(1,14) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,14)-(1,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (1,14)-(1,17)) + │ ├── closing_loc: (1,17)-(1,18) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "b" + ├── locals: [:"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,9)-(1,10) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,20)-(1,23) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt b/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt new file mode 100644 index 00000000000000..168fdbbb4282a5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_forward_args__no_parens.txt @@ -0,0 +1,42 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,2)-(2,3) = "m" + │ ├── opening_loc: (2,3)-(2,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (2,4)-(2,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (2,4)-(2,7)) + │ ├── closing_loc: (2,7)-(2,8) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── locals: [:"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (3,0)-(3,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_env.txt b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt new file mode 100644 index 00000000000000..57b835d9d47553 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_env.txt @@ -0,0 +1,52 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,20)-(1,30) = "test_splat" + │ ├── opening_loc: (1,30)-(1,31) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,31)-(1,40)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,31)-(1,40)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "test_splat" + ├── locals: [:testing] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,8)-(1,9) = "(" + ├── rparen_loc: (1,18)-(1,19) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,42)-(1,45) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt new file mode 100644 index 00000000000000..2d57ad3189850c --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwarg.txt @@ -0,0 +1,40 @@ +@ 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) + │ │ ├── @ KeywordParameterNode (location: (1,9)-(1,13)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (1,9)-(1,11) = "b:" + │ │ │ └── value: + │ │ │ @ IntegerNode (location: (1,12)-(1,13)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,19)-(1,20) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,21)-(1,24) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt new file mode 100644 index 00000000000000..0d005c20576e43 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat.txt @@ -0,0 +1,36 @@ +@ 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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,15)-(1,16) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,17)-(1,20) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt new file mode 100644 index 00000000000000..60c8e7bcb847b5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt @@ -0,0 +1,36 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,19)) + ├── name: :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) + │ │ └── @ KeywordParameterNode (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: nil + │ │ ├── name_loc: ∅ + │ │ └── operator_loc: (1,12)-(1,14) = "**" + │ └── block: ∅ + ├── body: ∅ + ├── locals: [:b, :**] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,14)-(1,15) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,16)-(1,19) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt b/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt new file mode 100644 index 00000000000000..6b46d9e2d4da0b --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_lvar.txt @@ -0,0 +1,40 @@ +@ 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) + │ │ └── @ KeywordParameterNode (location: (1,8)-(1,16)) + │ │ ├── name: :kw + │ │ ├── name_loc: (1,8)-(1,11) = "kw:" + │ │ └── value: + │ │ @ SymbolNode (location: (1,12)-(1,16)) + │ │ ├── opening_loc: (1,12)-(1,13) = ":" + │ │ ├── value_loc: (1,13)-(1,16) = "val" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "val" + │ ├── keyword_rest: ∅ + │ └── block: ∅ + ├── body: + │ @ StatementsNode (location: (1,19)-(1,21)) + │ └── body: (length: 1) + │ └── @ LocalVariableReadNode (location: (1,19)-(1,21)) + │ ├── name: :kw + │ └── depth: 0 + ├── locals: [:kw] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,16)-(1,17) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,23)-(1,26) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt b/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt new file mode 100644 index 00000000000000..ba0bd443242d7f --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_no_parens.txt @@ -0,0 +1,32 @@ +@ 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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (2,0)-(2,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_kwarg_val.txt b/test/prism/snapshots/seattlerb/defn_kwarg_val.txt new file mode 100644 index 00000000000000..5933c969db3dfc --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_kwarg_val.txt @@ -0,0 +1,34 @@ +@ 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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,12)-(1,13) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,14)-(1,17) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_no_kwargs.txt b/test/prism/snapshots/seattlerb/defn_no_kwargs.txt new file mode 100644 index 00000000000000..0ef0634a537d57 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_no_kwargs.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,17)) + ├── name: :x + ├── name_loc: (1,4)-(1,5) = "x" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (1,6)-(1,11)) + │ ├── requireds: (length: 0) + │ ├── optionals: (length: 0) + │ ├── rest: ∅ + │ ├── posts: (length: 0) + │ ├── keywords: (length: 0) + │ ├── keyword_rest: + │ │ @ NoKeywordsParameterNode (location: (1,6)-(1,11)) + │ │ ├── operator_loc: (1,6)-(1,8) = "**" + │ │ └── keyword_loc: (1,8)-(1,11) = "nil" + │ └── block: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,11)-(1,12) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,14)-(1,17) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_oneliner.txt b/test/prism/snapshots/seattlerb/defn_oneliner.txt new file mode 100644 index 00000000000000..55227da074dd60 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_oneliner.txt @@ -0,0 +1,45 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,16)-(1,22) = "system" + │ ├── opening_loc: (1,22)-(1,23) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,23)-(1,26)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,23)-(1,26)) + │ │ ├── name: :cmd + │ │ └── depth: 0 + │ ├── closing_loc: (1,26)-(1,27) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "system" + ├── locals: [:cmd] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,8)-(1,9) = "(" + ├── rparen_loc: (1,12)-(1,13) = ")" + ├── equal_loc: (1,14)-(1,15) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt new file mode 100644 index 00000000000000..359332adba700e --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_oneliner_eq2.txt @@ -0,0 +1,45 @@ +@ 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] + │ ├── def_keyword_loc: (2,2)-(2,5) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (2,8)-(2,9) = "(" + │ ├── rparen_loc: (2,10)-(2,11) = ")" + │ ├── equal_loc: (2,12)-(2,13) = "=" + │ └── end_keyword_loc: ∅ + ├── end_keyword_loc: (3,0)-(3,3) = "end" + └── name: :X diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt b/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt new file mode 100644 index 00000000000000..11592879050382 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_oneliner_noargs.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,17)) + ├── name: :exec + ├── name_loc: (1,4)-(1,8) = "exec" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,11)-(1,17)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,11)-(1,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,17) = "system" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "system" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (1,9)-(1,10) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt new file mode 100644 index 00000000000000..6634a2c3750555 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,19)) + ├── name: :exec + ├── name_loc: (1,4)-(1,8) = "exec" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,13)-(1,19)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,13)-(1,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,13)-(1,19) = "system" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "system" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,8)-(1,9) = "(" + ├── rparen_loc: (1,9)-(1,10) = ")" + ├── equal_loc: (1,11)-(1,12) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt b/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt new file mode 100644 index 00000000000000..5fe7779944243d --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_oneliner_rescue.txt @@ -0,0 +1,152 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,8) = "system" + │ │ │ ├── opening_loc: (2,8)-(2,9) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (2,9)-(2,12)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (2,9)-(2,12)) + │ │ │ │ ├── name: :cmd + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: (2,12)-(2,13) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "system" + │ │ ├── rescue_clause: + │ │ │ @ RescueNode (location: (3,0)-(4,5)) + │ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue" + │ │ │ ├── exceptions: (length: 0) + │ │ │ ├── operator_loc: ∅ + │ │ │ ├── reference: ∅ + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (4,2)-(4,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ NilNode (location: (4,2)-(4,5)) + │ │ │ └── consequent: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (5,0)-(5,3) = "end" + │ ├── locals: [:cmd] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,8)-(1,9) = "(" + │ ├── rparen_loc: (1,12)-(1,13) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,0)-(5,3) = "end" + ├── @ DefNode (location: (8,0)-(10,3)) + │ ├── name: :exec + │ ├── name_loc: (8,4)-(8,8) = "exec" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (8,9)-(8,12)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (8,9)-(8,12)) + │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,8) = "system" + │ │ │ ├── opening_loc: (9,8)-(9,9) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (9,9)-(9,12)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (9,9)-(9,12)) + │ │ │ │ ├── name: :cmd + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: (9,12)-(9,13) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "system" + │ │ ├── keyword_loc: (9,14)-(9,20) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (9,21)-(9,24)) + │ ├── locals: [:cmd] + │ ├── def_keyword_loc: (8,0)-(8,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (8,8)-(8,9) = "(" + │ ├── rparen_loc: (8,12)-(8,13) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (10,0)-(10,3) = "end" + └── @ DefNode (location: (13,0)-(13,38)) + ├── name: :exec + ├── name_loc: (13,4)-(13,8) = "exec" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (13,9)-(13,12)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (13,9)-(13,12)) + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,16)-(13,22) = "system" + │ │ ├── opening_loc: (13,22)-(13,23) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (13,23)-(13,26)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (13,23)-(13,26)) + │ │ │ ├── name: :cmd + │ │ │ └── depth: 0 + │ │ ├── closing_loc: (13,26)-(13,27) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "system" + │ ├── keyword_loc: (13,28)-(13,34) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (13,35)-(13,38)) + ├── locals: [:cmd] + ├── def_keyword_loc: (13,0)-(13,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (13,8)-(13,9) = "(" + ├── rparen_loc: (13,12)-(13,13) = ")" + ├── equal_loc: (13,14)-(13,15) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt b/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt new file mode 100644 index 00000000000000..e82a9c8091f9ac --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_opt_last_arg.txt @@ -0,0 +1,32 @@ +@ 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (2,0)-(2,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_opt_reg.txt b/test/prism/snapshots/seattlerb/defn_opt_reg.txt new file mode 100644 index 00000000000000..437eaa7472edd8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_opt_reg.txt @@ -0,0 +1,34 @@ +@ 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,14)-(1,15) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,16)-(1,19) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt b/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt new file mode 100644 index 00000000000000..4ad2a5303e7377 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_opt_splat_arg.txt @@ -0,0 +1,39 @@ +@ 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,6)-(1,7) = "(" + ├── rparen_loc: (1,19)-(1,20) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,21)-(1,24) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_powarg.txt b/test/prism/snapshots/seattlerb/defn_powarg.txt new file mode 100644 index 00000000000000..a903d1f74115c1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_powarg.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,17)) + ├── name: :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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,12)-(1,13) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,14)-(1,17) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt b/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt new file mode 100644 index 00000000000000..0b6614abbcbc01 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_reg_opt_reg.txt @@ -0,0 +1,40 @@ +@ 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)) + │ │ ├── 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,18)-(1,19) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,20)-(1,23) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_splat_arg.txt b/test/prism/snapshots/seattlerb/defn_splat_arg.txt new file mode 100644 index 00000000000000..69b1c0749a1a8a --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_splat_arg.txt @@ -0,0 +1,32 @@ +@ 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: nil + │ │ ├── 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,10)-(1,11) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,12)-(1,15) = "end" diff --git a/test/prism/snapshots/seattlerb/defn_unary_not.txt b/test/prism/snapshots/seattlerb/defn_unary_not.txt new file mode 100644 index 00000000000000..61afb79ad1c570 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defn_unary_not.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,17)) + ├── name: :"!@" + ├── name_loc: (1,4)-(1,6) = "!@" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,8)-(1,12)) + │ └── body: (length: 1) + │ └── @ TrueNode (location: (1,8)-(1,12)) + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (1,14)-(1,17) = "end" diff --git a/test/prism/snapshots/seattlerb/defns_reserved.txt b/test/prism/snapshots/seattlerb/defns_reserved.txt new file mode 100644 index 00000000000000..96860b49ce04c0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defns_reserved.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,20)) + ├── name: :return + ├── name_loc: (1,9)-(1,15) = "return" + ├── receiver: + │ @ SelfNode (location: (1,4)-(1,8)) + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: (1,8)-(1,9) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (1,17)-(1,20) = "end" diff --git a/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt new file mode 100644 index 00000000000000..8b2002ac39a4ce --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(1,30)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,30)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,30)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,30)) + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (1,14)-(1,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,14)-(1,15) = "x" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "x" + │ │ ├── call_operator_loc: (1,15)-(1,16) = "." + │ │ ├── message_loc: (1,16)-(1,17) = "y" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,18)-(1,25)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,18)-(1,20) = "do" + │ │ │ └── closing_loc: (1,22)-(1,25) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "y" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,2)-(1,5) = "def" + │ ├── operator_loc: (1,10)-(1,11) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,27)-(1,30) = "end" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/seattlerb/defs_comments.txt b/test/prism/snapshots/seattlerb/defs_comments.txt new file mode 100644 index 00000000000000..a2976e7ee28219 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_comments.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (4,0)-(5,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (4,0)-(5,3)) + └── body: (length: 1) + └── @ DefNode (location: (4,0)-(5,3)) + ├── name: :blah + ├── name_loc: (4,9)-(4,13) = "blah" + ├── receiver: + │ @ SelfNode (location: (4,4)-(4,8)) + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (4,0)-(4,3) = "def" + ├── operator_loc: (4,8)-(4,9) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (5,0)-(5,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defs_endless_command.txt b/test/prism/snapshots/seattlerb/defs_endless_command.txt new file mode 100644 index 00000000000000..257b632a3dbc3b --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_endless_command.txt @@ -0,0 +1,44 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "x" + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,20)-(1,35)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,20)-(1,35)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,20)-(1,32) = "other_method" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,33)-(1,35)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,33)-(1,35)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "other_method" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: (1,5)-(1,6) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (1,18)-(1,19) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt b/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt new file mode 100644 index 00000000000000..0b18829492e825 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_endless_command_rescue.txt @@ -0,0 +1,50 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "x" + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (1,20)-(1,45)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,20)-(1,45)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,20)-(1,32) = "other_method" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,33)-(1,45)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (1,33)-(1,45)) + │ │ ├── expression: + │ │ │ @ IntegerNode (location: (1,33)-(1,35)) + │ │ │ └── flags: decimal + │ │ ├── keyword_loc: (1,36)-(1,42) = "rescue" + │ │ └── rescue_expression: + │ │ @ IntegerNode (location: (1,43)-(1,45)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "other_method" + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: (1,5)-(1,6) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (1,18)-(1,19) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defs_kwarg.txt b/test/prism/snapshots/seattlerb/defs_kwarg.txt new file mode 100644 index 00000000000000..8343c1f178fea5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_kwarg.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,3)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(2,3)) + ├── name: :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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: (1,8)-(1,9) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (2,0)-(2,3) = "end" diff --git a/test/prism/snapshots/seattlerb/defs_oneliner.txt b/test/prism/snapshots/seattlerb/defs_oneliner.txt new file mode 100644 index 00000000000000..629de9b138dbb0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_oneliner.txt @@ -0,0 +1,46 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,21)-(1,27) = "system" + │ ├── opening_loc: (1,27)-(1,28) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,28)-(1,31)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,28)-(1,31)) + │ │ ├── name: :cmd + │ │ └── depth: 0 + │ ├── closing_loc: (1,31)-(1,32) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "system" + ├── locals: [:cmd] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: (1,8)-(1,9) = "." + ├── lparen_loc: (1,13)-(1,14) = "(" + ├── rparen_loc: (1,17)-(1,18) = ")" + ├── equal_loc: (1,19)-(1,20) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt new file mode 100644 index 00000000000000..45ae30eceaad4b --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_oneliner_eq2.txt @@ -0,0 +1,46 @@ +@ 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] + │ ├── def_keyword_loc: (2,2)-(2,5) = "def" + │ ├── operator_loc: (2,10)-(2,11) = "." + │ ├── lparen_loc: (2,13)-(2,14) = "(" + │ ├── rparen_loc: (2,15)-(2,16) = ")" + │ ├── equal_loc: (2,17)-(2,18) = "=" + │ └── end_keyword_loc: ∅ + ├── end_keyword_loc: (3,0)-(3,3) = "end" + └── name: :X diff --git a/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt b/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt new file mode 100644 index 00000000000000..9e1bea2d2cdf0e --- /dev/null +++ b/test/prism/snapshots/seattlerb/defs_oneliner_rescue.txt @@ -0,0 +1,155 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,8) = "system" + │ │ │ ├── opening_loc: (2,8)-(2,9) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (2,9)-(2,12)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (2,9)-(2,12)) + │ │ │ │ ├── name: :cmd + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: (2,12)-(2,13) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "system" + │ │ ├── rescue_clause: + │ │ │ @ RescueNode (location: (3,0)-(4,5)) + │ │ │ ├── keyword_loc: (3,0)-(3,6) = "rescue" + │ │ │ ├── exceptions: (length: 0) + │ │ │ ├── operator_loc: ∅ + │ │ │ ├── reference: ∅ + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (4,2)-(4,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ NilNode (location: (4,2)-(4,5)) + │ │ │ └── consequent: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (5,0)-(5,3) = "end" + │ ├── locals: [:cmd] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: (1,8)-(1,9) = "." + │ ├── lparen_loc: (1,13)-(1,14) = "(" + │ ├── rparen_loc: (1,17)-(1,18) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,0)-(5,3) = "end" + ├── @ DefNode (location: (8,0)-(10,3)) + │ ├── name: :exec + │ ├── name_loc: (8,9)-(8,13) = "exec" + │ ├── receiver: + │ │ @ SelfNode (location: (8,4)-(8,8)) + │ ├── parameters: + │ │ @ ParametersNode (location: (8,14)-(8,17)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (8,14)-(8,17)) + │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,8) = "system" + │ │ │ ├── opening_loc: (9,8)-(9,9) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (9,9)-(9,12)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (9,9)-(9,12)) + │ │ │ │ ├── name: :cmd + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: (9,12)-(9,13) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "system" + │ │ ├── keyword_loc: (9,14)-(9,20) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (9,21)-(9,24)) + │ ├── locals: [:cmd] + │ ├── def_keyword_loc: (8,0)-(8,3) = "def" + │ ├── operator_loc: (8,8)-(8,9) = "." + │ ├── lparen_loc: (8,13)-(8,14) = "(" + │ ├── rparen_loc: (8,17)-(8,18) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (10,0)-(10,3) = "end" + └── @ DefNode (location: (13,0)-(13,43)) + ├── name: :exec + ├── name_loc: (13,9)-(13,13) = "exec" + ├── receiver: + │ @ SelfNode (location: (13,4)-(13,8)) + ├── parameters: + │ @ ParametersNode (location: (13,14)-(13,17)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (13,14)-(13,17)) + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,21)-(13,27) = "system" + │ │ ├── opening_loc: (13,27)-(13,28) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (13,28)-(13,31)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (13,28)-(13,31)) + │ │ │ ├── name: :cmd + │ │ │ └── depth: 0 + │ │ ├── closing_loc: (13,31)-(13,32) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "system" + │ ├── keyword_loc: (13,33)-(13,39) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (13,40)-(13,43)) + ├── locals: [:cmd] + ├── def_keyword_loc: (13,0)-(13,3) = "def" + ├── operator_loc: (13,8)-(13,9) = "." + ├── lparen_loc: (13,13)-(13,14) = "(" + ├── rparen_loc: (13,17)-(13,18) = ")" + ├── equal_loc: (13,19)-(13,20) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/difficult0_.txt b/test/prism/snapshots/seattlerb/difficult0_.txt new file mode 100644 index 00000000000000..f4f9b11560975f --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult0_.txt @@ -0,0 +1,69 @@ +@ ProgramNode (location: (1,0)-(4,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(4,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(4,8)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,2)-(4,8)) + │ ├── receiver: + │ │ @ CallNode (location: (1,2)-(4,4)) + │ │ ├── receiver: + │ │ │ @ StringNode (location: (1,2)-(1,8)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (1,2)-(1,8) = "<<-END" + │ │ │ ├── content_loc: (2,0)-(2,0) = " a\n" + │ │ │ ├── closing_loc: (3,0)-(3,0) = " END\n" + │ │ │ └── unescaped: " a\n" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,8)-(1,9) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,9)-(4,4)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ InterpolatedStringNode (location: (1,9)-(4,4)) + │ │ │ ├── opening_loc: (1,9)-(1,10) = "'" + │ │ │ ├── parts: (length: 2) + │ │ │ │ ├── @ StringNode (location: (1,10)-(1,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (1,10)-(1,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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,4)-(4,5) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (4,5)-(4,8)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt b/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt new file mode 100644 index 00000000000000..fd98c2a5ef4baf --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult1_line_numbers.txt @@ -0,0 +1,242 @@ +@ 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)) + ├── statements: + │ @ StatementsNode (location: (2,2)-(11,11)) + │ └── body: (length: 10) + │ ├── @ CallNode (location: (2,2)-(2,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,3) = "p" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (2,4)-(2,5)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (2,4)-(2,5)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "p" + │ ├── @ CallNode (location: (3,2)-(3,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (3,2)-(3,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,2)-(3,3) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── call_operator_loc: (3,3)-(3,4) = "." + │ │ ├── message_loc: (3,4)-(3,5) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,6)-(3,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (3,6)-(3,7)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── @ CallNode (location: (4,2)-(4,10)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (4,2)-(4,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,2)-(4,3) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── call_operator_loc: (4,3)-(4,4) = "." + │ │ ├── message_loc: (4,4)-(4,5) = "d" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (4,6)-(4,10)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ IntegerNode (location: (4,6)-(4,7)) + │ │ │ │ └── flags: decimal + │ │ │ └── @ IntegerNode (location: (4,9)-(4,10)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "d" + │ ├── @ CallNode (location: (5,2)-(5,7)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (5,2)-(5,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,2)-(5,3) = "e" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "e" + │ │ ├── call_operator_loc: (5,3)-(5,4) = "." + │ │ ├── message_loc: (5,4)-(5,5) = "f" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,6)-(5,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (5,6)-(5,7)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "f" + │ ├── @ CallNode (location: (6,2)-(6,10)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (6,2)-(6,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (6,2)-(6,3) = "g" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "g" + │ │ ├── call_operator_loc: (6,3)-(6,4) = "." + │ │ ├── message_loc: (6,4)-(6,5) = "h" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (6,6)-(6,10)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ IntegerNode (location: (6,6)-(6,7)) + │ │ │ │ └── flags: decimal + │ │ │ └── @ IntegerNode (location: (6,9)-(6,10)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "h" + │ ├── @ CallNode (location: (7,2)-(7,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,2)-(7,3) = "p" + │ │ ├── opening_loc: (7,3)-(7,4) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,4)-(7,5)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (7,4)-(7,5)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (7,5)-(7,6) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "p" + │ ├── @ CallNode (location: (8,2)-(8,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (8,2)-(8,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (8,2)-(8,3) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── call_operator_loc: (8,3)-(8,4) = "." + │ │ ├── message_loc: (8,4)-(8,5) = "b" + │ │ ├── opening_loc: (8,5)-(8,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (8,6)-(8,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (8,6)-(8,7)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (8,7)-(8,8) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── @ CallNode (location: (9,2)-(9,11)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (9,2)-(9,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,3) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── call_operator_loc: (9,3)-(9,4) = "." + │ │ ├── message_loc: (9,4)-(9,5) = "d" + │ │ ├── opening_loc: (9,5)-(9,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,6)-(9,10)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "d" + │ ├── @ CallNode (location: (10,2)-(10,8)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (10,2)-(10,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (10,2)-(10,3) = "e" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "e" + │ │ ├── call_operator_loc: (10,3)-(10,4) = "." + │ │ ├── message_loc: (10,4)-(10,5) = "f" + │ │ ├── opening_loc: (10,5)-(10,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (10,6)-(10,7)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (10,6)-(10,7)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (10,7)-(10,8) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "f" + │ └── @ CallNode (location: (11,2)-(11,11)) + │ ├── receiver: + │ │ @ CallNode (location: (11,2)-(11,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,2)-(11,3) = "g" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "g" + │ ├── call_operator_loc: (11,3)-(11,4) = "." + │ ├── message_loc: (11,4)-(11,5) = "h" + │ ├── opening_loc: (11,5)-(11,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,6)-(11,10)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "h" + ├── consequent: ∅ + └── end_keyword_loc: (12,0)-(12,3) = "end" diff --git a/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt b/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt new file mode 100644 index 00000000000000..ab8857b6d3a17c --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult1_line_numbers2.txt @@ -0,0 +1,73 @@ +@ 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)) + │ ├── statements: + │ │ @ StatementsNode (location: (2,2)-(5,6)) + │ │ └── body: (length: 4) + │ │ ├── @ CallNode (location: (2,2)-(2,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,3) = "p" + │ │ │ ├── opening_loc: (2,3)-(2,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (2,4)-(2,7)) + │ │ │ │ └── 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: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "p" + │ │ ├── @ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,2)-(4,3) = "p" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (4,4)-(4,5)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (4,4)-(4,5)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "p" + │ │ └── @ 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (7,0)-(7,1) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/difficult2_.txt b/test/prism/snapshots/seattlerb/difficult2_.txt new file mode 100644 index 00000000000000..6bada8e1be2afb --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult2_.txt @@ -0,0 +1,66 @@ +@ 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 + │ ├── statements: + │ │ @ StatementsNode (location: (1,4)-(1,9)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "b" + │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,6)-(1,8)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ ├── 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (2,0)-(2,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (2,2)-(2,6)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (2,2)-(2,6)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (2,2)-(2,6)) + │ ├── key: + │ │ @ SymbolNode (location: (2,2)-(2,4)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/seattlerb/difficult3_.txt b/test/prism/snapshots/seattlerb/difficult3_.txt new file mode 100644 index 00000000000000..315602ea1e2405 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3_.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,18)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,18)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,15)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,15)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ SplatNode (location: (1,12)-(1,14)) + │ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*" + │ │ │ │ │ └── expression: + │ │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3_2.txt b/test/prism/snapshots/seattlerb/difficult3_2.txt new file mode 100644 index 00000000000000..c1ebe5b4cfd66c --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3_2.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,13)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,11)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,10)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (1,5)-(1,7)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3_3.txt b/test/prism/snapshots/seattlerb/difficult3_3.txt new file mode 100644 index 00000000000000..46160cc33ce9d8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3_3.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (1,5)-(1,7)) + │ │ │ │ ├── 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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3_4.txt b/test/prism/snapshots/seattlerb/difficult3_4.txt new file mode 100644 index 00000000000000..67fe5715a3a0bb --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3_4.txt @@ -0,0 +1,37 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── statements: + │ │ @ StatementsNode (location: (1,6)-(1,10)) + │ │ └── body: (length: 1) + │ │ └── @ TrueNode (location: (1,6)-(1,10)) + │ ├── consequent: + │ │ @ ElseNode (location: (1,10)-(1,17)) + │ │ ├── else_keyword_loc: (1,10)-(1,11) = ":" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (1,12)-(1,17)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ FalseNode (location: (1,12)-(1,17)) + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + └── operator_loc: (1,1)-(1,2) = "=" diff --git a/test/prism/snapshots/seattlerb/difficult3_5.txt b/test/prism/snapshots/seattlerb/difficult3_5.txt new file mode 100644 index 00000000000000..174557dc5e8047 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3_5.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,19)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(1,19)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,7)-(1,8) = "{" + │ ├── closing_loc: (1,18)-(1,19) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,6)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,4)-(1,5) = "(" + │ │ └── closing_loc: (1,5)-(1,6) = ")" + │ └── body: + │ @ StatementsNode (location: (1,9)-(1,17)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,9)-(1,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,9)-(1,10) = "g" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,11)-(1,17)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,11)-(1,13) = "do" + │ │ └── closing_loc: (1,14)-(1,17) = "end" + │ ├── flags: ∅ + │ └── name: "g" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__10.txt b/test/prism/snapshots/seattlerb/difficult3__10.txt new file mode 100644 index 00000000000000..c70e73eb86a41a --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__10.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,18)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,18)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,15)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,15)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ SplatNode (location: (1,9)-(1,11)) + │ │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ │ └── expression: + │ │ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,13)-(1,14)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__11.txt b/test/prism/snapshots/seattlerb/difficult3__11.txt new file mode 100644 index 00000000000000..6dce59266831cf --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__11.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,14)) + │ ├── locals: [:a] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,11)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,11)) + │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ └── @ SplatNode (location: (1,9)-(1,10)) + │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ └── expression: ∅ + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__12.txt b/test/prism/snapshots/seattlerb/difficult3__12.txt new file mode 100644 index 00000000000000..67947d6301775d --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__12.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,14)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ SplatNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,12)-(1,13)) + │ │ │ │ │ └── name: :b + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__6.txt b/test/prism/snapshots/seattlerb/difficult3__6.txt new file mode 100644 index 00000000000000..ea05a98bbd7eda --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__6.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(1,21)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,21)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,21)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,21)) + │ ├── locals: [:a, :b, :c, :d] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,19)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,18)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,18)) + │ │ │ │ ├── parameters: (length: 3) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ ├── @ SplatNode (location: (1,12)-(1,14)) + │ │ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*" + │ │ │ │ │ │ └── expression: + │ │ │ │ │ │ @ RequiredParameterNode (location: (1,13)-(1,14)) + │ │ │ │ │ │ └── name: :c + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,16)-(1,17)) + │ │ │ │ │ └── name: :d + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__7.txt b/test/prism/snapshots/seattlerb/difficult3__7.txt new file mode 100644 index 00000000000000..8c0aa4cf1b6c7c --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__7.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,17)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,14)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,14)) + │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ └── @ SplatNode (location: (1,12)-(1,13)) + │ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*" + │ │ │ │ │ └── expression: ∅ + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__8.txt b/test/prism/snapshots/seattlerb/difficult3__8.txt new file mode 100644 index 00000000000000..c7e893600ca05d --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__8.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,20)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,20)) + │ ├── locals: [:a, :b, :c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,18)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,17)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,17)) + │ │ │ │ ├── parameters: (length: 3) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ ├── @ SplatNode (location: (1,12)-(1,13)) + │ │ │ │ │ │ ├── operator_loc: (1,12)-(1,13) = "*" + │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,15)-(1,16)) + │ │ │ │ │ └── name: :c + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult3__9.txt b/test/prism/snapshots/seattlerb/difficult3__9.txt new file mode 100644 index 00000000000000..5e1c6b1cab78d7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult3__9.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,2)-(1,15)) + │ ├── locals: [:a, :b] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,13)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,5)-(1,12)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (1,5)-(1,6)) + │ │ │ │ │ └── name: :a + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,8)-(1,12)) + │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ └── @ SplatNode (location: (1,9)-(1,11)) + │ │ │ │ │ ├── operator_loc: (1,9)-(1,10) = "*" + │ │ │ │ │ └── expression: + │ │ │ │ │ @ RequiredParameterNode (location: (1,10)-(1,11)) + │ │ │ │ │ └── name: :b + │ │ │ │ ├── opening_loc: (1,8)-(1,9) = "(" + │ │ │ │ └── closing_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) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt b/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt new file mode 100644 index 00000000000000..acdb72f84c4a65 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult4__leading_dots.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(2,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(2,2)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (2,0)-(2,1) = "." + ├── message_loc: (2,1)-(2,2) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt b/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt new file mode 100644 index 00000000000000..e569fbea1f6a48 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult4__leading_dots2.txt @@ -0,0 +1,14 @@ +@ 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)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (2,2)-(2,3)) + │ └── flags: decimal + ├── operator_loc: (2,0)-(2,2) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/difficult6_.txt b/test/prism/snapshots/seattlerb/difficult6_.txt new file mode 100644 index 00000000000000..dd12d42c1568e0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult6_.txt @@ -0,0 +1,57 @@ +@ ProgramNode (location: (1,0)-(1,25)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,25)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,25)) + ├── locals: [:a, :b] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,13)-(1,14) = "{" + ├── closing_loc: (1,24)-(1,25) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,12)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,3)-(1,11)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4)) + │ │ │ └── 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,15)-(1,16) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,17)-(1,23)) + │ └── arguments: (length: 1) + │ └── @ ArrayNode (location: (1,17)-(1,23)) + │ ├── 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: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/seattlerb/difficult6__7.txt b/test/prism/snapshots/seattlerb/difficult6__7.txt new file mode 100644 index 00000000000000..2ca623e8e83d5f --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult6__7.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,11)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,2) = "." + ├── message_loc: (1,2)-(1,3) = "b" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ └── 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: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,9)-(1,10)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,9)-(1,10)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,10) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── opening_loc: (1,8)-(1,9) = "{" + │ └── closing_loc: (1,10)-(1,11) = "}" + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/difficult6__8.txt b/test/prism/snapshots/seattlerb/difficult6__8.txt new file mode 100644 index 00000000000000..1f7c63ba1239d0 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult6__8.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "::" + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,8)) + │ └── 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: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,10)-(1,11)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,10)-(1,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,10)-(1,11) = "c" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "c" + │ ├── opening_loc: (1,9)-(1,10) = "{" + │ └── closing_loc: (1,11)-(1,12) = "}" + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/difficult7_.txt b/test/prism/snapshots/seattlerb/difficult7_.txt new file mode 100644 index 00000000000000..e567448bcfa928 --- /dev/null +++ b/test/prism/snapshots/seattlerb/difficult7_.txt @@ -0,0 +1,90 @@ +@ 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (2,8)-(2,9) = "a" + │ │ │ ├── closing_loc: (2,9)-(2,10) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ CallNode (location: (2,11)-(2,33)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,11)-(2,17) = "lambda" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (2,18)-(2,33)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (2,20)-(2,31)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ IfNode (location: (2,20)-(2,31)) + │ │ │ │ │ ├── if_keyword_loc: ∅ + │ │ │ │ │ ├── predicate: + │ │ │ │ │ │ @ CallNode (location: (2,20)-(2,21)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (2,20)-(2,21) = "b" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "b" + │ │ │ │ │ ├── statements: + │ │ │ │ │ │ @ StatementsNode (location: (2,24)-(2,27)) + │ │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (2,24)-(2,27)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (2,24)-(2,25) = "c" + │ │ │ │ │ │ ├── opening_loc: (2,25)-(2,26) = "(" + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: (2,26)-(2,27) = ")" + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ │ └── name: "c" + │ │ │ │ │ ├── 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)) + │ │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ │ ├── message_loc: (2,30)-(2,31) = "d" + │ │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ │ └── end_keyword_loc: ∅ + │ │ │ │ │ └── end_keyword_loc: ∅ + │ │ │ │ ├── opening_loc: (2,18)-(2,19) = "{" + │ │ │ │ └── closing_loc: (2,32)-(2,33) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "lambda" + │ │ └── operator_loc: ∅ + │ └── @ AssocNode (location: (3,8)-(3,14)) + │ ├── key: + │ │ @ SymbolNode (location: (3,8)-(3,10)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (3,8)-(3,9) = "e" + │ │ ├── closing_loc: (3,9)-(3,10) = ":" + │ │ └── unescaped: "e" + │ ├── value: + │ │ @ NilNode (location: (3,11)-(3,14)) + │ └── operator_loc: ∅ + └── closing_loc: (4,6)-(4,7) = "}" diff --git a/test/prism/snapshots/seattlerb/do_bug.txt b/test/prism/snapshots/seattlerb/do_bug.txt new file mode 100644 index 00000000000000..49b3605da3f63d --- /dev/null +++ b/test/prism/snapshots/seattlerb/do_bug.txt @@ -0,0 +1,60 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,2)-(1,3)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (2,0)-(4,3)) + ├── receiver: + │ @ CallNode (location: (2,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,0)-(2,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (2,1)-(2,2) = "." + ├── message_loc: (2,2)-(2,3) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (2,4)-(4,3)) + │ ├── locals: [:c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (2,7)-(2,10)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (2,8)-(2,9)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (2,8)-(2,9)) + │ │ │ │ └── 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" + ├── flags: ∅ + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/do_lambda.txt b/test/prism/snapshots/seattlerb/do_lambda.txt new file mode 100644 index 00000000000000..4713fb3e4b7dcc --- /dev/null +++ b/test/prism/snapshots/seattlerb/do_lambda.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,11)) + ├── locals: [] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,5)-(1,7) = "do" + ├── closing_loc: (1,8)-(1,11) = "end" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,4)) + │ ├── parameters: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (1,2)-(1,3) = "(" + │ └── closing_loc: (1,3)-(1,4) = ")" + └── body: ∅ diff --git a/test/prism/snapshots/seattlerb/dot2_nil__26.txt b/test/prism/snapshots/seattlerb/dot2_nil__26.txt new file mode 100644 index 00000000000000..6e10c488189b7a --- /dev/null +++ b/test/prism/snapshots/seattlerb/dot2_nil__26.txt @@ -0,0 +1,20 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,3)) + ├── left: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── right: ∅ + ├── operator_loc: (1,1)-(1,3) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/seattlerb/dot3_nil__26.txt b/test/prism/snapshots/seattlerb/dot3_nil__26.txt new file mode 100644 index 00000000000000..0da36ab4713a0f --- /dev/null +++ b/test/prism/snapshots/seattlerb/dot3_nil__26.txt @@ -0,0 +1,20 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,4)) + ├── left: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── right: ∅ + ├── operator_loc: (1,1)-(1,4) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/seattlerb/dstr_evstr.txt b/test/prism/snapshots/seattlerb/dstr_evstr.txt new file mode 100644 index 00000000000000..c070c86f96ccdd --- /dev/null +++ b/test/prism/snapshots/seattlerb/dstr_evstr.txt @@ -0,0 +1,37 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,10) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── closing_loc: (1,10)-(1,11) = "}" + └── closing_loc: (1,11)-(1,12) = "\"" diff --git a/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt b/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt new file mode 100644 index 00000000000000..a51f7fe994e08a --- /dev/null +++ b/test/prism/snapshots/seattlerb/dstr_evstr_empty_end.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ InterpolatedSymbolNode (location: (1,0)-(1,11)) + ├── opening_loc: (1,0)-(1,2) = ":\"" + ├── parts: (length: 1) + │ └── @ EmbeddedStatementsNode (location: (1,2)-(1,10)) + │ ├── opening_loc: (1,2)-(1,4) = "\#{" + │ ├── statements: + │ │ @ StatementsNode (location: (1,4)-(1,9)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,9) = "field" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "field" + │ └── closing_loc: (1,9)-(1,10) = "}" + └── closing_loc: (1,10)-(1,11) = "\"" diff --git a/test/prism/snapshots/seattlerb/dstr_lex_state.txt b/test/prism/snapshots/seattlerb/dstr_lex_state.txt new file mode 100644 index 00000000000000..60d9eff91eefff --- /dev/null +++ b/test/prism/snapshots/seattlerb/dstr_lex_state.txt @@ -0,0 +1,32 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ InterpolatedStringNode (location: (1,0)-(1,8)) + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,3)-(1,4) = "p" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,4)-(1,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ SymbolNode (location: (1,4)-(1,6)) + │ │ │ ├── opening_loc: (1,4)-(1,5) = ":" + │ │ │ ├── value_loc: (1,5)-(1,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "p" + │ └── closing_loc: (1,6)-(1,7) = "}" + └── closing_loc: (1,7)-(1,8) = "\"" diff --git a/test/prism/snapshots/seattlerb/dstr_str.txt b/test/prism/snapshots/seattlerb/dstr_str.txt new file mode 100644 index 00000000000000..42bd37a1ac9527 --- /dev/null +++ b/test/prism/snapshots/seattlerb/dstr_str.txt @@ -0,0 +1,27 @@ +@ 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 new file mode 100644 index 00000000000000..a52ac4043cd5e7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/dsym_esc_to_sym.txt @@ -0,0 +1,10 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ SymbolNode (location: (1,0)-(1,17)) + ├── opening_loc: (1,0)-(1,2) = ":\"" + ├── value_loc: (1,2)-(1,16) = "Variet\\303\\240" + ├── closing_loc: (1,16)-(1,17) = "\"" + └── unescaped: "Varietà" diff --git a/test/prism/snapshots/seattlerb/dsym_to_sym.txt b/test/prism/snapshots/seattlerb/dsym_to_sym.txt new file mode 100644 index 00000000000000..1d7fcf801f96bd --- /dev/null +++ b/test/prism/snapshots/seattlerb/dsym_to_sym.txt @@ -0,0 +1,33 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ ├── opening_loc: (3,6)-(3,7) = ":" + │ ├── value_loc: (3,7)-(3,9) = "<<" + │ ├── closing_loc: ∅ + │ └── unescaped: "<<" + ├── old_name: + │ @ SymbolNode (location: (3,10)-(3,13)) + │ ├── opening_loc: (3,10)-(3,11) = ":" + │ ├── value_loc: (3,11)-(3,13) = ">>" + │ ├── closing_loc: ∅ + │ └── unescaped: ">>" + └── keyword_loc: (3,0)-(3,5) = "alias" diff --git a/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt b/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt new file mode 100644 index 00000000000000..1fd43f61663e3e --- /dev/null +++ b/test/prism/snapshots/seattlerb/eq_begin_line_numbers.txt @@ -0,0 +1,9 @@ +@ 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 new file mode 100644 index 00000000000000..38c745deeffe2f --- /dev/null +++ b/test/prism/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(3,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,8)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "h" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "h" + ├── call_operator_loc: ∅ + ├── message_loc: (1,1)-(1,4) = "[k]" + ├── opening_loc: (1,1)-(1,2) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(3,8)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (1,2)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "k" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "k" + │ └── @ 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: ∅ + ├── flags: ∅ + └── name: "[]=" diff --git a/test/prism/snapshots/seattlerb/evstr_evstr.txt b/test/prism/snapshots/seattlerb/evstr_evstr.txt new file mode 100644 index 00000000000000..373f49364e0b8c --- /dev/null +++ b/test/prism/snapshots/seattlerb/evstr_evstr.txt @@ -0,0 +1,41 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,3)-(1,4) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,8) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── closing_loc: (1,8)-(1,9) = "}" + └── closing_loc: (1,9)-(1,10) = "\"" diff --git a/test/prism/snapshots/seattlerb/evstr_str.txt b/test/prism/snapshots/seattlerb/evstr_str.txt new file mode 100644 index 00000000000000..196014e3077bc7 --- /dev/null +++ b/test/prism/snapshots/seattlerb/evstr_str.txt @@ -0,0 +1,31 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,3)-(1,4) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── 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 new file mode 100644 index 00000000000000..f9679d8df6a030 --- /dev/null +++ b/test/prism/snapshots/seattlerb/expr_not_bang.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,5)) + ├── receiver: + │ @ CallNode (location: (1,2)-(1,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,2)-(1,3) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/seattlerb/f_kw.txt b/test/prism/snapshots/seattlerb/f_kw.txt new file mode 100644 index 00000000000000..cbc29b9c96e9a5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/f_kw.txt @@ -0,0 +1,32 @@ +@ 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) + │ │ └── @ KeywordParameterNode (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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (1,12)-(1,15) = "end" diff --git a/test/prism/snapshots/seattlerb/f_kw__required.txt b/test/prism/snapshots/seattlerb/f_kw__required.txt new file mode 100644 index 00000000000000..16d94d6b4629d3 --- /dev/null +++ b/test/prism/snapshots/seattlerb/f_kw__required.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,13)) + ├── name: :x + ├── name_loc: (1,4)-(1,5) = "x" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (1,6)-(1,8)) + │ ├── requireds: (length: 0) + │ ├── optionals: (length: 0) + │ ├── rest: ∅ + │ ├── posts: (length: 0) + │ ├── keywords: (length: 1) + │ │ └── @ KeywordParameterNode (location: (1,6)-(1,8)) + │ │ ├── name: :k + │ │ ├── name_loc: (1,6)-(1,8) = "k:" + │ │ └── value: ∅ + │ ├── keyword_rest: ∅ + │ └── block: ∅ + ├── body: ∅ + ├── locals: [:k] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (1,10)-(1,13) = "end" diff --git a/test/prism/snapshots/seattlerb/flip2_env_lvar.txt b/test/prism/snapshots/seattlerb/flip2_env_lvar.txt new file mode 100644 index 00000000000000..1bd74d2b8276fe --- /dev/null +++ b/test/prism/snapshots/seattlerb/flip2_env_lvar.txt @@ -0,0 +1,36 @@ +@ 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)) + │ ├── left: + │ │ @ CallNode (location: (1,3)-(1,4)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,3)-(1,4) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── right: + │ │ @ CallNode (location: (1,6)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── operator_loc: (1,4)-(1,6) = ".." + │ └── flags: ∅ + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (1,13)-(1,16) = "end" diff --git a/test/prism/snapshots/seattlerb/float_with_if_modifier.txt b/test/prism/snapshots/seattlerb/float_with_if_modifier.txt new file mode 100644 index 00000000000000..798dba2d052e6f --- /dev/null +++ b/test/prism/snapshots/seattlerb/float_with_if_modifier.txt @@ -0,0 +1,15 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ IfNode (location: (1,0)-(1,10)) + ├── if_keyword_loc: (1,3)-(1,5) = "if" + ├── predicate: + │ @ TrueNode (location: (1,6)-(1,10)) + ├── 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 new file mode 100644 index 00000000000000..1d8b569dfe9b0d --- /dev/null +++ b/test/prism/snapshots/seattlerb/heredoc__backslash_dos_format.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [:str] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ LocalVariableWriteNode (location: (1,0)-(1,12)) + ├── name: :str + ├── depth: 0 + ├── name_loc: (1,0)-(1,3) = "str" + ├── value: + │ @ StringNode (location: (1,6)-(1,12)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,6)-(1,12) = "<<-XXX" + │ ├── content_loc: (2,0)-(3,0) = "before\\\r\nafter\r\n" + │ ├── closing_loc: (4,0)-(4,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 new file mode 100644 index 00000000000000..3f98b7cd4371ef --- /dev/null +++ b/test/prism/snapshots/seattlerb/heredoc_backslash_nl.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(5,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,7)) + └── body: (length: 2) + ├── @ StringNode (location: (1,0)-(3,1)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,0)-(1,1) = "\"" + │ ├── content_loc: (1,1)-(2,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)-(7,0) = " why would someone do this? \\\n blah\n" + ├── closing_loc: (8,0)-(8,0) = "DESC\n" + └── unescaped: " why would someone do this? blah\n" diff --git a/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt b/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt new file mode 100644 index 00000000000000..29770b2ba379d1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/heredoc_bad_hex_escape.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [:s] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ LocalVariableWriteNode (location: (1,0)-(1,9)) + ├── name: :s + ├── depth: 0 + ├── name_loc: (1,0)-(1,1) = "s" + ├── value: + │ @ StringNode (location: (1,4)-(1,9)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,4)-(1,9) = "<" diff --git a/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt b/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt new file mode 100644 index 00000000000000..779a26b9a4a165 --- /dev/null +++ b/test/prism/snapshots/seattlerb/safe_call_rhs_newline.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [:c] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ LocalVariableWriteNode (location: (1,0)-(1,8)) + ├── name: :c + ├── depth: 0 + ├── name_loc: (1,0)-(1,1) = "c" + ├── value: + │ @ CallNode (location: (1,4)-(1,8)) + │ ├── receiver: + │ │ @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,5)-(1,7) = "&." + │ ├── message_loc: (1,7)-(1,8) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + └── operator_loc: (1,2)-(1,3) = "=" diff --git a/test/prism/snapshots/seattlerb/safe_calls.txt b/test/prism/snapshots/seattlerb/safe_calls.txt new file mode 100644 index 00000000000000..f4f9644f12e33d --- /dev/null +++ b/test/prism/snapshots/seattlerb/safe_calls.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,10)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (1,1)-(1,3) = "&." + │ ├── message_loc: (1,3)-(1,4) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + ├── call_operator_loc: (1,4)-(1,6) = "&." + ├── message_loc: (1,6)-(1,7) = "c" + ├── opening_loc: (1,7)-(1,8) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,8)-(1,9)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,8)-(1,9)) + │ └── flags: decimal + ├── closing_loc: (1,9)-(1,10) = ")" + ├── block: ∅ + ├── flags: safe_navigation + └── name: "c" diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn.txt b/test/prism/snapshots/seattlerb/safe_op_asgn.txt new file mode 100644 index 00000000000000..eee4cd1b422e77 --- /dev/null +++ b/test/prism/snapshots/seattlerb/safe_op_asgn.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallOperatorWriteNode (location: (1,0)-(1,11)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "&." + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: safe_navigation + ├── read_name: "b" + ├── write_name: "b=" + ├── operator: :+ + ├── operator_loc: (1,5)-(1,7) = "+=" + └── value: + @ CallNode (location: (1,8)-(1,11)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,8)-(1,9) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,10)-(1,11)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,10)-(1,11)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/safe_op_asgn2.txt b/test/prism/snapshots/seattlerb/safe_op_asgn2.txt new file mode 100644 index 00000000000000..f7d02d3e5566a1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/safe_op_asgn2.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(2,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,1)) + └── body: (length: 1) + └── @ CallOrWriteNode (location: (1,0)-(2,1)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "&." + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: safe_navigation + ├── read_name: "b" + ├── write_name: "b=" + ├── operator_loc: (1,5)-(1,8) = "||=" + └── value: + @ CallNode (location: (2,0)-(2,1)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (2,0)-(2,1) = "x" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt b/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt new file mode 100644 index 00000000000000..49e52658712cfc --- /dev/null +++ b/test/prism/snapshots/seattlerb/slashy_newlines_within_string.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(6,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(6,5)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(4,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "puts" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,5)-(4,8)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "puts" + └── @ CallNode (location: (6,0)-(6,5)) + ├── receiver: + │ @ CallNode (location: (6,0)-(6,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,0)-(6,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (6,2)-(6,3) = "+" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (6,4)-(6,5)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (6,4)-(6,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,4)-(6,5) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "+" diff --git a/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt b/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt new file mode 100644 index 00000000000000..7392e71525f778 --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_arg_no_paren.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,5)) + ├── locals: [:a] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,3)-(1,4) = "{" + ├── closing_loc: (1,4)-(1,5) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,3)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,2)-(1,3)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (1,2)-(1,3)) + │ │ │ └── name: :a + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + └── body: ∅ diff --git a/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt new file mode 100644 index 00000000000000..0661b2a2aa1a26 --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt @@ -0,0 +1,44 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,23)) + ├── locals: [:b, :c, :d, :e, :f] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,21)-(1,22) = "{" + ├── closing_loc: (1,22)-(1,23) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,21)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,3)-(1,20)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4)) + │ │ │ └── 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 new file mode 100644 index 00000000000000..4cce2844976df3 --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_block_iter_call.txt @@ -0,0 +1,57 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(4,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(4,3)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(4,3)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,8)-(1,10) = "do" + │ ├── closing_loc: (4,0)-(4,3) = "end" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,5)-(1,7)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ └── closing_loc: (1,6)-(1,7) = ")" + │ └── body: + │ @ StatementsNode (location: (2,0)-(3,3)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (2,0)-(3,3)) + │ ├── receiver: + │ │ @ CallNode (location: (2,0)-(2,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,0)-(2,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (2,1)-(2,2) = "." + │ ├── message_loc: (2,2)-(2,3) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (2,4)-(3,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (2,4)-(2,6) = "do" + │ │ └── closing_loc: (3,0)-(3,3) = "end" + │ ├── flags: ∅ + │ └── name: "b" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt b/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt new file mode 100644 index 00000000000000..46f401eb5a31dc --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt @@ -0,0 +1,51 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(4,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(4,3)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(4,3)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,8)-(1,10) = "do" + │ ├── closing_loc: (4,0)-(4,3) = "end" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,5)-(1,7)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ └── closing_loc: (1,6)-(1,7) = ")" + │ └── body: + │ @ StatementsNode (location: (2,0)-(3,3)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (2,0)-(3,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,0)-(2,1) = "a" + │ ├── opening_loc: (2,1)-(2,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (2,2)-(2,3)) + │ │ └── 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: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (2,5)-(2,7) = "do" + │ │ └── closing_loc: (3,0)-(3,3) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/stabby_block_kw.txt b/test/prism/snapshots/seattlerb/stabby_block_kw.txt new file mode 100644 index 00000000000000..e3613e4b362a4e --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_block_kw.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,13)) + ├── locals: [:k] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,10)-(1,11) = "{" + ├── closing_loc: (1,12)-(1,13) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,3)-(1,9)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,4)-(1,8)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (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 new file mode 100644 index 00000000000000..0139100071e97e --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_block_kw__required.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,11)) + ├── locals: [:k] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,8)-(1,9) = "{" + ├── closing_loc: (1,10)-(1,11) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,3)-(1,7)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,4)-(1,6)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (location: (1,4)-(1,6)) + │ │ │ ├── name: :k + │ │ │ ├── name_loc: (1,4)-(1,6) = "k:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ └── closing_loc: (1,6)-(1,7) = ")" + └── body: ∅ diff --git a/test/prism/snapshots/seattlerb/stabby_proc_scope.txt b/test/prism/snapshots/seattlerb/stabby_proc_scope.txt new file mode 100644 index 00000000000000..059192d67f1c6f --- /dev/null +++ b/test/prism/snapshots/seattlerb/stabby_proc_scope.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,11)) + ├── locals: [:a, :b] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,9)-(1,10) = "{" + ├── closing_loc: (1,10)-(1,11) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,8)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,3)-(1,4)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4)) + │ │ │ └── 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 new file mode 100644 index 00000000000000..09e8628e8b257f --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_backslashes.txt @@ -0,0 +1,23 @@ +@ ProgramNode (location: (1,0)-(1,204)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,204)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,204)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "x" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,204)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "x" diff --git a/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt new file mode 100644 index 00000000000000..56fdd6cd7d131f --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_double_double_escaped_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,7)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (1,8)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,8)-(1,9) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt new file mode 100644 index 00000000000000..906ef18d65bdb2 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_double_escaped_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,6)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (1,7)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,7)-(1,8) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_double_newline.txt b/test/prism/snapshots/seattlerb/str_double_newline.txt new file mode 100644 index 00000000000000..67953d770fc2da --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_double_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,3)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(2,1)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (1,2)-(2,1)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,2)-(1,3) = "\"" + │ │ ├── content_loc: (1,3)-(1,0) = "\n" + │ │ ├── closing_loc: (2,0)-(2,1) = "\"" + │ │ └── unescaped: "\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (2,2)-(2,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (2,2)-(2,3) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_evstr.txt b/test/prism/snapshots/seattlerb/str_evstr.txt new file mode 100644 index 00000000000000..8062024ed45433 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_evstr.txt @@ -0,0 +1,31 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,6) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── closing_loc: (1,6)-(1,7) = "}" + └── closing_loc: (1,7)-(1,8) = "\"" diff --git a/test/prism/snapshots/seattlerb/str_evstr_escape.txt b/test/prism/snapshots/seattlerb/str_evstr_escape.txt new file mode 100644 index 00000000000000..9dd987d22643ce --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_evstr_escape.txt @@ -0,0 +1,37 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,5)-(1,6) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── closing_loc: (1,6)-(1,7) = "}" + │ └── @ StringNode (location: (1,7)-(1,15)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (1,7)-(1,15) = "\\302\\275" + │ ├── closing_loc: ∅ + │ └── unescaped: "½" + └── closing_loc: (1,15)-(1,16) = "\"" diff --git a/test/prism/snapshots/seattlerb/str_heredoc_interp.txt b/test/prism/snapshots/seattlerb/str_heredoc_interp.txt new file mode 100644 index 00000000000000..465469430cb86a --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_heredoc_interp.txt @@ -0,0 +1,31 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,3) = "x" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "x" + │ │ └── closing_loc: (2,3)-(2,4) = "}" + │ └── @ StringNode (location: (2,4)-(3,0)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (2,4)-(3,0) = "\nblah2\n" + │ ├── closing_loc: ∅ + │ └── unescaped: "\nblah2\n" + └── closing_loc: (4,0)-(4,0) = "\n" diff --git a/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt b/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt new file mode 100644 index 00000000000000..c168afca2d49dd --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_interp_ternary_or_label.txt @@ -0,0 +1,101 @@ +@ 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (1,3)-(1,4)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,3)-(1,4) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: (1,4)-(1,5) = "." + │ │ │ ├── message_loc: (1,5)-(1,7) = "b?" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b?" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (1,10)-(1,17)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (1,10)-(1,17)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (1,10)-(1,14)) + │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── message_loc: (1,12)-(1,13) = "+" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (1,13)-(1,14)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,13)-(1,14)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,13)-(1,14) = "a" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "a" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "+" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,14)-(1,15) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,15)-(1,17)) + │ │ │ │ └── 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: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── consequent: + │ │ │ @ ElseNode (location: (1,17)-(1,21)) + │ │ │ ├── else_keyword_loc: (1,17)-(1,18) = ":" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (1,19)-(1,21)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ StringNode (location: (1,19)-(1,21)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: (1,19)-(1,20) = "\"" + │ │ │ │ ├── content_loc: (1,20)-(1,20) = "" + │ │ │ │ ├── closing_loc: (1,20)-(1,21) = "\"" + │ │ │ │ └── unescaped: "" + │ │ │ └── end_keyword_loc: ∅ + │ │ └── end_keyword_loc: ∅ + │ └── closing_loc: (1,21)-(1,22) = "}" + └── closing_loc: (1,22)-(1,23) = "\"" diff --git a/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt b/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt new file mode 100644 index 00000000000000..7bf71b7858b9e8 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_lit_concat_bad_encodings.txt @@ -0,0 +1,20 @@ +@ ProgramNode (location: (1,0)-(2,66)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,66)) + └── body: (length: 1) + └── @ StringConcatNode (location: (1,0)-(2,66)) + ├── left: + │ @ StringNode (location: (1,0)-(1,62)) + │ ├── flags: ∅ + │ ├── 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" + └── right: + @ StringNode (location: (2,8)-(2,66)) + ├── flags: ∅ + ├── 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" diff --git a/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt b/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt new file mode 100644 index 00000000000000..89f20da7b59584 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_newline_hash_line_number.txt @@ -0,0 +1,13 @@ +@ 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 new file mode 100644 index 00000000000000..6651fcdde06f59 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_pct_Q_nested.txt @@ -0,0 +1,37 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,13)-(1,17) = "nest" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "nest" + │ │ └── 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 new file mode 100644 index 00000000000000..85ad89bc60673f --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_pct_nested_nested.txt @@ -0,0 +1,39 @@ +@ 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 new file mode 100644 index 00000000000000..c4dd5bacae2725 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_pct_q.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,9)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,3) = "%q{" + ├── content_loc: (1,3)-(1,8) = "a b c" + ├── closing_loc: (1,8)-(1,9) = "}" + └── unescaped: "a b c" diff --git a/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt new file mode 100644 index 00000000000000..6b155de8864169 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_single_double_escaped_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,7)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (1,8)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,8)-(1,9) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt b/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt new file mode 100644 index 00000000000000..ba2e204b687267 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_single_escaped_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,6)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (1,7)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,7)-(1,8) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_single_newline.txt b/test/prism/snapshots/seattlerb/str_single_newline.txt new file mode 100644 index 00000000000000..18a96fbee60fcf --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_single_newline.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,3)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(2,1)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (1,2)-(2,1)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,2)-(1,3) = "'" + │ │ ├── content_loc: (1,3)-(1,0) = "\n" + │ │ ├── closing_loc: (2,0)-(2,1) = "'" + │ │ └── unescaped: "\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (2,2)-(2,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (2,2)-(2,3) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "b" diff --git a/test/prism/snapshots/seattlerb/str_str.txt b/test/prism/snapshots/seattlerb/str_str.txt new file mode 100644 index 00000000000000..f183980f5e73c9 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_str.txt @@ -0,0 +1,27 @@ +@ 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 new file mode 100644 index 00000000000000..68873d81825c66 --- /dev/null +++ b/test/prism/snapshots/seattlerb/str_str_str.txt @@ -0,0 +1,33 @@ +@ 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 new file mode 100644 index 00000000000000..41109adcc3a484 --- /dev/null +++ b/test/prism/snapshots/seattlerb/super_arg.txt @@ -0,0 +1,15 @@ +@ 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)) + │ └── 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 new file mode 100644 index 00000000000000..ab423959a09c50 --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbol_empty.txt @@ -0,0 +1,10 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ SymbolNode (location: (1,0)-(1,3)) + ├── opening_loc: (1,0)-(1,2) = ":'" + ├── value_loc: (1,2)-(1,2) = "" + ├── closing_loc: (1,2)-(1,3) = "'" + └── unescaped: "" diff --git a/test/prism/snapshots/seattlerb/symbol_list.txt b/test/prism/snapshots/seattlerb/symbol_list.txt new file mode 100644 index 00000000000000..834543195d60a1 --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbol_list.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,13)) + ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,5)-(1,6) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,10)-(1,11) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── closing_loc: (1,11)-(1,12) = "}" + │ └── closing_loc: ∅ + ├── opening_loc: (1,0)-(1,3) = "%I[" + └── closing_loc: (1,12)-(1,13) = "]" diff --git a/test/prism/snapshots/seattlerb/symbols.txt b/test/prism/snapshots/seattlerb/symbols.txt new file mode 100644 index 00000000000000..1d4eae94aa6705 --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbols.txt @@ -0,0 +1,24 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,9)) + ├── elements: (length: 3) + │ ├── @ SymbolNode (location: (1,3)-(1,4)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,3)-(1,4) = "a" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "a" + │ ├── @ SymbolNode (location: (1,5)-(1,6)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,5)-(1,6) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ └── @ SymbolNode (location: (1,7)-(1,8)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (1,7)-(1,8) = "c" + │ ├── closing_loc: ∅ + │ └── unescaped: "c" + ├── opening_loc: (1,0)-(1,3) = "%i(" + └── closing_loc: (1,8)-(1,9) = ")" diff --git a/test/prism/snapshots/seattlerb/symbols_empty.txt b/test/prism/snapshots/seattlerb/symbols_empty.txt new file mode 100644 index 00000000000000..74800d6bc6f92d --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbols_empty.txt @@ -0,0 +1,9 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,4)) + ├── elements: (length: 0) + ├── opening_loc: (1,0)-(1,3) = "%i(" + └── closing_loc: (1,3)-(1,4) = ")" diff --git a/test/prism/snapshots/seattlerb/symbols_empty_space.txt b/test/prism/snapshots/seattlerb/symbols_empty_space.txt new file mode 100644 index 00000000000000..bff515a6dca26e --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbols_empty_space.txt @@ -0,0 +1,9 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,5)) + ├── elements: (length: 0) + ├── opening_loc: (1,0)-(1,3) = "%i(" + └── closing_loc: (1,4)-(1,5) = ")" diff --git a/test/prism/snapshots/seattlerb/symbols_interp.txt b/test/prism/snapshots/seattlerb/symbols_interp.txt new file mode 100644 index 00000000000000..6d7f614211838b --- /dev/null +++ b/test/prism/snapshots/seattlerb/symbols_interp.txt @@ -0,0 +1,24 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,15)) + ├── elements: (length: 3) + │ ├── @ SymbolNode (location: (1,3)-(1,4)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,3)-(1,4) = "a" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "a" + │ ├── @ SymbolNode (location: (1,5)-(1,12)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,5)-(1,12) = "b\#{1+1}" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b\#{1+1}" + │ └── @ SymbolNode (location: (1,13)-(1,14)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (1,13)-(1,14) = "c" + │ ├── closing_loc: ∅ + │ └── unescaped: "c" + ├── opening_loc: (1,0)-(1,3) = "%i(" + └── closing_loc: (1,14)-(1,15) = ")" diff --git a/test/prism/snapshots/seattlerb/thingy.txt b/test/prism/snapshots/seattlerb/thingy.txt new file mode 100644 index 00000000000000..96c76e64b6d05a --- /dev/null +++ b/test/prism/snapshots/seattlerb/thingy.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(3,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,7)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,6)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "f" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "f" + │ ├── call_operator_loc: (1,1)-(1,2) = "." + │ ├── message_loc: ∅ + │ ├── opening_loc: (1,2)-(1,3) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,3)-(1,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,3)-(1,5)) + │ │ └── flags: decimal + │ ├── closing_loc: (1,5)-(1,6) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "call" + └── @ CallNode (location: (3,0)-(3,7)) + ├── receiver: + │ @ CallNode (location: (3,0)-(3,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "f" + ├── call_operator_loc: (3,1)-(3,3) = "::" + ├── message_loc: ∅ + ├── opening_loc: (3,3)-(3,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (3,4)-(3,6)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (3,4)-(3,6)) + │ └── flags: decimal + ├── closing_loc: (3,6)-(3,7) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "call" diff --git a/test/prism/snapshots/seattlerb/uminus_float.txt b/test/prism/snapshots/seattlerb/uminus_float.txt new file mode 100644 index 00000000000000..b509e2f7f365bd --- /dev/null +++ b/test/prism/snapshots/seattlerb/uminus_float.txt @@ -0,0 +1,6 @@ +@ 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 new file mode 100644 index 00000000000000..e69aaaadeccc86 --- /dev/null +++ b/test/prism/snapshots/seattlerb/unary_minus.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,2)) + ├── receiver: + │ @ CallNode (location: (1,1)-(1,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,1)-(1,2) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "-" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "-@" diff --git a/test/prism/snapshots/seattlerb/unary_plus.txt b/test/prism/snapshots/seattlerb/unary_plus.txt new file mode 100644 index 00000000000000..4d6c27805a0652 --- /dev/null +++ b/test/prism/snapshots/seattlerb/unary_plus.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,2)) + ├── receiver: + │ @ CallNode (location: (1,1)-(1,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,1)-(1,2) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "+" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "+@" diff --git a/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt b/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt new file mode 100644 index 00000000000000..9d1cb6a12c1fd5 --- /dev/null +++ b/test/prism/snapshots/seattlerb/unary_plus_on_literal.txt @@ -0,0 +1,20 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,3)) + ├── receiver: + │ @ SymbolNode (location: (1,1)-(1,3)) + │ ├── opening_loc: (1,1)-(1,2) = ":" + │ ├── value_loc: (1,2)-(1,3) = "a" + │ ├── closing_loc: ∅ + │ └── unescaped: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "+" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "+@" diff --git a/test/prism/snapshots/seattlerb/unary_tilde.txt b/test/prism/snapshots/seattlerb/unary_tilde.txt new file mode 100644 index 00000000000000..aa413484dcdfdd --- /dev/null +++ b/test/prism/snapshots/seattlerb/unary_tilde.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,2)) + ├── receiver: + │ @ CallNode (location: (1,1)-(1,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,1)-(1,2) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "~" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "~" diff --git a/test/prism/snapshots/seattlerb/utf8_bom.txt b/test/prism/snapshots/seattlerb/utf8_bom.txt new file mode 100644 index 00000000000000..6e563935219b47 --- /dev/null +++ b/test/prism/snapshots/seattlerb/utf8_bom.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (2,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (2,0)-(2,3)) + └── body: (length: 1) + └── @ CallNode (location: (2,0)-(2,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (2,0)-(2,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (2,2)-(2,3)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (2,2)-(2,3)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/seattlerb/when_splat.txt b/test/prism/snapshots/seattlerb/when_splat.txt new file mode 100644 index 00000000000000..bdeae40fba9eda --- /dev/null +++ b/test/prism/snapshots/seattlerb/when_splat.txt @@ -0,0 +1,38 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,6) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,14)-(1,15) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── statements: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,22)-(1,25) = "end" diff --git a/test/prism/snapshots/seattlerb/words_interp.txt b/test/prism/snapshots/seattlerb/words_interp.txt new file mode 100644 index 00000000000000..eddc835f0203be --- /dev/null +++ b/test/prism/snapshots/seattlerb/words_interp.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,9)) + ├── 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 new file mode 100644 index 00000000000000..ae6a5d2b0b39dd --- /dev/null +++ b/test/prism/snapshots/seattlerb/yield_arg.txt @@ -0,0 +1,14 @@ +@ 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)) + │ └── 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 new file mode 100644 index 00000000000000..6964a034c41642 --- /dev/null +++ b/test/prism/snapshots/seattlerb/yield_call_assocs.txt @@ -0,0 +1,193 @@ +@ 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)) + │ │ └── arguments: (length: 2) + │ │ ├── @ IntegerNode (location: (1,6)-(1,7)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordHashNode (location: (1,9)-(1,16)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,9)-(1,16)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,9)-(1,11)) + │ │ │ ├── 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)) + │ │ └── arguments: (length: 2) + │ │ ├── @ IntegerNode (location: (3,6)-(3,7)) + │ │ │ └── flags: decimal + │ │ └── @ KeywordHashNode (location: (3,9)-(3,25)) + │ │ └── elements: (length: 2) + │ │ ├── @ AssocNode (location: (3,9)-(3,16)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (3,9)-(3,11)) + │ │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (5,6)-(5,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,6)-(5,7) = "y" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,8)-(5,13)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ KeywordHashNode (location: (5,8)-(5,13)) + │ │ │ └── elements: (length: 1) + │ │ │ └── @ AssocNode (location: (5,8)-(5,13)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (5,8)-(5,10)) + │ │ │ │ ├── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "y" + │ └── rparen_loc: ∅ + ├── @ YieldNode (location: (7,0)-(7,11)) + │ ├── keyword_loc: (7,0)-(7,5) = "yield" + │ ├── lparen_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,6)-(7,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (7,6)-(7,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,6)-(7,7) = "y" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,8)-(7,11)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ KeywordHashNode (location: (7,8)-(7,11)) + │ │ │ └── elements: (length: 1) + │ │ │ └── @ AssocNode (location: (7,8)-(7,11)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (7,8)-(7,10)) + │ │ │ │ ├── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "y" + │ └── rparen_loc: ∅ + ├── @ YieldNode (location: (9,0)-(9,12)) + │ ├── keyword_loc: (9,0)-(9,5) = "yield" + │ ├── lparen_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,6)-(9,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (9,6)-(9,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,6)-(9,7) = "y" + │ │ ├── opening_loc: (9,7)-(9,8) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,8)-(9,11)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ KeywordHashNode (location: (9,8)-(9,11)) + │ │ │ └── elements: (length: 1) + │ │ │ └── @ AssocNode (location: (9,8)-(9,11)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (9,8)-(9,10)) + │ │ │ │ ├── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "y" + │ └── rparen_loc: ∅ + └── @ YieldNode (location: (11,0)-(11,13)) + ├── keyword_loc: (11,0)-(11,5) = "yield" + ├── lparen_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (11,6)-(11,13)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (11,6)-(11,13)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,6)-(11,7) = "y" + │ ├── opening_loc: (11,7)-(11,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,8)-(11,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (11,8)-(11,12)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (11,8)-(11,12)) + │ │ ├── key: + │ │ │ @ CallNode (location: (11,8)-(11,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,8)-(11,9) = "z" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "z" + │ │ ├── value: + │ │ │ @ IntegerNode (location: (11,11)-(11,12)) + │ │ │ └── flags: decimal + │ │ └── operator_loc: (11,9)-(11,11) = "=>" + │ ├── closing_loc: (11,12)-(11,13) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "y" + └── rparen_loc: ∅ diff --git a/test/prism/snapshots/seattlerb/yield_empty_parens.txt b/test/prism/snapshots/seattlerb/yield_empty_parens.txt new file mode 100644 index 00000000000000..5ecd89823fd182 --- /dev/null +++ b/test/prism/snapshots/seattlerb/yield_empty_parens.txt @@ -0,0 +1,10 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ YieldNode (location: (1,0)-(1,7)) + ├── keyword_loc: (1,0)-(1,5) = "yield" + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── arguments: ∅ + └── rparen_loc: (1,6)-(1,7) = ")" diff --git a/test/prism/snapshots/single_quote_heredocs.txt b/test/prism/snapshots/single_quote_heredocs.txt new file mode 100644 index 00000000000000..cea79aa6b7cbf5 --- /dev/null +++ b/test/prism/snapshots/single_quote_heredocs.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,8)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,8) = "<<-'EOS'" + ├── content_loc: (2,0)-(2,0) = " cd L:\\Work\\MG3710IQPro\\Develop\n" + ├── closing_loc: (3,0)-(3,0) = "EOS\n" + └── unescaped: " cd L:\\Work\\MG3710IQPro\\Develop\n" diff --git a/test/prism/snapshots/spanning_heredoc.txt b/test/prism/snapshots/spanning_heredoc.txt new file mode 100644 index 00000000000000..9ebb067ecfbcab --- /dev/null +++ b/test/prism/snapshots/spanning_heredoc.txt @@ -0,0 +1,301 @@ +@ ProgramNode (location: (4,0)-(51,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (4,0)-(51,2)) + └── body: (length: 8) + ├── @ CallNode (location: (4,0)-(7,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,0)-(4,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (4,3)-(7,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (4,3)-(7,7)) + │ │ ├── receiver: + │ │ │ @ StringNode (location: (4,3)-(4,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (4,3)-(4,7) = "<<-A" + │ │ │ ├── content_loc: (5,0)-(5,0) = "a\n" + │ │ │ ├── closing_loc: (6,0)-(6,0) = "A\n" + │ │ │ └── unescaped: "a\n" + │ │ ├── call_operator_loc: (4,7)-(4,8) = "." + │ │ ├── message_loc: (4,8)-(4,12) = "gsub" + │ │ ├── opening_loc: (4,12)-(4,13) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (4,13)-(7,6)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ InterpolatedRegularExpressionNode (location: (4,13)-(7,2)) + │ │ │ │ ├── opening_loc: (4,13)-(4,14) = "/" + │ │ │ │ ├── parts: (length: 2) + │ │ │ │ │ ├── @ StringNode (location: (4,14)-(4,0)) + │ │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── content_loc: (4,14)-(4,0) = "b\\\n" + │ │ │ │ │ │ ├── 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) = "/" + │ │ │ │ └── flags: ∅ + │ │ │ └── @ 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "gsub" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (10,0)-(13,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (10,0)-(10,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (10,3)-(13,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (10,3)-(10,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (10,3)-(10,7) = "<<-A" + │ │ │ ├── content_loc: (11,0)-(11,0) = "c\n" + │ │ │ ├── closing_loc: (12,0)-(12,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,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (10,10)-(10,0) = "d\\\n" + │ │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (16,0)-(19,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (16,0)-(16,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (16,3)-(19,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (16,3)-(16,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (16,3)-(16,7) = "<<-A" + │ │ │ ├── content_loc: (17,0)-(17,0) = "e\n" + │ │ │ ├── closing_loc: (18,0)-(18,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,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (16,12)-(16,0) = "f\\\n" + │ │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (22,0)-(25,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (22,0)-(22,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (22,3)-(25,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (22,3)-(22,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (22,3)-(22,7) = "<<-A" + │ │ │ ├── content_loc: (23,0)-(23,0) = "g\n" + │ │ │ ├── closing_loc: (24,0)-(24,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,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (22,12)-(22,0) = "h\\\n" + │ │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (28,0)-(31,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (28,0)-(28,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (28,3)-(31,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (28,3)-(28,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (28,3)-(28,7) = "<<-A" + │ │ │ ├── content_loc: (29,0)-(29,0) = "i\n" + │ │ │ ├── closing_loc: (30,0)-(30,0) = "A\n" + │ │ │ └── unescaped: "i\n" + │ │ └── @ ArrayNode (location: (28,9)-(31,2)) + │ │ ├── elements: (length: 2) + │ │ │ ├── @ StringNode (location: (28,12)-(28,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (28,12)-(28,0) = "j\\\n" + │ │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (35,0)-(38,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,3)-(38,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (35,3)-(35,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (35,3)-(35,7) = "<<-A" + │ │ │ ├── content_loc: (36,0)-(36,0) = "k\n" + │ │ │ ├── closing_loc: (37,0)-(37,0) = "A\n" + │ │ │ └── unescaped: "k\n" + │ │ └── @ ArrayNode (location: (35,9)-(38,2)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ InterpolatedStringNode (location: (35,12)-(38,1)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── parts: (length: 2) + │ │ │ │ ├── @ StringNode (location: (35,12)-(35,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (35,12)-(35,0) = "l\\\n" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "l" + │ │ │ │ └── @ 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + ├── @ CallNode (location: (41,0)-(44,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,0)-(41,2) = "pp" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (41,3)-(44,2)) + │ │ └── arguments: (length: 2) + │ │ ├── @ StringNode (location: (41,3)-(41,7)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: (41,3)-(41,7) = "<<-A" + │ │ │ ├── content_loc: (42,0)-(42,0) = "m\n" + │ │ │ ├── closing_loc: (43,0)-(43,0) = "A\n" + │ │ │ └── unescaped: "m\n" + │ │ └── @ ArrayNode (location: (41,9)-(44,2)) + │ │ ├── elements: (length: 2) + │ │ │ ├── @ SymbolNode (location: (41,12)-(41,0)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (41,12)-(41,0) = "n\\\n" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "n\\\n" + │ │ │ └── @ SymbolNode (location: (44,0)-(44,1)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "pp" + └── @ CallNode (location: (48,0)-(51,2)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (48,0)-(48,2) = "pp" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (48,3)-(51,2)) + │ └── arguments: (length: 2) + │ ├── @ StringNode (location: (48,3)-(48,7)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (48,3)-(48,7) = "<<-A" + │ │ ├── content_loc: (49,0)-(49,0) = "o\n" + │ │ ├── closing_loc: (50,0)-(50,0) = "A\n" + │ │ └── unescaped: "o\n" + │ └── @ ArrayNode (location: (48,9)-(51,2)) + │ ├── elements: (length: 1) + │ │ └── @ InterpolatedSymbolNode (location: (48,12)-(51,1)) + │ │ ├── opening_loc: ∅ + │ │ ├── parts: (length: 2) + │ │ │ ├── @ SymbolNode (location: (48,12)-(48,0)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (48,12)-(48,0) = "p\\\n" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "p" + │ │ │ └── @ StringNode (location: (51,0)-(51,1)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (51,0)-(51,1) = "p" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "p" + │ │ └── closing_loc: ∅ + │ ├── opening_loc: (48,9)-(48,12) = "%I[" + │ └── closing_loc: (51,1)-(51,2) = "]" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "pp" diff --git a/test/prism/snapshots/strings.txt b/test/prism/snapshots/strings.txt new file mode 100644 index 00000000000000..e3a72eefdff7df --- /dev/null +++ b/test/prism/snapshots/strings.txt @@ -0,0 +1,516 @@ +@ 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)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (35,8)-(35,11) = "bbb" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bbb" + │ │ │ └── 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)) + │ ├── 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: ∅ + │ ├── message_loc: (39,6)-(39,7) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (41,0)-(41,5)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ 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)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (55,7)-(55,10) = "bbb" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bbb" + │ │ │ └── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (67,8)-(67,9) = "c" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "c" + │ │ │ │ │ └── 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)) + │ ├── 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)) + │ ├── 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" + ├── @ StringConcatNode (location: (99,0)-(99,6)) + │ ├── left: + │ │ @ StringNode (location: (99,0)-(99,2)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (99,0)-(99,1) = "?" + │ │ ├── content_loc: (99,1)-(99,2) = "a" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "a" + │ └── right: + │ @ 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" + ├── @ StringNode (location: (101,0)-(101,7)) + │ ├── flags: ∅ + │ ├── opening_loc: (101,0)-(101,3) = "%Q{" + │ ├── content_loc: (101,3)-(101,6) = "abc" + │ ├── closing_loc: (101,6)-(101,7) = "}" + │ └── unescaped: "abc" + ├── @ StringNode (location: (103,0)-(103,5)) + │ ├── flags: ∅ + │ ├── opening_loc: (103,0)-(103,2) = "%^" + │ ├── content_loc: (103,2)-(103,4) = "\#$" + │ ├── closing_loc: (103,4)-(103,5) = "^" + │ └── unescaped: "\#$" + └── @ StringNode (location: (105,0)-(105,4)) + ├── flags: ∅ + ├── opening_loc: (105,0)-(105,2) = "%@" + ├── content_loc: (105,2)-(105,3) = "#" + ├── closing_loc: (105,3)-(105,4) = "@" + └── unescaped: "#" diff --git a/test/prism/snapshots/super.txt b/test/prism/snapshots/super.txt new file mode 100644 index 00000000000000..24a7ae81a98e2f --- /dev/null +++ b/test/prism/snapshots/super.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(7,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,14)) + └── body: (length: 4) + ├── @ 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)) + │ │ └── 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)) + │ └── 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: ∅ diff --git a/test/prism/snapshots/symbols.txt b/test/prism/snapshots/symbols.txt new file mode 100644 index 00000000000000..d445d8a90fa6af --- /dev/null +++ b/test/prism/snapshots/symbols.txt @@ -0,0 +1,398 @@ +@ ProgramNode (location: (1,0)-(93,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(93,13)) + └── body: (length: 47) + ├── @ SymbolNode (location: (1,0)-(1,6)) + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,4)-(3,7) = "var" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "var" + │ │ └── 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)) + │ ├── elements: (length: 4) + │ │ ├── @ SymbolNode (location: (7,1)-(7,4)) + │ │ │ ├── opening_loc: (7,1)-(7,2) = ":" + │ │ │ ├── value_loc: (7,2)-(7,4) = "Υ" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "Υ" + │ │ ├── @ SymbolNode (location: (7,6)-(7,9)) + │ │ │ ├── opening_loc: (7,6)-(7,7) = ":" + │ │ │ ├── value_loc: (7,7)-(7,9) = "ά" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "ά" + │ │ ├── @ SymbolNode (location: (7,11)-(7,14)) + │ │ │ ├── opening_loc: (7,11)-(7,12) = ":" + │ │ │ ├── value_loc: (7,12)-(7,14) = "ŗ" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "ŗ" + │ │ └── @ SymbolNode (location: (7,16)-(7,19)) + │ │ ├── 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)) + │ ├── opening_loc: (9,0)-(9,1) = ":" + │ ├── value_loc: (9,1)-(9,3) = "-@" + │ ├── closing_loc: ∅ + │ └── unescaped: "-@" + ├── @ SymbolNode (location: (11,0)-(11,2)) + │ ├── opening_loc: (11,0)-(11,1) = ":" + │ ├── value_loc: (11,1)-(11,2) = "-" + │ ├── closing_loc: ∅ + │ └── unescaped: "-" + ├── @ SymbolNode (location: (13,0)-(13,2)) + │ ├── opening_loc: (13,0)-(13,1) = ":" + │ ├── value_loc: (13,1)-(13,2) = "%" + │ ├── closing_loc: ∅ + │ └── unescaped: "%" + ├── @ SymbolNode (location: (15,0)-(15,2)) + │ ├── opening_loc: (15,0)-(15,1) = ":" + │ ├── value_loc: (15,1)-(15,2) = "|" + │ ├── closing_loc: ∅ + │ └── unescaped: "|" + ├── @ SymbolNode (location: (17,0)-(17,3)) + │ ├── opening_loc: (17,0)-(17,1) = ":" + │ ├── value_loc: (17,1)-(17,3) = "+@" + │ ├── closing_loc: ∅ + │ └── unescaped: "+@" + ├── @ SymbolNode (location: (19,0)-(19,2)) + │ ├── opening_loc: (19,0)-(19,1) = ":" + │ ├── value_loc: (19,1)-(19,2) = "+" + │ ├── closing_loc: ∅ + │ └── unescaped: "+" + ├── @ SymbolNode (location: (21,0)-(21,2)) + │ ├── opening_loc: (21,0)-(21,1) = ":" + │ ├── value_loc: (21,1)-(21,2) = "/" + │ ├── closing_loc: ∅ + │ └── unescaped: "/" + ├── @ SymbolNode (location: (23,0)-(23,3)) + │ ├── opening_loc: (23,0)-(23,1) = ":" + │ ├── value_loc: (23,1)-(23,3) = "**" + │ ├── closing_loc: ∅ + │ └── unescaped: "**" + ├── @ SymbolNode (location: (25,0)-(25,2)) + │ ├── opening_loc: (25,0)-(25,1) = ":" + │ ├── value_loc: (25,1)-(25,2) = "*" + │ ├── closing_loc: ∅ + │ └── unescaped: "*" + ├── @ SymbolNode (location: (27,0)-(27,3)) + │ ├── opening_loc: (27,0)-(27,1) = ":" + │ ├── value_loc: (27,1)-(27,3) = "~@" + │ ├── closing_loc: ∅ + │ └── unescaped: "~@" + ├── @ ArrayNode (location: (29,0)-(29,16)) + │ ├── 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)) + │ ├── opening_loc: (31,0)-(31,1) = ":" + │ ├── value_loc: (31,1)-(31,2) = "~" + │ ├── closing_loc: ∅ + │ └── unescaped: "~" + ├── @ SymbolNode (location: (33,0)-(33,2)) + │ ├── opening_loc: (33,0)-(33,1) = ":" + │ ├── value_loc: (33,1)-(33,2) = "a" + │ ├── closing_loc: ∅ + │ └── unescaped: "a" + ├── @ ArrayNode (location: (35,0)-(35,9)) + │ ├── elements: (length: 3) + │ │ ├── @ SymbolNode (location: (35,3)-(35,4)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (35,3)-(35,4) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ SymbolNode (location: (35,5)-(35,6)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (35,5)-(35,6) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ └── @ SymbolNode (location: (35,7)-(35,8)) + │ │ ├── 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)) + │ ├── elements: (length: 4) + │ │ ├── @ SymbolNode (location: (37,3)-(37,4)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (37,3)-(37,4) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ SymbolNode (location: (37,5)-(37,10)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (37,5)-(37,10) = "b\#{1}" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b\#{1}" + │ │ ├── @ SymbolNode (location: (37,11)-(37,16)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (37,11)-(37,16) = "\#{2}c" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\#{2}c" + │ │ └── @ SymbolNode (location: (37,17)-(37,23)) + │ │ ├── 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)) + │ ├── elements: (length: 4) + │ │ ├── @ SymbolNode (location: (39,3)-(39,4)) + │ │ │ ├── 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)) + │ ├── opening_loc: (41,0)-(41,1) = ":" + │ ├── value_loc: (41,1)-(41,4) = "@@a" + │ ├── closing_loc: ∅ + │ └── unescaped: "@@a" + ├── @ SymbolNode (location: (43,0)-(43,5)) + │ ├── opening_loc: (43,0)-(43,1) = ":" + │ ├── value_loc: (43,1)-(43,5) = "👍" + │ ├── closing_loc: ∅ + │ └── unescaped: "👍" + ├── @ ArrayNode (location: (45,0)-(45,7)) + │ ├── elements: (length: 1) + │ │ └── @ SymbolNode (location: (45,3)-(45,6)) + │ │ ├── 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)) + │ ├── opening_loc: (47,0)-(47,1) = ":" + │ ├── value_loc: (47,1)-(47,3) = "$a" + │ ├── closing_loc: ∅ + │ └── unescaped: "$a" + ├── @ SymbolNode (location: (49,0)-(49,3)) + │ ├── opening_loc: (49,0)-(49,1) = ":" + │ ├── value_loc: (49,1)-(49,3) = "@a" + │ ├── closing_loc: ∅ + │ └── unescaped: "@a" + ├── @ SymbolNode (location: (51,0)-(51,3)) + │ ├── opening_loc: (51,0)-(51,1) = ":" + │ ├── value_loc: (51,1)-(51,3) = "do" + │ ├── closing_loc: ∅ + │ └── unescaped: "do" + ├── @ SymbolNode (location: (53,0)-(53,2)) + │ ├── opening_loc: (53,0)-(53,1) = ":" + │ ├── value_loc: (53,1)-(53,2) = "&" + │ ├── closing_loc: ∅ + │ └── unescaped: "&" + ├── @ SymbolNode (location: (55,0)-(55,2)) + │ ├── opening_loc: (55,0)-(55,1) = ":" + │ ├── value_loc: (55,1)-(55,2) = "`" + │ ├── closing_loc: ∅ + │ └── unescaped: "`" + ├── @ SymbolNode (location: (57,0)-(57,3)) + │ ├── opening_loc: (57,0)-(57,1) = ":" + │ ├── value_loc: (57,1)-(57,3) = "!@" + │ ├── closing_loc: ∅ + │ └── unescaped: "!@" + ├── @ SymbolNode (location: (59,0)-(59,3)) + │ ├── opening_loc: (59,0)-(59,1) = ":" + │ ├── value_loc: (59,1)-(59,3) = "!~" + │ ├── closing_loc: ∅ + │ └── unescaped: "!~" + ├── @ SymbolNode (location: (61,0)-(61,2)) + │ ├── opening_loc: (61,0)-(61,1) = ":" + │ ├── value_loc: (61,1)-(61,2) = "!" + │ ├── closing_loc: ∅ + │ └── unescaped: "!" + ├── @ SymbolNode (location: (63,0)-(63,3)) + │ ├── opening_loc: (63,0)-(63,1) = ":" + │ ├── value_loc: (63,1)-(63,3) = "[]" + │ ├── closing_loc: ∅ + │ └── unescaped: "[]" + ├── @ SymbolNode (location: (65,0)-(65,4)) + │ ├── opening_loc: (65,0)-(65,1) = ":" + │ ├── value_loc: (65,1)-(65,4) = "[]=" + │ ├── closing_loc: ∅ + │ └── unescaped: "[]=" + ├── @ SymbolNode (location: (67,0)-(67,2)) + │ ├── opening_loc: (67,0)-(67,1) = ":" + │ ├── value_loc: (67,1)-(67,2) = "^" + │ ├── closing_loc: ∅ + │ └── unescaped: "^" + ├── @ SymbolNode (location: (69,0)-(69,3)) + │ ├── opening_loc: (69,0)-(69,1) = ":" + │ ├── value_loc: (69,1)-(69,3) = "==" + │ ├── closing_loc: ∅ + │ └── unescaped: "==" + ├── @ SymbolNode (location: (71,0)-(71,4)) + │ ├── opening_loc: (71,0)-(71,1) = ":" + │ ├── value_loc: (71,1)-(71,4) = "===" + │ ├── closing_loc: ∅ + │ └── unescaped: "===" + ├── @ SymbolNode (location: (73,0)-(73,3)) + │ ├── opening_loc: (73,0)-(73,1) = ":" + │ ├── value_loc: (73,1)-(73,3) = "=~" + │ ├── closing_loc: ∅ + │ └── unescaped: "=~" + ├── @ SymbolNode (location: (75,0)-(75,3)) + │ ├── opening_loc: (75,0)-(75,1) = ":" + │ ├── value_loc: (75,1)-(75,3) = ">=" + │ ├── closing_loc: ∅ + │ └── unescaped: ">=" + ├── @ SymbolNode (location: (77,0)-(77,3)) + │ ├── opening_loc: (77,0)-(77,1) = ":" + │ ├── value_loc: (77,1)-(77,3) = ">>" + │ ├── closing_loc: ∅ + │ └── unescaped: ">>" + ├── @ SymbolNode (location: (79,0)-(79,2)) + │ ├── opening_loc: (79,0)-(79,1) = ":" + │ ├── value_loc: (79,1)-(79,2) = ">" + │ ├── closing_loc: ∅ + │ └── unescaped: ">" + ├── @ SymbolNode (location: (81,0)-(81,4)) + │ ├── opening_loc: (81,0)-(81,1) = ":" + │ ├── value_loc: (81,1)-(81,4) = "<=>" + │ ├── closing_loc: ∅ + │ └── unescaped: "<=>" + ├── @ SymbolNode (location: (83,0)-(83,3)) + │ ├── opening_loc: (83,0)-(83,1) = ":" + │ ├── value_loc: (83,1)-(83,3) = "<=" + │ ├── closing_loc: ∅ + │ └── unescaped: "<=" + ├── @ SymbolNode (location: (85,0)-(85,3)) + │ ├── opening_loc: (85,0)-(85,1) = ":" + │ ├── value_loc: (85,1)-(85,3) = "<<" + │ ├── closing_loc: ∅ + │ └── unescaped: "<<" + ├── @ SymbolNode (location: (87,0)-(87,2)) + │ ├── opening_loc: (87,0)-(87,1) = ":" + │ ├── value_loc: (87,1)-(87,2) = "<" + │ ├── closing_loc: ∅ + │ └── unescaped: "<" + ├── @ SymbolNode (location: (89,0)-(89,9)) + │ ├── opening_loc: (89,0)-(89,1) = ":" + │ ├── value_loc: (89,1)-(89,9) = "__LINE__" + │ ├── closing_loc: ∅ + │ └── unescaped: "__LINE__" + ├── @ SymbolNode (location: (91,0)-(91,9)) + │ ├── opening_loc: (91,0)-(91,1) = ":" + │ ├── value_loc: (91,1)-(91,9) = "__FILE__" + │ ├── closing_loc: ∅ + │ └── unescaped: "__FILE__" + └── @ SymbolNode (location: (93,0)-(93,13)) + ├── opening_loc: (93,0)-(93,1) = ":" + ├── value_loc: (93,1)-(93,13) = "__ENCODING__" + ├── closing_loc: ∅ + └── unescaped: "__ENCODING__" diff --git a/test/prism/snapshots/ternary_operator.txt b/test/prism/snapshots/ternary_operator.txt new file mode 100644 index 00000000000000..13aa17e81a16b6 --- /dev/null +++ b/test/prism/snapshots/ternary_operator.txt @@ -0,0 +1,285 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── statements: + │ │ @ StatementsNode (location: (1,4)-(1,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,4)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,5) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,8)-(1,9) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + ├── @ IfNode (location: (3,0)-(3,27)) + │ ├── if_keyword_loc: ∅ + │ ├── predicate: + │ │ @ CallNode (location: (3,0)-(3,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,13)-(3,14) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,26)-(3,27) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "c" + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,6) = "empty?" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "empty?" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,6) = "empty?" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "empty?" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,0)-(9,6) = "empty?" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "empty?" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,2) = "a?" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "a?" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,0)-(13,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── statements: + │ │ @ StatementsNode (location: (13,3)-(13,7)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (13,3)-(13,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,3)-(13,7) = "var1" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "var1" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,10)-(13,14) = "var2" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "var2" + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + └── @ IfNode (location: (15,0)-(15,12)) + ├── if_keyword_loc: ∅ + ├── predicate: + │ @ CallNode (location: (15,0)-(15,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,4) = "nil?" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "nil?" + ├── 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 new file mode 100644 index 00000000000000..b0b060255ce9cb --- /dev/null +++ b/test/prism/snapshots/tilde_heredocs.txt @@ -0,0 +1,209 @@ +@ ProgramNode (location: (1,0)-(88,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(88,6)) + └── body: (length: 18) + ├── @ StringNode (location: (1,0)-(1,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,0)-(1,6) = "<<~EOF" + │ ├── content_loc: (2,0)-(2,0) = " a\n" + │ ├── closing_loc: (3,0)-(3,0) = "EOF\n" + │ └── unescaped: "a\n" + ├── @ StringNode (location: (5,0)-(5,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (5,0)-(5,6) = "<<~EOF" + │ ├── content_loc: (6,0)-(8,0) = "\ta\n b\n\t\tc\n" + │ ├── closing_loc: (9,0)-(9,0) = "EOF\n" + │ └── unescaped: "\ta\nb\n\t\tc\n" + ├── @ InterpolatedStringNode (location: (11,0)-(11,6)) + │ ├── opening_loc: (11,0)-(11,6) = "<<~EOF" + │ ├── parts: (length: 2) + │ │ ├── @ EmbeddedStatementsNode (location: (12,2)-(12,6)) + │ │ │ ├── opening_loc: (12,2)-(12,4) = "\#{" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (12,4)-(12,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (12,4)-(12,5)) + │ │ │ │ └── flags: decimal + │ │ │ └── closing_loc: (12,5)-(12,6) = "}" + │ │ └── @ StringNode (location: (12,6)-(12,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (12,6)-(12,0) = " a\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: " a\n" + │ └── closing_loc: (13,0)-(13,0) = "EOF\n" + ├── @ InterpolatedStringNode (location: (15,0)-(15,6)) + │ ├── opening_loc: (15,0)-(15,6) = "<<~EOF" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (16,0)-(16,4)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (16,0)-(16,4) = " a " + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a " + │ │ ├── @ EmbeddedStatementsNode (location: (16,4)-(16,8)) + │ │ │ ├── opening_loc: (16,4)-(16,6) = "\#{" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (16,6)-(16,7)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (16,6)-(16,7)) + │ │ │ │ └── flags: decimal + │ │ │ └── closing_loc: (16,7)-(16,8) = "}" + │ │ └── @ StringNode (location: (16,8)-(16,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (16,8)-(16,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (17,0)-(17,0) = "EOF\n" + ├── @ InterpolatedStringNode (location: (19,0)-(19,6)) + │ ├── opening_loc: (19,0)-(19,6) = "<<~EOF" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (20,0)-(21,1)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (20,0)-(21,1) = " a\n " + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: " a\n" + │ │ ├── @ EmbeddedStatementsNode (location: (21,1)-(21,5)) + │ │ │ ├── opening_loc: (21,1)-(21,3) = "\#{" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (21,3)-(21,4)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (21,3)-(21,4)) + │ │ │ │ └── flags: decimal + │ │ │ └── closing_loc: (21,4)-(21,5) = "}" + │ │ └── @ StringNode (location: (21,5)-(21,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (21,5)-(21,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (22,0)-(22,0) = "EOF\n" + ├── @ InterpolatedStringNode (location: (24,0)-(24,6)) + │ ├── opening_loc: (24,0)-(24,6) = "<<~EOF" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (25,0)-(26,2)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (25,0)-(26,2) = " a\n " + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a\n" + │ │ ├── @ EmbeddedStatementsNode (location: (26,2)-(26,6)) + │ │ │ ├── opening_loc: (26,2)-(26,4) = "\#{" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (26,4)-(26,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (26,4)-(26,5)) + │ │ │ │ └── flags: decimal + │ │ │ └── closing_loc: (26,5)-(26,6) = "}" + │ │ └── @ StringNode (location: (26,6)-(26,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (26,6)-(26,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (27,0)-(27,0) = "EOF\n" + ├── @ StringNode (location: (29,0)-(29,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (29,0)-(29,6) = "<<~EOF" + │ ├── content_loc: (30,0)-(31,0) = " a\n b\n" + │ ├── closing_loc: (32,0)-(32,0) = "EOF\n" + │ └── unescaped: "a\nb\n" + ├── @ StringNode (location: (34,0)-(34,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (34,0)-(34,6) = "<<~EOF" + │ ├── content_loc: (35,0)-(36,0) = " a\n b\n" + │ ├── closing_loc: (37,0)-(37,0) = "EOF\n" + │ └── unescaped: "a\n b\n" + ├── @ StringNode (location: (39,0)-(39,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (39,0)-(39,6) = "<<~EOF" + │ ├── content_loc: (40,0)-(41,0) = "\t\t\ta\n\t\tb\n" + │ ├── closing_loc: (42,0)-(42,0) = "EOF\n" + │ └── unescaped: "\ta\nb\n" + ├── @ StringNode (location: (44,0)-(44,8)) + │ ├── flags: ∅ + │ ├── opening_loc: (44,0)-(44,8) = "<<~'EOF'" + │ ├── content_loc: (45,0)-(45,0) = " a \#{1}\n" + │ ├── closing_loc: (46,0)-(46,0) = "EOF\n" + │ └── unescaped: "a \#{1}\n" + ├── @ StringNode (location: (48,0)-(48,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (48,0)-(48,6) = "<<~EOF" + │ ├── content_loc: (49,0)-(50,0) = "\ta\n\t b\n" + │ ├── closing_loc: (51,0)-(51,0) = "EOF\n" + │ └── unescaped: "a\n b\n" + ├── @ StringNode (location: (53,0)-(53,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (53,0)-(53,6) = "<<~EOF" + │ ├── content_loc: (54,0)-(55,0) = "\t a\n\tb\n" + │ ├── closing_loc: (56,0)-(56,0) = "EOF\n" + │ └── unescaped: " a\nb\n" + ├── @ StringNode (location: (58,0)-(58,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (58,0)-(58,6) = "<<~EOF" + │ ├── content_loc: (59,0)-(60,0) = " \ta\n b\n" + │ ├── closing_loc: (61,0)-(61,0) = "EOF\n" + │ └── unescaped: "a\nb\n" + ├── @ StringNode (location: (63,0)-(63,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (63,0)-(63,6) = "<<~EOF" + │ ├── content_loc: (64,0)-(66,0) = " a\n\n b\n" + │ ├── closing_loc: (67,0)-(67,0) = "EOF\n" + │ └── unescaped: "a\n\nb\n" + ├── @ StringNode (location: (69,0)-(69,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (69,0)-(69,6) = "<<~EOF" + │ ├── content_loc: (70,0)-(72,0) = " a\n\n b\n" + │ ├── closing_loc: (73,0)-(73,0) = "EOF\n" + │ └── unescaped: "a\n\nb\n" + ├── @ StringNode (location: (75,0)-(75,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (75,0)-(75,6) = "<<~EOF" + │ ├── content_loc: (76,0)-(80,0) = " a\n\n\n\n b\n" + │ ├── closing_loc: (81,0)-(81,0) = "EOF\n" + │ └── unescaped: "a\n\n\n\nb\n" + ├── @ InterpolatedStringNode (location: (83,0)-(83,6)) + │ ├── opening_loc: (83,0)-(83,6) = "<<~EOF" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (84,0)-(85,2)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (84,0)-(85,2) = "\n " + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ ├── @ EmbeddedStatementsNode (location: (85,2)-(85,6)) + │ │ │ ├── opening_loc: (85,2)-(85,4) = "\#{" + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (85,4)-(85,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (85,4)-(85,5)) + │ │ │ │ └── flags: decimal + │ │ │ └── closing_loc: (85,5)-(85,6) = "}" + │ │ └── @ StringNode (location: (85,6)-(85,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (85,6)-(85,0) = "a\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "a\n" + │ └── closing_loc: (86,0)-(86,0) = " EOF\n" + └── @ InterpolatedStringNode (location: (88,0)-(88,6)) + ├── opening_loc: (88,0)-(88,6) = "<<~EOT" + ├── parts: (length: 2) + │ ├── @ EmbeddedStatementsNode (location: (89,2)-(89,6)) + │ │ ├── opening_loc: (89,2)-(89,4) = "\#{" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (89,4)-(89,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ IntegerNode (location: (89,4)-(89,5)) + │ │ │ └── flags: decimal + │ │ └── closing_loc: (89,5)-(89,6) = "}" + │ └── @ StringNode (location: (89,6)-(90,0)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (89,6)-(90,0) = "\n\tb\n" + │ ├── closing_loc: ∅ + │ └── unescaped: "\n\tb\n" + └── closing_loc: (91,0)-(91,0) = "EOT\n" diff --git a/test/prism/snapshots/undef.txt b/test/prism/snapshots/undef.txt new file mode 100644 index 00000000000000..8ab7acacec36db --- /dev/null +++ b/test/prism/snapshots/undef.txt @@ -0,0 +1,105 @@ +@ 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)) + │ │ ├── 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (3,6)-(3,7) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (3,9)-(3,10)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ │ ├── opening_loc: (11,6)-(11,7) = ":" + │ │ │ ├── value_loc: (11,7)-(11,8) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ ├── @ SymbolNode (location: (11,10)-(11,12)) + │ │ │ ├── opening_loc: (11,10)-(11,11) = ":" + │ │ │ ├── value_loc: (11,11)-(11,12) = "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "b" + │ │ └── @ SymbolNode (location: (11,14)-(11,16)) + │ │ ├── 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)) + │ │ ├── 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)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (17,6)-(17,14) = "Constant" + │ ├── closing_loc: ∅ + │ └── unescaped: "Constant" + └── keyword_loc: (17,0)-(17,5) = "undef" diff --git a/test/prism/snapshots/unescaping.txt b/test/prism/snapshots/unescaping.txt new file mode 100644 index 00000000000000..a59dc016262cc0 --- /dev/null +++ b/test/prism/snapshots/unescaping.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(7,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,7)) + └── body: (length: 4) + ├── @ ArrayNode (location: (1,0)-(1,10)) + │ ├── 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)) + │ ├── opening_loc: (3,0)-(3,1) = "/" + │ ├── content_loc: (3,1)-(3,7) = "\\c\#{1}" + │ ├── closing_loc: (3,7)-(3,8) = "/" + │ ├── unescaped: "\u0003{1}" + │ └── flags: ∅ + ├── @ 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)-(8,0) = " \\c\#{1}\n" + ├── closing_loc: (9,0)-(9,0) = "HERE\n" + └── unescaped: "\u0003{1}\n" diff --git a/test/prism/snapshots/unless.txt b/test/prism/snapshots/unless.txt new file mode 100644 index 00000000000000..27455d08c6b260 --- /dev/null +++ b/test/prism/snapshots/unless.txt @@ -0,0 +1,122 @@ +@ 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (14,18)-(14,22) = "bar?" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar?" + ├── statements: + │ @ StatementsNode (location: (14,0)-(14,10)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (14,0)-(14,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (14,0)-(14,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (14,4)-(14,10)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (14,4)-(14,6)) + │ │ │ ├── opening_loc: (14,4)-(14,5) = ":" + │ │ │ ├── value_loc: (14,5)-(14,6) = "a" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "a" + │ │ └── @ SymbolNode (location: (14,8)-(14,10)) + │ │ ├── opening_loc: (14,8)-(14,9) = ":" + │ │ ├── value_loc: (14,9)-(14,10) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── consequent: ∅ + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/unparser/corpus/literal/alias.txt b/test/prism/snapshots/unparser/corpus/literal/alias.txt new file mode 100644 index 00000000000000..e7267976851f58 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/alias.txt @@ -0,0 +1,27 @@ +@ 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)) + │ ├── 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)) + │ ├── opening_loc: (2,11)-(2,12) = ":" + │ ├── value_loc: (2,12)-(2,15) = "bar" + │ ├── closing_loc: ∅ + │ └── unescaped: "bar" + └── keyword_loc: (2,0)-(2,5) = "alias" diff --git a/test/prism/snapshots/unparser/corpus/literal/assignment.txt b/test/prism/snapshots/unparser/corpus/literal/assignment.txt new file mode 100644 index 00000000000000..ec6678281ae8f9 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/assignment.txt @@ -0,0 +1,999 @@ +@ 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)) + │ ├── targets: (length: 2) + │ │ ├── @ GlobalVariableTargetNode (location: (2,1)-(2,3)) + │ │ │ └── name: :$a + │ │ └── @ GlobalVariableTargetNode (location: (2,5)-(2,7)) + │ │ └── name: :$b + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ MultiTargetNode (location: (3,1)-(3,5)) + │ │ │ ├── targets: (length: 2) + │ │ │ │ ├── @ LocalVariableTargetNode (location: (3,2)-(3,3)) + │ │ │ │ │ ├── name: :a + │ │ │ │ │ └── depth: 0 + │ │ │ │ └── @ SplatNode (location: (3,3)-(3,4)) + │ │ │ │ ├── operator_loc: (3,3)-(3,4) = "," + │ │ │ │ └── expression: ∅ + │ │ │ ├── lparen_loc: (3,1)-(3,2) = "(" + │ │ │ └── rparen_loc: (3,4)-(3,5) = ")" + │ │ └── @ LocalVariableTargetNode (location: (3,7)-(3,8)) + │ │ ├── name: :b + │ │ └── depth: 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)) + │ ├── targets: (length: 1) + │ │ └── @ SplatNode (location: (4,1)-(4,3)) + │ │ ├── operator_loc: (4,1)-(4,2) = "*" + │ │ └── expression: + │ │ @ LocalVariableTargetNode (location: (4,2)-(4,3)) + │ │ ├── name: :a + │ │ └── depth: 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)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (4,7)-(4,8) = "[" + │ └── closing_loc: (4,8)-(4,9) = "]" + ├── @ MultiWriteNode (location: (5,0)-(5,15)) + │ ├── targets: (length: 1) + │ │ └── @ SplatNode (location: (5,1)-(5,5)) + │ │ ├── operator_loc: (5,1)-(5,2) = "*" + │ │ └── expression: + │ │ @ LocalVariableTargetNode (location: (5,2)-(5,5)) + │ │ ├── name: :foo + │ │ └── depth: 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ ClassVariableTargetNode (location: (6,1)-(6,4)) + │ │ │ └── name: :@@a + │ │ └── @ ClassVariableTargetNode (location: (6,6)-(6,9)) + │ │ └── name: :@@b + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ InstanceVariableTargetNode (location: (7,1)-(7,3)) + │ │ │ └── name: :@a + │ │ └── @ InstanceVariableTargetNode (location: (7,5)-(7,7)) + │ │ └── name: :@b + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (8,1)-(8,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ MultiTargetNode (location: (8,4)-(8,10)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (8,5)-(8,6)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ └── @ LocalVariableTargetNode (location: (8,8)-(8,9)) + │ │ │ ├── name: :c + │ │ │ └── depth: 0 + │ │ ├── lparen_loc: (8,4)-(8,5) = "(" + │ │ └── rparen_loc: (8,9)-(8,10) = ")" + │ ├── 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)) + │ ├── elements: (length: 2) + │ │ ├── @ IntegerNode (location: (8,15)-(8,16)) + │ │ │ └── flags: decimal + │ │ └── @ ArrayNode (location: (8,18)-(8,24)) + │ │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (9,1)-(9,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ SplatNode (location: (9,4)-(9,5)) + │ │ ├── operator_loc: (9,4)-(9,5) = "*" + │ │ └── expression: ∅ + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (10,1)-(10,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ SplatNode (location: (10,4)-(10,8)) + │ │ ├── operator_loc: (10,4)-(10,5) = "*" + │ │ └── expression: + │ │ @ LocalVariableTargetNode (location: (10,5)-(10,8)) + │ │ ├── name: :foo + │ │ └── depth: 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (11,1)-(11,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (11,4)-(11,5)) + │ │ ├── name: :b + │ │ └── depth: 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (12,1)-(12,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (12,4)-(12,5)) + │ │ ├── name: :b + │ │ └── depth: 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (13,1)-(13,2)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ SplatNode (location: (13,2)-(13,3)) + │ │ ├── operator_loc: (13,2)-(13,3) = "," + │ │ └── expression: ∅ + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (14,1)-(14,6)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (14,1)-(14,2)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: (14,2)-(14,3) = "." + │ │ │ ├── message_loc: (14,3)-(14,6) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "foo=" + │ │ └── @ CallNode (location: (14,8)-(14,13)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (14,8)-(14,9)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: (14,9)-(14,10) = "." + │ │ ├── message_loc: (14,10)-(14,13) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar=" + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (15,1)-(15,8)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (15,1)-(15,2)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,2)-(15,8) = "[*foo]" + │ │ │ ├── opening_loc: (15,2)-(15,3) = "[" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (15,3)-(15,7)) + │ │ │ │ └── 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: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "[]=" + │ │ └── @ CallNode (location: (15,10)-(15,14)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (15,10)-(15,11)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,11)-(15,14) = "[1]" + │ │ ├── opening_loc: (15,11)-(15,12) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (15,12)-(15,13)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (15,12)-(15,13)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (15,13)-(15,14) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]=" + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (16,1)-(16,5)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (16,1)-(16,2)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (16,2)-(16,5) = "[0]" + │ │ │ ├── opening_loc: (16,2)-(16,3) = "[" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (16,3)-(16,4)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (16,3)-(16,4)) + │ │ │ │ └── flags: decimal + │ │ │ ├── closing_loc: (16,4)-(16,5) = "]" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "[]=" + │ │ └── @ CallNode (location: (16,7)-(16,11)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (16,7)-(16,8)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,8)-(16,11) = "[1]" + │ │ ├── opening_loc: (16,8)-(16,9) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (16,9)-(16,10)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (16,9)-(16,10)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: (16,10)-(16,11) = "]" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]=" + │ ├── 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)) + │ ├── 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)) + │ ├── targets: (length: 1) + │ │ └── @ SplatNode (location: (17,1)-(17,7)) + │ │ ├── operator_loc: (17,1)-(17,2) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (17,2)-(17,7)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (17,2)-(17,3)) + │ │ │ ├── name: :c + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: (17,3)-(17,4) = "." + │ │ ├── message_loc: (17,4)-(17,7) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "foo=" + │ ├── 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)) + │ │ │ ├── targets: (length: 2) + │ │ │ │ ├── @ LocalVariableTargetNode (location: (23,6)-(23,7)) + │ │ │ │ │ ├── name: :b + │ │ │ │ │ └── depth: 0 + │ │ │ │ └── @ LocalVariableTargetNode (location: (23,9)-(23,10)) + │ │ │ │ ├── name: :c + │ │ │ │ └── depth: 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,6)-(25,9) = "foo" + │ │ ├── opening_loc: (25,9)-(25,10) = "(" + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: (25,10)-(25,11) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "foo" + │ └── operator_loc: (25,4)-(25,5) = "=" + ├── @ CallNode (location: (26,0)-(26,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (26,0)-(26,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: (26,3)-(26,4) = "." + │ ├── message_loc: (26,4)-(26,7) = "[]=" + │ ├── opening_loc: (26,7)-(26,8) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (26,8)-(26,9) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (27,0)-(27,13)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (27,0)-(27,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: (27,3)-(27,4) = "." + │ ├── message_loc: (27,4)-(27,7) = "[]=" + │ ├── opening_loc: (27,7)-(27,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,8)-(27,12)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (28,0)-(28,11)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (28,0)-(28,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: (28,3)-(28,4) = "." + │ ├── message_loc: (28,4)-(28,7) = "[]=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (28,7)-(28,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ TrueNode (location: (28,7)-(28,11)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (29,0)-(29,19)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (29,0)-(29,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (29,3)-(29,11) = "[*index]" + │ ├── opening_loc: (29,3)-(29,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (29,4)-(29,19)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SplatNode (location: (29,4)-(29,10)) + │ │ │ ├── operator_loc: (29,4)-(29,5) = "*" + │ │ │ └── expression: + │ │ │ @ CallNode (location: (29,5)-(29,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,5)-(29,10) = "index" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "index" + │ │ └── @ CallNode (location: (29,14)-(29,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (29,14)-(29,19) = "value" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "value" + │ ├── closing_loc: (29,10)-(29,11) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (30,0)-(30,17)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (30,0)-(30,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (30,3)-(30,9) = "[1..2]" + │ ├── opening_loc: (30,3)-(30,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (30,4)-(30,17)) + │ │ └── arguments: (length: 2) + │ │ ├── @ RangeNode (location: (30,4)-(30,8)) + │ │ │ ├── left: + │ │ │ │ @ IntegerNode (location: (30,4)-(30,5)) + │ │ │ │ └── flags: decimal + │ │ │ ├── right: + │ │ │ │ @ IntegerNode (location: (30,7)-(30,8)) + │ │ │ │ └── flags: decimal + │ │ │ ├── operator_loc: (30,5)-(30,7) = ".." + │ │ │ └── flags: ∅ + │ │ └── @ CallNode (location: (30,12)-(30,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,12)-(30,17) = "value" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "value" + │ ├── closing_loc: (30,8)-(30,9) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (31,0)-(31,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (31,0)-(31,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,3)-(31,5) = "[]" + │ ├── opening_loc: (31,3)-(31,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,8)-(31,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (31,8)-(31,9)) + │ │ └── flags: decimal + │ ├── closing_loc: (31,4)-(31,5) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (32,0)-(32,17)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (32,0)-(32,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (32,3)-(32,9) = "[a, b]" + │ ├── opening_loc: (32,3)-(32,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (32,4)-(32,17)) + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,12)-(32,17) = "value" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "value" + │ ├── closing_loc: (32,8)-(32,9) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (33,0)-(33,18)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (33,0)-(33,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,3)-(33,10) = "[index]" + │ ├── opening_loc: (33,3)-(33,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (33,4)-(33,18)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (33,4)-(33,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (33,4)-(33,9) = "index" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "index" + │ │ └── @ CallNode (location: (33,13)-(33,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (33,13)-(33,18) = "value" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "value" + │ ├── closing_loc: (33,9)-(33,10) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ 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)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (35,0)-(35,1)) + │ │ ├── name: :x + │ │ └── depth: 0 + │ ├── call_operator_loc: (35,1)-(35,2) = "." + │ ├── message_loc: (35,2)-(35,3) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,4)-(35,7)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "x=" + ├── @ CallNode (location: (36,0)-(36,12)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (36,0)-(36,1)) + │ │ ├── name: :x + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (36,1)-(36,6) = "[%()]" + │ ├── opening_loc: (36,1)-(36,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (36,2)-(36,12)) + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (36,9)-(36,12) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (36,5)-(36,6) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallOrWriteNode (location: (37,0)-(37,14)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (37,0)-(37,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,1)-(37,6) = "[%()]" + │ ├── opening_loc: (37,1)-(37,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,2)-(37,5)) + │ │ └── 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) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator_loc: (37,7)-(37,10) = "||=" + │ └── value: + │ @ CallNode (location: (37,11)-(37,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,11)-(37,14) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ 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)-(40,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (40,5)-(40,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (41,0)-(41,0) = "HEREDOC\n" + │ └── operator_loc: (39,2)-(39,3) = "=" + ├── @ CallNode (location: (42,0)-(42,14)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (42,0)-(42,1)) + │ │ ├── name: :x + │ │ └── depth: 0 + │ ├── call_operator_loc: (42,1)-(42,2) = "." + │ ├── message_loc: (42,2)-(42,3) = "x" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (42,4)-(42,14)) + │ │ └── 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)-(43,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (43,5)-(43,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (44,0)-(44,0) = "HEREDOC\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "x=" + ├── @ CallNode (location: (45,0)-(45,16)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (45,0)-(45,1)) + │ │ ├── name: :x + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (45,1)-(45,3) = "[]" + │ ├── opening_loc: (45,1)-(45,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (45,6)-(45,16)) + │ │ └── 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)-(46,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (46,5)-(46,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (47,0)-(47,0) = "HEREDOC\n" + │ ├── closing_loc: (45,2)-(45,3) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallOrWriteNode (location: (48,0)-(48,21)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (48,0)-(48,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (48,1)-(48,13) = "[<<-HEREDOC]" + │ ├── opening_loc: (48,1)-(48,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (48,2)-(48,12)) + │ │ └── 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)-(49,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (49,5)-(49,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (50,0)-(50,0) = "HEREDOC\n" + │ ├── closing_loc: (48,12)-(48,13) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator_loc: (48,14)-(48,17) = "||=" + │ └── value: + │ @ CallNode (location: (48,18)-(48,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (48,18)-(48,21) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── @ 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)-(52,0)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (52,5)-(52,0) = "\n" + │ ├── closing_loc: ∅ + │ └── unescaped: "\n" + └── closing_loc: (53,0)-(53,0) = "HEREDOC\n" diff --git a/test/prism/snapshots/unparser/corpus/literal/block.txt b/test/prism/snapshots/unparser/corpus/literal/block.txt new file mode 100644 index 00000000000000..3e8309a057c373 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/block.txt @@ -0,0 +1,1366 @@ +@ ProgramNode (location: (1,0)-(96,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(96,1)) + └── body: (length: 30) + ├── @ CallNode (location: (1,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,4)-(2,1)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,4)-(1,5) = "{" + │ │ └── closing_loc: (2,0)-(2,1) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (3,0)-(4,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,4)-(4,1)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (3,6)-(3,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (3,7)-(3,8)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (3,7)-(3,8)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (5,0)-(6,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,4)-(6,1)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (5,6)-(5,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (5,7)-(5,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (5,7)-(5,8)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (5,8)-(5,9)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── name_loc: ∅ + │ │ │ │ │ └── operator_loc: (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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (7,0)-(8,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (7,4)-(8,1)) + │ │ ├── locals: [:a, :x] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (7,6)-(7,13)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (7,7)-(7,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (7,7)-(7,8)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (7,8)-(7,9)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── name_loc: ∅ + │ │ │ │ │ └── operator_loc: (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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (9,0)-(10,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,0)-(9,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (9,4)-(10,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (9,6)-(9,12)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (9,7)-(9,11)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (9,7)-(9,8)) + │ │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (11,0)-(13,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,3) = "foo" + │ ├── opening_loc: (11,3)-(11,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,4)-(11,5)) + │ │ └── 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: [] + │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (14,0)-(16,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (14,0)-(14,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (14,4)-(16,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (14,6)-(14,13)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (14,7)-(14,12)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (14,7)-(14,8)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (17,0)-(19,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (17,4)-(19,1)) + │ │ ├── locals: [:a, :*] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (17,6)-(17,12)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (17,7)-(17,11)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (17,7)-(17,8)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (17,10)-(17,11)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (20,0)-(22,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (20,0)-(20,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (20,4)-(22,1)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (21,2)-(21,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (21,2)-(21,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,2)-(21,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── opening_loc: (20,4)-(20,5) = "{" + │ │ └── closing_loc: (22,0)-(22,1) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (23,0)-(25,1)) + │ ├── receiver: + │ │ @ CallNode (location: (23,0)-(23,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,0)-(23,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (23,3)-(23,4) = "." + │ ├── message_loc: (23,4)-(23,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (23,8)-(25,1)) + │ │ ├── locals: [:a, :b, :c] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (23,10)-(23,21)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (23,11)-(23,20)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredDestructuredParameterNode (location: (23,11)-(23,17)) + │ │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (23,12)-(23,13)) + │ │ │ │ │ │ │ │ └── name: :a + │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (23,15)-(23,16)) + │ │ │ │ │ │ │ └── name: :b + │ │ │ │ │ │ ├── opening_loc: (23,11)-(23,12) = "(" + │ │ │ │ │ │ └── closing_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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (24,2)-(24,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (23,8)-(23,9) = "{" + │ │ └── closing_loc: (25,0)-(25,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (26,0)-(27,1)) + │ ├── receiver: + │ │ @ CallNode (location: (26,0)-(26,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (26,0)-(26,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (26,3)-(26,4) = "." + │ ├── message_loc: (26,4)-(26,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (26,8)-(27,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (26,10)-(26,17)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (26,11)-(26,13)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (26,11)-(26,13)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (28,0)-(29,1)) + │ ├── receiver: + │ │ @ CallNode (location: (28,0)-(28,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,0)-(28,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (28,3)-(28,4) = "." + │ ├── message_loc: (28,4)-(28,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (28,8)-(29,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (28,10)-(28,16)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (28,11)-(28,12)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (28,11)-(28,12)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (30,0)-(31,1)) + │ ├── receiver: + │ │ @ CallNode (location: (30,0)-(30,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (30,0)-(30,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (30,3)-(30,4) = "." + │ ├── message_loc: (30,4)-(30,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (30,8)-(31,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (30,10)-(30,18)) + │ │ │ ├── parameters: ∅ + │ │ │ ├── locals: (length: 2) + │ │ │ │ ├── @ BlockLocalVariableNode (location: (30,13)-(30,14)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (32,0)-(34,1)) + │ ├── receiver: + │ │ @ CallNode (location: (32,0)-(32,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,0)-(32,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (32,3)-(32,4) = "." + │ ├── message_loc: (32,4)-(32,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (32,8)-(34,1)) + │ │ ├── locals: [:*] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (32,10)-(32,13)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (32,11)-(32,12)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (32,11)-(32,12)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (33,2)-(33,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (32,8)-(32,9) = "{" + │ │ └── closing_loc: (34,0)-(34,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (35,0)-(37,1)) + │ ├── receiver: + │ │ @ CallNode (location: (35,0)-(35,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,0)-(35,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (35,3)-(35,4) = "." + │ ├── message_loc: (35,4)-(35,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (35,8)-(37,1)) + │ │ ├── locals: [] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (35,10)-(35,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (35,11)-(35,14)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (35,11)-(35,14)) + │ │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ │ └── @ SplatNode (location: (35,12)-(35,13)) + │ │ │ │ │ │ ├── operator_loc: (35,12)-(35,13) = "*" + │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ ├── opening_loc: (35,11)-(35,12) = "(" + │ │ │ │ │ └── closing_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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (36,2)-(36,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (35,8)-(35,9) = "{" + │ │ └── closing_loc: (37,0)-(37,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (38,0)-(40,1)) + │ ├── receiver: + │ │ @ CallNode (location: (38,0)-(38,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (38,0)-(38,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (38,3)-(38,4) = "." + │ ├── message_loc: (38,4)-(38,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (38,8)-(40,1)) + │ │ ├── locals: [] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (38,10)-(38,17)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (38,11)-(38,16)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (38,11)-(38,16)) + │ │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (38,12)-(38,15)) + │ │ │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ │ │ └── @ SplatNode (location: (38,13)-(38,14)) + │ │ │ │ │ │ │ ├── operator_loc: (38,13)-(38,14) = "*" + │ │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ │ ├── opening_loc: (38,12)-(38,13) = "(" + │ │ │ │ │ │ └── closing_loc: (38,14)-(38,15) = ")" + │ │ │ │ │ ├── opening_loc: (38,11)-(38,12) = "(" + │ │ │ │ │ └── closing_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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,2)-(39,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (38,8)-(38,9) = "{" + │ │ └── closing_loc: (40,0)-(40,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (41,0)-(43,1)) + │ ├── receiver: + │ │ @ CallNode (location: (41,0)-(41,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (41,0)-(41,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (41,3)-(41,4) = "." + │ ├── message_loc: (41,4)-(41,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (41,8)-(43,1)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (41,10)-(41,20)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (41,11)-(41,19)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (41,11)-(41,19)) + │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (41,12)-(41,13)) + │ │ │ │ │ │ │ └── name: :a + │ │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (41,15)-(41,18)) + │ │ │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ │ │ └── @ SplatNode (location: (41,16)-(41,17)) + │ │ │ │ │ │ │ ├── operator_loc: (41,16)-(41,17) = "*" + │ │ │ │ │ │ │ └── expression: ∅ + │ │ │ │ │ │ ├── opening_loc: (41,15)-(41,16) = "(" + │ │ │ │ │ │ └── closing_loc: (41,17)-(41,18) = ")" + │ │ │ │ │ ├── opening_loc: (41,11)-(41,12) = "(" + │ │ │ │ │ └── closing_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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (42,2)-(42,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (41,8)-(41,9) = "{" + │ │ └── closing_loc: (43,0)-(43,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (44,0)-(46,1)) + │ ├── receiver: + │ │ @ CallNode (location: (44,0)-(44,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (44,0)-(44,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (44,3)-(44,4) = "." + │ ├── message_loc: (44,4)-(44,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (44,8)-(46,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (44,10)-(44,18)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (44,11)-(44,17)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (44,11)-(44,17)) + │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (44,12)-(44,13)) + │ │ │ │ │ │ │ └── name: :a + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (44,15)-(44,16)) + │ │ │ │ │ │ └── name: :b + │ │ │ │ │ ├── opening_loc: (44,11)-(44,12) = "(" + │ │ │ │ │ └── closing_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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (45,2)-(45,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── opening_loc: (44,8)-(44,9) = "{" + │ │ └── closing_loc: (46,0)-(46,1) = "}" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (47,0)-(48,5)) + │ ├── receiver: + │ │ @ CallNode (location: (47,0)-(48,1)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (47,0)-(47,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (47,0)-(47,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: (47,3)-(47,4) = "." + │ │ ├── message_loc: (47,4)-(47,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (47,8)-(48,1)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (47,8)-(47,9) = "{" + │ │ │ └── closing_loc: (48,0)-(48,1) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── call_operator_loc: (48,1)-(48,2) = "." + │ ├── message_loc: (48,2)-(48,5) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "baz" + ├── @ CallNode (location: (49,0)-(51,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (49,0)-(49,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (49,2)-(51,3)) + │ │ ├── locals: [:e] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ BeginNode (location: (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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (52,0)-(56,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (52,0)-(52,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (52,2)-(56,3)) + │ │ ├── locals: [:bar] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ BeginNode (location: (53,2)-(56,3)) + │ │ │ ├── begin_keyword_loc: ∅ + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (53,2)-(53,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (53,2)-(53,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (53,2)-(53,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (57,0)-(61,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (57,0)-(57,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (57,2)-(61,3)) + │ │ ├── locals: [] + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (58,2)-(58,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (59,19)-(59,22) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ ├── operator_loc: ∅ + │ │ │ │ ├── reference: ∅ + │ │ │ │ ├── statements: + │ │ │ │ │ @ StatementsNode (location: (60,2)-(60,5)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (60,2)-(60,5)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (60,2)-(60,5) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (62,0)-(66,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (62,0)-(62,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (62,2)-(66,3)) + │ │ ├── locals: [:exception] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ BeginNode (location: (63,2)-(66,3)) + │ │ │ ├── begin_keyword_loc: ∅ + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (63,2)-(63,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (63,2)-(63,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (63,2)-(63,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (64,19)-(64,22) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (65,2)-(65,5) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (67,0)-(71,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (67,0)-(67,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (67,2)-(71,3)) + │ │ ├── locals: [] + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (68,2)-(68,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (69,8)-(69,11) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ ├── operator_loc: ∅ + │ │ │ │ ├── reference: ∅ + │ │ │ │ ├── statements: + │ │ │ │ │ @ StatementsNode (location: (70,2)-(70,5)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (70,2)-(70,5)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (70,2)-(70,5) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (72,0)-(75,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (72,0)-(72,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (72,2)-(75,3)) + │ │ ├── locals: [] + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (73,2)-(73,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (76,0)-(81,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (76,0)-(76,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (76,2)-(81,3)) + │ │ ├── locals: [] + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (77,2)-(77,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (80,2)-(80,5) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (82,0)-(86,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (82,0)-(82,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (82,2)-(86,3)) + │ │ ├── locals: [:exception] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ BeginNode (location: (83,2)-(86,3)) + │ │ │ ├── begin_keyword_loc: ∅ + │ │ │ ├── statements: + │ │ │ │ @ StatementsNode (location: (83,2)-(83,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (83,2)-(83,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (83,2)-(83,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (84,8)-(84,11) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (85,2)-(85,5) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (87,0)-(89,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (87,0)-(87,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (87,2)-(89,3)) + │ │ ├── locals: [] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallNode (location: (90,0)-(93,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (90,0)-(90,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (90,2)-(93,3)) + │ │ ├── locals: [] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (94,0)-(96,1)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (94,0)-(94,3) = "bar" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (94,4)-(96,1)) + │ ├── locals: [:_1, :_2] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (95,2)-(95,9)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (95,2)-(95,9)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (95,2)-(95,4)) + │ │ │ ├── name: :_1 + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (95,5)-(95,6) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (95,7)-(95,9)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (95,7)-(95,9)) + │ │ │ ├── name: :_2 + │ │ │ └── depth: 0 + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ ├── opening_loc: (94,4)-(94,5) = "{" + │ └── closing_loc: (96,0)-(96,1) = "}" + ├── flags: ∅ + └── name: "bar" diff --git a/test/prism/snapshots/unparser/corpus/literal/case.txt b/test/prism/snapshots/unparser/corpus/literal/case.txt new file mode 100644 index 00000000000000..8cfc9277947f3a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/case.txt @@ -0,0 +1,429 @@ +@ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (2,5)-(2,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── statements: + │ │ │ @ StatementsNode (location: (3,2)-(3,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (3,2)-(3,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,2)-(3,5) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ WhenNode (location: (4,0)-(5,5)) + │ │ ├── keyword_loc: (4,0)-(4,4) = "when" + │ │ ├── conditions: (length: 1) + │ │ │ └── @ CallNode (location: (4,5)-(4,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,5)-(4,8) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── statements: + │ │ @ StatementsNode (location: (5,2)-(5,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (5,2)-(5,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,2)-(5,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,5)-(7,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,5)-(8,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── statements: ∅ + │ │ └── @ WhenNode (location: (9,0)-(10,5)) + │ │ ├── keyword_loc: (9,0)-(9,4) = "when" + │ │ ├── conditions: (length: 1) + │ │ │ └── @ CallNode (location: (9,5)-(9,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,5)-(9,8) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── statements: + │ │ @ StatementsNode (location: (10,2)-(10,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (10,2)-(10,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,2)-(10,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (12,5)-(12,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (13,5)-(13,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── statements: + │ │ │ @ StatementsNode (location: (14,2)-(14,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (14,2)-(14,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (14,2)-(14,5) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ WhenNode (location: (15,0)-(16,5)) + │ │ ├── keyword_loc: (15,0)-(15,4) = "when" + │ │ ├── conditions: (length: 1) + │ │ │ └── @ CallNode (location: (15,5)-(15,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,5)-(15,8) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── statements: + │ │ @ StatementsNode (location: (16,2)-(16,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (16,2)-(16,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,2)-(16,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (18,5)-(18,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (19,5)-(19,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── @ CallNode (location: (19,10)-(19,13)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,10)-(19,13) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── statements: + │ │ @ StatementsNode (location: (20,2)-(20,8)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (20,2)-(20,8)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (22,5)-(22,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,6)-(23,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── statements: + │ │ @ StatementsNode (location: (24,2)-(24,8)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (24,2)-(24,8)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (26,5)-(26,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (27,5)-(27,8) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── statements: + │ │ @ StatementsNode (location: (28,2)-(28,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (28,2)-(28,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,2)-(28,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (32,5)-(32,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (33,6)-(33,9)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (33,6)-(33,9) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (33,10)-(33,11) = "|" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (33,12)-(33,15)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (33,12)-(33,15)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (33,12)-(33,15) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "|" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,5)-(35,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (36,6)-(36,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (36,6)-(36,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── call_operator_loc: (36,9)-(36,10) = "." + │ │ ├── message_loc: (36,10)-(36,13) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (36,14)-(36,15)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (36,14)-(36,15)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "baz=" + │ └── statements: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (35,0)-(35,4) = "case" + └── end_keyword_loc: (37,0)-(37,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/class.txt b/test/prism/snapshots/unparser/corpus/literal/class.txt new file mode 100644 index 00000000000000..9e67bd753aec15 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/class.txt @@ -0,0 +1,231 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (4,9)-(4,10) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,9)-(7,10) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── body: + │ │ @ StatementsNode (location: (8,2)-(8,3)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (8,2)-(8,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (8,2)-(8,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (27,2)-(27,9) = "include" + │ │ │ ├── opening_loc: (27,9)-(27,10) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (27,10)-(27,15)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (27,10)-(27,15)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ ConstantReadNode (location: (27,10)-(27,11)) + │ │ │ │ │ └── name: :B + │ │ │ │ ├── call_operator_loc: (27,11)-(27,12) = "." + │ │ │ │ ├── message_loc: (27,12)-(27,15) = "new" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "new" + │ │ │ ├── closing_loc: (27,15)-(27,16) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "include" + │ │ └── @ 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)) + │ │ │ ├── opening_loc: (30,4)-(30,5) = ":" + │ │ │ ├── value_loc: (30,5)-(30,8) = "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bar" + │ │ ├── locals: [] + │ │ ├── def_keyword_loc: (29,2)-(29,5) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (31,2)-(31,5) = "end" + │ ├── end_keyword_loc: (32,0)-(32,3) = "end" + │ └── name: :A + └── @ ClassNode (location: (34,0)-(35,3)) + ├── locals: [] + ├── class_keyword_loc: (34,0)-(34,5) = "class" + ├── constant_path: + │ @ ConstantPathNode (location: (34,6)-(34,9)) + │ ├── parent: ∅ + │ ├── child: + │ │ @ ConstantReadNode (location: (34,8)-(34,9)) + │ │ └── name: :A + │ └── delimiter_loc: (34,6)-(34,8) = "::" + ├── inheritance_operator_loc: ∅ + ├── superclass: ∅ + ├── body: ∅ + ├── end_keyword_loc: (35,0)-(35,3) = "end" + └── name: :A diff --git a/test/prism/snapshots/unparser/corpus/literal/control.txt b/test/prism/snapshots/unparser/corpus/literal/control.txt new file mode 100644 index 00000000000000..7ab821e051b200 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/control.txt @@ -0,0 +1,129 @@ +@ 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)) + │ └── 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)) + │ └── 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)) + │ └── arguments: (length: 1) + │ └── @ IfNode (location: (8,7)-(8,19)) + │ ├── if_keyword_loc: ∅ + │ ├── predicate: + │ │ @ TrueNode (location: (8,7)-(8,11)) + │ ├── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ IfNode (location: (9,6)-(9,18)) + │ │ ├── if_keyword_loc: ∅ + │ │ ├── predicate: + │ │ │ @ TrueNode (location: (9,6)-(9,10)) + │ │ ├── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ IfNode (location: (10,5)-(10,17)) + │ │ ├── if_keyword_loc: ∅ + │ │ ├── predicate: + │ │ │ @ TrueNode (location: (10,5)-(10,9)) + │ │ ├── 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)) + └── 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)) + ├── 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 new file mode 100644 index 00000000000000..421c45fd9b9232 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/def.txt @@ -0,0 +1,1170 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,3) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,2)-(4,3) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (6,2)-(6,3) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "c" + │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,2)-(8,3) = "d" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "d" + │ │ │ └── end_keyword_loc: (9,0)-(9,3) = "end" + │ │ └── end_keyword_loc: (9,0)-(9,3) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (9,0)-(9,3) = "end" + ├── @ DefNode (location: (11,0)-(19,3)) + │ ├── name: :foo + │ ├── name_loc: (11,4)-(11,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (12,2)-(12,3) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── keyword_loc: (12,4)-(12,10) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ CallNode (location: (12,11)-(12,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (12,11)-(12,12) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (14,2)-(14,3) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (16,2)-(16,3) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "c" + │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,2)-(18,3) = "d" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "d" + │ │ │ └── end_keyword_loc: (19,0)-(19,3) = "end" + │ │ └── end_keyword_loc: (19,0)-(19,3) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (11,0)-(11,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (19,0)-(19,3) = "end" + ├── @ DefNode (location: (21,0)-(22,3)) + │ ├── name: :foo + │ ├── name_loc: (21,4)-(21,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (21,8)-(21,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 2) + │ │ │ ├── @ KeywordParameterNode (location: (21,8)-(21,12)) + │ │ │ │ ├── name: :bar + │ │ │ │ ├── name_loc: (21,8)-(21,12) = "bar:" + │ │ │ │ └── value: ∅ + │ │ │ └── @ KeywordParameterNode (location: (21,14)-(21,18)) + │ │ │ ├── name: :baz + │ │ │ ├── name_loc: (21,14)-(21,18) = "baz:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar, :baz] + │ ├── def_keyword_loc: (21,0)-(21,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (21,7)-(21,8) = "(" + │ ├── rparen_loc: (21,18)-(21,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (22,0)-(22,3) = "end" + ├── @ DefNode (location: (24,0)-(25,3)) + │ ├── name: :foo + │ ├── name_loc: (24,4)-(24,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (24,0)-(24,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (25,0)-(25,3) = "end" + ├── @ DefNode (location: (27,0)-(29,3)) + │ ├── name: :foo + │ ├── name_loc: (27,4)-(27,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (28,2)-(28,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (28,2)-(28,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,2)-(28,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (27,0)-(27,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (29,0)-(29,3) = "end" + ├── @ DefNode (location: (31,0)-(37,3)) + │ ├── name: :foo + │ ├── name_loc: (31,4)-(31,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (32,2)-(37,3)) + │ │ ├── begin_keyword_loc: ∅ + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (32,2)-(32,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (32,2)-(32,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (32,2)-(32,5) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (34,2)-(34,5) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (36,2)-(36,5) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── end_keyword_loc: (37,0)-(37,3) = "end" + │ │ └── end_keyword_loc: (37,0)-(37,3) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (31,0)-(31,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (37,0)-(37,3) = "end" + ├── @ DefNode (location: (39,0)-(43,3)) + │ ├── name: :foo + │ ├── name_loc: (39,4)-(39,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (40,2)-(43,3)) + │ │ ├── begin_keyword_loc: ∅ + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (40,2)-(40,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (40,2)-(40,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (40,2)-(40,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (42,2)-(42,5) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── end_keyword_loc: (43,0)-(43,3) = "end" + │ │ └── end_keyword_loc: (43,0)-(43,3) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (39,0)-(39,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (43,0)-(43,3) = "end" + ├── @ DefNode (location: (45,0)-(49,3)) + │ ├── name: :foo + │ ├── name_loc: (45,4)-(45,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (46,2)-(49,3)) + │ │ ├── begin_keyword_loc: ∅ + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (46,2)-(46,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (46,2)-(46,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (46,2)-(46,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (48,2)-(48,5) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── consequent: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (49,0)-(49,3) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (45,0)-(45,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (49,0)-(49,3) = "end" + ├── @ DefNode (location: (51,0)-(53,3)) + │ ├── name: :foo + │ ├── name_loc: (51,4)-(51,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (51,8)-(51,11)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (51,8)-(51,11)) + │ │ │ └── name: :bar + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (52,2)-(52,5)) + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (52,2)-(52,5)) + │ │ ├── name: :bar + │ │ └── depth: 0 + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (51,0)-(51,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (51,7)-(51,8) = "(" + │ ├── rparen_loc: (51,11)-(51,12) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (53,0)-(53,3) = "end" + ├── @ DefNode (location: (55,0)-(57,3)) + │ ├── name: :foo + │ ├── name_loc: (55,4)-(55,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (55,8)-(55,16)) + │ │ ├── requireds: (length: 2) + │ │ │ ├── @ RequiredParameterNode (location: (55,8)-(55,11)) + │ │ │ │ └── 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] + │ ├── 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] + │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (63,15)-(63,18) = "baz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "baz" + │ │ │ │ └── @ NilNode (location: (63,20)-(63,23)) + │ │ │ ├── opening_loc: (63,14)-(63,15) = "(" + │ │ │ └── closing_loc: (63,23)-(63,24) = ")" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (63,0)-(63,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (63,7)-(63,8) = "(" + │ ├── rparen_loc: (63,24)-(63,25) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (64,0)-(64,3) = "end" + ├── @ DefNode (location: (66,0)-(68,3)) + │ ├── name: :foo + │ ├── name_loc: (66,4)-(66,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (66,8)-(66,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (66,8)-(66,18)) + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (66,8)-(66,11) = "bar" + │ │ │ ├── operator_loc: (66,12)-(66,13) = "=" + │ │ │ └── value: + │ │ │ @ TrueNode (location: (66,14)-(66,18)) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (67,2)-(67,5)) + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (67,2)-(67,5)) + │ │ ├── name: :bar + │ │ └── depth: 0 + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (66,0)-(66,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (66,7)-(66,8) = "(" + │ ├── rparen_loc: (66,18)-(66,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (68,0)-(68,3) = "end" + ├── @ DefNode (location: (70,0)-(72,3)) + │ ├── name: :foo + │ ├── name_loc: (70,4)-(70,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (70,8)-(70,23)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (70,8)-(70,11)) + │ │ │ └── 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] + │ ├── 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) + │ │ │ └── @ KeywordParameterNode (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] + │ ├── 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) + │ │ │ └── @ KeywordParameterNode (location: (77,8)-(77,16)) + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (77,8)-(77,12) = "bar:" + │ │ │ └── value: + │ │ │ @ CallNode (location: (77,13)-(77,16)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (77,13)-(77,16) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (77,0)-(77,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (77,7)-(77,8) = "(" + │ ├── rparen_loc: (77,16)-(77,17) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (78,0)-(78,3) = "end" + ├── @ DefNode (location: (80,0)-(81,3)) + │ ├── name: :foo + │ ├── name_loc: (80,4)-(80,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (80,8)-(80,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 1) + │ │ │ └── @ KeywordParameterNode (location: (80,8)-(80,18)) + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (80,8)-(80,12) = "bar:" + │ │ │ └── value: + │ │ │ @ CallNode (location: (80,13)-(80,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (80,13)-(80,16) = "bar" + │ │ │ ├── opening_loc: (80,16)-(80,17) = "(" + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: (80,17)-(80,18) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (80,0)-(80,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (80,7)-(80,8) = "(" + │ ├── rparen_loc: (80,18)-(80,19) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (81,0)-(81,3) = "end" + ├── @ DefNode (location: (83,0)-(85,3)) + │ ├── name: :foo + │ ├── name_loc: (83,4)-(83,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (83,8)-(83,9)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: + │ │ │ @ RestParameterNode (location: (83,8)-(83,9)) + │ │ │ ├── name: nil + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (84,2)-(84,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [:*] + │ ├── def_keyword_loc: (83,0)-(83,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (83,7)-(83,8) = "(" + │ ├── rparen_loc: (83,9)-(83,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (85,0)-(85,3) = "end" + ├── @ DefNode (location: (87,0)-(89,3)) + │ ├── name: :foo + │ ├── name_loc: (87,4)-(87,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (87,8)-(87,12)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: + │ │ │ @ RestParameterNode (location: (87,8)-(87,12)) + │ │ │ ├── name: :bar + │ │ │ ├── name_loc: (87,9)-(87,12) = "bar" + │ │ │ └── operator_loc: (87,8)-(87,9) = "*" + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (88,2)-(88,5)) + │ │ └── body: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (88,2)-(88,5)) + │ │ ├── name: :bar + │ │ └── depth: 0 + │ ├── locals: [:bar] + │ ├── def_keyword_loc: (87,0)-(87,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (87,7)-(87,8) = "(" + │ ├── rparen_loc: (87,12)-(87,13) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (89,0)-(89,3) = "end" + ├── @ DefNode (location: (91,0)-(93,3)) + │ ├── name: :foo + │ ├── name_loc: (91,4)-(91,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (91,8)-(91,17)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (91,8)-(91,11)) + │ │ │ └── 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] + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (96,2)-(96,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [:baz, :bor] + │ ├── def_keyword_loc: (95,0)-(95,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (95,7)-(95,8) = "(" + │ ├── rparen_loc: (95,24)-(95,25) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (97,0)-(97,3) = "end" + ├── @ DefNode (location: (99,0)-(101,3)) + │ ├── name: :foo + │ ├── name_loc: (99,4)-(99,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (99,8)-(99,32)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (99,8)-(99,18)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (100,2)-(100,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [:baz, :bor, :block] + │ ├── def_keyword_loc: (99,0)-(99,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (99,7)-(99,8) = "(" + │ ├── rparen_loc: (99,32)-(99,33) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (101,0)-(101,3) = "end" + ├── @ DefNode (location: (103,0)-(105,3)) + │ ├── name: :foo + │ ├── name_loc: (103,4)-(103,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (103,8)-(103,29)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (103,8)-(103,11)) + │ │ │ └── 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] + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (108,2)-(108,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [:block] + │ ├── def_keyword_loc: (107,0)-(107,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (107,7)-(107,8) = "(" + │ ├── rparen_loc: (107,14)-(107,15) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (109,0)-(109,3) = "end" + ├── @ DefNode (location: (111,0)-(113,3)) + │ ├── name: :foo + │ ├── name_loc: (111,4)-(111,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (111,8)-(111,19)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (111,8)-(111,11)) + │ │ │ └── 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] + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (116,2)-(116,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ CallNode (location: (117,2)-(117,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (117,2)-(117,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── locals: [] + │ ├── def_keyword_loc: (115,0)-(115,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (118,0)-(118,3) = "end" + ├── @ DefNode (location: (120,0)-(121,3)) + │ ├── name: :f + │ ├── name_loc: (120,4)-(120,5) = "f" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (120,6)-(120,11)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredDestructuredParameterNode (location: (120,6)-(120,11)) + │ │ │ ├── parameters: (length: 1) + │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (120,7)-(120,10)) + │ │ │ │ ├── parameters: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (120,8)-(120,9)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── opening_loc: (120,7)-(120,8) = "(" + │ │ │ │ └── closing_loc: (120,9)-(120,10) = ")" + │ │ │ ├── opening_loc: (120,6)-(120,7) = "(" + │ │ │ └── closing_loc: (120,10)-(120,11) = ")" + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:a] + │ ├── def_keyword_loc: (120,0)-(120,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (120,5)-(120,6) = "(" + │ ├── rparen_loc: (120,11)-(120,12) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (121,0)-(121,3) = "end" + ├── @ DefNode (location: (123,0)-(124,3)) + │ ├── name: :foo + │ ├── name_loc: (123,4)-(123,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (123,8)-(123,26)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 2) + │ │ │ ├── @ KeywordParameterNode (location: (123,8)-(123,12)) + │ │ │ │ ├── name: :bar + │ │ │ │ ├── name_loc: (123,8)-(123,12) = "bar:" + │ │ │ │ └── value: ∅ + │ │ │ └── @ KeywordParameterNode (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] + │ ├── 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)-(128,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (128,7)-(128,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (129,0)-(129,0) = " HEREDOC\n" + │ ├── locals: [] + │ ├── def_keyword_loc: (126,0)-(126,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (130,0)-(130,3) = "end" + └── @ DefNode (location: (132,0)-(134,3)) + ├── name: :f + ├── name_loc: (132,4)-(132,5) = "f" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (133,2)-(133,5)) + │ └── body: (length: 1) + │ └── @ StringNode (location: (133,2)-(133,5)) + │ ├── flags: ∅ + │ ├── opening_loc: (133,2)-(133,4) = "%(" + │ ├── content_loc: (133,4)-(133,4) = "" + │ ├── closing_loc: (133,4)-(133,5) = ")" + │ └── unescaped: "" + ├── locals: [] + ├── def_keyword_loc: (132,0)-(132,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (134,0)-(134,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/defined.txt b/test/prism/snapshots/unparser/corpus/literal/defined.txt new file mode 100644 index 00000000000000..ffa9bfbba8c18a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/defined.txt @@ -0,0 +1,50 @@ +@ 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)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (3,11)-(3,12)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ └── @ LocalVariableTargetNode (location: (3,14)-(3,15)) + │ │ │ ├── name: :b + │ │ │ └── depth: 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)) + │ │ ├── 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 new file mode 100644 index 00000000000000..a035c840664452 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/defs.txt @@ -0,0 +1,357 @@ +@ ProgramNode (location: (1,0)-(40,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(40,3)) + └── body: (length: 10) + ├── @ DefNode (location: (1,0)-(2,3)) + │ ├── name: :foo + │ ├── name_loc: (1,9)-(1,12) = "foo" + │ ├── receiver: + │ │ @ SelfNode (location: (1,4)-(1,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: (1,8)-(1,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (2,0)-(2,3) = "end" + ├── @ DefNode (location: (4,0)-(6,3)) + │ ├── name: :foo + │ ├── name_loc: (4,9)-(4,12) = "foo" + │ ├── receiver: + │ │ @ SelfNode (location: (4,4)-(4,8)) + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (5,2)-(5,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (5,2)-(5,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,2)-(5,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (4,0)-(4,3) = "def" + │ ├── operator_loc: (4,8)-(4,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (6,0)-(6,3) = "end" + ├── @ DefNode (location: (8,0)-(11,3)) + │ ├── name: :foo + │ ├── name_loc: (8,9)-(8,12) = "foo" + │ ├── receiver: + │ │ @ SelfNode (location: (8,4)-(8,8)) + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (9,2)-(10,5)) + │ │ └── body: (length: 2) + │ │ ├── @ CallNode (location: (9,2)-(9,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ CallNode (location: (10,2)-(10,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,2)-(10,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── locals: [] + │ ├── def_keyword_loc: (8,0)-(8,3) = "def" + │ ├── operator_loc: (8,8)-(8,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (11,0)-(11,3) = "end" + ├── @ DefNode (location: (13,0)-(15,3)) + │ ├── name: :bar + │ ├── name_loc: (13,8)-(13,11) = "bar" + │ ├── receiver: + │ │ @ ConstantReadNode (location: (13,4)-(13,7)) + │ │ └── name: :Foo + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (14,2)-(14,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (14,2)-(14,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,2)-(14,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (13,0)-(13,3) = "def" + │ ├── operator_loc: (13,7)-(13,8) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (15,0)-(15,3) = "end" + ├── @ DefNode (location: (17,0)-(20,3)) + │ ├── name: :bar + │ ├── name_loc: (18,3)-(18,6) = "bar" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (17,4)-(18,2)) + │ │ ├── body: + │ │ │ @ CallNode (location: (17,5)-(18,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (17,5)-(17,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (17,9)-(18,1)) + │ │ │ │ ├── locals: [:bar] + │ │ │ │ ├── parameters: + │ │ │ │ │ @ BlockParametersNode (location: (17,11)-(17,16)) + │ │ │ │ │ ├── parameters: + │ │ │ │ │ │ @ ParametersNode (location: (17,12)-(17,15)) + │ │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ │ └── @ RequiredParameterNode (location: (17,12)-(17,15)) + │ │ │ │ │ │ │ └── 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) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,2)-(19,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (17,0)-(17,3) = "def" + │ ├── operator_loc: (18,2)-(18,3) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (20,0)-(20,3) = "end" + ├── @ DefNode (location: (22,0)-(24,3)) + │ ├── name: :bar + │ ├── name_loc: (22,13)-(22,16) = "bar" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (22,4)-(22,12)) + │ │ ├── body: + │ │ │ @ CallNode (location: (22,5)-(22,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (22,5)-(22,8) = "foo" + │ │ │ ├── opening_loc: (22,8)-(22,9) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (22,9)-(22,10)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (22,9)-(22,10)) + │ │ │ │ └── flags: decimal + │ │ │ ├── closing_loc: (22,10)-(22,11) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,2)-(23,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (22,0)-(22,3) = "def" + │ ├── operator_loc: (22,12)-(22,13) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (24,0)-(24,3) = "end" + ├── @ DefNode (location: (26,0)-(28,3)) + │ ├── name: :bar + │ ├── name_loc: (26,19)-(26,22) = "bar" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (26,4)-(26,18)) + │ │ ├── body: + │ │ │ @ CallNode (location: (26,5)-(26,17)) + │ │ │ ├── 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) = "." + │ │ │ ├── message_loc: (26,14)-(26,17) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "baz" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (27,2)-(27,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── locals: [] + │ ├── def_keyword_loc: (26,0)-(26,3) = "def" + │ ├── operator_loc: (26,18)-(26,19) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (28,0)-(28,3) = "end" + ├── @ DefNode (location: (30,0)-(32,3)) + │ ├── name: :bar + │ ├── name_loc: (30,15)-(30,18) = "bar" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (30,4)-(30,14)) + │ │ ├── body: + │ │ │ @ ConstantPathNode (location: (30,5)-(30,13)) + │ │ │ ├── parent: + │ │ │ │ @ ConstantReadNode (location: (30,5)-(30,8)) + │ │ │ │ └── name: :Foo + │ │ │ ├── child: + │ │ │ │ @ ConstantReadNode (location: (30,10)-(30,13)) + │ │ │ │ └── name: :Bar + │ │ │ └── delimiter_loc: (30,8)-(30,10) = "::" + │ │ ├── opening_loc: (30,4)-(30,5) = "(" + │ │ └── closing_loc: (30,13)-(30,14) = ")" + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (31,2)-(31,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (31,2)-(31,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,2)-(31,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── locals: [] + │ ├── def_keyword_loc: (30,0)-(30,3) = "def" + │ ├── operator_loc: (30,14)-(30,15) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (32,0)-(32,3) = "end" + ├── @ DefNode (location: (34,0)-(36,3)) + │ ├── name: :bar + │ ├── name_loc: (34,8)-(34,11) = "bar" + │ ├── receiver: + │ │ @ ConstantReadNode (location: (34,4)-(34,7)) + │ │ └── name: :Foo + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (35,2)-(35,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (35,2)-(35,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,2)-(35,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── locals: [] + │ ├── def_keyword_loc: (34,0)-(34,3) = "def" + │ ├── operator_loc: (34,7)-(34,8) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (36,0)-(36,3) = "end" + └── @ DefNode (location: (38,0)-(40,3)) + ├── name: :bar + ├── name_loc: (38,8)-(38,11) = "bar" + ├── receiver: + │ @ CallNode (location: (38,4)-(38,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (38,4)-(38,7) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (39,2)-(39,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (39,2)-(39,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (39,2)-(39,5) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "baz" + ├── locals: [] + ├── def_keyword_loc: (38,0)-(38,3) = "def" + ├── operator_loc: (38,7)-(38,8) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (40,0)-(40,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/dstr.txt b/test/prism/snapshots/unparser/corpus/literal/dstr.txt new file mode 100644 index 00000000000000..52365b29465137 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/dstr.txt @@ -0,0 +1,333 @@ +@ 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)) + │ ├── 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)) + │ ├── 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)-(6,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (6,0)-(6,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)-(8,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (7,3)-(8,0) = "a\nb\n" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "a\nb\n" + │ │ │ └── closing_loc: (9,0)-(9,0) = " HEREDOC\n" + │ │ └── @ CallNode (location: (10,2)-(10,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,2)-(10,3) = "x" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "x" + │ ├── 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)-(13,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (13,0)-(13,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)-(14,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (14,3)-(14,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)-(15,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (15,3)-(15,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)-(16,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (16,3)-(16,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (17,0)-(17,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)-(20,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (19,3)-(20,0) = "\na\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\na\n" + │ │ └── closing_loc: (21,0)-(21,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)) + │ ├── 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)) + │ │ └── 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)-(28,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (28,9)-(28,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (29,0)-(29,0) = " HEREDOC\n" + │ ├── consequent: ∅ + │ └── end_keyword_loc: (30,0)-(30,3) = "end" + ├── @ CallNode (location: (31,0)-(31,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,0)-(31,3) = "foo" + │ ├── opening_loc: (31,3)-(31,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,4)-(31,14)) + │ │ └── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (32,4)-(32,7) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ └── closing_loc: (32,7)-(32,8) = "}" + │ │ │ └── @ StringNode (location: (32,8)-(32,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (32,8)-(32,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (33,0)-(33,0) = "HEREDOC\n" + │ ├── closing_loc: (31,14)-(31,15) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + └── @ CallNode (location: (34,0)-(37,1)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (34,0)-(34,3) = "foo" + ├── opening_loc: (34,3)-(34,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (34,4)-(34,14)) + │ └── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (35,4)-(35,7) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── closing_loc: (35,7)-(35,8) = "}" + │ │ └── @ StringNode (location: (35,8)-(35,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (35,8)-(35,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (36,0)-(36,0) = "HEREDOC\n" + ├── closing_loc: (34,14)-(34,15) = ")" + ├── block: + │ @ BlockNode (location: (34,16)-(37,1)) + │ ├── locals: [:x] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (34,18)-(34,21)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (34,19)-(34,20)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (34,19)-(34,20)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/unparser/corpus/literal/empty.txt b/test/prism/snapshots/unparser/corpus/literal/empty.txt new file mode 100644 index 00000000000000..870bdb6ad54607 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/empty.txt @@ -0,0 +1,5 @@ +@ ProgramNode (location: (1,0)-(0,0)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(0,0)) + └── body: (length: 0) diff --git a/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt b/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt new file mode 100644 index 00000000000000..838b4bf6f040c6 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/empty_begin.txt @@ -0,0 +1,9 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ ParenthesesNode (location: (1,0)-(1,2)) + ├── body: ∅ + ├── opening_loc: (1,0)-(1,1) = "(" + └── closing_loc: (1,1)-(1,2) = ")" diff --git a/test/prism/snapshots/unparser/corpus/literal/flipflop.txt b/test/prism/snapshots/unparser/corpus/literal/flipflop.txt new file mode 100644 index 00000000000000..48913a9e3fe5a6 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/flipflop.txt @@ -0,0 +1,183 @@ +@ 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)) + │ │ │ ├── left: + │ │ │ │ @ ParenthesesNode (location: (1,4)-(1,12)) + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (1,5)-(1,11)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,5)-(1,11)) + │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ @ CallNode (location: (1,5)-(1,6)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (1,5)-(1,6) = "i" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "i" + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,7)-(1,9) = "==" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "==" + │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ @ CallNode (location: (1,15)-(1,16)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (1,15)-(1,16) = "i" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "i" + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,17)-(1,19) = "==" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (1,20)-(1,21)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ IntegerNode (location: (1,20)-(1,21)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "==" + │ │ │ │ ├── opening_loc: (1,14)-(1,15) = "(" + │ │ │ │ └── closing_loc: (1,21)-(1,22) = ")" + │ │ │ ├── operator_loc: (1,12)-(1,14) = ".." + │ │ │ └── flags: ∅ + │ │ ├── opening_loc: (1,3)-(1,4) = "(" + │ │ └── closing_loc: (1,22)-(1,23) = ")" + │ ├── statements: + │ │ @ StatementsNode (location: (2,2)-(2,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (2,2)-(2,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── left: + │ │ │ @ ParenthesesNode (location: (4,4)-(4,12)) + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (4,5)-(4,11)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (4,5)-(4,11)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ CallNode (location: (4,5)-(4,6)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (4,5)-(4,6) = "i" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "i" + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,7)-(4,9) = "==" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (4,10)-(4,11)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ IntegerNode (location: (4,10)-(4,11)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "==" + │ │ │ ├── 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)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ CallNode (location: (4,16)-(4,17)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (4,16)-(4,17) = "i" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "i" + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,18)-(4,20) = "==" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (4,21)-(4,22)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ IntegerNode (location: (4,21)-(4,22)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "==" + │ │ │ ├── opening_loc: (4,15)-(4,16) = "(" + │ │ │ └── closing_loc: (4,22)-(4,23) = ")" + │ │ ├── operator_loc: (4,12)-(4,15) = "..." + │ │ └── flags: exclude_end + │ ├── opening_loc: (4,3)-(4,4) = "(" + │ └── closing_loc: (4,23)-(4,24) = ")" + ├── statements: + │ @ StatementsNode (location: (5,2)-(5,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (5,2)-(5,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,2)-(5,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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 new file mode 100644 index 00000000000000..52fb1a46734b6c --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/for.txt @@ -0,0 +1,166 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "bar" + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(3,3)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,13)-(1,16) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (2,2)-(2,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (2,2)-(2,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,5) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ ForNode (location: (4,0)-(6,3)) + │ ├── index: + │ │ @ LocalVariableTargetNode (location: (4,4)-(4,5)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── collection: + │ │ @ CallNode (location: (4,9)-(4,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (4,9)-(4,12) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── statements: + │ │ @ StatementsNode (location: (5,2)-(5,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (5,2)-(5,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,2)-(5,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (7,5)-(7,6)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ └── @ SplatNode (location: (7,8)-(7,10)) + │ │ │ ├── operator_loc: (7,8)-(7,9) = "*" + │ │ │ └── expression: + │ │ │ @ LocalVariableTargetNode (location: (7,9)-(7,10)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── lparen_loc: (7,4)-(7,5) = "(" + │ │ └── rparen_loc: (7,10)-(7,11) = ")" + │ ├── collection: + │ │ @ CallNode (location: (7,15)-(7,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,15)-(7,18) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── statements: + │ │ @ StatementsNode (location: (8,2)-(8,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (8,2)-(8,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (8,2)-(8,5) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (10,5)-(10,6)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (10,8)-(10,9)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── lparen_loc: (10,4)-(10,5) = "(" + │ └── rparen_loc: (10,9)-(10,10) = ")" + ├── collection: + │ @ CallNode (location: (10,14)-(10,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (10,14)-(10,17) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── statements: + │ @ StatementsNode (location: (11,2)-(11,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (11,2)-(11,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,2)-(11,5) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "baz" + ├── for_keyword_loc: (10,0)-(10,3) = "for" + ├── in_keyword_loc: (10,11)-(10,13) = "in" + ├── do_keyword_loc: (10,18)-(10,20) = "do" + └── end_keyword_loc: (12,0)-(12,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/hookexe.txt b/test/prism/snapshots/unparser/corpus/literal/hookexe.txt new file mode 100644 index 00000000000000..1637f956190dc2 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/hookexe.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(7,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,1)) + └── body: (length: 3) + ├── @ PreExecutionNode (location: (1,0)-(3,1)) + │ ├── statements: + │ │ @ StatementsNode (location: (2,2)-(2,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (2,2)-(2,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,0)-(4,3) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── @ PostExecutionNode (location: (5,0)-(7,1)) + ├── statements: + │ @ StatementsNode (location: (6,2)-(6,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (6,2)-(6,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,2)-(6,5) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "baz" + ├── keyword_loc: (5,0)-(5,3) = "END" + ├── opening_loc: (5,4)-(5,5) = "{" + └── closing_loc: (7,0)-(7,1) = "}" diff --git a/test/prism/snapshots/unparser/corpus/literal/if.txt b/test/prism/snapshots/unparser/corpus/literal/if.txt new file mode 100644 index 00000000000000..bf399d7dc956bd --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/if.txt @@ -0,0 +1,268 @@ +@ 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)) + │ │ ├── opening_loc: (1,3)-(1,4) = "/" + │ │ ├── content_loc: (1,4)-(1,7) = "foo" + │ │ ├── closing_loc: (1,7)-(1,8) = "/" + │ │ ├── unescaped: "foo" + │ │ └── flags: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (2,2)-(2,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (2,2)-(2,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,5) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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 + │ ├── 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 + │ ├── 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 + │ ├── 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 + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (18,3)-(18,6) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (22,8)-(22,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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 + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (26,8)-(26,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,7)-(28,10) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,8)-(29,11) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,3)-(31,6) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (31,7)-(33,1)) + │ │ ├── locals: [:pair] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (31,9)-(31,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (31,10)-(31,14)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (31,10)-(31,14)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── 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)) + │ │ │ ├── opening_loc: (34,9)-(34,10) = ":" + │ │ │ ├── value_loc: (34,10)-(34,13) = "foo" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "foo" + │ │ └── operator_loc: (34,7)-(34,8) = "=" + │ └── @ LocalVariableReadNode (location: (35,2)-(35,5)) + │ ├── name: :foo + │ └── depth: 0 + ├── consequent: ∅ + └── end_keyword_loc: (36,0)-(36,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt b/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt new file mode 100644 index 00000000000000..06cf243ee8684a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/kwbegin.txt @@ -0,0 +1,489 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,2)-(10,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,2)-(14,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (16,2)-(16,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (20,2)-(20,3) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── @ CallNode (location: (21,2)-(21,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,2)-(21,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,2)-(23,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,2)-(35,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,2)-(37,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,2)-(39,3) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (41,2)-(41,3) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (47,4)-(47,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (51,2)-(51,5) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ └── @ CallNode (location: (52,2)-(52,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (52,2)-(52,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (56,2)-(56,7) = "raise" + │ │ │ ├── opening_loc: (56,7)-(56,8) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (56,8)-(56,17)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ ConstantReadNode (location: (56,8)-(56,17)) + │ │ │ │ └── name: :Exception + │ │ │ ├── closing_loc: (56,17)-(56,18) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (56,32)-(56,35) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (75,2)-(75,5) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── 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)) + │ │ │ ├── opening_loc: (79,8)-(79,9) = ":" + │ │ │ ├── value_loc: (79,9)-(79,12) = "bar" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "bar" + │ │ └── keyword_loc: (79,2)-(79,7) = "undef" + │ ├── keyword_loc: (79,13)-(79,19) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (79,20)-(79,23)) + └── end_keyword_loc: (80,0)-(80,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/lambda.txt b/test/prism/snapshots/unparser/corpus/literal/lambda.txt new file mode 100644 index 00000000000000..d1c6c75987edb9 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/lambda.txt @@ -0,0 +1,143 @@ +@ ProgramNode (location: (1,0)-(13,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(13,1)) + └── body: (length: 6) + ├── @ CallNode (location: (1,0)-(2,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,6) = "lambda" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,7)-(2,1)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,7)-(1,8) = "{" + │ │ └── closing_loc: (2,0)-(2,1) = "}" + │ ├── flags: ∅ + │ └── name: "lambda" + ├── @ CallNode (location: (3,0)-(5,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,6) = "lambda" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,7)-(5,1)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (3,9)-(3,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (3,10)-(3,14)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (3,10)-(3,11)) + │ │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "lambda" + ├── @ LambdaNode (location: (6,0)-(7,1)) + │ ├── locals: [] + │ ├── operator_loc: (6,0)-(6,2) = "->" + │ ├── opening_loc: (6,5)-(6,6) = "{" + │ ├── closing_loc: (7,0)-(7,1) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (6,2)-(6,4)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (6,2)-(6,3) = "(" + │ │ └── closing_loc: (6,3)-(6,4) = ")" + │ └── body: ∅ + ├── @ LambdaNode (location: (8,0)-(9,1)) + │ ├── locals: [:a] + │ ├── operator_loc: (8,0)-(8,2) = "->" + │ ├── opening_loc: (8,6)-(8,7) = "{" + │ ├── closing_loc: (9,0)-(9,1) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (8,2)-(8,5)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (8,3)-(8,4)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (8,3)-(8,4)) + │ │ │ │ └── name: :a + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (8,2)-(8,3) = "(" + │ │ └── closing_loc: (8,4)-(8,5) = ")" + │ └── body: ∅ + ├── @ LambdaNode (location: (10,0)-(11,1)) + │ ├── locals: [:a, :b] + │ ├── operator_loc: (10,0)-(10,2) = "->" + │ ├── opening_loc: (10,9)-(10,10) = "{" + │ ├── closing_loc: (11,0)-(11,1) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (10,2)-(10,8)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (10,3)-(10,7)) + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ RequiredParameterNode (location: (10,3)-(10,4)) + │ │ │ │ │ └── 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] + ├── 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 new file mode 100644 index 00000000000000..63524c5ef844cc --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/literal.txt @@ -0,0 +1,1108 @@ +@ 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)-(2,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (2,5)-(2,0) = "\n" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "\n" + │ │ │ │ └── closing_loc: (3,0)-(3,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)) + │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ ├── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (6,0)-(6,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,0)-(6,1) = "a" + │ │ ├── opening_loc: (6,1)-(6,2) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (6,2)-(6,12)) + │ │ │ └── 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)-(7,0)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (7,5)-(7,0) = "\n" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "\n" + │ │ │ └── closing_loc: (8,0)-(8,0) = "HEREDOC\n" + │ │ ├── closing_loc: (6,12)-(6,13) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "a" + │ ├── call_operator_loc: (6,13)-(6,14) = "." + │ ├── message_loc: (6,14)-(6,15) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (9,0)-(9,8)) + │ ├── receiver: + │ │ @ CallNode (location: (9,0)-(9,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,0)-(9,1) = "a" + │ │ ├── opening_loc: (9,1)-(9,2) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,2)-(9,5)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "a" + │ ├── call_operator_loc: (9,6)-(9,7) = "." + │ ├── message_loc: (9,7)-(9,8) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── @ 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)-(11,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (11,5)-(11,0) = "\n" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "\n" + │ │ │ │ └── closing_loc: (12,0)-(12,0) = "HEREDOC\n" + │ │ │ └── operator_loc: (10,8)-(10,10) = "=>" + │ │ └── @ AssocSplatNode (location: (10,23)-(10,28)) + │ │ ├── value: + │ │ │ @ CallNode (location: (10,25)-(10,28)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (10,25)-(10,28) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,18)-(13,21) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── 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)) + │ ├── receiver: + │ │ @ IntegerNode (location: (16,1)-(16,3)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (16,0)-(16,1) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+@" + ├── @ 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 + ├── @ StringConcatNode (location: (28,0)-(28,11)) + │ ├── left: + │ │ @ 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" + │ └── right: + │ @ 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" + ├── @ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,10)-(29,13) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ ├── opening_loc: (43,0)-(43,1) = ":" + │ ├── value_loc: (43,1)-(43,4) = "foo" + │ ├── closing_loc: ∅ + │ └── unescaped: "foo" + ├── @ SymbolNode (location: (44,0)-(44,6)) + │ ├── 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)) + │ ├── opening_loc: (45,0)-(45,1) = ":" + │ ├── value_loc: (45,1)-(45,4) = "foo" + │ ├── closing_loc: ∅ + │ └── unescaped: "foo" + ├── @ SymbolNode (location: (46,0)-(46,6)) + │ ├── 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)) + │ ├── 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)) + │ ├── opening_loc: (48,0)-(48,2) = ":\"" + │ ├── value_loc: (1,0)-(0,0) = "" + │ ├── closing_loc: (48,2)-(48,3) = "\"" + │ └── unescaped: "" + ├── @ RegularExpressionNode (location: (49,0)-(49,5)) + │ ├── opening_loc: (49,0)-(49,1) = "/" + │ ├── content_loc: (49,1)-(49,4) = "foo" + │ ├── closing_loc: (49,4)-(49,5) = "/" + │ ├── unescaped: "foo" + │ └── flags: ∅ + ├── @ RegularExpressionNode (location: (50,0)-(50,28)) + │ ├── opening_loc: (50,0)-(50,1) = "/" + │ ├── content_loc: (50,1)-(50,27) = "[^-+',.\\/:@[:alnum:]\\[\\]]+" + │ ├── closing_loc: (50,27)-(50,28) = "/" + │ ├── unescaped: "[^-+',./:@[:alnum:][]]+" + │ └── flags: ∅ + ├── @ InterpolatedRegularExpressionNode (location: (51,0)-(51,12)) + │ ├── 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) = "/" + │ └── flags: ∅ + ├── @ InterpolatedRegularExpressionNode (location: (52,0)-(52,15)) + │ ├── 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" + │ └── flags: ignore_case, extended, multi_line + ├── @ InterpolatedRegularExpressionNode (location: (53,0)-(53,13)) + │ ├── 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) = "/" + │ └── flags: ∅ + ├── @ RegularExpressionNode (location: (54,0)-(54,4)) + │ ├── opening_loc: (54,0)-(54,1) = "/" + │ ├── content_loc: (54,1)-(54,3) = "\\n" + │ ├── closing_loc: (54,3)-(54,4) = "/" + │ ├── unescaped: "\n" + │ └── flags: ∅ + ├── @ RegularExpressionNode (location: (55,0)-(55,4)) + │ ├── opening_loc: (55,0)-(55,1) = "/" + │ ├── content_loc: (55,1)-(55,3) = "\\n" + │ ├── closing_loc: (55,3)-(55,4) = "/" + │ ├── unescaped: "\n" + │ └── flags: ∅ + ├── @ RegularExpressionNode (location: (56,0)-(56,5)) + │ ├── opening_loc: (56,0)-(56,1) = "/" + │ ├── content_loc: (56,1)-(56,3) = "\\n" + │ ├── closing_loc: (56,3)-(56,5) = "/x" + │ ├── unescaped: "\n" + │ └── flags: extended + ├── @ RegularExpressionNode (location: (57,0)-(57,7)) + │ ├── opening_loc: (57,0)-(57,1) = "/" + │ ├── content_loc: (57,1)-(57,5) = "\\/\\/" + │ ├── closing_loc: (57,5)-(57,7) = "/x" + │ ├── unescaped: "//" + │ └── flags: extended + ├── @ 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (58,7)-(58,10) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + │ ├── left: + │ │ @ ParenthesesNode (location: (60,0)-(60,11)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (60,1)-(60,10)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (60,1)-(60,10)) + │ │ │ ├── receiver: + │ │ │ │ @ FloatNode (location: (60,1)-(60,4)) + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (60,5)-(60,6) = "/" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (60,7)-(60,10)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ FloatNode (location: (60,7)-(60,10)) + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "/" + │ │ ├── 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) = ".." + │ └── flags: ∅ + ├── @ RangeNode (location: (61,0)-(61,14)) + │ ├── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ FloatNode (location: (61,4)-(61,7)) + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (61,8)-(61,9) = "/" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (61,10)-(61,13)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ FloatNode (location: (61,10)-(61,13)) + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "/" + │ │ ├── opening_loc: (61,3)-(61,4) = "(" + │ │ └── closing_loc: (61,13)-(61,14) = ")" + │ ├── operator_loc: (61,1)-(61,3) = ".." + │ └── flags: ∅ + ├── @ RangeNode (location: (62,0)-(62,16)) + │ ├── left: + │ │ @ ParenthesesNode (location: (62,0)-(62,11)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (62,1)-(62,10)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (62,1)-(62,10)) + │ │ │ ├── receiver: + │ │ │ │ @ FloatNode (location: (62,1)-(62,4)) + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (62,5)-(62,6) = "/" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (62,7)-(62,10)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ FloatNode (location: (62,7)-(62,10)) + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "/" + │ │ ├── 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) = ".." + │ └── flags: ∅ + ├── @ FloatNode (location: (63,0)-(63,4)) + ├── @ FloatNode (location: (64,0)-(64,3)) + ├── @ ArrayNode (location: (65,0)-(65,6)) + │ ├── 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)) + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (66,8)-(66,10) = "n2" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "n2" + │ ├── opening_loc: (66,0)-(66,1) = "[" + │ └── closing_loc: (66,10)-(66,11) = "]" + ├── @ ArrayNode (location: (67,0)-(67,3)) + │ ├── 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)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (68,0)-(68,1) = "[" + │ └── closing_loc: (68,1)-(68,2) = "]" + ├── @ ArrayNode (location: (69,0)-(69,10)) + │ ├── 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)) + │ ├── 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)) + │ ├── 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)) + │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (76,15)-(76,18) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (78,2)-(78,3) = "a" + │ │ │ ├── closing_loc: (78,3)-(78,4) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ SymbolNode (location: (78,5)-(78,7)) + │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ │ ├── 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)-(81,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (81,4)-(81,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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (83,0)-(83,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (83,4)-(86,1)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (84,2)-(85,7)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ InterpolatedStringNode (location: (84,2)-(85,7)) + │ │ │ ├── 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)-(84,0)) + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── content_loc: (84,6)-(84,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) = "}" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ SymbolNode (location: (87,0)-(88,2)) + │ ├── 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)-(89,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (89,1)-(89,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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (90,2)-(90,5) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── 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 new file mode 100644 index 00000000000000..826b8628f7aca5 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/module.txt @@ -0,0 +1,105 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,2)-(11,9) = "include" + │ │ ├── opening_loc: (11,9)-(11,10) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (11,10)-(11,15)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (11,10)-(11,15)) + │ │ │ ├── receiver: + │ │ │ │ @ ConstantReadNode (location: (11,10)-(11,11)) + │ │ │ │ └── name: :B + │ │ │ ├── call_operator_loc: (11,11)-(11,12) = "." + │ │ │ ├── message_loc: (11,12)-(11,15) = "new" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "new" + │ │ ├── closing_loc: (11,15)-(11,16) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "include" + │ └── @ 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)) + │ │ ├── opening_loc: (14,4)-(14,5) = ":" + │ │ ├── value_loc: (14,5)-(14,8) = "bar" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bar" + │ ├── locals: [] + │ ├── def_keyword_loc: (13,2)-(13,5) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (15,2)-(15,5) = "end" + ├── end_keyword_loc: (16,0)-(16,3) = "end" + └── name: :A diff --git a/test/prism/snapshots/unparser/corpus/literal/opasgn.txt b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt new file mode 100644 index 00000000000000..91f92de04df3e3 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/opasgn.txt @@ -0,0 +1,519 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,6)-(6,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── 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)) + │ ├── 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) = "." + │ ├── message_loc: (8,10)-(8,13) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (9,0)-(9,17)) + │ ├── 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: ∅ + │ ├── message_loc: (9,10)-(9,13) = "[k]" + │ ├── opening_loc: (9,10)-(9,11) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,11)-(9,17)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (9,11)-(9,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,11)-(9,12) = "k" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "k" + │ │ └── @ CallNode (location: (9,16)-(9,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,16)-(9,17) = "v" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "v" + │ ├── closing_loc: (9,12)-(9,13) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallOperatorWriteNode (location: (10,0)-(10,8)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "b" + │ ├── write_name: "b=" + │ ├── operator_loc: (15,4)-(15,7) = "&&=" + │ └── value: + │ @ CallNode (location: (15,8)-(15,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,8)-(15,9) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── @ CallOrWriteNode (location: (16,0)-(16,9)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "b" + │ ├── write_name: "b=" + │ ├── operator_loc: (16,4)-(16,7) = "||=" + │ └── value: + │ @ IntegerNode (location: (16,8)-(16,9)) + │ └── flags: decimal + ├── @ CallOperatorWriteNode (location: (17,0)-(17,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (17,0)-(17,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,1)-(17,4) = "[b]" + │ ├── opening_loc: (17,1)-(17,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,2)-(17,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (17,2)-(17,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,2)-(17,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (17,3)-(17,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :+ + │ ├── operator_loc: (17,5)-(17,7) = "+=" + │ └── value: + │ @ IntegerNode (location: (17,8)-(17,9)) + │ └── flags: decimal + ├── @ CallOperatorWriteNode (location: (18,0)-(18,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (18,0)-(18,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (18,1)-(18,4) = "[b]" + │ ├── opening_loc: (18,1)-(18,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (18,2)-(18,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (18,2)-(18,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (18,2)-(18,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (18,3)-(18,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :- + │ ├── operator_loc: (18,5)-(18,7) = "-=" + │ └── value: + │ @ IntegerNode (location: (18,8)-(18,9)) + │ └── flags: decimal + ├── @ CallOperatorWriteNode (location: (19,0)-(19,10)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (19,0)-(19,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,1)-(19,4) = "[b]" + │ ├── opening_loc: (19,1)-(19,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (19,2)-(19,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (19,2)-(19,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,2)-(19,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (19,3)-(19,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :** + │ ├── operator_loc: (19,5)-(19,8) = "**=" + │ └── value: + │ @ IntegerNode (location: (19,9)-(19,10)) + │ └── flags: decimal + ├── @ CallOperatorWriteNode (location: (20,0)-(20,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (20,0)-(20,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (20,1)-(20,4) = "[b]" + │ ├── opening_loc: (20,1)-(20,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (20,2)-(20,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (20,2)-(20,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (20,2)-(20,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (20,3)-(20,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :* + │ ├── operator_loc: (20,5)-(20,7) = "*=" + │ └── value: + │ @ IntegerNode (location: (20,8)-(20,9)) + │ └── flags: decimal + ├── @ CallOperatorWriteNode (location: (21,0)-(21,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (21,0)-(21,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,1)-(21,4) = "[b]" + │ ├── opening_loc: (21,1)-(21,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,2)-(21,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (21,2)-(21,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,2)-(21,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (21,3)-(21,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :/ + │ ├── operator_loc: (21,5)-(21,7) = "/=" + │ └── value: + │ @ IntegerNode (location: (21,8)-(21,9)) + │ └── flags: decimal + ├── @ CallAndWriteNode (location: (22,0)-(22,10)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (22,0)-(22,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (22,1)-(22,4) = "[b]" + │ ├── opening_loc: (22,1)-(22,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (22,2)-(22,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (22,2)-(22,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (22,2)-(22,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (22,3)-(22,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator_loc: (22,5)-(22,8) = "&&=" + │ └── value: + │ @ CallNode (location: (22,9)-(22,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (22,9)-(22,10) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── @ CallOrWriteNode (location: (23,0)-(23,10)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (23,0)-(23,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,1)-(23,4) = "[b]" + │ ├── opening_loc: (23,1)-(23,2) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (23,2)-(23,3)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (23,2)-(23,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,2)-(23,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (23,3)-(23,4) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator_loc: (23,5)-(23,8) = "||=" + │ └── value: + │ @ IntegerNode (location: (23,9)-(23,10)) + │ └── flags: decimal + └── @ CallOperatorWriteNode (location: (24,0)-(24,10)) + ├── receiver: + │ @ CallNode (location: (24,0)-(24,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (24,0)-(24,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (24,3)-(24,4) = "." + ├── message_loc: (24,4)-(24,5) = "A" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: ∅ + ├── 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 new file mode 100644 index 00000000000000..a40093634c283a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/pattern.txt @@ -0,0 +1,426 @@ +@ ProgramNode (location: (1,0)-(41,8)) +├── locals: [:a, :x, :y] +└── statements: + @ StatementsNode (location: (1,0)-(41,8)) + └── body: (length: 4) + ├── @ CaseNode (location: (1,0)-(33,3)) + │ ├── predicate: + │ │ @ CallNode (location: (1,5)-(1,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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: ∅ + │ │ │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,2)-(5,3) = "y" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "y" + │ │ │ ├── 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 + │ │ │ │ ├── assocs: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (6,5)-(6,7)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ SymbolNode (location: (6,5)-(6,7)) + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── value_loc: (6,5)-(6,6) = "x" + │ │ │ │ │ │ ├── closing_loc: (6,6)-(6,7) = ":" + │ │ │ │ │ │ └── unescaped: "x" + │ │ │ │ │ ├── value: ∅ + │ │ │ │ │ └── operator_loc: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── assocs: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (8,4)-(8,7)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ AssocSplatNode (location: (8,4)-(8,7)) + │ │ │ │ │ │ ├── value: + │ │ │ │ │ │ │ @ LocalVariableTargetNode (location: (8,6)-(8,7)) + │ │ │ │ │ │ │ ├── name: :a + │ │ │ │ │ │ │ └── depth: 0 + │ │ │ │ │ │ └── operator_loc: (8,4)-(8,6) = "**" + │ │ │ │ │ ├── value: ∅ + │ │ │ │ │ └── operator_loc: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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)) + │ │ │ │ ├── statements: + │ │ │ │ │ @ StatementsNode (location: (10,3)-(10,5)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ HashPatternNode (location: (10,3)-(10,5)) + │ │ │ │ │ ├── constant: ∅ + │ │ │ │ │ ├── assocs: (length: 0) + │ │ │ │ │ ├── kwrest: ∅ + │ │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── assocs: (length: 2) + │ │ │ │ │ ├── @ AssocNode (location: (14,4)-(14,8)) + │ │ │ │ │ │ ├── key: + │ │ │ │ │ │ │ @ SymbolNode (location: (14,4)-(14,6)) + │ │ │ │ │ │ │ ├── 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)) + │ │ │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── assocs: (length: 0) + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── assocs: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (18,4)-(18,9)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ NoKeywordsParameterNode (location: (18,4)-(18,9)) + │ │ │ │ │ │ ├── operator_loc: (18,4)-(18,6) = "**" + │ │ │ │ │ │ └── keyword_loc: (18,6)-(18,9) = "nil" + │ │ │ │ │ ├── value: ∅ + │ │ │ │ │ └── operator_loc: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── assocs: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (20,4)-(20,10)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ SymbolNode (location: (20,4)-(20,8)) + │ │ │ │ │ │ ├── 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: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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" + ├── @ CaseNode (location: (34,0)-(36,3)) + │ ├── predicate: + │ │ @ CallNode (location: (34,5)-(34,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (34,5)-(34,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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" + ├── @ CaseNode (location: (37,0)-(40,3)) + │ ├── predicate: + │ │ @ CallNode (location: (37,5)-(37,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,5)-(37,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 new file mode 100644 index 00000000000000..5247dcc4f54cb6 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/pragma.txt @@ -0,0 +1,19 @@ +@ 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (4,0)-(4,7) = "__dir__" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "__dir__" diff --git a/test/prism/snapshots/unparser/corpus/literal/range.txt b/test/prism/snapshots/unparser/corpus/literal/range.txt new file mode 100644 index 00000000000000..8d22fd530e4397 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/range.txt @@ -0,0 +1,49 @@ +@ 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)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (1,1)-(1,2)) + │ │ │ └── flags: decimal + │ │ ├── right: ∅ + │ │ ├── operator_loc: (1,2)-(1,4) = ".." + │ │ └── flags: ∅ + │ ├── opening_loc: (1,0)-(1,1) = "(" + │ └── closing_loc: (1,4)-(1,5) = ")" + ├── @ RangeNode (location: (2,0)-(2,4)) + │ ├── left: + │ │ @ IntegerNode (location: (2,0)-(2,1)) + │ │ └── flags: decimal + │ ├── right: + │ │ @ IntegerNode (location: (2,3)-(2,4)) + │ │ └── flags: decimal + │ ├── operator_loc: (2,1)-(2,3) = ".." + │ └── flags: ∅ + ├── @ ParenthesesNode (location: (3,0)-(3,6)) + │ ├── body: + │ │ @ StatementsNode (location: (3,1)-(3,5)) + │ │ └── body: (length: 1) + │ │ └── @ RangeNode (location: (3,1)-(3,5)) + │ │ ├── left: + │ │ │ @ IntegerNode (location: (3,1)-(3,2)) + │ │ │ └── flags: decimal + │ │ ├── right: ∅ + │ │ ├── operator_loc: (3,2)-(3,5) = "..." + │ │ └── flags: exclude_end + │ ├── opening_loc: (3,0)-(3,1) = "(" + │ └── closing_loc: (3,5)-(3,6) = ")" + └── @ RangeNode (location: (4,0)-(4,5)) + ├── left: + │ @ IntegerNode (location: (4,0)-(4,1)) + │ └── flags: decimal + ├── right: + │ @ IntegerNode (location: (4,4)-(4,5)) + │ └── flags: decimal + ├── operator_loc: (4,1)-(4,4) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/unparser/corpus/literal/rescue.txt b/test/prism/snapshots/unparser/corpus/literal/rescue.txt new file mode 100644 index 00000000000000..0472a94534a68a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/rescue.txt @@ -0,0 +1,99 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── keyword_loc: (1,4)-(1,10) = "rescue" + │ └── rescue_expression: + │ @ CallNode (location: (1,11)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ RescueModifierNode (location: (2,0)-(2,21)) + │ ├── expression: + │ │ @ CallNode (location: (2,0)-(2,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,0)-(2,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (2,18)-(2,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,18)-(2,21) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── @ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,5)-(3,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,23)-(3,26)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,23)-(3,26) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── opening_loc: (3,4)-(3,5) = "(" + │ └── closing_loc: (3,26)-(3,27) = ")" + └── operator_loc: (3,2)-(3,3) = "=" diff --git a/test/prism/snapshots/unparser/corpus/literal/send.txt b/test/prism/snapshots/unparser/corpus/literal/send.txt new file mode 100644 index 00000000000000..d2ec4b582f75dd --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/send.txt @@ -0,0 +1,2117 @@ +@ 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)) + │ │ │ │ ├── targets: (length: 2) + │ │ │ │ │ ├── @ LocalVariableTargetNode (location: (2,12)-(2,13)) + │ │ │ │ │ │ ├── name: :a + │ │ │ │ │ │ └── depth: 0 + │ │ │ │ │ └── @ LocalVariableTargetNode (location: (2,15)-(2,16)) + │ │ │ │ │ ├── name: :_ + │ │ │ │ │ └── depth: 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (2,20)-(2,21) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (7,2)-(7,7)) + │ │ │ ├── name: :local + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: (7,7)-(7,8) = "." + │ │ ├── message_loc: (7,8)-(7,11) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── end_keyword_loc: (8,0)-(8,3) = "end" + │ └── name: :A + ├── @ CallNode (location: (9,0)-(10,7)) + │ ├── 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) = "." + │ ├── message_loc: (10,4)-(10,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (11,0)-(12,7)) + │ ├── 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) = "." + │ ├── message_loc: (12,4)-(12,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (13,0)-(15,7)) + │ ├── 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) = "." + │ ├── message_loc: (15,4)-(15,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (16,0)-(19,7)) + │ ├── receiver: + │ │ @ CaseNode (location: (16,0)-(19,3)) + │ │ ├── predicate: + │ │ │ @ ParenthesesNode (location: (16,5)-(17,10)) + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (16,6)-(17,9)) + │ │ │ │ └── body: (length: 2) + │ │ │ │ ├── @ DefNode (location: (16,6)-(17,3)) + │ │ │ │ │ ├── name: :foo + │ │ │ │ │ ├── name_loc: (16,10)-(16,13) = "foo" + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── def_keyword_loc: (16,6)-(16,9) = "def" + │ │ │ │ │ ├── operator_loc: ∅ + │ │ │ │ │ ├── lparen_loc: ∅ + │ │ │ │ │ ├── rparen_loc: ∅ + │ │ │ │ │ ├── equal_loc: ∅ + │ │ │ │ │ └── end_keyword_loc: (17,0)-(17,3) = "end" + │ │ │ │ └── @ SymbolNode (location: (17,5)-(17,9)) + │ │ │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,5)-(18,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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) = "." + │ ├── message_loc: (19,4)-(19,7) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "baz" + ├── @ CallNode (location: (20,0)-(22,7)) + │ ├── receiver: + │ │ @ CaseNode (location: (20,0)-(22,3)) + │ │ ├── predicate: + │ │ │ @ CallNode (location: (20,5)-(20,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (20,5)-(20,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (21,5)-(21,8) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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) = "." + │ ├── message_loc: (22,4)-(22,7) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "baz" + ├── @ CallNode (location: (23,0)-(24,7)) + │ ├── 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) = "." + │ ├── message_loc: (24,4)-(24,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (25,0)-(26,7)) + │ ├── receiver: + │ │ @ DefNode (location: (25,0)-(26,3)) + │ │ ├── name: :foo + │ │ ├── name_loc: (25,9)-(25,12) = "foo" + │ │ ├── receiver: + │ │ │ @ SelfNode (location: (25,4)-(25,8)) + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── locals: [] + │ │ ├── def_keyword_loc: (25,0)-(25,3) = "def" + │ │ ├── operator_loc: (25,8)-(25,9) = "." + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (26,0)-(26,3) = "end" + │ ├── call_operator_loc: (26,3)-(26,4) = "." + │ ├── message_loc: (26,4)-(26,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (27,0)-(28,7)) + │ ├── receiver: + │ │ @ DefNode (location: (27,0)-(28,3)) + │ │ ├── name: :foo + │ │ ├── name_loc: (27,4)-(27,7) = "foo" + │ │ ├── receiver: ∅ + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── locals: [] + │ │ ├── def_keyword_loc: (27,0)-(27,3) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (28,0)-(28,3) = "end" + │ ├── call_operator_loc: (28,3)-(28,4) = "." + │ ├── message_loc: (28,4)-(28,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (29,0)-(30,7)) + │ ├── receiver: + │ │ @ UntilNode (location: (29,0)-(30,3)) + │ │ ├── keyword_loc: (29,0)-(29,5) = "until" + │ │ ├── closing_loc: (30,0)-(30,3) = "end" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (29,6)-(29,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,6)-(29,9) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── statements: ∅ + │ │ └── flags: ∅ + │ ├── call_operator_loc: (30,3)-(30,4) = "." + │ ├── message_loc: (30,4)-(30,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (31,0)-(32,7)) + │ ├── receiver: + │ │ @ WhileNode (location: (31,0)-(32,3)) + │ │ ├── keyword_loc: (31,0)-(31,5) = "while" + │ │ ├── closing_loc: (32,0)-(32,3) = "end" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (31,6)-(31,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (31,6)-(31,9) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── statements: ∅ + │ │ └── flags: ∅ + │ ├── call_operator_loc: (32,3)-(32,4) = "." + │ ├── message_loc: (32,4)-(32,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (33,0)-(34,5)) + │ ├── receiver: + │ │ @ CallNode (location: (33,0)-(34,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (33,0)-(33,4) = "loop" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (33,5)-(34,1)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (33,5)-(33,6) = "{" + │ │ │ └── closing_loc: (34,0)-(34,1) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "loop" + │ ├── call_operator_loc: (34,1)-(34,2) = "." + │ ├── message_loc: (34,2)-(34,5) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (35,0)-(36,7)) + │ ├── receiver: + │ │ @ IfNode (location: (35,0)-(36,3)) + │ │ ├── if_keyword_loc: (35,0)-(35,2) = "if" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (35,3)-(35,6)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (35,3)-(35,6) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── statements: ∅ + │ │ ├── consequent: ∅ + │ │ └── end_keyword_loc: (36,0)-(36,3) = "end" + │ ├── call_operator_loc: (36,3)-(36,4) = "." + │ ├── message_loc: (36,4)-(36,7) = "baz" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "baz" + ├── @ CallNode (location: (37,0)-(37,19)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (37,0)-(37,15)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (37,1)-(37,14)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (37,1)-(37,14)) + │ │ │ ├── receiver: + │ │ │ │ @ RegularExpressionNode (location: (37,1)-(37,6)) + │ │ │ │ ├── opening_loc: (37,1)-(37,2) = "/" + │ │ │ │ ├── content_loc: (37,2)-(37,5) = "bar" + │ │ │ │ ├── closing_loc: (37,5)-(37,6) = "/" + │ │ │ │ ├── unescaped: "bar" + │ │ │ │ └── flags: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,7)-(37,9) = "=~" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (37,10)-(37,14)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (37,10)-(37,14)) + │ │ │ │ ├── opening_loc: (37,10)-(37,11) = ":" + │ │ │ │ ├── value_loc: (37,11)-(37,14) = "foo" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "foo" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "=~" + │ │ ├── opening_loc: (37,0)-(37,1) = "(" + │ │ └── closing_loc: (37,14)-(37,15) = ")" + │ ├── call_operator_loc: (37,15)-(37,16) = "." + │ ├── message_loc: (37,16)-(37,19) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (38,0)-(38,10)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (38,0)-(38,6)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (38,1)-(38,5)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ RangeNode (location: (38,1)-(38,5)) + │ │ │ ├── left: + │ │ │ │ @ IntegerNode (location: (38,1)-(38,2)) + │ │ │ │ └── flags: decimal + │ │ │ ├── right: + │ │ │ │ @ IntegerNode (location: (38,4)-(38,5)) + │ │ │ │ └── flags: decimal + │ │ │ ├── operator_loc: (38,2)-(38,4) = ".." + │ │ │ └── flags: ∅ + │ │ ├── opening_loc: (38,0)-(38,1) = "(" + │ │ └── closing_loc: (38,5)-(38,6) = ")" + │ ├── call_operator_loc: (38,6)-(38,7) = "." + │ ├── message_loc: (38,7)-(38,10) = "max" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "max" + ├── @ CallNode (location: (39,0)-(39,18)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (39,0)-(39,14)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (39,1)-(39,13)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (39,1)-(39,13)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (39,1)-(39,4)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (39,1)-(39,4) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (39,5)-(39,7) = "=~" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (39,8)-(39,13)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ RegularExpressionNode (location: (39,8)-(39,13)) + │ │ │ │ ├── opening_loc: (39,8)-(39,9) = "/" + │ │ │ │ ├── content_loc: (39,9)-(39,12) = "bar" + │ │ │ │ ├── closing_loc: (39,12)-(39,13) = "/" + │ │ │ │ ├── unescaped: "bar" + │ │ │ │ └── flags: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "=~" + │ │ ├── opening_loc: (39,0)-(39,1) = "(" + │ │ └── closing_loc: (39,13)-(39,14) = ")" + │ ├── call_operator_loc: (39,14)-(39,15) = "." + │ ├── message_loc: (39,15)-(39,18) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (40,0)-(40,13)) + │ ├── receiver: + │ │ @ RegularExpressionNode (location: (40,0)-(40,5)) + │ │ ├── opening_loc: (40,0)-(40,1) = "/" + │ │ ├── content_loc: (40,1)-(40,4) = "bar" + │ │ ├── closing_loc: (40,4)-(40,5) = "/" + │ │ ├── unescaped: "bar" + │ │ └── flags: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (40,6)-(40,8) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (40,9)-(40,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (40,9)-(40,13)) + │ │ ├── opening_loc: (40,9)-(40,10) = ":" + │ │ ├── value_loc: (40,10)-(40,13) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ CallNode (location: (41,0)-(41,12)) + │ ├── receiver: + │ │ @ RegularExpressionNode (location: (41,0)-(41,5)) + │ │ ├── opening_loc: (41,0)-(41,1) = "/" + │ │ ├── content_loc: (41,1)-(41,4) = "bar" + │ │ ├── closing_loc: (41,4)-(41,5) = "/" + │ │ ├── unescaped: "bar" + │ │ └── flags: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,6)-(41,8) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (41,9)-(41,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (41,9)-(41,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (41,9)-(41,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ RangeNode (location: (42,0)-(42,8)) + │ ├── left: + │ │ @ IntegerNode (location: (42,0)-(42,1)) + │ │ └── flags: decimal + │ ├── right: + │ │ @ CallNode (location: (42,3)-(42,8)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (42,3)-(42,4)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: (42,4)-(42,5) = "." + │ │ ├── message_loc: (42,5)-(42,8) = "max" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "max" + │ ├── operator_loc: (42,1)-(42,3) = ".." + │ └── flags: ∅ + ├── @ CallNode (location: (43,0)-(43,5)) + │ ├── receiver: + │ │ @ ConstantReadNode (location: (43,0)-(43,1)) + │ │ └── name: :A + │ ├── call_operator_loc: (43,1)-(43,2) = "." + │ ├── message_loc: (43,2)-(43,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (44,0)-(44,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (44,0)-(44,3) = "FOO" + │ ├── opening_loc: (44,3)-(44,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (44,4)-(44,5) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "FOO" + ├── @ CallNode (location: (45,0)-(45,4)) + │ ├── receiver: + │ │ @ CallNode (location: (45,0)-(45,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (45,0)-(45,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (45,1)-(45,3) = "&." + │ ├── message_loc: (45,3)-(45,4) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "b" + ├── @ CallNode (location: (46,0)-(46,5)) + │ ├── receiver: + │ │ @ CallNode (location: (46,0)-(46,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (46,0)-(46,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (46,1)-(46,2) = "." + │ ├── message_loc: (46,2)-(46,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (47,0)-(47,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (47,0)-(47,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── @ CallNode (location: (48,0)-(48,18)) + │ ├── receiver: + │ │ @ CallNode (location: (48,0)-(48,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (48,0)-(48,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (48,4)-(48,6) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (48,7)-(48,18)) + │ │ └── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (48,8)-(48,11)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (48,8)-(48,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (48,12)-(48,13) = "*" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (48,14)-(48,17)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (48,14)-(48,17)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (48,14)-(48,17) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "*" + │ │ ├── opening_loc: (48,7)-(48,8) = "(" + │ │ └── closing_loc: (48,17)-(48,18) = ")" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ CallNode (location: (49,0)-(49,12)) + │ ├── receiver: + │ │ @ CallNode (location: (49,0)-(49,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (49,0)-(49,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (49,4)-(49,6) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (49,7)-(49,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ RegularExpressionNode (location: (49,7)-(49,12)) + │ │ ├── opening_loc: (49,7)-(49,8) = "/" + │ │ ├── content_loc: (49,8)-(49,11) = "bar" + │ │ ├── closing_loc: (49,11)-(49,12) = "/" + │ │ ├── unescaped: "bar" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ CallNode (location: (50,0)-(50,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (50,6)-(50,9) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ ├── right: + │ │ │ │ │ @ CallNode (location: (50,13)-(50,16)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (50,13)-(50,16) = "bar" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "bar" + │ │ │ │ └── operator_loc: (50,10)-(50,12) = "||" + │ │ │ ├── opening_loc: (50,5)-(50,6) = "(" + │ │ │ └── closing_loc: (50,16)-(50,17) = ")" + │ │ └── operator_loc: (50,4)-(50,5) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (51,0)-(51,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (51,5)-(51,10) = "block" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "block" + │ │ └── operator_loc: (51,4)-(51,5) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (52,0)-(52,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (52,0)-(52,3) = "foo" + │ ├── opening_loc: (52,3)-(52,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (52,4)-(52,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (52,4)-(52,9)) + │ │ ├── operator_loc: (52,4)-(52,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (52,5)-(52,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (52,5)-(52,9) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (52,17)-(52,18) = ")" + │ ├── block: + │ │ @ BlockArgumentNode (location: (52,11)-(52,17)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (52,12)-(52,17)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (52,12)-(52,17) = "block" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "block" + │ │ └── operator_loc: (52,11)-(52,12) = "&" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (53,0)-(53,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (53,0)-(53,3) = "foo" + │ ├── opening_loc: (53,3)-(53,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (53,4)-(53,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (53,4)-(53,14)) + │ │ ├── operator_loc: (53,4)-(53,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (53,5)-(53,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (53,5)-(53,14) = "arguments" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "arguments" + │ ├── closing_loc: (53,14)-(53,15) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (54,0)-(54,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (54,0)-(54,3) = "foo" + │ ├── opening_loc: (54,3)-(54,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (54,4)-(54,8)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (55,0)-(55,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (55,0)-(55,3) = "foo" + │ ├── opening_loc: (55,3)-(55,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (55,4)-(55,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (55,4)-(55,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (55,4)-(55,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (55,7)-(55,8) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (56,0)-(56,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (56,0)-(56,3) = "foo" + │ ├── opening_loc: (56,3)-(56,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (56,4)-(56,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (56,4)-(56,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (56,4)-(56,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ SplatNode (location: (56,9)-(56,14)) + │ │ ├── operator_loc: (56,9)-(56,10) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (56,10)-(56,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (56,10)-(56,14) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (56,14)-(56,15) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (57,0)-(57,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (57,0)-(57,3) = "foo" + │ ├── opening_loc: (57,3)-(57,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (57,4)-(57,16)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (57,4)-(57,16)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (57,4)-(57,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (57,4)-(57,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (57,8)-(57,10) = "=~" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (57,11)-(57,16)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ RegularExpressionNode (location: (57,11)-(57,16)) + │ │ │ ├── opening_loc: (57,11)-(57,12) = "/" + │ │ │ ├── content_loc: (57,12)-(57,15) = "bar" + │ │ │ ├── closing_loc: (57,15)-(57,16) = "/" + │ │ │ ├── unescaped: "bar" + │ │ │ └── flags: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "=~" + │ ├── closing_loc: (57,16)-(57,17) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (58,0)-(58,12)) + │ ├── receiver: + │ │ @ CallNode (location: (58,0)-(58,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (58,0)-(58,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (58,3)-(58,4) = "." + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (58,9)-(58,12) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── operator_loc: (58,8)-(58,9) = "&" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (59,0)-(59,26)) + │ ├── receiver: + │ │ @ CallNode (location: (59,0)-(59,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (59,0)-(59,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (59,3)-(59,4) = "." + │ ├── message_loc: (59,4)-(59,7) = "bar" + │ ├── opening_loc: (59,7)-(59,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (59,8)-(59,25)) + │ │ └── arguments: (length: 3) + │ │ ├── @ SplatNode (location: (59,8)-(59,13)) + │ │ │ ├── operator_loc: (59,8)-(59,9) = "*" + │ │ │ └── expression: + │ │ │ @ CallNode (location: (59,9)-(59,13)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (59,9)-(59,13) = "arga" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "arga" + │ │ ├── @ CallNode (location: (59,15)-(59,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (59,15)-(59,18) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ SplatNode (location: (59,20)-(59,25)) + │ │ ├── operator_loc: (59,20)-(59,21) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (59,21)-(59,25)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (59,21)-(59,25) = "argb" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "argb" + │ ├── closing_loc: (59,25)-(59,26) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (60,0)-(60,14)) + │ ├── receiver: + │ │ @ CallNode (location: (60,0)-(60,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (60,0)-(60,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (60,3)-(60,4) = "." + │ ├── message_loc: (60,4)-(60,7) = "bar" + │ ├── opening_loc: (60,7)-(60,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (60,8)-(60,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (60,8)-(60,13)) + │ │ ├── operator_loc: (60,8)-(60,9) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (60,9)-(60,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (60,9)-(60,13) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (60,13)-(60,14) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (61,0)-(61,19)) + │ ├── receiver: + │ │ @ CallNode (location: (61,0)-(61,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (61,0)-(61,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (61,3)-(61,4) = "." + │ ├── message_loc: (61,4)-(61,7) = "bar" + │ ├── opening_loc: (61,7)-(61,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (61,8)-(61,18)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SplatNode (location: (61,8)-(61,13)) + │ │ │ ├── operator_loc: (61,8)-(61,9) = "*" + │ │ │ └── expression: + │ │ │ @ CallNode (location: (61,9)-(61,13)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (61,9)-(61,13) = "args" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "args" + │ │ └── @ CallNode (location: (61,15)-(61,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (61,15)-(61,18) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: (61,18)-(61,19) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (62,0)-(62,18)) + │ ├── receiver: + │ │ @ CallNode (location: (62,0)-(62,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (62,0)-(62,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (62,3)-(62,4) = "." + │ ├── message_loc: (62,4)-(62,7) = "bar" + │ ├── opening_loc: (62,7)-(62,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (62,8)-(62,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (62,8)-(62,12)) + │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (62,15)-(62,18) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── operator_loc: (62,14)-(62,15) = "&" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (63,0)-(63,17)) + │ ├── receiver: + │ │ @ CallNode (location: (63,0)-(63,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (63,0)-(63,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (63,3)-(63,4) = "." + │ ├── message_loc: (63,4)-(63,7) = "bar" + │ ├── opening_loc: (63,7)-(63,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (63,8)-(63,16)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (63,8)-(63,16)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (63,8)-(63,16)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (63,8)-(63,12)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (63,8)-(63,11) = "baz" + │ │ │ ├── closing_loc: (63,11)-(63,12) = ":" + │ │ │ └── unescaped: "baz" + │ │ ├── value: + │ │ │ @ CallNode (location: (63,13)-(63,16)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (63,13)-(63,16) = "boz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "boz" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: (63,16)-(63,17) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (64,0)-(64,26)) + │ ├── receiver: + │ │ @ CallNode (location: (64,0)-(64,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (64,0)-(64,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (64,3)-(64,4) = "." + │ ├── message_loc: (64,4)-(64,7) = "bar" + │ ├── opening_loc: (64,7)-(64,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (64,8)-(64,25)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (64,8)-(64,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (64,8)-(64,11) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ KeywordHashNode (location: (64,13)-(64,25)) + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (64,22)-(64,25) = "boz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "boz" + │ │ └── operator_loc: (64,19)-(64,21) = "=>" + │ ├── closing_loc: (64,25)-(64,26) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (65,0)-(65,19)) + │ ├── receiver: + │ │ @ CallNode (location: (65,0)-(65,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (65,0)-(65,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (65,3)-(65,4) = "." + │ ├── message_loc: (65,4)-(65,7) = "bar" + │ ├── opening_loc: (65,7)-(65,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (65,8)-(65,18)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (65,8)-(65,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (65,8)-(65,11) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ SplatNode (location: (65,13)-(65,18)) + │ │ ├── operator_loc: (65,13)-(65,14) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (65,14)-(65,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (65,14)-(65,18) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (65,18)-(65,19) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (66,0)-(66,26)) + │ ├── receiver: + │ │ @ CallNode (location: (66,0)-(66,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (66,0)-(66,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (66,3)-(66,4) = "." + │ ├── message_loc: (66,4)-(66,7) = "bar" + │ ├── opening_loc: (66,7)-(66,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (66,8)-(66,18)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (66,8)-(66,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (66,8)-(66,11) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ SplatNode (location: (66,13)-(66,18)) + │ │ ├── operator_loc: (66,13)-(66,14) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (66,14)-(66,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (66,14)-(66,18) = "args" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "args" + │ ├── closing_loc: (66,26)-(66,27) = ")" + │ ├── block: + │ │ @ BlockArgumentNode (location: (66,20)-(66,26)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (66,21)-(66,26)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (66,21)-(66,26) = "block" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "block" + │ │ └── operator_loc: (66,20)-(66,21) = "&" + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (67,0)-(67,16)) + │ ├── receiver: + │ │ @ CallNode (location: (67,0)-(67,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (67,0)-(67,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (67,3)-(67,4) = "." + │ ├── message_loc: (67,4)-(67,7) = "bar" + │ ├── opening_loc: (67,7)-(67,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (67,8)-(67,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (67,8)-(67,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (67,8)-(67,11) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (68,0)-(68,26)) + │ ├── receiver: + │ │ @ CallNode (location: (68,0)-(68,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (68,0)-(68,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (68,3)-(68,4) = "." + │ ├── message_loc: (68,4)-(68,7) = "bar" + │ ├── opening_loc: (68,7)-(68,8) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (68,8)-(68,25)) + │ │ └── 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)) + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (68,10)-(68,13) = "foo" + │ │ │ │ │ ├── closing_loc: (68,13)-(68,14) = ":" + │ │ │ │ │ └── unescaped: "foo" + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (68,15)-(68,18)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (68,15)-(68,18) = "boz" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "boz" + │ │ │ │ └── operator_loc: ∅ + │ │ │ └── closing_loc: (68,19)-(68,20) = "}" + │ │ └── @ CallNode (location: (68,22)-(68,25)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (68,22)-(68,25) = "boz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "boz" + │ ├── closing_loc: (68,25)-(68,26) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── @ CallNode (location: (69,0)-(69,12)) + │ ├── receiver: + │ │ @ CallNode (location: (69,0)-(69,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (69,0)-(69,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (69,3)-(69,4) = "." + │ ├── message_loc: (69,4)-(69,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (69,8)-(69,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (69,8)-(69,12)) + │ │ ├── opening_loc: (69,8)-(69,9) = ":" + │ │ ├── value_loc: (69,9)-(69,12) = "baz" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "baz" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar=" + ├── @ CallNode (location: (70,0)-(70,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (70,0)-(70,3) = "foo" + │ ├── opening_loc: (70,3)-(70,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (70,4)-(70,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (70,4)-(70,8)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (70,4)-(70,8)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (70,4)-(70,6)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (70,4)-(70,5) = "a" + │ │ │ ├── closing_loc: (70,5)-(70,6) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ CallNode (location: (70,7)-(70,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (70,7)-(70,8) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: (70,8)-(70,9) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (71,0)-(71,11)) + │ ├── receiver: + │ │ @ CallNode (location: (71,0)-(71,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (71,0)-(71,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (71,3)-(71,4) = "." + │ ├── message_loc: (71,4)-(71,5) = "&" + │ ├── opening_loc: (71,5)-(71,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (71,6)-(71,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (71,6)-(71,10)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (71,6)-(71,10)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (71,6)-(71,8)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (71,6)-(71,7) = "a" + │ │ │ ├── closing_loc: (71,7)-(71,8) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: + │ │ │ @ CallNode (location: (71,9)-(71,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (71,9)-(71,10) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ └── operator_loc: ∅ + │ ├── closing_loc: (71,10)-(71,11) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "&" + ├── @ CallNode (location: (72,0)-(72,10)) + │ ├── receiver: + │ │ @ CallNode (location: (72,0)-(72,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (72,0)-(72,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (72,3)-(72,4) = "." + │ ├── message_loc: (72,4)-(72,5) = "&" + │ ├── opening_loc: (72,5)-(72,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (72,6)-(72,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (72,6)-(72,9)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (72,6)-(72,9)) + │ │ ├── value: + │ │ │ @ CallNode (location: (72,8)-(72,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (72,8)-(72,9) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── operator_loc: (72,6)-(72,8) = "**" + │ ├── closing_loc: (72,9)-(72,10) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "&" + ├── @ CallNode (location: (73,0)-(73,9)) + │ ├── receiver: + │ │ @ CallNode (location: (73,0)-(73,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (73,0)-(73,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (73,3)-(73,9) = "[*baz]" + │ ├── opening_loc: (73,3)-(73,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (73,4)-(73,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (73,4)-(73,8)) + │ │ ├── operator_loc: (73,4)-(73,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (73,5)-(73,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (73,5)-(73,8) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── closing_loc: (73,8)-(73,9) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (74,0)-(74,9)) + │ ├── receiver: + │ │ @ CallNode (location: (74,0)-(74,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (74,0)-(74,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (74,3)-(74,9) = "[1, 2]" + │ ├── opening_loc: (74,3)-(74,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (74,4)-(74,8)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (75,0)-(75,5)) + │ ├── receiver: + │ │ @ CallNode (location: (75,0)-(75,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (75,0)-(75,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (75,3)-(75,5) = "[]" + │ ├── opening_loc: (75,3)-(75,4) = "[" + │ ├── arguments: ∅ + │ ├── closing_loc: (75,4)-(75,5) = "]" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ CallNode (location: (76,0)-(76,8)) + │ ├── receiver: + │ │ @ SelfNode (location: (76,0)-(76,4)) + │ ├── call_operator_loc: (76,4)-(76,5) = "." + │ ├── message_loc: (76,5)-(76,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (77,0)-(77,13)) + │ ├── receiver: + │ │ @ SelfNode (location: (77,0)-(77,4)) + │ ├── call_operator_loc: (77,4)-(77,5) = "." + │ ├── message_loc: (77,5)-(77,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (77,9)-(77,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (77,9)-(77,13)) + │ │ ├── opening_loc: (77,9)-(77,10) = ":" + │ │ ├── value_loc: (77,10)-(77,13) = "bar" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo=" + ├── @ CallNode (location: (78,0)-(78,17)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (78,0)-(78,7)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (78,1)-(78,6)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (78,1)-(78,6)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (78,1)-(78,2)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (78,1)-(78,2) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (78,3)-(78,4) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (78,5)-(78,6)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (78,5)-(78,6)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (78,5)-(78,6) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── opening_loc: (78,0)-(78,1) = "(" + │ │ └── closing_loc: (78,6)-(78,7) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (78,8)-(78,9) = "/" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (78,10)-(78,17)) + │ │ └── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (78,11)-(78,12)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (78,11)-(78,12) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "c" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (78,13)-(78,14) = "-" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (78,15)-(78,16)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (78,15)-(78,16)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (78,15)-(78,16) = "d" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "d" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "-" + │ │ ├── opening_loc: (78,10)-(78,11) = "(" + │ │ └── closing_loc: (78,16)-(78,17) = ")" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "/" + ├── @ CallNode (location: (79,0)-(79,19)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (79,0)-(79,7)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (79,1)-(79,6)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (79,1)-(79,6)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (79,1)-(79,2)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (79,1)-(79,2) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (79,3)-(79,4) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (79,5)-(79,6)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (79,5)-(79,6)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (79,5)-(79,6) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── opening_loc: (79,0)-(79,1) = "(" + │ │ └── closing_loc: (79,6)-(79,7) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (79,8)-(79,9) = "/" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (79,10)-(79,19)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (79,10)-(79,19)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (79,10)-(79,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (79,10)-(79,11) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── call_operator_loc: (79,11)-(79,12) = "." + │ │ ├── message_loc: (79,12)-(79,13) = "-" + │ │ ├── opening_loc: (79,13)-(79,14) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (79,14)-(79,18)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ CallNode (location: (79,14)-(79,15)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (79,14)-(79,15) = "e" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "e" + │ │ │ └── @ CallNode (location: (79,17)-(79,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (79,17)-(79,18) = "f" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "f" + │ │ ├── closing_loc: (79,18)-(79,19) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "-" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "/" + ├── @ CallNode (location: (80,0)-(80,17)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (80,0)-(80,7)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (80,1)-(80,6)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (80,1)-(80,6)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (80,1)-(80,2)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (80,1)-(80,2) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (80,3)-(80,4) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (80,5)-(80,6)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (80,5)-(80,6)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (80,5)-(80,6) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── opening_loc: (80,0)-(80,1) = "(" + │ │ └── closing_loc: (80,6)-(80,7) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (80,8)-(80,9) = "/" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (80,10)-(80,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (80,10)-(80,17)) + │ │ ├── receiver: + │ │ │ @ CallNode (location: (80,10)-(80,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (80,10)-(80,11) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── call_operator_loc: (80,11)-(80,12) = "." + │ │ ├── message_loc: (80,12)-(80,13) = "-" + │ │ ├── opening_loc: (80,13)-(80,14) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (80,14)-(80,16)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ SplatNode (location: (80,14)-(80,16)) + │ │ │ ├── operator_loc: (80,14)-(80,15) = "*" + │ │ │ └── expression: + │ │ │ @ CallNode (location: (80,15)-(80,16)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (80,15)-(80,16) = "f" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "f" + │ │ ├── closing_loc: (80,16)-(80,17) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "-" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "/" + ├── @ CallNode (location: (81,0)-(81,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (81,0)-(81,1) = "x" + │ ├── opening_loc: (81,1)-(81,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (81,2)-(81,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (81,2)-(81,7)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (81,2)-(81,7)) + │ │ ├── value: + │ │ │ @ CallNode (location: (81,4)-(81,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (81,4)-(81,7) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── operator_loc: (81,2)-(81,4) = "**" + │ ├── closing_loc: (81,7)-(81,8) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "x" + ├── @ CallNode (location: (82,0)-(82,6)) + │ ├── receiver: + │ │ @ CallNode (location: (82,0)-(82,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (82,0)-(82,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (82,3)-(82,5) = "&." + │ ├── message_loc: (82,5)-(82,6) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "!" + ├── @ CallNode (location: (83,0)-(83,8)) + │ ├── receiver: + │ │ @ CallNode (location: (83,0)-(83,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (83,0)-(83,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (83,3)-(83,4) = "." + │ ├── message_loc: (83,4)-(83,5) = "~" + │ ├── opening_loc: (83,5)-(83,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (83,6)-(83,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (83,6)-(83,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (83,6)-(83,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: (83,7)-(83,8) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "~" + └── @ CallNode (location: (84,0)-(84,7)) + ├── receiver: + │ @ CallNode (location: (84,0)-(84,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (84,0)-(84,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (84,1)-(84,3) = "&." + ├── message_loc: (84,3)-(84,4) = "+" + ├── opening_loc: (84,4)-(84,5) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (84,5)-(84,6)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (84,5)-(84,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (84,5)-(84,6) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── closing_loc: (84,6)-(84,7) = ")" + ├── block: ∅ + ├── flags: safe_navigation + └── name: "+" diff --git a/test/prism/snapshots/unparser/corpus/literal/since/27.txt b/test/prism/snapshots/unparser/corpus/literal/since/27.txt new file mode 100644 index 00000000000000..f9277521a3cb54 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/since/27.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(4,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,5)) + └── body: (length: 2) + ├── @ LambdaNode (location: (1,0)-(3,1)) + │ ├── locals: [:_1, :_2] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,3)-(1,4) = "{" + │ ├── closing_loc: (3,0)-(3,1) = "}" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (2,2)-(2,9)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (2,2)-(2,9)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (2,2)-(2,4)) + │ │ ├── name: :_1 + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,5)-(2,6) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (2,7)-(2,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (2,7)-(2,9)) + │ │ ├── name: :_2 + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + └── @ ParenthesesNode (location: (4,0)-(4,5)) + ├── body: + │ @ StatementsNode (location: (4,1)-(4,4)) + │ └── body: (length: 1) + │ └── @ RangeNode (location: (4,1)-(4,4)) + │ ├── left: ∅ + │ ├── right: + │ │ @ IntegerNode (location: (4,3)-(4,4)) + │ │ └── flags: decimal + │ ├── operator_loc: (4,1)-(4,3) = ".." + │ └── flags: ∅ + ├── opening_loc: (4,0)-(4,1) = "(" + └── closing_loc: (4,4)-(4,5) = ")" diff --git a/test/prism/snapshots/unparser/corpus/literal/since/30.txt b/test/prism/snapshots/unparser/corpus/literal/since/30.txt new file mode 100644 index 00000000000000..f595ebb7804c40 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/since/30.txt @@ -0,0 +1,83 @@ +@ 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 new file mode 100644 index 00000000000000..d66a2017c2541a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/since/31.txt @@ -0,0 +1,87 @@ +@ 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: nil + │ │ ├── name_loc: ∅ + │ │ └── operator_loc: (1,8)-(1,9) = "&" + │ ├── body: + │ │ @ StatementsNode (location: (2,2)-(2,7)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (2,2)-(2,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── 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) = "&" + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:&] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ ├── rparen_loc: (1,9)-(1,10) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + └── @ DefNode (location: (5,0)-(7,3)) + ├── name: :foo + ├── name_loc: (5,4)-(5,7) = "foo" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (5,8)-(5,12)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (5,8)-(5,9)) + │ │ └── name: :a + │ ├── optionals: (length: 0) + │ ├── rest: ∅ + │ ├── posts: (length: 0) + │ ├── keywords: (length: 0) + │ ├── keyword_rest: ∅ + │ └── block: + │ @ BlockParameterNode (location: (5,11)-(5,12)) + │ ├── name: nil + │ ├── name_loc: ∅ + │ └── operator_loc: (5,11)-(5,12) = "&" + ├── body: + │ @ StatementsNode (location: (6,2)-(6,7)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (6,2)-(6,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── 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) = "&" + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:a, :&] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (5,7)-(5,8) = "(" + ├── rparen_loc: (5,12)-(5,13) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (7,0)-(7,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/since/32.txt b/test/prism/snapshots/unparser/corpus/literal/since/32.txt new file mode 100644 index 00000000000000..aa8c15e0fb2c09 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/since/32.txt @@ -0,0 +1,101 @@ +@ 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: nil + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,5) = "bar" + │ │ ├── opening_loc: (2,5)-(2,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (2,6)-(2,18)) + │ │ │ └── arguments: (length: 2) + │ │ │ ├── @ LocalVariableReadNode (location: (2,6)-(2,14)) + │ │ │ │ ├── name: :argument + │ │ │ │ └── depth: 0 + │ │ │ └── @ KeywordHashNode (location: (2,16)-(2,18)) + │ │ │ └── elements: (length: 1) + │ │ │ └── @ AssocSplatNode (location: (2,16)-(2,18)) + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: (2,16)-(2,18) = "**" + │ │ ├── closing_loc: (2,18)-(2,19) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:argument, :**] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ ├── rparen_loc: (1,20)-(1,21) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + └── @ DefNode (location: (5,0)-(7,3)) + ├── name: :foo + ├── name_loc: (5,4)-(5,7) = "foo" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (5,8)-(5,19)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (5,8)-(5,16)) + │ │ └── name: :argument + │ ├── optionals: (length: 0) + │ ├── rest: + │ │ @ RestParameterNode (location: (5,18)-(5,19)) + │ │ ├── name: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,2)-(6,5) = "bar" + │ ├── opening_loc: (6,5)-(6,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (6,6)-(6,17)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:argument, :*] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (5,7)-(5,8) = "(" + ├── rparen_loc: (5,19)-(5,20) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (7,0)-(7,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/literal/singletons.txt b/test/prism/snapshots/unparser/corpus/literal/singletons.txt new file mode 100644 index 00000000000000..45c06f7b07d1bb --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/singletons.txt @@ -0,0 +1,9 @@ +@ ProgramNode (location: (1,0)-(4,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,4)) + └── body: (length: 4) + ├── @ FalseNode (location: (1,0)-(1,5)) + ├── @ NilNode (location: (2,0)-(2,3)) + ├── @ SelfNode (location: (3,0)-(3,4)) + └── @ TrueNode (location: (4,0)-(4,4)) diff --git a/test/prism/snapshots/unparser/corpus/literal/super.txt b/test/prism/snapshots/unparser/corpus/literal/super.txt new file mode 100644 index 00000000000000..7a6c241d6f3e4a --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/super.txt @@ -0,0 +1,271 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,6)-(3,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,6)-(3,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── 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)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (4,6)-(4,7)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (4,6)-(4,7) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ └── @ CallNode (location: (4,9)-(4,10)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (4,9)-(4,10) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── rparen_loc: (4,10)-(4,11) = ")" + │ └── block: ∅ + ├── @ SuperNode (location: (5,0)-(5,12)) + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,7)-(5,12) = "block" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "block" + │ └── operator_loc: (5,6)-(5,7) = "&" + ├── @ SuperNode (location: (6,0)-(6,15)) + │ ├── keyword_loc: (6,0)-(6,5) = "super" + │ ├── lparen_loc: (6,5)-(6,6) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (6,6)-(6,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (6,6)-(6,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,6)-(6,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── rparen_loc: (6,15)-(6,16) = ")" + │ └── block: + │ @ BlockArgumentNode (location: (6,9)-(6,15)) + │ ├── expression: + │ │ @ CallNode (location: (6,10)-(6,15)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,10)-(6,15) = "block" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (7,6)-(9,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,6)-(7,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (7,8)-(9,1)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (8,2)-(8,5)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (8,2)-(8,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,2)-(8,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── opening_loc: (7,8)-(7,9) = "{" + │ │ │ └── closing_loc: (9,0)-(9,1) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "a" + │ ├── rparen_loc: (9,1)-(9,2) = ")" + │ └── block: ∅ + ├── @ ForwardingSuperNode (location: (10,0)-(12,1)) + │ └── block: + │ @ BlockNode (location: (10,6)-(12,1)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (11,2)-(11,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (11,2)-(11,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,2)-(11,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (13,6)-(13,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,6)-(13,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── rparen_loc: (13,7)-(13,8) = ")" + │ └── block: + │ @ BlockNode (location: (13,9)-(15,1)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (14,2)-(14,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (14,2)-(14,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (14,2)-(14,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: (13,9)-(13,10) = "{" + │ └── closing_loc: (15,0)-(15,1) = "}" + ├── @ SuperNode (location: (16,0)-(18,1)) + │ ├── keyword_loc: (16,0)-(16,5) = "super" + │ ├── lparen_loc: (16,5)-(16,6) = "(" + │ ├── arguments: ∅ + │ ├── rparen_loc: (16,6)-(16,7) = ")" + │ └── block: + │ @ BlockNode (location: (16,8)-(18,1)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (17,2)-(17,5)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (17,2)-(17,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,2)-(17,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (19,6)-(19,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,6)-(19,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ └── @ CallNode (location: (19,9)-(19,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,9)-(19,10) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + ├── rparen_loc: (19,10)-(19,11) = ")" + └── block: + @ BlockNode (location: (19,12)-(21,1)) + ├── locals: [] + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (20,2)-(20,5)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (20,2)-(20,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (20,2)-(20,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── opening_loc: (19,12)-(19,13) = "{" + └── closing_loc: (21,0)-(21,1) = "}" diff --git a/test/prism/snapshots/unparser/corpus/literal/unary.txt b/test/prism/snapshots/unparser/corpus/literal/unary.txt new file mode 100644 index 00000000000000..b8586036bf7442 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/unary.txt @@ -0,0 +1,245 @@ +@ ProgramNode (location: (1,0)-(8,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(8,9)) + └── body: (length: 8) + ├── @ CallNode (location: (1,0)-(1,2)) + │ ├── receiver: + │ │ @ IntegerNode (location: (1,1)-(1,2)) + │ │ └── flags: decimal + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (2,0)-(2,5)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (2,1)-(2,5)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (2,2)-(2,4)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (2,2)-(2,4)) + │ │ │ ├── receiver: + │ │ │ │ @ IntegerNode (location: (2,3)-(2,4)) + │ │ │ │ └── flags: decimal + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,3) = "!" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "!" + │ │ ├── opening_loc: (2,1)-(2,2) = "(" + │ │ └── closing_loc: (2,4)-(2,5) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (2,0)-(2,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (3,0)-(3,16)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (3,1)-(3,16)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (3,2)-(3,15)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (3,2)-(3,15)) + │ │ │ ├── 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)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (3,4)-(3,7) = "foo" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "foo" + │ │ │ │ │ ├── right: + │ │ │ │ │ │ @ CallNode (location: (3,11)-(3,14)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (3,11)-(3,14) = "bar" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "bar" + │ │ │ │ │ └── operator_loc: (3,8)-(3,10) = "||" + │ │ │ │ ├── opening_loc: (3,3)-(3,4) = "(" + │ │ │ │ └── closing_loc: (3,14)-(3,15) = ")" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,2)-(3,3) = "!" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "!" + │ │ ├── opening_loc: (3,1)-(3,2) = "(" + │ │ └── closing_loc: (3,15)-(3,16) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (4,0)-(4,9)) + │ ├── receiver: + │ │ @ CallNode (location: (4,1)-(4,9)) + │ │ ├── receiver: + │ │ │ @ ParenthesesNode (location: (4,1)-(4,5)) + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (4,2)-(4,4)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (4,2)-(4,4)) + │ │ │ │ ├── receiver: + │ │ │ │ │ @ IntegerNode (location: (4,3)-(4,4)) + │ │ │ │ │ └── flags: decimal + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,2)-(4,3) = "!" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "!" + │ │ │ ├── opening_loc: (4,1)-(4,2) = "(" + │ │ │ └── closing_loc: (4,4)-(4,5) = ")" + │ │ ├── call_operator_loc: (4,5)-(4,6) = "." + │ │ ├── message_loc: (4,6)-(4,9) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "baz" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,0)-(4,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (5,0)-(5,2)) + │ ├── receiver: + │ │ @ CallNode (location: (5,1)-(5,2)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,1)-(5,2) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "~" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "~" + ├── @ CallNode (location: (6,0)-(6,2)) + │ ├── receiver: + │ │ @ CallNode (location: (6,1)-(6,2)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,1)-(6,2) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,0)-(6,1) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-@" + ├── @ CallNode (location: (7,0)-(7,2)) + │ ├── receiver: + │ │ @ CallNode (location: (7,1)-(7,2)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,1)-(7,2) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,1) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+@" + └── @ CallNode (location: (8,0)-(8,9)) + ├── receiver: + │ @ CallNode (location: (8,1)-(8,9)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (8,1)-(8,5)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (8,2)-(8,4)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (8,2)-(8,4)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (8,3)-(8,4)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (8,3)-(8,4) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (8,2)-(8,3) = "-" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "-@" + │ │ ├── opening_loc: (8,1)-(8,2) = "(" + │ │ └── closing_loc: (8,4)-(8,5) = ")" + │ ├── call_operator_loc: (8,5)-(8,6) = "." + │ ├── message_loc: (8,6)-(8,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (8,0)-(8,1) = "-" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "-@" diff --git a/test/prism/snapshots/unparser/corpus/literal/undef.txt b/test/prism/snapshots/unparser/corpus/literal/undef.txt new file mode 100644 index 00000000000000..f89eb11fe577dc --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/undef.txt @@ -0,0 +1,26 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── opening_loc: (2,6)-(2,7) = ":" + │ │ ├── value_loc: (2,7)-(2,10) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ └── @ SymbolNode (location: (2,12)-(2,16)) + │ ├── opening_loc: (2,12)-(2,13) = ":" + │ ├── value_loc: (2,13)-(2,16) = "bar" + │ ├── closing_loc: ∅ + │ └── unescaped: "bar" + └── keyword_loc: (2,0)-(2,5) = "undef" diff --git a/test/prism/snapshots/unparser/corpus/literal/variables.txt b/test/prism/snapshots/unparser/corpus/literal/variables.txt new file mode 100644 index 00000000000000..94b6f067dc544b --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/variables.txt @@ -0,0 +1,52 @@ +@ ProgramNode (location: (1,0)-(10,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(10,17)) + └── body: (length: 10) + ├── @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── @ 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)) + ├── @ ConstantReadNode (location: (7,0)-(7,5)) + │ └── name: :CONST + ├── @ ConstantPathNode (location: (8,0)-(8,13)) + │ ├── parent: + │ │ @ ConstantReadNode (location: (8,0)-(8,6)) + │ │ └── name: :SCOPED + │ ├── child: + │ │ @ ConstantReadNode (location: (8,8)-(8,13)) + │ │ └── name: :CONST + │ └── delimiter_loc: (8,6)-(8,8) = "::" + ├── @ ConstantPathNode (location: (9,0)-(9,10)) + │ ├── parent: ∅ + │ ├── child: + │ │ @ ConstantReadNode (location: (9,2)-(9,10)) + │ │ └── name: :TOPLEVEL + │ └── delimiter_loc: (9,0)-(9,2) = "::" + └── @ ConstantPathNode (location: (10,0)-(10,17)) + ├── parent: + │ @ ConstantPathNode (location: (10,0)-(10,10)) + │ ├── parent: ∅ + │ ├── child: + │ │ @ ConstantReadNode (location: (10,2)-(10,10)) + │ │ └── name: :TOPLEVEL + │ └── delimiter_loc: (10,0)-(10,2) = "::" + ├── child: + │ @ ConstantReadNode (location: (10,12)-(10,17)) + │ └── name: :CONST + └── delimiter_loc: (10,10)-(10,12) = "::" diff --git a/test/prism/snapshots/unparser/corpus/literal/while.txt b/test/prism/snapshots/unparser/corpus/literal/while.txt new file mode 100644 index 00000000000000..aa47d33766c0ea --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/while.txt @@ -0,0 +1,696 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,2)-(2,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (2,6)-(6,3)) + │ │ │ ├── locals: [:bar, :foo] + │ │ │ ├── parameters: + │ │ │ │ @ BlockParametersNode (location: (2,8)-(2,13)) + │ │ │ │ ├── parameters: + │ │ │ │ │ @ ParametersNode (location: (2,9)-(2,12)) + │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (2,9)-(2,12)) + │ │ │ │ │ │ └── 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)) + │ │ │ │ ├── keyword_loc: (3,4)-(3,9) = "while" + │ │ │ │ ├── closing_loc: (5,4)-(5,7) = "end" + │ │ │ │ ├── predicate: + │ │ │ │ │ @ CallNode (location: (3,10)-(3,13)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (3,10)-(3,13) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ ├── 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) = "=" + │ │ │ │ └── flags: ∅ + │ │ │ ├── opening_loc: (2,6)-(2,7) = "{" + │ │ │ └── closing_loc: (6,2)-(6,3) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── keyword_loc: (10,12)-(10,17) = "while" + │ │ ├── closing_loc: ∅ + │ │ ├── predicate: + │ │ │ @ CallNode (location: (10,18)-(10,28)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (10,18)-(10,21)) + │ │ │ │ ├── name: :foo + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (10,22)-(10,24) = "!=" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (10,25)-(10,28)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (10,25)-(10,28)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (10,25)-(10,28) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "!=" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (10,8)-(10,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── operator_loc: (10,6)-(10,7) = "=" + │ │ └── flags: ∅ + │ ├── locals: [:foo] + │ ├── def_keyword_loc: (9,0)-(9,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (11,0)-(11,3) = "end" + ├── @ ModuleNode (location: (13,0)-(15,3)) + │ ├── locals: [:foo] + │ ├── module_keyword_loc: (13,0)-(13,6) = "module" + │ ├── constant_path: + │ │ @ ConstantReadNode (location: (13,7)-(13,8)) + │ │ └── name: :A + │ ├── body: + │ │ @ StatementsNode (location: (14,2)-(14,21)) + │ │ └── body: (length: 1) + │ │ └── @ WhileNode (location: (14,2)-(14,21)) + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (14,8)-(14,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── operator_loc: (14,6)-(14,7) = "=" + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (18,8)-(18,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── operator_loc: (18,6)-(18,7) = "=" + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── keyword_loc: (22,2)-(22,7) = "while" + │ │ ├── closing_loc: (24,2)-(24,5) = "end" + │ │ ├── predicate: + │ │ │ @ CallNode (location: (22,8)-(22,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (22,8)-(22,11) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (23,10)-(23,13) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── operator_loc: (23,8)-(23,9) = "=" + │ │ └── flags: ∅ + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (28,2)-(28,6) = "each" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (28,7)-(32,3)) + │ │ │ ├── locals: [:baz, :foo] + │ │ │ ├── parameters: + │ │ │ │ @ BlockParametersNode (location: (28,9)-(28,14)) + │ │ │ │ ├── parameters: + │ │ │ │ │ @ ParametersNode (location: (28,10)-(28,13)) + │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (28,10)-(28,13)) + │ │ │ │ │ │ └── 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)) + │ │ │ │ ├── keyword_loc: (29,4)-(29,9) = "while" + │ │ │ │ ├── closing_loc: (31,4)-(31,7) = "end" + │ │ │ │ ├── predicate: + │ │ │ │ │ @ CallNode (location: (29,10)-(29,13)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (29,10)-(29,13) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ ├── 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)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (30,12)-(30,15) = "bar" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "bar" + │ │ │ │ │ └── operator_loc: (30,10)-(30,11) = "=" + │ │ │ │ └── flags: ∅ + │ │ │ ├── opening_loc: (28,7)-(28,8) = "{" + │ │ │ └── closing_loc: (32,2)-(32,3) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "each" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (36,2)-(36,6) = "each" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (36,7)-(40,3)) + │ │ │ ├── locals: [:foo] + │ │ │ ├── parameters: + │ │ │ │ @ BlockParametersNode (location: (36,9)-(36,14)) + │ │ │ │ ├── parameters: + │ │ │ │ │ @ ParametersNode (location: (36,10)-(36,13)) + │ │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (36,10)-(36,13)) + │ │ │ │ │ │ └── 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)) + │ │ │ │ ├── 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)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (38,12)-(38,15) = "bar" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "bar" + │ │ │ │ │ └── operator_loc: (38,10)-(38,11) = "=" + │ │ │ │ └── flags: ∅ + │ │ │ ├── opening_loc: (36,7)-(36,8) = "{" + │ │ │ └── closing_loc: (40,2)-(40,3) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "each" + │ ├── 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)) + │ │ │ ├── keyword_loc: (44,4)-(44,9) = "while" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── predicate: + │ │ │ │ @ CallNode (location: (44,10)-(44,13)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (44,10)-(44,13) = "baz" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "baz" + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (43,2)-(43,5) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ ├── rescue_clause: ∅ + │ │ │ │ ├── else_clause: ∅ + │ │ │ │ ├── ensure_clause: ∅ + │ │ │ │ └── end_keyword_loc: (44,0)-(44,3) = "end" + │ │ │ └── flags: begin_modifier + │ │ ├── opening_loc: (42,4)-(42,5) = "(" + │ │ └── closing_loc: (44,13)-(44,14) = ")" + │ └── operator_loc: (42,2)-(42,3) = "=" + ├── @ WhileNode (location: (45,0)-(47,13)) + │ ├── keyword_loc: (47,4)-(47,9) = "while" + │ ├── closing_loc: ∅ + │ ├── predicate: + │ │ @ CallNode (location: (47,10)-(47,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (47,10)-(47,13) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (46,2)-(46,5) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── rescue_clause: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (47,0)-(47,3) = "end" + │ └── flags: begin_modifier + ├── @ UntilNode (location: (48,0)-(51,13)) + │ ├── keyword_loc: (51,4)-(51,9) = "until" + │ ├── closing_loc: ∅ + │ ├── predicate: + │ │ @ CallNode (location: (51,10)-(51,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (51,10)-(51,13) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (49,2)-(49,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ └── @ CallNode (location: (50,2)-(50,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (50,2)-(50,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── rescue_clause: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (51,0)-(51,3) = "end" + │ └── flags: begin_modifier + ├── @ WhileNode (location: (52,0)-(55,13)) + │ ├── keyword_loc: (55,4)-(55,9) = "while" + │ ├── closing_loc: ∅ + │ ├── predicate: + │ │ @ CallNode (location: (55,10)-(55,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (55,10)-(55,13) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (53,2)-(53,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ └── @ CallNode (location: (54,2)-(54,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (54,2)-(54,5) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── rescue_clause: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_keyword_loc: (55,0)-(55,3) = "end" + │ └── flags: begin_modifier + ├── @ WhileNode (location: (56,0)-(57,3)) + │ ├── keyword_loc: (56,0)-(56,5) = "while" + │ ├── closing_loc: (57,0)-(57,3) = "end" + │ ├── predicate: + │ │ @ FalseNode (location: (56,6)-(56,11)) + │ ├── statements: ∅ + │ └── flags: ∅ + ├── @ WhileNode (location: (58,0)-(60,3)) + │ ├── 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 + │ └── flags: ∅ + ├── @ WhileNode (location: (61,0)-(64,3)) + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (61,7)-(61,10) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (61,11)-(62,1)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (61,11)-(61,12) = "{" + │ │ │ │ └── closing_loc: (62,0)-(62,1) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ ├── opening_loc: (63,2)-(63,3) = ":" + │ │ ├── value_loc: (63,3)-(63,7) = "body" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "body" + │ └── flags: ∅ + ├── @ UntilNode (location: (65,0)-(66,3)) + │ ├── keyword_loc: (65,0)-(65,5) = "until" + │ ├── closing_loc: (66,0)-(66,3) = "end" + │ ├── predicate: + │ │ @ FalseNode (location: (65,6)-(65,11)) + │ ├── statements: ∅ + │ └── flags: ∅ + ├── @ UntilNode (location: (67,0)-(69,3)) + │ ├── 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 + │ └── flags: ∅ + └── @ UntilNode (location: (70,0)-(73,3)) + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (70,7)-(70,10) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (70,11)-(71,1)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (70,11)-(70,12) = "{" + │ │ │ └── closing_loc: (71,0)-(71,1) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "foo" + │ ├── 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)) + │ ├── opening_loc: (72,2)-(72,3) = ":" + │ ├── value_loc: (72,3)-(72,7) = "body" + │ ├── closing_loc: ∅ + │ └── unescaped: "body" + └── flags: ∅ diff --git a/test/prism/snapshots/unparser/corpus/literal/yield.txt b/test/prism/snapshots/unparser/corpus/literal/yield.txt new file mode 100644 index 00000000000000..fc9bc27cc1994c --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/literal/yield.txt @@ -0,0 +1,54 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (2,6)-(2,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (2,6)-(2,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ └── 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)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (3,6)-(3,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,6)-(3,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ └── @ CallNode (location: (3,9)-(3,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,9)-(3,10) = "b" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "b" + └── rparen_loc: (3,10)-(3,11) = ")" diff --git a/test/prism/snapshots/unparser/corpus/semantic/and.txt b/test/prism/snapshots/unparser/corpus/semantic/and.txt new file mode 100644 index 00000000000000..b4136ecdace9e4 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/semantic/and.txt @@ -0,0 +1,233 @@ +@ 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)) + │ │ ├── left: + │ │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── right: + │ │ │ @ CallNode (location: (1,4)-(1,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,4)-(1,5) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── operator_loc: (1,1)-(1,4) = "..." + │ │ └── flags: exclude_end + │ ├── right: + │ │ @ RangeNode (location: (1,9)-(1,14)) + │ │ ├── left: + │ │ │ @ CallNode (location: (1,9)-(1,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,9)-(1,10) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── right: + │ │ │ @ CallNode (location: (1,13)-(1,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,13)-(1,14) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── operator_loc: (1,10)-(1,13) = "..." + │ │ └── flags: exclude_end + │ └── operator_loc: (1,6)-(1,8) = "or" + ├── @ AndNode (location: (2,0)-(2,15)) + │ ├── left: + │ │ @ RangeNode (location: (2,0)-(2,5)) + │ │ ├── left: + │ │ │ @ CallNode (location: (2,0)-(2,1)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,0)-(2,1) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── right: + │ │ │ @ CallNode (location: (2,4)-(2,5)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,4)-(2,5) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── operator_loc: (2,1)-(2,4) = "..." + │ │ └── flags: exclude_end + │ ├── right: + │ │ @ RangeNode (location: (2,10)-(2,15)) + │ │ ├── left: + │ │ │ @ CallNode (location: (2,10)-(2,11)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,10)-(2,11) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── right: + │ │ │ @ CallNode (location: (2,14)-(2,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,14)-(2,15) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── operator_loc: (2,11)-(2,14) = "..." + │ │ └── flags: exclude_end + │ └── 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)) + │ │ │ ├── left: + │ │ │ │ @ CallNode (location: (4,3)-(4,4)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,3)-(4,4) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (4,7)-(4,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,7)-(4,8) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── operator_loc: (4,4)-(4,7) = "..." + │ │ │ └── flags: exclude_end + │ │ ├── right: + │ │ │ @ FlipFlopNode (location: (4,12)-(4,17)) + │ │ │ ├── left: + │ │ │ │ @ CallNode (location: (4,12)-(4,13)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,12)-(4,13) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "c" + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (4,16)-(4,17)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (4,16)-(4,17) = "d" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "d" + │ │ │ ├── operator_loc: (4,13)-(4,16) = "..." + │ │ │ └── flags: exclude_end + │ │ └── operator_loc: (4,9)-(4,11) = "or" + │ ├── 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)) + │ │ ├── left: + │ │ │ @ CallNode (location: (7,3)-(7,4)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,3)-(7,4) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── right: + │ │ │ @ CallNode (location: (7,7)-(7,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,7)-(7,8) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "b" + │ │ ├── operator_loc: (7,4)-(7,7) = "..." + │ │ └── flags: exclude_end + │ ├── right: + │ │ @ FlipFlopNode (location: (7,13)-(7,18)) + │ │ ├── left: + │ │ │ @ CallNode (location: (7,13)-(7,14)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,13)-(7,14) = "c" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "c" + │ │ ├── right: + │ │ │ @ CallNode (location: (7,17)-(7,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,17)-(7,18) = "d" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "d" + │ │ ├── operator_loc: (7,14)-(7,17) = "..." + │ │ └── flags: exclude_end + │ └── operator_loc: (7,9)-(7,12) = "and" + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (8,0)-(8,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/semantic/block.txt b/test/prism/snapshots/unparser/corpus/semantic/block.txt new file mode 100644 index 00000000000000..741a810c4bc721 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/semantic/block.txt @@ -0,0 +1,187 @@ +@ ProgramNode (location: (1,0)-(26,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(26,3)) + └── body: (length: 6) + ├── @ CallNode (location: (1,0)-(2,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,4)-(2,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,4)-(1,6) = "do" + │ │ └── closing_loc: (2,0)-(2,3) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (4,0)-(6,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (4,0)-(4,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (4,4)-(6,3)) + │ │ ├── locals: [] + │ │ ├── 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" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (8,0)-(11,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (8,0)-(8,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (8,4)-(11,3)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (9,2)-(10,5)) + │ │ │ └── body: (length: 2) + │ │ │ ├── @ RescueModifierNode (location: (9,2)-(9,16)) + │ │ │ │ ├── expression: + │ │ │ │ │ @ NilNode (location: (9,2)-(9,5)) + │ │ │ │ ├── keyword_loc: (9,6)-(9,12) = "rescue" + │ │ │ │ └── rescue_expression: + │ │ │ │ @ NilNode (location: (9,13)-(9,16)) + │ │ │ └── @ NilNode (location: (10,2)-(10,5)) + │ │ ├── opening_loc: (8,4)-(8,6) = "do" + │ │ └── closing_loc: (11,0)-(11,3) = "end" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (13,0)-(14,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,4)-(14,3)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (13,7)-(13,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (13,8)-(13,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (13,8)-(13,9)) + │ │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (16,0)-(20,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (16,0)-(16,3) = "foo" + │ ├── opening_loc: (16,3)-(16,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (16,4)-(16,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (16,4)-(16,10)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (16,4)-(16,10) = "<<-DOC" + │ │ ├── content_loc: (17,0)-(17,0) = " b\n" + │ │ ├── closing_loc: (18,0)-(18,0) = "DOC\n" + │ │ └── unescaped: " b\n" + │ ├── closing_loc: (16,10)-(16,11) = ")" + │ ├── block: + │ │ @ BlockNode (location: (16,12)-(20,3)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (16,15)-(16,18)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (16,16)-(16,17)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (16,16)-(16,17)) + │ │ │ │ │ └── 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" + │ ├── flags: ∅ + │ └── name: "foo" + └── @ CallNode (location: (22,0)-(26,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (22,0)-(22,3) = "foo" + ├── opening_loc: (22,3)-(22,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (22,4)-(22,10)) + │ └── arguments: (length: 1) + │ └── @ StringNode (location: (22,4)-(22,10)) + │ ├── flags: ∅ + │ ├── opening_loc: (22,4)-(22,10) = "<<-DOC" + │ ├── content_loc: (23,0)-(23,0) = " b\n" + │ ├── closing_loc: (24,0)-(24,0) = "DOC\n" + │ └── unescaped: " b\n" + ├── closing_loc: (22,10)-(22,11) = ")" + ├── block: + │ @ BlockNode (location: (22,12)-(26,3)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (25,2)-(25,3)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (25,2)-(25,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,2)-(25,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── opening_loc: (22,12)-(22,14) = "do" + │ └── closing_loc: (26,0)-(26,3) = "end" + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/unparser/corpus/semantic/def.txt b/test/prism/snapshots/unparser/corpus/semantic/def.txt new file mode 100644 index 00000000000000..0f9242b53a3cc7 --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/semantic/def.txt @@ -0,0 +1,89 @@ +@ 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)) + │ │ │ ├── receiver: + │ │ │ │ @ CallNode (location: (2,3)-(2,4)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (2,3)-(2,4) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "a" + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,5)-(2,6) = "-" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (2,7)-(2,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (2,7)-(2,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (2,7)-(2,8) = "b" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "b" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "-" + │ │ ├── opening_loc: (2,2)-(2,3) = "(" + │ │ └── closing_loc: (2,8)-(2,9) = ")" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + └── @ DefNode (location: (5,0)-(7,3)) + ├── name: :foo + ├── name_loc: (5,4)-(5,7) = "foo" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (6,2)-(6,20)) + │ └── body: (length: 1) + │ └── @ RescueModifierNode (location: (6,2)-(6,20)) + │ ├── expression: + │ │ @ CallNode (location: (6,2)-(6,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,2)-(6,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── keyword_loc: (6,4)-(6,10) = "rescue" + │ └── rescue_expression: + │ @ ConstantReadNode (location: (6,11)-(6,20)) + │ └── name: :Exception + ├── locals: [] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (7,0)-(7,3) = "end" diff --git a/test/prism/snapshots/unparser/corpus/semantic/dstr.txt b/test/prism/snapshots/unparser/corpus/semantic/dstr.txt new file mode 100644 index 00000000000000..126886f3e0c88f --- /dev/null +++ b/test/prism/snapshots/unparser/corpus/semantic/dstr.txt @@ -0,0 +1,547 @@ +@ 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) = "< 1]" + │ ├── opening_loc: (7,4)-(7,5) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,5)-(7,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (7,5)-(7,14)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (7,5)-(7,14)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (7,5)-(7,9)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (9,6)-(9,16)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (9,6)-(9,16)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (9,6)-(9,10)) + │ │ │ ├── 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)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (11,6)-(11,16)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (11,6)-(11,16)) + │ ├── key: + │ │ @ SymbolNode (location: (11,6)-(11,10)) + │ │ ├── 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 new file mode 100644 index 00000000000000..238ba6ff28b0ea --- /dev/null +++ b/test/prism/snapshots/whitequark/args_assocs_comma.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,15) = "[:baz => 1,]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,13)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,4)-(1,13)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,4)-(1,13)) + │ ├── key: + │ │ @ SymbolNode (location: (1,4)-(1,8)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/whitequark/args_assocs_legacy.txt b/test/prism/snapshots/whitequark/args_assocs_legacy.txt new file mode 100644 index 00000000000000..518b76076400f7 --- /dev/null +++ b/test/prism/snapshots/whitequark/args_assocs_legacy.txt @@ -0,0 +1,171 @@ +@ ProgramNode (location: (1,0)-(11,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(11,17)) + └── body: (length: 6) + ├── @ CallNode (location: (1,0)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "fun" + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,4)-(1,13)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,4)-(1,13)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,4)-(1,8)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "fun" + │ ├── opening_loc: (3,3)-(3,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,4)-(3,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (3,4)-(3,13)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (3,4)-(3,13)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (3,4)-(3,8)) + │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,16)-(3,19) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── operator_loc: (3,15)-(3,16) = "&" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (5,0)-(5,21)) + │ ├── receiver: + │ │ @ SelfNode (location: (5,0)-(5,4)) + │ ├── call_operator_loc: (5,4)-(5,5) = "." + │ ├── message_loc: (5,5)-(5,8) = "[]=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,9)-(5,21)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (5,9)-(5,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,9)-(5,12) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ KeywordHashNode (location: (5,14)-(5,21)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (5,14)-(5,21)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (5,14)-(5,16)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]=" + ├── @ CallNode (location: (7,0)-(7,15)) + │ ├── receiver: + │ │ @ SelfNode (location: (7,0)-(7,4)) + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,4)-(7,15) = "[:bar => 1]" + │ ├── opening_loc: (7,4)-(7,5) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,5)-(7,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (7,5)-(7,14)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (7,5)-(7,14)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (7,5)-(7,9)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "[]" + ├── @ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (9,6)-(9,16)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (9,6)-(9,16)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (9,6)-(9,10)) + │ │ │ ├── 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)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (11,6)-(11,16)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (11,6)-(11,16)) + │ ├── key: + │ │ @ SymbolNode (location: (11,6)-(11,10)) + │ │ ├── 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 new file mode 100644 index 00000000000000..2cc3008c2e2299 --- /dev/null +++ b/test/prism/snapshots/whitequark/args_block_pass.txt @@ -0,0 +1,28 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,8) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── operator_loc: (1,4)-(1,5) = "&" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/args_cmd.txt b/test/prism/snapshots/whitequark/args_cmd.txt new file mode 100644 index 00000000000000..cd16a4d354ed42 --- /dev/null +++ b/test/prism/snapshots/whitequark/args_cmd.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,10)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: (1,3)-(1,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,9)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,4)-(1,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,6)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "f" + ├── closing_loc: (1,9)-(1,10) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/args_star.txt b/test/prism/snapshots/whitequark/args_star.txt new file mode 100644 index 00000000000000..13b48ff6bb9e43 --- /dev/null +++ b/test/prism/snapshots/whitequark/args_star.txt @@ -0,0 +1,68 @@ +@ ProgramNode (location: (1,0)-(3,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,14)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "fun" + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (1,4)-(1,8)) + │ │ ├── operator_loc: (1,4)-(1,5) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (1,5)-(1,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,8) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (1,8)-(1,9) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + └── @ CallNode (location: (3,0)-(3,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,0)-(3,3) = "fun" + ├── opening_loc: (3,3)-(3,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (3,4)-(3,8)) + │ └── arguments: (length: 1) + │ └── @ SplatNode (location: (3,4)-(3,8)) + │ ├── operator_loc: (3,4)-(3,5) = "*" + │ └── expression: + │ @ CallNode (location: (3,5)-(3,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,5)-(3,8) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── closing_loc: (3,14)-(3,15) = ")" + ├── block: + │ @ BlockArgumentNode (location: (3,10)-(3,14)) + │ ├── expression: + │ │ @ CallNode (location: (3,11)-(3,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,11)-(3,14) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ └── operator_loc: (3,10)-(3,11) = "&" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/array_assocs.txt b/test/prism/snapshots/whitequark/array_assocs.txt new file mode 100644 index 00000000000000..4509ddde8b199a --- /dev/null +++ b/test/prism/snapshots/whitequark/array_assocs.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(3,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,13)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(1,10)) + │ ├── elements: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,2)-(1,8)) + │ │ └── 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)) + ├── elements: (length: 2) + │ ├── @ IntegerNode (location: (3,2)-(3,3)) + │ │ └── flags: decimal + │ └── @ KeywordHashNode (location: (3,5)-(3,11)) + │ └── 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 new file mode 100644 index 00000000000000..4bf2b19039d29c --- /dev/null +++ b/test/prism/snapshots/whitequark/array_plain.txt @@ -0,0 +1,13 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,6)) + ├── 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 new file mode 100644 index 00000000000000..c25c8719b6268b --- /dev/null +++ b/test/prism/snapshots/whitequark/array_splat.txt @@ -0,0 +1,62 @@ +@ ProgramNode (location: (1,0)-(5,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,9)) + └── body: (length: 3) + ├── @ ArrayNode (location: (1,0)-(1,6)) + │ ├── elements: (length: 1) + │ │ └── @ SplatNode (location: (1,1)-(1,5)) + │ │ ├── operator_loc: (1,1)-(1,2) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (1,2)-(1,5)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,5) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: (1,0)-(1,1) = "[" + │ └── closing_loc: (1,5)-(1,6) = "]" + ├── @ ArrayNode (location: (3,0)-(3,12)) + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,5)-(3,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ └── @ 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)) + ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,5)-(5,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── opening_loc: (5,0)-(5,1) = "[" + └── closing_loc: (5,8)-(5,9) = "]" diff --git a/test/prism/snapshots/whitequark/array_symbols.txt b/test/prism/snapshots/whitequark/array_symbols.txt new file mode 100644 index 00000000000000..cca5be139a5be9 --- /dev/null +++ b/test/prism/snapshots/whitequark/array_symbols.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,11)) + ├── elements: (length: 2) + │ ├── @ SymbolNode (location: (1,3)-(1,6)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,3)-(1,6) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ └── @ SymbolNode (location: (1,7)-(1,10)) + │ ├── opening_loc: ∅ + │ ├── value_loc: (1,7)-(1,10) = "bar" + │ ├── closing_loc: ∅ + │ └── unescaped: "bar" + ├── opening_loc: (1,0)-(1,3) = "%i[" + └── closing_loc: (1,10)-(1,11) = "]" diff --git a/test/prism/snapshots/whitequark/array_symbols_empty.txt b/test/prism/snapshots/whitequark/array_symbols_empty.txt new file mode 100644 index 00000000000000..3beafc362aed27 --- /dev/null +++ b/test/prism/snapshots/whitequark/array_symbols_empty.txt @@ -0,0 +1,13 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(1,4)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (1,0)-(1,3) = "%I(" + │ └── closing_loc: (1,3)-(1,4) = ")" + └── @ ArrayNode (location: (3,0)-(3,4)) + ├── elements: (length: 0) + ├── opening_loc: (3,0)-(3,3) = "%i[" + └── closing_loc: (3,3)-(3,4) = "]" diff --git a/test/prism/snapshots/whitequark/array_symbols_interp.txt b/test/prism/snapshots/whitequark/array_symbols_interp.txt new file mode 100644 index 00000000000000..de1a25f97ecd88 --- /dev/null +++ b/test/prism/snapshots/whitequark/array_symbols_interp.txt @@ -0,0 +1,64 @@ +@ ProgramNode (location: (1,0)-(3,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,13)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(1,14)) + │ ├── elements: (length: 2) + │ │ ├── @ SymbolNode (location: (1,3)-(1,6)) + │ │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,9)-(1,12) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,8)-(3,11) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── closing_loc: (3,11)-(3,12) = "}" + │ └── closing_loc: ∅ + ├── opening_loc: (3,0)-(3,3) = "%I[" + └── closing_loc: (3,12)-(3,13) = "]" diff --git a/test/prism/snapshots/whitequark/array_words.txt b/test/prism/snapshots/whitequark/array_words.txt new file mode 100644 index 00000000000000..4301158d054e81 --- /dev/null +++ b/test/prism/snapshots/whitequark/array_words.txt @@ -0,0 +1,21 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ ArrayNode (location: (1,0)-(1,11)) + ├── elements: (length: 2) + │ ├── @ StringNode (location: (1,3)-(1,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (1,3)-(1,6) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ └── @ StringNode (location: (1,7)-(1,10)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (1,7)-(1,10) = "bar" + │ ├── closing_loc: ∅ + │ └── unescaped: "bar" + ├── opening_loc: (1,0)-(1,3) = "%w[" + └── closing_loc: (1,10)-(1,11) = "]" diff --git a/test/prism/snapshots/whitequark/array_words_empty.txt b/test/prism/snapshots/whitequark/array_words_empty.txt new file mode 100644 index 00000000000000..dff4df566279b6 --- /dev/null +++ b/test/prism/snapshots/whitequark/array_words_empty.txt @@ -0,0 +1,13 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(1,4)) + │ ├── elements: (length: 0) + │ ├── opening_loc: (1,0)-(1,3) = "%W(" + │ └── closing_loc: (1,3)-(1,4) = ")" + └── @ ArrayNode (location: (3,0)-(3,4)) + ├── elements: (length: 0) + ├── opening_loc: (3,0)-(3,3) = "%w[" + └── closing_loc: (3,3)-(3,4) = "]" diff --git a/test/prism/snapshots/whitequark/array_words_interp.txt b/test/prism/snapshots/whitequark/array_words_interp.txt new file mode 100644 index 00000000000000..8645425e2581fe --- /dev/null +++ b/test/prism/snapshots/whitequark/array_words_interp.txt @@ -0,0 +1,76 @@ +@ ProgramNode (location: (1,0)-(3,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,22)) + └── body: (length: 2) + ├── @ ArrayNode (location: (1,0)-(1,14)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,9)-(1,12) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,9)-(3,12) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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 new file mode 100644 index 00000000000000..13268c70b10105 --- /dev/null +++ b/test/prism/snapshots/whitequark/asgn_cmd.txt @@ -0,0 +1,53 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,12)-(1,13) = "m" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,14)-(1,17)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (1,14)-(1,17)) + │ │ │ │ ├── name: :foo + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "m" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,6)-(3,7) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,8)-(3,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (3,8)-(3,11)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + └── operator_loc: (3,4)-(3,5) = "=" diff --git a/test/prism/snapshots/whitequark/asgn_mrhs.txt b/test/prism/snapshots/whitequark/asgn_mrhs.txt new file mode 100644 index 00000000000000..bb860152890a46 --- /dev/null +++ b/test/prism/snapshots/whitequark/asgn_mrhs.txt @@ -0,0 +1,83 @@ +@ 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)) + │ │ ├── elements: (length: 1) + │ │ │ └── @ SplatNode (location: (1,6)-(1,10)) + │ │ │ ├── operator_loc: (1,6)-(1,7) = "*" + │ │ │ └── expression: + │ │ │ @ CallNode (location: (1,7)-(1,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,7)-(1,10) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── 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)) + │ │ ├── elements: (length: 2) + │ │ │ ├── @ CallNode (location: (3,6)-(3,9)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,6)-(3,9) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── @ 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)) + │ ├── elements: (length: 2) + │ │ ├── @ CallNode (location: (5,6)-(5,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,6)-(5,9) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── @ SplatNode (location: (5,11)-(5,15)) + │ │ ├── operator_loc: (5,11)-(5,12) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (5,12)-(5,15)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,12)-(5,15) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + └── operator_loc: (5,4)-(5,5) = "=" diff --git a/test/prism/snapshots/whitequark/back_ref.txt b/test/prism/snapshots/whitequark/back_ref.txt new file mode 100644 index 00000000000000..eafd6f144aa054 --- /dev/null +++ b/test/prism/snapshots/whitequark/back_ref.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ BackReferenceReadNode (location: (1,0)-(1,2)) diff --git a/test/prism/snapshots/whitequark/bang.txt b/test/prism/snapshots/whitequark/bang.txt new file mode 100644 index 00000000000000..da83d817a5f652 --- /dev/null +++ b/test/prism/snapshots/whitequark/bang.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,4)) + ├── receiver: + │ @ CallNode (location: (1,1)-(1,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,1)-(1,4) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/whitequark/bang_cmd.txt b/test/prism/snapshots/whitequark/bang_cmd.txt new file mode 100644 index 00000000000000..27b0a1ebdf2673 --- /dev/null +++ b/test/prism/snapshots/whitequark/bang_cmd.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,6)) + ├── receiver: + │ @ CallNode (location: (1,1)-(1,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,1)-(1,2) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,3)-(1,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,3)-(1,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,3)-(1,6) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/whitequark/begin_cmdarg.txt b/test/prism/snapshots/whitequark/begin_cmdarg.txt new file mode 100644 index 00000000000000..833863958fcb50 --- /dev/null +++ b/test/prism/snapshots/whitequark/begin_cmdarg.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(1,28)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,28)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,28)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,28)) + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (1,8)-(1,9)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: (1,9)-(1,10) = "." + │ │ ├── message_loc: (1,10)-(1,15) = "times" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,16)-(1,24)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (1,19)-(1,20)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (1,19)-(1,20)) + │ │ │ │ └── flags: decimal + │ │ │ ├── opening_loc: (1,16)-(1,18) = "do" + │ │ │ └── closing_loc: (1,21)-(1,24) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "times" + │ ├── rescue_clause: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (1,25)-(1,28) = "end" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt b/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt new file mode 100644 index 00000000000000..0bea43c7f2627d --- /dev/null +++ b/test/prism/snapshots/whitequark/beginless_erange_after_newline.txt @@ -0,0 +1,22 @@ +@ ProgramNode (location: (1,0)-(2,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,6)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + └── @ RangeNode (location: (2,0)-(2,6)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (2,3)-(2,6)) + │ └── flags: decimal + ├── operator_loc: (2,0)-(2,3) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt b/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt new file mode 100644 index 00000000000000..ab2fa8064fd520 --- /dev/null +++ b/test/prism/snapshots/whitequark/beginless_irange_after_newline.txt @@ -0,0 +1,22 @@ +@ ProgramNode (location: (1,0)-(2,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,5)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + └── @ RangeNode (location: (2,0)-(2,5)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (2,2)-(2,5)) + │ └── flags: decimal + ├── operator_loc: (2,0)-(2,2) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/beginless_range.txt b/test/prism/snapshots/whitequark/beginless_range.txt new file mode 100644 index 00000000000000..7ec06309c49556 --- /dev/null +++ b/test/prism/snapshots/whitequark/beginless_range.txt @@ -0,0 +1,19 @@ +@ ProgramNode (location: (1,0)-(3,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,5)) + └── body: (length: 2) + ├── @ RangeNode (location: (1,0)-(1,6)) + │ ├── left: ∅ + │ ├── right: + │ │ @ IntegerNode (location: (1,3)-(1,6)) + │ │ └── flags: decimal + │ ├── operator_loc: (1,0)-(1,3) = "..." + │ └── flags: exclude_end + └── @ RangeNode (location: (3,0)-(3,5)) + ├── left: ∅ + ├── right: + │ @ IntegerNode (location: (3,2)-(3,5)) + │ └── flags: decimal + ├── operator_loc: (3,0)-(3,2) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/blockarg.txt b/test/prism/snapshots/whitequark/blockarg.txt new file mode 100644 index 00000000000000..ce1c33a0f0795e --- /dev/null +++ b/test/prism/snapshots/whitequark/blockarg.txt @@ -0,0 +1,30 @@ +@ 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,12)-(1,13) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,15)-(1,18) = "end" diff --git a/test/prism/snapshots/whitequark/blockargs.txt b/test/prism/snapshots/whitequark/blockargs.txt new file mode 100644 index 00000000000000..a9692cbaed773f --- /dev/null +++ b/test/prism/snapshots/whitequark/blockargs.txt @@ -0,0 +1,1260 @@ +@ ProgramNode (location: (1,0)-(71,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(71,7)) + └── body: (length: 35) + ├── @ CallNode (location: (1,0)-(1,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,1)-(1,5)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,1)-(1,2) = "{" + │ │ └── closing_loc: (1,4)-(1,5) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (3,0)-(3,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,1)-(3,8)) + │ │ ├── locals: [] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (3,3)-(3,6)) + │ │ │ ├── parameters: ∅ + │ │ │ ├── locals: (length: 0) + │ │ │ ├── opening_loc: (3,3)-(3,4) = "|" + │ │ │ └── closing_loc: (3,5)-(3,6) = "|" + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,1)-(3,2) = "{" + │ │ └── closing_loc: (3,7)-(3,8) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (5,0)-(5,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,1)-(5,9)) + │ │ ├── locals: [:b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (5,3)-(5,7)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (5,4)-(5,6)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 0) + │ │ │ │ ├── keyword_rest: ∅ + │ │ │ │ └── block: + │ │ │ │ @ BlockParameterNode (location: (5,4)-(5,6)) + │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (7,0)-(7,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (7,1)-(7,16)) + │ │ ├── locals: [:baz, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (7,3)-(7,14)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (7,4)-(7,13)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 0) + │ │ │ │ ├── keyword_rest: + │ │ │ │ │ @ KeywordRestParameterNode (location: (7,4)-(7,9)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (9,0)-(9,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,0)-(9,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (9,1)-(9,12)) + │ │ ├── locals: [:*, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (9,3)-(9,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (9,4)-(9,9)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (9,4)-(9,5)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (11,0)-(11,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (11,1)-(11,16)) + │ │ ├── locals: [:r, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (11,3)-(11,14)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (11,4)-(11,13)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (11,4)-(11,6)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (13,0)-(13,13)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,1)-(13,13)) + │ │ ├── locals: [:s, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (13,3)-(13,11)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (13,4)-(13,10)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (13,4)-(13,6)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (15,0)-(15,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (15,1)-(15,9)) + │ │ ├── locals: [:s] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (15,3)-(15,7)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (15,4)-(15,6)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (15,4)-(15,6)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (17,0)-(17,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (17,1)-(17,8)) + │ │ ├── locals: [:*] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (17,3)-(17,6)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (17,4)-(17,5)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (17,4)-(17,5)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (19,0)-(21,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,0)-(19,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (19,1)-(21,3)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (19,3)-(21,1)) + │ │ │ ├── parameters: ∅ + │ │ │ ├── locals: (length: 1) + │ │ │ │ └── @ BlockLocalVariableNode (location: (20,0)-(20,1)) + │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (23,0)-(23,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,0)-(23,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (23,1)-(23,9)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (23,3)-(23,7)) + │ │ │ ├── parameters: ∅ + │ │ │ ├── locals: (length: 1) + │ │ │ │ └── @ BlockLocalVariableNode (location: (23,5)-(23,6)) + │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (25,0)-(25,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,0)-(25,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (25,1)-(25,12)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (25,3)-(25,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (25,4)-(25,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (25,4)-(25,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (27,0)-(27,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,0)-(27,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (27,1)-(27,15)) + │ │ ├── locals: [:a, :*, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (27,3)-(27,13)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (27,4)-(27,12)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (27,4)-(27,5)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (27,7)-(27,8)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (29,0)-(29,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (29,0)-(29,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (29,1)-(29,19)) + │ │ ├── locals: [:a, :r, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (29,3)-(29,17)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (29,4)-(29,16)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (29,4)-(29,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (31,0)-(31,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,0)-(31,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (31,1)-(31,16)) + │ │ ├── locals: [:a, :s, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (31,3)-(31,14)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (31,4)-(31,13)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (31,4)-(31,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (33,0)-(33,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,0)-(33,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (33,1)-(33,12)) + │ │ ├── locals: [:a, :s] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (33,3)-(33,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (33,4)-(33,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (33,4)-(33,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (35,0)-(35,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (35,1)-(35,11)) + │ │ ├── locals: [:a, :*] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (35,3)-(35,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (35,4)-(35,8)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (35,4)-(35,5)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (35,7)-(35,8)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (37,0)-(37,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,0)-(37,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (37,1)-(37,12)) + │ │ ├── locals: [:a, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (37,3)-(37,10)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (37,4)-(37,9)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (37,4)-(37,5)) + │ │ │ │ │ │ └── name: :a + │ │ │ │ │ └── @ RequiredParameterNode (location: (37,7)-(37,8)) + │ │ │ │ │ └── name: :b + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (37,8)-(37,9)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── name_loc: ∅ + │ │ │ │ │ └── operator_loc: (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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (39,0)-(39,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (39,0)-(39,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (39,1)-(39,11)) + │ │ ├── locals: [:a, :c] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (39,3)-(39,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (39,4)-(39,8)) + │ │ │ │ ├── requireds: (length: 2) + │ │ │ │ │ ├── @ RequiredParameterNode (location: (39,4)-(39,5)) + │ │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (41,0)-(41,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,0)-(41,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (41,1)-(41,17)) + │ │ ├── locals: [:a, :o, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (41,3)-(41,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (41,4)-(41,14)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (41,4)-(41,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (43,0)-(43,24)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (43,0)-(43,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (43,1)-(43,24)) + │ │ ├── locals: [:a, :o, :r, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (43,3)-(43,22)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (43,4)-(43,21)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (43,4)-(43,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (45,0)-(45,27)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (45,0)-(45,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (45,1)-(45,27)) + │ │ ├── locals: [:a, :o, :o1, :r, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (45,3)-(45,25)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (45,4)-(45,24)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (45,4)-(45,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (47,0)-(47,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (47,0)-(47,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (47,1)-(47,20)) + │ │ ├── locals: [:a, :o, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (47,3)-(47,18)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (47,4)-(47,17)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (47,4)-(47,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (49,0)-(49,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (49,0)-(49,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (49,1)-(49,9)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (49,3)-(49,7)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (49,4)-(49,6)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (49,4)-(49,5)) + │ │ │ │ │ └── name: :a + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: + │ │ │ │ │ @ RestParameterNode (location: (49,5)-(49,6)) + │ │ │ │ │ ├── name: nil + │ │ │ │ │ ├── name_loc: ∅ + │ │ │ │ │ └── operator_loc: (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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (51,0)-(51,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (51,0)-(51,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (51,1)-(51,8)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (51,3)-(51,6)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (51,4)-(51,5)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (51,4)-(51,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (53,0)-(53,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (53,0)-(53,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (53,1)-(53,8)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (53,3)-(53,6)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (53,4)-(53,5)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (53,4)-(53,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (55,0)-(55,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (55,0)-(55,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (55,1)-(55,8)) + │ │ ├── locals: [:a] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (55,3)-(55,6)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (55,4)-(55,5)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (55,4)-(55,5)) + │ │ │ │ │ └── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (57,0)-(57,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (57,0)-(57,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (57,1)-(57,17)) + │ │ ├── locals: [:foo, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (57,3)-(57,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (57,4)-(57,14)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 1) + │ │ │ │ │ └── @ KeywordParameterNode (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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (59,0)-(59,32)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (59,0)-(59,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (59,1)-(59,32)) + │ │ ├── locals: [:foo, :bar, :baz, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (59,3)-(59,30)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (59,4)-(59,29)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 2) + │ │ │ │ │ ├── @ KeywordParameterNode (location: (59,4)-(59,10)) + │ │ │ │ │ │ ├── name: :foo + │ │ │ │ │ │ ├── name_loc: (59,4)-(59,8) = "foo:" + │ │ │ │ │ │ └── value: + │ │ │ │ │ │ @ IntegerNode (location: (59,9)-(59,10)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ └── @ KeywordParameterNode (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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (61,0)-(61,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (61,0)-(61,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (61,1)-(61,11)) + │ │ ├── locals: [:foo] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (61,3)-(61,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (61,4)-(61,8)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 1) + │ │ │ │ │ └── @ KeywordParameterNode (location: (61,4)-(61,8)) + │ │ │ │ │ ├── name: :foo + │ │ │ │ │ ├── name_loc: (61,4)-(61,8) = "foo:" + │ │ │ │ │ └── value: ∅ + │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (63,0)-(63,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (63,0)-(63,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (63,1)-(63,14)) + │ │ ├── locals: [:o, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (63,3)-(63,12)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (63,4)-(63,11)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (63,4)-(63,7)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (65,0)-(65,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (65,0)-(65,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (65,1)-(65,18)) + │ │ ├── locals: [:o, :r, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (65,3)-(65,16)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (65,4)-(65,15)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (65,4)-(65,7)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (67,0)-(67,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (67,0)-(67,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (67,1)-(67,21)) + │ │ ├── locals: [:o, :r, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (67,3)-(67,19)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (67,4)-(67,18)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (67,4)-(67,7)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + ├── @ CallNode (location: (69,0)-(69,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (69,0)-(69,1) = "f" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (69,1)-(69,17)) + │ │ ├── locals: [:o, :p, :b] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (69,3)-(69,15)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (69,4)-(69,14)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (69,4)-(69,7)) + │ │ │ │ │ ├── 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) = "}" + │ ├── flags: ∅ + │ └── name: "f" + └── @ CallNode (location: (71,0)-(71,7)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (71,0)-(71,1) = "f" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (71,1)-(71,7)) + │ ├── locals: [] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (71,3)-(71,5)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (71,3)-(71,4) = "|" + │ │ └── closing_loc: (71,4)-(71,5) = "|" + │ ├── body: ∅ + │ ├── opening_loc: (71,1)-(71,2) = "{" + │ └── closing_loc: (71,6)-(71,7) = "}" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/whitequark/break.txt b/test/prism/snapshots/whitequark/break.txt new file mode 100644 index 00000000000000..7f375d2d3fd19b --- /dev/null +++ b/test/prism/snapshots/whitequark/break.txt @@ -0,0 +1,53 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,6)-(3,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,6)-(3,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── keyword_loc: (3,0)-(3,5) = "break" + ├── @ BreakNode (location: (5,0)-(5,7)) + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,5)-(5,7)) + │ │ └── 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)) + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,6)-(7,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 new file mode 100644 index 00000000000000..58e972f226127b --- /dev/null +++ b/test/prism/snapshots/whitequark/break_block.txt @@ -0,0 +1,38 @@ +@ 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,6)-(1,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,6)-(1,9) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,10)-(1,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,10)-(1,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,10)-(1,13) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,14)-(1,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,14)-(1,16) = "do" + │ │ └── closing_loc: (1,17)-(1,20) = "end" + │ ├── flags: ∅ + │ └── name: "fun" + └── 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 new file mode 100644 index 00000000000000..fd7380e15daf55 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_435.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ InterpolatedStringNode (location: (1,0)-(1,14)) + ├── opening_loc: (1,0)-(1,1) = "\"" + ├── parts: (length: 1) + │ └── @ EmbeddedStatementsNode (location: (1,1)-(1,13)) + │ ├── opening_loc: (1,1)-(1,3) = "\#{" + │ ├── statements: + │ │ @ StatementsNode (location: (1,3)-(1,12)) + │ │ └── body: (length: 1) + │ │ └── @ LambdaNode (location: (1,3)-(1,12)) + │ │ ├── locals: [:foo] + │ │ ├── operator_loc: (1,3)-(1,5) = "->" + │ │ ├── opening_loc: (1,10)-(1,11) = "{" + │ │ ├── closing_loc: (1,11)-(1,12) = "}" + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (1,6)-(1,9)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (1,6)-(1,9)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (1,6)-(1,9)) + │ │ │ │ │ └── name: :foo + │ │ │ │ ├── optionals: (length: 0) + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── posts: (length: 0) + │ │ │ │ ├── keywords: (length: 0) + │ │ │ │ ├── keyword_rest: ∅ + │ │ │ │ └── block: ∅ + │ │ │ ├── locals: (length: 0) + │ │ │ ├── opening_loc: ∅ + │ │ │ └── closing_loc: ∅ + │ │ └── body: ∅ + │ └── closing_loc: (1,12)-(1,13) = "}" + └── closing_loc: (1,13)-(1,14) = "\"" diff --git a/test/prism/snapshots/whitequark/bug_447.txt b/test/prism/snapshots/whitequark/bug_447.txt new file mode 100644 index 00000000000000..40a6d81e4caaf7 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_447.txt @@ -0,0 +1,51 @@ +@ ProgramNode (location: (1,0)-(3,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,14)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,4)) + │ │ └── arguments: (length: 1) + │ │ └── @ ArrayNode (location: (1,2)-(1,4)) + │ │ ├── elements: (length: 0) + │ │ ├── opening_loc: (1,2)-(1,3) = "[" + │ │ └── closing_loc: (1,3)-(1,4) = "]" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,5)-(1,11)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,5)-(1,7) = "do" + │ │ └── closing_loc: (1,8)-(1,11) = "end" + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (3,0)-(3,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,0)-(3,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (3,2)-(3,7)) + │ └── arguments: (length: 2) + │ ├── @ ArrayNode (location: (3,2)-(3,4)) + │ │ ├── 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: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (3,8)-(3,10) = "do" + │ └── closing_loc: (3,11)-(3,14) = "end" + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/bug_452.txt b/test/prism/snapshots/whitequark/bug_452.txt new file mode 100644 index 00000000000000..e7ecdcb2c761d5 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_452.txt @@ -0,0 +1,61 @@ +@ ProgramNode (location: (1,0)-(1,37)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,37)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,2) = "td" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,3)-(1,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,3)-(1,21)) + │ │ ├── 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) = "." + │ │ ├── message_loc: (1,11)-(1,19) = "toString" + │ │ ├── opening_loc: (1,19)-(1,20) = "(" + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: (1,20)-(1,21) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "toString" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "td" + └── @ CallNode (location: (1,23)-(1,37)) + ├── receiver: + │ @ CallNode (location: (1,23)-(1,25)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,23)-(1,25) = "td" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "td" + ├── call_operator_loc: (1,25)-(1,26) = "." + ├── message_loc: (1,26)-(1,29) = "num" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,30)-(1,37)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,30)-(1,32) = "do" + │ └── closing_loc: (1,34)-(1,37) = "end" + ├── flags: ∅ + └── name: "num" diff --git a/test/prism/snapshots/whitequark/bug_466.txt b/test/prism/snapshots/whitequark/bug_466.txt new file mode 100644 index 00000000000000..f69841c32dd9af --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_466.txt @@ -0,0 +1,65 @@ +@ ProgramNode (location: (1,0)-(1,27)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,27)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,27)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "foo" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,19)) + │ └── 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)) + │ │ │ ├── receiver: + │ │ │ │ @ ParenthesesNode (location: (1,7)-(1,12)) + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (1,8)-(1,11)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,8)-(1,11)) + │ │ │ │ │ ├── receiver: + │ │ │ │ │ │ @ IntegerNode (location: (1,8)-(1,9)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,9)-(1,10) = "+" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ IntegerNode (location: (1,10)-(1,11)) + │ │ │ │ │ │ └── flags: decimal + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "+" + │ │ │ │ ├── opening_loc: (1,7)-(1,8) = "(" + │ │ │ │ └── closing_loc: (1,11)-(1,12) = ")" + │ │ │ ├── call_operator_loc: (1,12)-(1,13) = "." + │ │ │ ├── message_loc: (1,13)-(1,17) = "to_i" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "to_i" + │ │ └── closing_loc: (1,17)-(1,18) = "}" + │ └── closing_loc: (1,18)-(1,19) = "\"" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,20)-(1,27)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,20)-(1,22) = "do" + │ └── closing_loc: (1,24)-(1,27) = "end" + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/whitequark/bug_473.txt b/test/prism/snapshots/whitequark/bug_473.txt new file mode 100644 index 00000000000000..cfdeb9d2f3d217 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_473.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,9)) + │ └── 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)) + │ │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/bug_480.txt b/test/prism/snapshots/whitequark/bug_480.txt new file mode 100644 index 00000000000000..d7beb238e7702d --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_480.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,12)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/bug_481.txt b/test/prism/snapshots/whitequark/bug_481.txt new file mode 100644 index 00000000000000..7baad1034c6287 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_481.txt @@ -0,0 +1,48 @@ +@ ProgramNode (location: (1,0)-(1,28)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,28)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ DefNode (location: (1,2)-(1,14)) + │ │ ├── name: :x + │ │ ├── name_loc: (1,6)-(1,7) = "x" + │ │ ├── receiver: ∅ + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── locals: [] + │ │ ├── def_keyword_loc: (1,2)-(1,5) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ │ ├── rparen_loc: (1,8)-(1,9) = ")" + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (1,11)-(1,14) = "end" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (1,16)-(1,28)) + ├── receiver: + │ @ IntegerNode (location: (1,16)-(1,17)) + │ └── flags: decimal + ├── call_operator_loc: (1,17)-(1,18) = "." + ├── message_loc: (1,18)-(1,21) = "tap" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,22)-(1,28)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,22)-(1,24) = "do" + │ └── closing_loc: (1,25)-(1,28) = "end" + ├── flags: ∅ + └── name: "tap" diff --git a/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt b/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt new file mode 100644 index 00000000000000..65d733166a613c --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_ascii_8bit_in_literal.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (2,9)-(2,75)) +├── locals: [] +└── statements: + @ StatementsNode (location: (2,9)-(2,75)) + └── body: (length: 1) + └── @ StringNode (location: (2,9)-(2,75)) + ├── flags: ∅ + ├── opening_loc: (2,9)-(2,10) = "\"" + ├── content_loc: (2,10)-(2,74) = "\\xD0\\xBF\\xD1\\x80\\xD0\\xBE\\xD0\\xB2\\xD0\\xB5\\xD1\\x80\\xD0\\xBA\\xD0\\xB0" + ├── closing_loc: (2,74)-(2,75) = "\"" + └── unescaped: "проверка" diff --git a/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt b/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt new file mode 100644 index 00000000000000..6945f3e3018604 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_cmd_string_lookahead.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,4) = "desc" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,5)-(1,10)) + │ └── arguments: (length: 1) + │ └── @ StringNode (location: (1,5)-(1,10)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,5)-(1,6) = "\"" + │ ├── content_loc: (1,6)-(1,9) = "foo" + │ ├── closing_loc: (1,9)-(1,10) = "\"" + │ └── unescaped: "foo" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,11)-(1,17)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,11)-(1,13) = "do" + │ └── closing_loc: (1,14)-(1,17) = "end" + ├── flags: ∅ + └── name: "desc" diff --git a/test/prism/snapshots/whitequark/bug_cmdarg.txt b/test/prism/snapshots/whitequark/bug_cmdarg.txt new file mode 100644 index 00000000000000..d3968f4eabd7cb --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_cmdarg.txt @@ -0,0 +1,99 @@ +@ ProgramNode (location: (1,0)-(5,26)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,26)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,6) = "assert" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,7)-(1,15)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,7)-(1,15)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,7)-(1,15)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,7)-(1,10)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "assert" + ├── @ CallNode (location: (3,0)-(3,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,6) = "assert" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,7)-(3,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,7)-(3,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,7)-(3,11) = "dogs" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "dogs" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "assert" + └── @ CallNode (location: (5,0)-(5,26)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,1) = "f" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (5,2)-(5,26)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (5,2)-(5,26)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (5,2)-(5,26)) + │ ├── key: + │ │ @ SymbolNode (location: (5,2)-(5,4)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (5,2)-(5,3) = "x" + │ │ ├── closing_loc: (5,3)-(5,4) = ":" + │ │ └── unescaped: "x" + │ ├── value: + │ │ @ LambdaNode (location: (5,5)-(5,26)) + │ │ ├── locals: [] + │ │ ├── operator_loc: (5,5)-(5,7) = "->" + │ │ ├── opening_loc: (5,8)-(5,10) = "do" + │ │ ├── closing_loc: (5,23)-(5,26) = "end" + │ │ ├── parameters: ∅ + │ │ └── body: + │ │ @ StatementsNode (location: (5,11)-(5,22)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (5,11)-(5,22)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,11)-(5,15) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (5,16)-(5,22)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (5,16)-(5,18) = "do" + │ │ │ └── closing_loc: (5,19)-(5,22) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ └── operator_loc: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt b/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt new file mode 100644 index 00000000000000..1b45d0132befc9 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_def_no_paren_eql_begin.txt @@ -0,0 +1,18 @@ +@ ProgramNode (location: (1,0)-(4,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(4,3)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(4,3)) + ├── name: :foo + ├── name_loc: (1,4)-(1,7) = "foo" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (4,0)-(4,3) = "end" diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt b/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt new file mode 100644 index 00000000000000..75be678df60ea0 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_do_block_in_call_args.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(1,33)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,33)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,33)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "bar" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,33)) + │ └── 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)) + │ │ ├── receiver: + │ │ │ @ SelfNode (location: (1,13)-(1,17)) + │ │ ├── call_operator_loc: (1,17)-(1,18) = "." + │ │ ├── message_loc: (1,18)-(1,22) = "each" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,23)-(1,29)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,23)-(1,25) = "do" + │ │ │ └── closing_loc: (1,26)-(1,29) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "each" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,4)-(1,7) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,30)-(1,33) = "end" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "bar" diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt b/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt new file mode 100644 index 00000000000000..2a0fc1fa702f17 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_do_block_in_cmdarg.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,17)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "tap" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,17)) + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,9) = "proc" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,10)-(1,16)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,10)-(1,12) = "do" + │ │ │ └── closing_loc: (1,13)-(1,16) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "proc" + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ └── closing_loc: (1,16)-(1,17) = ")" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "tap" diff --git a/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt b/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt new file mode 100644 index 00000000000000..d1212e077a4f82 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_do_block_in_hash_brace.txt @@ -0,0 +1,365 @@ +@ ProgramNode (location: (1,0)-(9,52)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(9,52)) + └── body: (length: 5) + ├── @ CallNode (location: (1,0)-(1,42)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,42)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (1,2)-(1,6)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,14)-(1,18) = "proc" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (1,19)-(1,25)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (1,19)-(1,21) = "do" + │ │ │ │ │ │ └── closing_loc: (1,22)-(1,25) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "proc" + │ │ │ │ └── operator_loc: ∅ + │ │ │ └── @ AssocNode (location: (1,27)-(1,41)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (1,27)-(1,29)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (1,27)-(1,28) = "b" + │ │ │ │ ├── closing_loc: (1,28)-(1,29) = ":" + │ │ │ │ └── unescaped: "b" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (1,30)-(1,41)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,30)-(1,34) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (1,35)-(1,41)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (1,35)-(1,37) = "do" + │ │ │ │ │ └── closing_loc: (1,38)-(1,41) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ └── operator_loc: ∅ + │ │ └── closing_loc: (1,41)-(1,42) = "}" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (3,0)-(3,40)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,2)-(3,40)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (3,2)-(3,6)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (3,12)-(3,16) = "proc" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (3,17)-(3,23)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (3,17)-(3,19) = "do" + │ │ │ │ │ │ └── closing_loc: (3,20)-(3,23) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "proc" + │ │ │ │ └── operator_loc: (3,9)-(3,11) = "**" + │ │ │ └── @ AssocNode (location: (3,25)-(3,39)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (3,25)-(3,27)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (3,25)-(3,26) = "b" + │ │ │ │ ├── closing_loc: (3,26)-(3,27) = ":" + │ │ │ │ └── unescaped: "b" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (3,28)-(3,39)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,28)-(3,32) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (3,33)-(3,39)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (3,33)-(3,35) = "do" + │ │ │ │ │ └── closing_loc: (3,36)-(3,39) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ └── operator_loc: ∅ + │ │ └── closing_loc: (3,39)-(3,40) = "}" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (5,0)-(5,43)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,2)-(5,43)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (5,2)-(5,6)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── opening_loc: (5,9)-(5,10) = ":" + │ │ │ │ │ ├── value_loc: (5,10)-(5,11) = "a" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ └── unescaped: "a" + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (5,15)-(5,26)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (5,15)-(5,19) = "proc" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (5,20)-(5,26)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (5,20)-(5,22) = "do" + │ │ │ │ │ │ └── closing_loc: (5,23)-(5,26) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "proc" + │ │ │ │ └── operator_loc: (5,12)-(5,14) = "=>" + │ │ │ └── @ AssocNode (location: (5,28)-(5,42)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (5,28)-(5,30)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (5,28)-(5,29) = "b" + │ │ │ │ ├── closing_loc: (5,29)-(5,30) = ":" + │ │ │ │ └── unescaped: "b" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (5,31)-(5,42)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,31)-(5,35) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (5,36)-(5,42)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (5,36)-(5,38) = "do" + │ │ │ │ │ └── closing_loc: (5,39)-(5,42) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ └── operator_loc: ∅ + │ │ └── closing_loc: (5,42)-(5,43) = "}" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (7,0)-(7,40)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,2)-(7,40)) + │ │ └── arguments: (length: 2) + │ │ ├── @ SymbolNode (location: (7,2)-(7,6)) + │ │ │ ├── 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)) + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (7,9)-(7,10) = "a" + │ │ │ │ │ ├── closing_loc: (7,10)-(7,11) = ":" + │ │ │ │ │ └── unescaped: "a" + │ │ │ │ ├── value: + │ │ │ │ │ @ CallNode (location: (7,12)-(7,23)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (7,12)-(7,16) = "proc" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: + │ │ │ │ │ │ @ BlockNode (location: (7,17)-(7,23)) + │ │ │ │ │ │ ├── locals: [] + │ │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ │ ├── opening_loc: (7,17)-(7,19) = "do" + │ │ │ │ │ │ └── closing_loc: (7,20)-(7,23) = "end" + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "proc" + │ │ │ │ └── operator_loc: ∅ + │ │ │ └── @ AssocNode (location: (7,25)-(7,39)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (7,25)-(7,27)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (7,25)-(7,26) = "b" + │ │ │ │ ├── closing_loc: (7,26)-(7,27) = ":" + │ │ │ │ └── unescaped: "b" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (7,28)-(7,39)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (7,28)-(7,32) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (7,33)-(7,39)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (7,33)-(7,35) = "do" + │ │ │ │ │ └── closing_loc: (7,36)-(7,39) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ └── operator_loc: ∅ + │ │ └── closing_loc: (7,39)-(7,40) = "}" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + └── @ CallNode (location: (9,0)-(9,52)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (9,0)-(9,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (9,2)-(9,52)) + │ └── arguments: (length: 2) + │ ├── @ SymbolNode (location: (9,2)-(9,6)) + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,9)-(9,13) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (9,14)-(9,20)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (9,14)-(9,16) = "do" + │ │ │ │ │ └── closing_loc: (9,17)-(9,20) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ ├── value: + │ │ │ │ @ CallNode (location: (9,24)-(9,35)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,24)-(9,28) = "proc" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (9,29)-(9,35)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (9,29)-(9,31) = "do" + │ │ │ │ │ └── closing_loc: (9,32)-(9,35) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "proc" + │ │ │ └── operator_loc: (9,21)-(9,23) = "=>" + │ │ └── @ AssocNode (location: (9,37)-(9,51)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (9,37)-(9,39)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (9,37)-(9,38) = "b" + │ │ │ ├── closing_loc: (9,38)-(9,39) = ":" + │ │ │ └── unescaped: "b" + │ │ ├── value: + │ │ │ @ CallNode (location: (9,40)-(9,51)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,40)-(9,44) = "proc" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (9,45)-(9,51)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (9,45)-(9,47) = "do" + │ │ │ │ └── closing_loc: (9,48)-(9,51) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "proc" + │ │ └── operator_loc: ∅ + │ └── closing_loc: (9,51)-(9,52) = "}" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/bug_heredoc_do.txt b/test/prism/snapshots/whitequark/bug_heredoc_do.txt new file mode 100644 index 00000000000000..306de35b9554ae --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_heredoc_do.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(3,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,3)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(3,3)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,10)) + │ └── arguments: (length: 1) + │ └── @ StringNode (location: (1,2)-(1,10)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,2)-(1,10) = "<<-TABLE" + │ ├── content_loc: (2,0)-(1,0) = "" + │ ├── closing_loc: (2,0)-(2,0) = "TABLE\n" + │ └── unescaped: "" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,11)-(3,3)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,11)-(1,13) = "do" + │ └── closing_loc: (3,0)-(3,3) = "end" + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/whitequark/bug_interp_single.txt b/test/prism/snapshots/whitequark/bug_interp_single.txt new file mode 100644 index 00000000000000..ce78954f81effc --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_interp_single.txt @@ -0,0 +1,33 @@ +@ 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)) + ├── 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 new file mode 100644 index 00000000000000..ff21708d38ebc1 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_lambda_leakage.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 2) + ├── @ LambdaNode (location: (1,0)-(1,12)) + │ ├── locals: [:scope] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,10)-(1,11) = "{" + │ ├── closing_loc: (1,11)-(1,12) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,2)-(1,9)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,3)-(1,8)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,8)) + │ │ │ │ └── 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)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,14)-(1,19) = "scope" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "scope" diff --git a/test/prism/snapshots/whitequark/bug_regex_verification.txt b/test/prism/snapshots/whitequark/bug_regex_verification.txt new file mode 100644 index 00000000000000..79ac10f3a5c2e7 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_regex_verification.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ RegularExpressionNode (location: (1,0)-(1,5)) + ├── opening_loc: (1,0)-(1,1) = "/" + ├── content_loc: (1,1)-(1,3) = "#)" + ├── closing_loc: (1,3)-(1,5) = "/x" + ├── unescaped: "#)" + └── flags: extended diff --git a/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt b/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt new file mode 100644 index 00000000000000..52734cc1e9c6b2 --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_rescue_empty_else.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,34)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,34)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,34)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: + │ @ RescueNode (location: (1,7)-(1,23)) + │ ├── keyword_loc: (1,7)-(1,13) = "rescue" + │ ├── exceptions: (length: 1) + │ │ └── @ ConstantReadNode (location: (1,14)-(1,23)) + │ │ └── name: :LoadError + │ ├── operator_loc: ∅ + │ ├── reference: ∅ + │ ├── statements: ∅ + │ └── consequent: ∅ + ├── else_clause: + │ @ ElseNode (location: (1,25)-(1,34)) + │ ├── else_keyword_loc: (1,25)-(1,29) = "else" + │ ├── statements: ∅ + │ └── end_keyword_loc: (1,31)-(1,34) = "end" + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,31)-(1,34) = "end" diff --git a/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt b/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt new file mode 100644 index 00000000000000..1d71742a6ff6ad --- /dev/null +++ b/test/prism/snapshots/whitequark/bug_while_not_parens_do.txt @@ -0,0 +1,28 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + └── body: (length: 1) + └── @ WhileNode (location: (1,0)-(1,23)) + ├── keyword_loc: (1,0)-(1,5) = "while" + ├── closing_loc: (1,20)-(1,23) = "end" + ├── predicate: + │ @ CallNode (location: (1,6)-(1,16)) + │ ├── 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: ∅ + │ ├── message_loc: (1,6)-(1,9) = "not" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── statements: ∅ + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/case_cond.txt b/test/prism/snapshots/whitequark/case_cond.txt new file mode 100644 index 00000000000000..c919344722f6b1 --- /dev/null +++ b/test/prism/snapshots/whitequark/case_cond.txt @@ -0,0 +1,33 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,11)-(1,14) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── statements: + │ @ StatementsNode (location: (1,16)-(1,21)) + │ └── body: (length: 1) + │ └── @ StringNode (location: (1,16)-(1,21)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,16)-(1,17) = "'" + │ ├── content_loc: (1,17)-(1,20) = "foo" + │ ├── closing_loc: (1,20)-(1,21) = "'" + │ └── unescaped: "foo" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,23)-(1,26) = "end" diff --git a/test/prism/snapshots/whitequark/case_cond_else.txt b/test/prism/snapshots/whitequark/case_cond_else.txt new file mode 100644 index 00000000000000..7e6b9ec30ff12c --- /dev/null +++ b/test/prism/snapshots/whitequark/case_cond_else.txt @@ -0,0 +1,45 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,11)-(1,14) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── statements: + │ @ StatementsNode (location: (1,16)-(1,21)) + │ └── body: (length: 1) + │ └── @ StringNode (location: (1,16)-(1,21)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,16)-(1,17) = "'" + │ ├── content_loc: (1,17)-(1,20) = "foo" + │ ├── closing_loc: (1,20)-(1,21) = "'" + │ └── unescaped: "foo" + ├── consequent: + │ @ ElseNode (location: (1,23)-(1,38)) + │ ├── else_keyword_loc: (1,23)-(1,27) = "else" + │ ├── statements: + │ │ @ StatementsNode (location: (1,28)-(1,33)) + │ │ └── body: (length: 1) + │ │ └── @ StringNode (location: (1,28)-(1,33)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,28)-(1,29) = "'" + │ │ ├── content_loc: (1,29)-(1,32) = "bar" + │ │ ├── closing_loc: (1,32)-(1,33) = "'" + │ │ └── unescaped: "bar" + │ └── end_keyword_loc: (1,35)-(1,38) = "end" + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,35)-(1,38) = "end" diff --git a/test/prism/snapshots/whitequark/case_expr.txt b/test/prism/snapshots/whitequark/case_expr.txt new file mode 100644 index 00000000000000..44c8045a5f207c --- /dev/null +++ b/test/prism/snapshots/whitequark/case_expr.txt @@ -0,0 +1,43 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,22)-(1,25) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,27)-(1,30) = "end" diff --git a/test/prism/snapshots/whitequark/case_expr_else.txt b/test/prism/snapshots/whitequark/case_expr_else.txt new file mode 100644 index 00000000000000..2c6a5f8c659c6e --- /dev/null +++ b/test/prism/snapshots/whitequark/case_expr_else.txt @@ -0,0 +1,59 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,22)-(1,25) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,32)-(1,35) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ └── end_keyword_loc: (1,37)-(1,40) = "end" + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,37)-(1,40) = "end" diff --git a/test/prism/snapshots/whitequark/casgn_scoped.txt b/test/prism/snapshots/whitequark/casgn_scoped.txt new file mode 100644 index 00000000000000..bb3a8b072a2e0b --- /dev/null +++ b/test/prism/snapshots/whitequark/casgn_scoped.txt @@ -0,0 +1,19 @@ +@ 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 new file mode 100644 index 00000000000000..bc48b1e84139dc --- /dev/null +++ b/test/prism/snapshots/whitequark/casgn_toplevel.txt @@ -0,0 +1,17 @@ +@ 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 new file mode 100644 index 00000000000000..90434d39dbbf3e --- /dev/null +++ b/test/prism/snapshots/whitequark/casgn_unscoped.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..b70f05b5445572 --- /dev/null +++ b/test/prism/snapshots/whitequark/character.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,2)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,2)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,2)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,1) = "?" + ├── content_loc: (1,1)-(1,2) = "a" + ├── closing_loc: ∅ + └── unescaped: "a" diff --git a/test/prism/snapshots/whitequark/class.txt b/test/prism/snapshots/whitequark/class.txt new file mode 100644 index 00000000000000..e38bec6c476389 --- /dev/null +++ b/test/prism/snapshots/whitequark/class.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(3,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,14)) + └── body: (length: 2) + ├── @ ClassNode (location: (1,0)-(1,13)) + │ ├── locals: [] + │ ├── class_keyword_loc: (1,0)-(1,5) = "class" + │ ├── constant_path: + │ │ @ ConstantReadNode (location: (1,6)-(1,9)) + │ │ └── name: :Foo + │ ├── inheritance_operator_loc: ∅ + │ ├── superclass: ∅ + │ ├── body: ∅ + │ ├── end_keyword_loc: (1,10)-(1,13) = "end" + │ └── name: :Foo + └── @ ClassNode (location: (3,0)-(3,14)) + ├── locals: [] + ├── class_keyword_loc: (3,0)-(3,5) = "class" + ├── constant_path: + │ @ ConstantReadNode (location: (3,6)-(3,9)) + │ └── name: :Foo + ├── inheritance_operator_loc: ∅ + ├── superclass: ∅ + ├── body: ∅ + ├── end_keyword_loc: (3,11)-(3,14) = "end" + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/class_definition_in_while_cond.txt b/test/prism/snapshots/whitequark/class_definition_in_while_cond.txt new file mode 100644 index 00000000000000..ce384a6a5acca0 --- /dev/null +++ b/test/prism/snapshots/whitequark/class_definition_in_while_cond.txt @@ -0,0 +1,171 @@ +@ ProgramNode (location: (1,0)-(7,44)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,44)) + └── body: (length: 4) + ├── @ WhileNode (location: (1,0)-(1,52)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,25)-(1,28) = "tap" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (1,29)-(1,35)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (1,29)-(1,31) = "do" + │ │ │ │ │ └── closing_loc: (1,32)-(1,35) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "tap" + │ │ │ └── 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" + │ └── flags: ∅ + ├── @ WhileNode (location: (3,0)-(3,48)) + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,21)-(3,24) = "tap" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (3,25)-(3,31)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (3,25)-(3,27) = "do" + │ │ │ │ └── closing_loc: (3,28)-(3,31) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "tap" + │ │ └── 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" + │ └── flags: ∅ + ├── @ WhileNode (location: (5,0)-(5,47)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,20)-(5,23) = "tap" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (5,24)-(5,30)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (5,24)-(5,26) = "do" + │ │ │ │ │ └── closing_loc: (5,27)-(5,30) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "tap" + │ │ │ └── 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" + │ └── flags: ∅ + └── @ WhileNode (location: (7,0)-(7,44)) + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,17)-(7,20) = "tap" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (7,21)-(7,27)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (7,21)-(7,23) = "do" + │ │ │ └── closing_loc: (7,24)-(7,27) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "tap" + │ ├── 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" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/class_super.txt b/test/prism/snapshots/whitequark/class_super.txt new file mode 100644 index 00000000000000..ea8bbd70d9dd8d --- /dev/null +++ b/test/prism/snapshots/whitequark/class_super.txt @@ -0,0 +1,18 @@ +@ ProgramNode (location: (1,0)-(1,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,20)) + └── body: (length: 1) + └── @ ClassNode (location: (1,0)-(1,20)) + ├── locals: [] + ├── class_keyword_loc: (1,0)-(1,5) = "class" + ├── constant_path: + │ @ ConstantReadNode (location: (1,6)-(1,9)) + │ └── name: :Foo + ├── inheritance_operator_loc: (1,10)-(1,11) = "<" + ├── superclass: + │ @ ConstantReadNode (location: (1,12)-(1,15)) + │ └── name: :Bar + ├── body: ∅ + ├── end_keyword_loc: (1,17)-(1,20) = "end" + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/class_super_label.txt b/test/prism/snapshots/whitequark/class_super_label.txt new file mode 100644 index 00000000000000..60826a72b9a0cf --- /dev/null +++ b/test/prism/snapshots/whitequark/class_super_label.txt @@ -0,0 +1,33 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,12)-(1,13) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,13)-(1,15)) + │ │ └── arguments: (length: 1) + │ │ └── @ SymbolNode (location: (1,13)-(1,15)) + │ │ ├── opening_loc: (1,13)-(1,14) = ":" + │ │ ├── value_loc: (1,14)-(1,15) = "b" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "b" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a" + ├── body: ∅ + ├── end_keyword_loc: (1,17)-(1,20) = "end" + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt b/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt new file mode 100644 index 00000000000000..5315ed5d17e1fb --- /dev/null +++ b/test/prism/snapshots/whitequark/comments_before_leading_dot__27.txt @@ -0,0 +1,85 @@ +@ ProgramNode (location: (1,0)-(18,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(18,4)) + └── body: (length: 4) + ├── @ CallNode (location: (1,0)-(3,5)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (3,0)-(3,2) = "&." + │ ├── message_loc: (3,2)-(3,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "foo" + ├── @ CallNode (location: (6,0)-(8,4)) + │ ├── receiver: + │ │ @ CallNode (location: (6,0)-(6,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (6,0)-(6,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (8,0)-(8,1) = "." + │ ├── message_loc: (8,1)-(8,4) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "foo" + ├── @ CallNode (location: (11,0)-(13,5)) + │ ├── receiver: + │ │ @ CallNode (location: (11,0)-(11,1)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,1) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: (13,0)-(13,2) = "&." + │ ├── message_loc: (13,2)-(13,5) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: safe_navigation + │ └── name: "foo" + └── @ CallNode (location: (16,0)-(18,4)) + ├── receiver: + │ @ CallNode (location: (16,0)-(16,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (16,0)-(16,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (18,0)-(18,1) = "." + ├── message_loc: (18,1)-(18,4) = "foo" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "foo" diff --git a/test/prism/snapshots/whitequark/complex.txt b/test/prism/snapshots/whitequark/complex.txt new file mode 100644 index 00000000000000..f81564d7006d5d --- /dev/null +++ b/test/prism/snapshots/whitequark/complex.txt @@ -0,0 +1,23 @@ +@ 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 new file mode 100644 index 00000000000000..085f240ebd3b83 --- /dev/null +++ b/test/prism/snapshots/whitequark/cond_begin.txt @@ -0,0 +1,39 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,7) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ └── closing_loc: (1,7)-(1,8) = ")" + ├── statements: + │ @ StatementsNode (location: (1,10)-(1,13)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,10)-(1,13)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,10)-(1,13) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── consequent: ∅ + └── end_keyword_loc: (1,15)-(1,18) = "end" diff --git a/test/prism/snapshots/whitequark/cond_begin_masgn.txt b/test/prism/snapshots/whitequark/cond_begin_masgn.txt new file mode 100644 index 00000000000000..9ec167665e87a1 --- /dev/null +++ b/test/prism/snapshots/whitequark/cond_begin_masgn.txt @@ -0,0 +1,49 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,4)-(1,7) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── @ MultiWriteNode (location: (1,9)-(1,19)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (1,9)-(1,10)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ └── @ LocalVariableTargetNode (location: (1,12)-(1,13)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── operator_loc: (1,14)-(1,15) = "=" + │ │ └── value: + │ │ @ CallNode (location: (1,16)-(1,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,19) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ └── closing_loc: (1,19)-(1,20) = ")" + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (1,22)-(1,25) = "end" diff --git a/test/prism/snapshots/whitequark/cond_eflipflop.txt b/test/prism/snapshots/whitequark/cond_eflipflop.txt new file mode 100644 index 00000000000000..89976af9e97adc --- /dev/null +++ b/test/prism/snapshots/whitequark/cond_eflipflop.txt @@ -0,0 +1,77 @@ +@ ProgramNode (location: (1,0)-(3,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,17)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,12)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (1,1)-(1,12)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,2)-(1,11)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ FlipFlopNode (location: (1,2)-(1,11)) + │ │ │ ├── left: + │ │ │ │ @ CallNode (location: (1,2)-(1,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,2)-(1,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (1,8)-(1,11)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,8)-(1,11) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── operator_loc: (1,5)-(1,8) = "..." + │ │ │ └── flags: exclude_end + │ │ ├── opening_loc: (1,1)-(1,2) = "(" + │ │ └── closing_loc: (1,11)-(1,12) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + └── @ IfNode (location: (3,0)-(3,17)) + ├── if_keyword_loc: (3,0)-(3,2) = "if" + ├── predicate: + │ @ FlipFlopNode (location: (3,3)-(3,12)) + │ ├── left: + │ │ @ CallNode (location: (3,3)-(3,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,3)-(3,6) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── right: + │ │ @ CallNode (location: (3,9)-(3,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,9)-(3,12) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── operator_loc: (3,6)-(3,9) = "..." + │ └── flags: exclude_end + ├── 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 new file mode 100644 index 00000000000000..1dcece1aef20ad --- /dev/null +++ b/test/prism/snapshots/whitequark/cond_iflipflop.txt @@ -0,0 +1,77 @@ +@ ProgramNode (location: (1,0)-(3,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,16)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: + │ │ @ ParenthesesNode (location: (1,1)-(1,11)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,2)-(1,10)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ FlipFlopNode (location: (1,2)-(1,10)) + │ │ │ ├── left: + │ │ │ │ @ CallNode (location: (1,2)-(1,5)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,2)-(1,5) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ ├── right: + │ │ │ │ @ CallNode (location: (1,7)-(1,10)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,7)-(1,10) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── operator_loc: (1,5)-(1,7) = ".." + │ │ │ └── flags: ∅ + │ │ ├── opening_loc: (1,1)-(1,2) = "(" + │ │ └── closing_loc: (1,10)-(1,11) = ")" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + └── @ IfNode (location: (3,0)-(3,16)) + ├── if_keyword_loc: (3,0)-(3,2) = "if" + ├── predicate: + │ @ FlipFlopNode (location: (3,3)-(3,11)) + │ ├── left: + │ │ @ CallNode (location: (3,3)-(3,6)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,3)-(3,6) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── right: + │ │ @ CallNode (location: (3,8)-(3,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,8)-(3,11) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── operator_loc: (3,6)-(3,8) = ".." + │ └── flags: ∅ + ├── 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 new file mode 100644 index 00000000000000..679e9036816164 --- /dev/null +++ b/test/prism/snapshots/whitequark/cond_match_current_line.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(3,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,13)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,6)) + │ ├── receiver: + │ │ @ MatchLastLineNode (location: (1,1)-(1,6)) + │ │ ├── opening_loc: (1,1)-(1,2) = "/" + │ │ ├── content_loc: (1,2)-(1,5) = "wat" + │ │ ├── closing_loc: (1,5)-(1,6) = "/" + │ │ ├── unescaped: "wat" + │ │ └── flags: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + └── @ IfNode (location: (3,0)-(3,13)) + ├── if_keyword_loc: (3,0)-(3,2) = "if" + ├── predicate: + │ @ MatchLastLineNode (location: (3,3)-(3,8)) + │ ├── opening_loc: (3,3)-(3,4) = "/" + │ ├── content_loc: (3,4)-(3,7) = "wat" + │ ├── closing_loc: (3,7)-(3,8) = "/" + │ ├── unescaped: "wat" + │ └── flags: ∅ + ├── statements: ∅ + ├── consequent: ∅ + └── end_keyword_loc: (3,10)-(3,13) = "end" diff --git a/test/prism/snapshots/whitequark/const_op_asgn.txt b/test/prism/snapshots/whitequark/const_op_asgn.txt new file mode 100644 index 00000000000000..fc6533ccd008ac --- /dev/null +++ b/test/prism/snapshots/whitequark/const_op_asgn.txt @@ -0,0 +1,96 @@ +@ 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: [] + │ ├── 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: [] + ├── def_keyword_loc: (9,0)-(9,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (9,22)-(9,25) = "end" diff --git a/test/prism/snapshots/whitequark/const_scoped.txt b/test/prism/snapshots/whitequark/const_scoped.txt new file mode 100644 index 00000000000000..1e2bccef968093 --- /dev/null +++ b/test/prism/snapshots/whitequark/const_scoped.txt @@ -0,0 +1,13 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ ConstantPathNode (location: (1,0)-(1,8)) + ├── parent: + │ @ ConstantReadNode (location: (1,0)-(1,3)) + │ └── name: :Bar + ├── child: + │ @ ConstantReadNode (location: (1,5)-(1,8)) + │ └── name: :Foo + └── delimiter_loc: (1,3)-(1,5) = "::" diff --git a/test/prism/snapshots/whitequark/const_toplevel.txt b/test/prism/snapshots/whitequark/const_toplevel.txt new file mode 100644 index 00000000000000..b54b069d06b0cd --- /dev/null +++ b/test/prism/snapshots/whitequark/const_toplevel.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ ConstantPathNode (location: (1,0)-(1,5)) + ├── parent: ∅ + ├── child: + │ @ ConstantReadNode (location: (1,2)-(1,5)) + │ └── name: :Foo + └── delimiter_loc: (1,0)-(1,2) = "::" diff --git a/test/prism/snapshots/whitequark/const_unscoped.txt b/test/prism/snapshots/whitequark/const_unscoped.txt new file mode 100644 index 00000000000000..5e272e1775ddd9 --- /dev/null +++ b/test/prism/snapshots/whitequark/const_unscoped.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ ConstantReadNode (location: (1,0)-(1,3)) + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/cpath.txt b/test/prism/snapshots/whitequark/cpath.txt new file mode 100644 index 00000000000000..b8925256461ffd --- /dev/null +++ b/test/prism/snapshots/whitequark/cpath.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(3,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,20)) + └── body: (length: 2) + ├── @ ModuleNode (location: (1,0)-(1,17)) + │ ├── locals: [] + │ ├── module_keyword_loc: (1,0)-(1,6) = "module" + │ ├── constant_path: + │ │ @ ConstantPathNode (location: (1,7)-(1,12)) + │ │ ├── parent: ∅ + │ │ ├── child: + │ │ │ @ ConstantReadNode (location: (1,9)-(1,12)) + │ │ │ └── name: :Foo + │ │ └── delimiter_loc: (1,7)-(1,9) = "::" + │ ├── body: ∅ + │ ├── end_keyword_loc: (1,14)-(1,17) = "end" + │ └── name: :Foo + └── @ ModuleNode (location: (3,0)-(3,20)) + ├── locals: [] + ├── module_keyword_loc: (3,0)-(3,6) = "module" + ├── constant_path: + │ @ ConstantPathNode (location: (3,7)-(3,15)) + │ ├── parent: + │ │ @ ConstantReadNode (location: (3,7)-(3,10)) + │ │ └── name: :Bar + │ ├── child: + │ │ @ ConstantReadNode (location: (3,12)-(3,15)) + │ │ └── name: :Foo + │ └── delimiter_loc: (3,10)-(3,12) = "::" + ├── body: ∅ + ├── end_keyword_loc: (3,17)-(3,20) = "end" + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/cvar.txt b/test/prism/snapshots/whitequark/cvar.txt new file mode 100644 index 00000000000000..7847ce44954bb5 --- /dev/null +++ b/test/prism/snapshots/whitequark/cvar.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ ClassVariableReadNode (location: (1,0)-(1,5)) + └── name: :@@foo diff --git a/test/prism/snapshots/whitequark/cvasgn.txt b/test/prism/snapshots/whitequark/cvasgn.txt new file mode 100644 index 00000000000000..e6a1c7e9737d9f --- /dev/null +++ b/test/prism/snapshots/whitequark/cvasgn.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..c0babc6ba187cc --- /dev/null +++ b/test/prism/snapshots/whitequark/dedenting_heredoc.txt @@ -0,0 +1,367 @@ +@ ProgramNode (location: (1,0)-(72,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(72,8)) + └── body: (length: 16) + ├── @ CallNode (location: (1,0)-(1,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ InterpolatedStringNode (location: (1,2)-(1,8)) + │ │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\"" + │ │ ├── parts: (length: 3) + │ │ │ ├── @ StringNode (location: (2,0)-(3,2)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (2,0)-(3,2) = " 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)-(3,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (3,10)-(3,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (4,0)-(4,0) = "E\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (6,0)-(6,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (6,0)-(6,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (6,2)-(6,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ InterpolatedStringNode (location: (6,2)-(6,8)) + │ │ ├── opening_loc: (6,2)-(6,8) = "<<~\"E\"" + │ │ ├── parts: (length: 3) + │ │ │ ├── @ StringNode (location: (7,0)-(8,2)) + │ │ │ │ ├── flags: ∅ + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── content_loc: (7,0)-(8,2) = " 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)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (8,4)-(8,7) = "foo" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "foo" + │ │ │ │ └── closing_loc: (8,7)-(8,8) = "}" + │ │ │ └── @ StringNode (location: (8,8)-(8,0)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (8,8)-(8,0) = "\n" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "\n" + │ │ └── closing_loc: (9,0)-(9,0) = "E\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (11,0)-(11,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,2)-(11,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (11,2)-(11,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (11,2)-(11,6) = "<<~E" + │ │ ├── content_loc: (12,0)-(13,0) = "\tx\n y\n" + │ │ ├── closing_loc: (14,0)-(14,0) = "E\n" + │ │ └── unescaped: "x\ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (16,0)-(16,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (16,0)-(16,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (16,2)-(16,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (16,2)-(16,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (16,2)-(16,6) = "<<~E" + │ │ ├── content_loc: (17,0)-(18,0) = "\tx\n y\n" + │ │ ├── closing_loc: (19,0)-(19,0) = "E\n" + │ │ └── unescaped: "\tx\ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (21,0)-(21,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,0)-(21,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,2)-(21,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (21,2)-(21,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (21,2)-(21,6) = "<<~E" + │ │ ├── content_loc: (22,0)-(23,0) = " \tx\n y\n" + │ │ ├── closing_loc: (24,0)-(24,0) = "E\n" + │ │ └── unescaped: "x\ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (26,0)-(26,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (26,0)-(26,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (26,2)-(26,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (26,2)-(26,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (26,2)-(26,6) = "<<~E" + │ │ ├── content_loc: (27,0)-(28,0) = " \tx\n\ty\n" + │ │ ├── closing_loc: (29,0)-(29,0) = "E\n" + │ │ └── unescaped: "\tx\ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (31,0)-(31,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,0)-(31,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,2)-(31,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (31,2)-(31,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (31,2)-(31,6) = "<<~E" + │ │ ├── content_loc: (32,0)-(33,0) = " x\n \\\ty\n" + │ │ ├── closing_loc: (34,0)-(34,0) = "E\n" + │ │ └── unescaped: " x\n\ty\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (36,0)-(36,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (36,0)-(36,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (36,2)-(36,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (36,2)-(36,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (36,2)-(36,6) = "<<~E" + │ │ ├── content_loc: (37,0)-(38,0) = " x\n \\ y\n" + │ │ ├── closing_loc: (39,0)-(39,0) = "E\n" + │ │ └── unescaped: " x\n y\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (41,0)-(41,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,0)-(41,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (41,2)-(41,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (41,2)-(41,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (41,2)-(41,6) = "<<~E" + │ │ ├── content_loc: (42,0)-(41,0) = "" + │ │ ├── closing_loc: (42,0)-(42,0) = " E\n" + │ │ └── unescaped: "" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (44,0)-(44,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (44,0)-(44,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (44,2)-(44,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (44,2)-(44,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (44,2)-(44,6) = "<<~E" + │ │ ├── content_loc: (45,0)-(47,0) = " x\n\ny\n" + │ │ ├── closing_loc: (48,0)-(48,0) = "E\n" + │ │ └── unescaped: " x\n\ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (50,0)-(50,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (50,0)-(50,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (50,2)-(50,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (50,2)-(50,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (50,2)-(50,6) = "<<~E" + │ │ ├── content_loc: (51,0)-(53,0) = " x\n \n y\n" + │ │ ├── closing_loc: (54,0)-(54,0) = "E\n" + │ │ └── unescaped: "x\n \ny\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (56,0)-(56,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (56,0)-(56,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (56,2)-(56,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (56,2)-(56,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (56,2)-(56,6) = "<<~E" + │ │ ├── content_loc: (57,0)-(58,0) = " x\n y\n" + │ │ ├── closing_loc: (59,0)-(59,0) = "E\n" + │ │ └── unescaped: "x\n y\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (61,0)-(61,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (61,0)-(61,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (61,2)-(61,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (61,2)-(61,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (61,2)-(61,6) = "<<~E" + │ │ ├── content_loc: (62,0)-(62,0) = " x\n" + │ │ ├── closing_loc: (63,0)-(63,0) = "E\n" + │ │ └── unescaped: "x\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (65,0)-(65,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (65,0)-(65,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (65,2)-(65,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (65,2)-(65,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (65,2)-(65,6) = "<<~E" + │ │ ├── content_loc: (66,0)-(66,0) = " ð\n" + │ │ ├── closing_loc: (67,0)-(67,0) = "E\n" + │ │ └── unescaped: "ð\n" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── @ CallNode (location: (69,0)-(69,6)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (69,0)-(69,1) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (69,2)-(69,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ StringNode (location: (69,2)-(69,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (69,2)-(69,6) = "<<~E" + │ │ ├── content_loc: (70,0)-(69,0) = "" + │ │ ├── closing_loc: (70,0)-(70,0) = "E\n" + │ │ └── unescaped: "" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + └── @ CallNode (location: (72,0)-(72,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (72,0)-(72,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (72,2)-(72,8)) + │ └── arguments: (length: 1) + │ └── @ InterpolatedXStringNode (location: (72,2)-(72,8)) + │ ├── opening_loc: (72,2)-(72,8) = "<<~`E`" + │ ├── parts: (length: 3) + │ │ ├── @ StringNode (location: (73,0)-(74,2)) + │ │ │ ├── flags: ∅ + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── content_loc: (73,0)-(74,2) = " 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (74,4)-(74,7) = "foo" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "foo" + │ │ │ └── closing_loc: (74,7)-(74,8) = "}" + │ │ └── @ StringNode (location: (74,8)-(74,0)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (74,8)-(74,0) = "\n" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "\n" + │ └── closing_loc: (75,0)-(75,0) = "E\n" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt b/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt new file mode 100644 index 00000000000000..ac083f3edc1343 --- /dev/null +++ b/test/prism/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,8)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'" + ├── content_loc: (2,0)-(3,0) = " baz\\\\\n qux\n" + ├── closing_loc: (4,0)-(4,0) = "FOO\n" + └── unescaped: "baz\\\nqux\n" diff --git a/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt b/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt new file mode 100644 index 00000000000000..6d123a3387403e --- /dev/null +++ b/test/prism/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,8)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,8) = "<<~'FOO'" + ├── content_loc: (2,0)-(3,0) = " baz\\\n qux\n" + ├── closing_loc: (4,0)-(4,0) = "FOO\n" + └── unescaped: "baz\\\nqux\n" diff --git a/test/prism/snapshots/whitequark/def.txt b/test/prism/snapshots/whitequark/def.txt new file mode 100644 index 00000000000000..d5e1139c4d2241 --- /dev/null +++ b/test/prism/snapshots/whitequark/def.txt @@ -0,0 +1,83 @@ +@ ProgramNode (location: (1,0)-(11,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(11,14)) + └── body: (length: 6) + ├── @ DefNode (location: (1,0)-(1,14)) + │ ├── name: :BEGIN + │ ├── name_loc: (1,4)-(1,9) = "BEGIN" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,11)-(1,14) = "end" + ├── @ DefNode (location: (3,0)-(3,12)) + │ ├── name: :END + │ ├── name_loc: (3,4)-(3,7) = "END" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,9)-(3,12) = "end" + ├── @ DefNode (location: (5,0)-(5,15)) + │ ├── name: :String + │ ├── name_loc: (5,4)-(5,10) = "String" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (5,0)-(5,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,12)-(5,15) = "end" + ├── @ DefNode (location: (7,0)-(7,16)) + │ ├── name: :String= + │ ├── name_loc: (7,4)-(7,11) = "String=" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (7,13)-(7,16) = "end" + ├── @ DefNode (location: (9,0)-(9,12)) + │ ├── name: :foo + │ ├── name_loc: (9,4)-(9,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (9,0)-(9,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (9,9)-(9,12) = "end" + └── @ DefNode (location: (11,0)-(11,14)) + ├── name: :until + ├── name_loc: (11,4)-(11,9) = "until" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (11,0)-(11,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (11,11)-(11,14) = "end" diff --git a/test/prism/snapshots/whitequark/defined.txt b/test/prism/snapshots/whitequark/defined.txt new file mode 100644 index 00000000000000..475e6a273475b9 --- /dev/null +++ b/test/prism/snapshots/whitequark/defined.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(5,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,13)) + └── body: (length: 3) + ├── @ DefinedNode (location: (1,0)-(1,13)) + │ ├── lparen_loc: ∅ + │ ├── value: + │ │ @ InstanceVariableReadNode (location: (1,9)-(1,13)) + │ │ └── name: :@foo + │ ├── rparen_loc: ∅ + │ └── keyword_loc: (1,0)-(1,8) = "defined?" + ├── @ DefinedNode (location: (3,0)-(3,12)) + │ ├── lparen_loc: ∅ + │ ├── value: + │ │ @ CallNode (location: (3,9)-(3,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,9)-(3,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,9)-(5,12) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── rparen_loc: (5,12)-(5,13) = ")" + └── keyword_loc: (5,0)-(5,8) = "defined?" diff --git a/test/prism/snapshots/whitequark/defs.txt b/test/prism/snapshots/whitequark/defs.txt new file mode 100644 index 00000000000000..bdb96e83b06184 --- /dev/null +++ b/test/prism/snapshots/whitequark/defs.txt @@ -0,0 +1,90 @@ +@ ProgramNode (location: (1,0)-(9,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(9,18)) + └── body: (length: 5) + ├── @ DefNode (location: (1,0)-(1,18)) + │ ├── name: :foo + │ ├── name_loc: (1,10)-(1,13) = "foo" + │ ├── receiver: + │ │ @ ParenthesesNode (location: (1,4)-(1,9)) + │ │ ├── body: + │ │ │ @ CallNode (location: (1,5)-(1,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,5)-(1,8) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── opening_loc: (1,4)-(1,5) = "(" + │ │ └── closing_loc: (1,8)-(1,9) = ")" + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: (1,9)-(1,10) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,15)-(1,18) = "end" + ├── @ DefNode (location: (3,0)-(3,19)) + │ ├── name: :foo + │ ├── name_loc: (3,11)-(3,14) = "foo" + │ ├── receiver: + │ │ @ ConstantReadNode (location: (3,4)-(3,10)) + │ │ └── name: :String + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: (3,10)-(3,11) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,16)-(3,19) = "end" + ├── @ DefNode (location: (5,0)-(5,20)) + │ ├── name: :foo + │ ├── name_loc: (5,12)-(5,15) = "foo" + │ ├── receiver: + │ │ @ ConstantReadNode (location: (5,4)-(5,10)) + │ │ └── name: :String + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (5,0)-(5,3) = "def" + │ ├── operator_loc: (5,10)-(5,12) = "::" + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (5,17)-(5,20) = "end" + ├── @ DefNode (location: (7,0)-(7,17)) + │ ├── name: :foo + │ ├── name_loc: (7,9)-(7,12) = "foo" + │ ├── receiver: + │ │ @ SelfNode (location: (7,4)-(7,8)) + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── locals: [] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: (7,8)-(7,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (7,14)-(7,17) = "end" + └── @ DefNode (location: (9,0)-(9,18)) + ├── name: :foo + ├── name_loc: (9,10)-(9,13) = "foo" + ├── receiver: + │ @ SelfNode (location: (9,4)-(9,8)) + ├── parameters: ∅ + ├── body: ∅ + ├── locals: [] + ├── def_keyword_loc: (9,0)-(9,3) = "def" + ├── operator_loc: (9,8)-(9,10) = "::" + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (9,15)-(9,18) = "end" diff --git a/test/prism/snapshots/whitequark/empty_stmt.txt b/test/prism/snapshots/whitequark/empty_stmt.txt new file mode 100644 index 00000000000000..870bdb6ad54607 --- /dev/null +++ b/test/prism/snapshots/whitequark/empty_stmt.txt @@ -0,0 +1,5 @@ +@ ProgramNode (location: (1,0)-(0,0)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(0,0)) + └── body: (length: 0) diff --git a/test/prism/snapshots/whitequark/endless_comparison_method.txt b/test/prism/snapshots/whitequark/endless_comparison_method.txt new file mode 100644 index 00000000000000..ee65681c02030f --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_comparison_method.txt @@ -0,0 +1,215 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,28) = "do_something" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "do_something" + │ ├── locals: [:other] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,6)-(1,7) = "(" + │ ├── rparen_loc: (1,12)-(1,13) = ")" + │ ├── equal_loc: (1,14)-(1,15) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (3,0)-(3,28)) + │ ├── name: :!= + │ ├── name_loc: (3,4)-(3,6) = "!=" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (3,7)-(3,12)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (3,7)-(3,12)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,16)-(3,28) = "do_something" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "do_something" + │ ├── locals: [:other] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (3,6)-(3,7) = "(" + │ ├── rparen_loc: (3,12)-(3,13) = ")" + │ ├── equal_loc: (3,14)-(3,15) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (5,0)-(5,28)) + │ ├── name: :<= + │ ├── name_loc: (5,4)-(5,6) = "<=" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (5,7)-(5,12)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (5,7)-(5,12)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,16)-(5,28) = "do_something" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "do_something" + │ ├── locals: [:other] + │ ├── def_keyword_loc: (5,0)-(5,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (5,6)-(5,7) = "(" + │ ├── rparen_loc: (5,12)-(5,13) = ")" + │ ├── equal_loc: (5,14)-(5,15) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (7,0)-(7,28)) + │ ├── name: :== + │ ├── name_loc: (7,4)-(7,6) = "==" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (7,7)-(7,12)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (7,7)-(7,12)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,16)-(7,28) = "do_something" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "do_something" + │ ├── locals: [:other] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (7,6)-(7,7) = "(" + │ ├── rparen_loc: (7,12)-(7,13) = ")" + │ ├── equal_loc: (7,14)-(7,15) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (9,0)-(9,29)) + │ ├── name: :=== + │ ├── name_loc: (9,4)-(9,7) = "===" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (9,8)-(9,13)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (9,8)-(9,13)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,17)-(9,29) = "do_something" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "do_something" + │ ├── locals: [:other] + │ ├── def_keyword_loc: (9,0)-(9,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (9,7)-(9,8) = "(" + │ ├── rparen_loc: (9,13)-(9,14) = ")" + │ ├── equal_loc: (9,15)-(9,16) = "=" + │ └── end_keyword_loc: ∅ + └── @ DefNode (location: (11,0)-(11,28)) + ├── name: :>= + ├── name_loc: (11,4)-(11,6) = ">=" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (11,7)-(11,12)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (11,7)-(11,12)) + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,16)-(11,28) = "do_something" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "do_something" + ├── locals: [:other] + ├── def_keyword_loc: (11,0)-(11,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (11,6)-(11,7) = "(" + ├── rparen_loc: (11,12)-(11,13) = ")" + ├── equal_loc: (11,14)-(11,15) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/endless_method.txt b/test/prism/snapshots/whitequark/endless_method.txt new file mode 100644 index 00000000000000..4d1d01bde04bce --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_method.txt @@ -0,0 +1,143 @@ +@ 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: [] + │ ├── 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)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (3,13)-(3,14)) + │ │ │ ├── name: :x + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,15)-(3,16) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,17)-(3,18)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (3,17)-(3,18)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ ├── locals: [:x] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (3,7)-(3,8) = "(" + │ ├── rparen_loc: (3,9)-(3,10) = ")" + │ ├── equal_loc: (3,11)-(3,12) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (5,0)-(5,18)) + │ ├── name: :foo + │ ├── name_loc: (5,8)-(5,11) = "foo" + │ ├── receiver: + │ │ @ CallNode (location: (5,4)-(5,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,4)-(5,7) = "obj" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "obj" + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (5,16)-(5,18)) + │ │ └── body: (length: 1) + │ │ └── @ IntegerNode (location: (5,16)-(5,18)) + │ │ └── flags: decimal + │ ├── locals: [] + │ ├── def_keyword_loc: (5,0)-(5,3) = "def" + │ ├── operator_loc: (5,7)-(5,8) = "." + │ ├── lparen_loc: (5,11)-(5,12) = "(" + │ ├── rparen_loc: (5,12)-(5,13) = ")" + │ ├── equal_loc: (5,14)-(5,15) = "=" + │ └── end_keyword_loc: ∅ + └── @ DefNode (location: (7,0)-(7,22)) + ├── name: :inc + ├── name_loc: (7,8)-(7,11) = "inc" + ├── receiver: + │ @ CallNode (location: (7,4)-(7,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,4)-(7,7) = "obj" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "obj" + ├── 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)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (7,17)-(7,18)) + │ │ ├── name: :x + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,19)-(7,20) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,21)-(7,22)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (7,21)-(7,22)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── locals: [:x] + ├── def_keyword_loc: (7,0)-(7,3) = "def" + ├── operator_loc: (7,7)-(7,8) = "." + ├── lparen_loc: (7,11)-(7,12) = "(" + ├── rparen_loc: (7,13)-(7,14) = ")" + ├── equal_loc: (7,15)-(7,16) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/endless_method_command_syntax.txt b/test/prism/snapshots/whitequark/endless_method_command_syntax.txt new file mode 100644 index 00000000000000..0943a1edf3d772 --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_method_command_syntax.txt @@ -0,0 +1,380 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,10)-(1,14) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,15)-(1,22)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (1,8)-(1,9) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (3,0)-(3,24)) + │ ├── name: :foo + │ ├── name_loc: (3,4)-(3,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (3,12)-(3,24)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (3,12)-(3,24)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,12)-(3,16) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,17)-(3,24)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (3,7)-(3,8) = "(" + │ ├── rparen_loc: (3,8)-(3,9) = ")" + │ ├── equal_loc: (3,10)-(3,11) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (5,0)-(5,19)) + │ ├── name: :foo + │ ├── name_loc: (5,4)-(5,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (5,8)-(5,9)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (5,8)-(5,9)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,13)-(5,17) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,18)-(5,19)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (5,18)-(5,19)) + │ │ │ ├── name: :x + │ │ │ └── depth: 0 + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [:x] + │ ├── def_keyword_loc: (5,0)-(5,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (5,7)-(5,8) = "(" + │ ├── rparen_loc: (5,9)-(5,10) = ")" + │ ├── equal_loc: (5,11)-(5,12) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (7,0)-(7,26)) + │ ├── name: :foo + │ ├── name_loc: (7,8)-(7,11) = "foo" + │ ├── receiver: + │ │ @ CallNode (location: (7,4)-(7,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,4)-(7,7) = "obj" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "obj" + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (7,14)-(7,26)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (7,14)-(7,26)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,14)-(7,18) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,19)-(7,26)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: (7,7)-(7,8) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: (7,12)-(7,13) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (9,0)-(9,28)) + │ ├── name: :foo + │ ├── name_loc: (9,8)-(9,11) = "foo" + │ ├── receiver: + │ │ @ CallNode (location: (9,4)-(9,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,4)-(9,7) = "obj" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "obj" + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (9,16)-(9,28)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (9,16)-(9,28)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,16)-(9,20) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,21)-(9,28)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [] + │ ├── def_keyword_loc: (9,0)-(9,3) = "def" + │ ├── operator_loc: (9,7)-(9,8) = "." + │ ├── lparen_loc: (9,11)-(9,12) = "(" + │ ├── rparen_loc: (9,12)-(9,13) = ")" + │ ├── equal_loc: (9,14)-(9,15) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (11,0)-(11,23)) + │ ├── name: :foo + │ ├── name_loc: (11,8)-(11,11) = "foo" + │ ├── receiver: + │ │ @ CallNode (location: (11,4)-(11,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,4)-(11,7) = "obj" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "obj" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,17)-(11,21) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (11,22)-(11,23)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (11,22)-(11,23)) + │ │ │ ├── name: :x + │ │ │ └── depth: 0 + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ ├── locals: [:x] + │ ├── def_keyword_loc: (11,0)-(11,3) = "def" + │ ├── operator_loc: (11,7)-(11,8) = "." + │ ├── lparen_loc: (11,11)-(11,12) = "(" + │ ├── rparen_loc: (11,13)-(11,14) = ")" + │ ├── equal_loc: (11,15)-(11,16) = "=" + │ └── end_keyword_loc: ∅ + ├── @ DefNode (location: (13,0)-(13,60)) + │ ├── name: :rescued + │ ├── name_loc: (13,4)-(13,11) = "rescued" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (13,12)-(13,13)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (13,12)-(13,13)) + │ │ │ └── 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) + │ │ └── @ CallNode (location: (13,17)-(13,60)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,17)-(13,22) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (13,23)-(13,60)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ RescueModifierNode (location: (13,23)-(13,60)) + │ │ │ ├── expression: + │ │ │ │ @ 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" + │ │ │ ├── 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) = "\"" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── locals: [:x] + │ ├── def_keyword_loc: (13,0)-(13,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (13,11)-(13,12) = "(" + │ ├── rparen_loc: (13,13)-(13,14) = ")" + │ ├── equal_loc: (13,15)-(13,16) = "=" + │ └── end_keyword_loc: ∅ + └── @ DefNode (location: (15,0)-(15,62)) + ├── name: :rescued + ├── name_loc: (15,9)-(15,16) = "rescued" + ├── receiver: + │ @ SelfNode (location: (15,4)-(15,8)) + ├── parameters: + │ @ ParametersNode (location: (15,17)-(15,18)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (15,17)-(15,18)) + │ │ └── 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) + │ └── @ CallNode (location: (15,22)-(15,62)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,22)-(15,27) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,28)-(15,62)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (15,28)-(15,62)) + │ │ ├── expression: + │ │ │ @ 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" + │ │ ├── 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) = "\"" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── locals: [:x] + ├── def_keyword_loc: (15,0)-(15,3) = "def" + ├── operator_loc: (15,8)-(15,9) = "." + ├── lparen_loc: (15,16)-(15,17) = "(" + ├── rparen_loc: (15,18)-(15,19) = ")" + ├── equal_loc: (15,20)-(15,21) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt b/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt new file mode 100644 index 00000000000000..ebdfd4c5cc6134 --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_method_forwarded_args_legacy.txt @@ -0,0 +1,42 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,15)-(1,18) = "bar" + │ ├── opening_loc: (1,18)-(1,19) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,19)-(1,22)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (1,19)-(1,22)) + │ ├── closing_loc: (1,22)-(1,23) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,11)-(1,12) = ")" + ├── equal_loc: (1,13)-(1,14) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt b/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt new file mode 100644 index 00000000000000..8f8e770fa973e3 --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_method_with_rescue_mod.txt @@ -0,0 +1,52 @@ +@ 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: [] + │ ├── 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: [] + ├── def_keyword_loc: (3,0)-(3,3) = "def" + ├── operator_loc: (3,8)-(3,9) = "." + ├── lparen_loc: (3,10)-(3,11) = "(" + ├── rparen_loc: (3,11)-(3,12) = ")" + ├── equal_loc: (3,13)-(3,14) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/endless_method_without_args.txt b/test/prism/snapshots/whitequark/endless_method_without_args.txt new file mode 100644 index 00000000000000..b7db96171e6397 --- /dev/null +++ b/test/prism/snapshots/whitequark/endless_method_without_args.txt @@ -0,0 +1,85 @@ +@ 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: [] + │ ├── 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: [] + │ ├── 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: [] + │ ├── 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: [] + ├── def_keyword_loc: (7,0)-(7,3) = "def" + ├── operator_loc: (7,8)-(7,9) = "." + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: (7,13)-(7,14) = "=" + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/ensure.txt b/test/prism/snapshots/whitequark/ensure.txt new file mode 100644 index 00000000000000..a82ec2c148ed4c --- /dev/null +++ b/test/prism/snapshots/whitequark/ensure.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,29)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,29)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,29)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,21)-(1,24) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── end_keyword_loc: (1,26)-(1,29) = "end" + └── end_keyword_loc: (1,26)-(1,29) = "end" diff --git a/test/prism/snapshots/whitequark/ensure_empty.txt b/test/prism/snapshots/whitequark/ensure_empty.txt new file mode 100644 index 00000000000000..0bab5d80c363ef --- /dev/null +++ b/test/prism/snapshots/whitequark/ensure_empty.txt @@ -0,0 +1,16 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,16)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: ∅ + ├── else_clause: ∅ + ├── ensure_clause: + │ @ EnsureNode (location: (1,6)-(1,16)) + │ ├── ensure_keyword_loc: (1,6)-(1,12) = "ensure" + │ ├── statements: ∅ + │ └── end_keyword_loc: (1,13)-(1,16) = "end" + └── end_keyword_loc: (1,13)-(1,16) = "end" diff --git a/test/prism/snapshots/whitequark/false.txt b/test/prism/snapshots/whitequark/false.txt new file mode 100644 index 00000000000000..00562f703a98c6 --- /dev/null +++ b/test/prism/snapshots/whitequark/false.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ FalseNode (location: (1,0)-(1,5)) diff --git a/test/prism/snapshots/whitequark/float.txt b/test/prism/snapshots/whitequark/float.txt new file mode 100644 index 00000000000000..14457fcff27890 --- /dev/null +++ b/test/prism/snapshots/whitequark/float.txt @@ -0,0 +1,7 @@ +@ 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 new file mode 100644 index 00000000000000..19118c0c5462b8 --- /dev/null +++ b/test/prism/snapshots/whitequark/for.txt @@ -0,0 +1,81 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── statements: + │ │ @ StatementsNode (location: (1,16)-(1,19)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,16)-(1,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,17) = "p" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,18)-(1,19)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (1,18)-(1,19)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "p" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,9)-(3,12) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (3,14)-(3,17)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,14)-(3,17)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,14)-(3,15) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,16)-(3,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (3,16)-(3,17)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── for_keyword_loc: (3,0)-(3,3) = "for" + ├── in_keyword_loc: (3,6)-(3,8) = "in" + ├── do_keyword_loc: ∅ + └── end_keyword_loc: (3,19)-(3,22) = "end" diff --git a/test/prism/snapshots/whitequark/for_mlhs.txt b/test/prism/snapshots/whitequark/for_mlhs.txt new file mode 100644 index 00000000000000..3fbca4d2992622 --- /dev/null +++ b/test/prism/snapshots/whitequark/for_mlhs.txt @@ -0,0 +1,53 @@ +@ 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (1,4)-(1,5)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (1,7)-(1,8)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── lparen_loc: ∅ + │ └── rparen_loc: ∅ + ├── collection: + │ @ CallNode (location: (1,12)-(1,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,12)-(1,15) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (1,17)-(1,23)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,17)-(1,23)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,17)-(1,18) = "p" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,19)-(1,23)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "p" + ├── for_keyword_loc: (1,0)-(1,3) = "for" + ├── in_keyword_loc: (1,9)-(1,11) = "in" + ├── do_keyword_loc: ∅ + └── end_keyword_loc: (1,25)-(1,28) = "end" diff --git a/test/prism/snapshots/whitequark/forward_arg.txt b/test/prism/snapshots/whitequark/forward_arg.txt new file mode 100644 index 00000000000000..37f836e372b839 --- /dev/null +++ b/test/prism/snapshots/whitequark/forward_arg.txt @@ -0,0 +1,42 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,14)-(1,17) = "bar" + │ ├── opening_loc: (1,17)-(1,18) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,18)-(1,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (1,18)-(1,21)) + │ ├── closing_loc: (1,21)-(1,22) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,11)-(1,12) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,24)-(1,27) = "end" diff --git a/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt b/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt new file mode 100644 index 00000000000000..7c498718cf9163 --- /dev/null +++ b/test/prism/snapshots/whitequark/forward_arg_with_open_args.txt @@ -0,0 +1,386 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (2,2)-(2,5) = "bar" + │ │ │ ├── opening_loc: (2,5)-(2,6) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (2,6)-(2,9)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ ForwardingArgumentsNode (location: (2,6)-(2,9)) + │ │ │ ├── closing_loc: (2,9)-(2,10) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── locals: [:"..."] + │ │ ├── def_keyword_loc: (1,1)-(1,4) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (3,0)-(3,3) = "end" + │ ├── opening_loc: (1,0)-(1,1) = "(" + │ └── closing_loc: (3,3)-(3,4) = ")" + ├── @ ParenthesesNode (location: (5,0)-(5,28)) + │ ├── body: + │ │ @ StatementsNode (location: (5,1)-(5,27)) + │ │ └── body: (length: 1) + │ │ └── @ DefNode (location: (5,1)-(5,27)) + │ │ ├── name: :foo + │ │ ├── name_loc: (5,5)-(5,8) = "foo" + │ │ ├── receiver: ∅ + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (5,9)-(5,12)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: + │ │ │ │ @ ForwardingParameterNode (location: (5,9)-(5,12)) + │ │ │ └── block: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (5,14)-(5,22)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (5,14)-(5,22)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,14)-(5,17) = "bar" + │ │ │ ├── opening_loc: (5,17)-(5,18) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,18)-(5,21)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ ForwardingArgumentsNode (location: (5,18)-(5,21)) + │ │ │ ├── closing_loc: (5,21)-(5,22) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "bar" + │ │ ├── locals: [:"..."] + │ │ ├── def_keyword_loc: (5,1)-(5,4) = "def" + │ │ ├── operator_loc: ∅ + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── equal_loc: ∅ + │ │ └── end_keyword_loc: (5,24)-(5,27) = "end" + │ ├── opening_loc: (5,0)-(5,1) = "(" + │ └── closing_loc: (5,27)-(5,28) = ")" + ├── @ DefNode (location: (7,0)-(8,3)) + │ ├── name: :foo + │ ├── name_loc: (7,4)-(7,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (7,8)-(7,11)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (7,8)-(7,11)) + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (8,0)-(8,3) = "end" + ├── @ DefNode (location: (10,0)-(10,26)) + │ ├── name: :foo + │ ├── name_loc: (10,4)-(10,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (10,8)-(10,11)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (10,8)-(10,11)) + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (10,13)-(10,21)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (10,13)-(10,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,13)-(10,16) = "bar" + │ │ ├── opening_loc: (10,16)-(10,17) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (10,17)-(10,20)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (10,17)-(10,20)) + │ │ ├── closing_loc: (10,20)-(10,21) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (10,0)-(10,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (10,23)-(10,26) = "end" + ├── @ DefNode (location: (12,0)-(14,3)) + │ ├── name: :foo + │ ├── name_loc: (12,4)-(12,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (12,8)-(12,14)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (12,8)-(12,9)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,2)-(13,5) = "bar" + │ │ ├── opening_loc: (13,5)-(13,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (13,6)-(13,9)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (13,6)-(13,9)) + │ │ ├── closing_loc: (13,9)-(13,10) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:a, :"..."] + │ ├── def_keyword_loc: (12,0)-(12,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (14,0)-(14,3) = "end" + ├── @ DefNode (location: (16,0)-(16,29)) + │ ├── name: :foo + │ ├── name_loc: (16,4)-(16,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (16,8)-(16,14)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (16,8)-(16,9)) + │ │ │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (16,16)-(16,19) = "bar" + │ │ ├── opening_loc: (16,19)-(16,20) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (16,20)-(16,23)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (16,20)-(16,23)) + │ │ ├── closing_loc: (16,23)-(16,24) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:a, :"..."] + │ ├── def_keyword_loc: (16,0)-(16,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (16,26)-(16,29) = "end" + ├── @ DefNode (location: (18,0)-(19,3)) + │ ├── name: :foo + │ ├── name_loc: (18,4)-(18,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (18,8)-(18,21)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (18,8)-(18,9)) + │ │ │ └── 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, :"..."] + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (22,2)-(22,5) = "bar" + │ │ ├── opening_loc: (22,5)-(22,6) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (22,6)-(22,9)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (22,6)-(22,9)) + │ │ ├── closing_loc: (22,9)-(22,10) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:b, :"..."] + │ ├── def_keyword_loc: (21,0)-(21,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (23,0)-(23,3) = "end" + ├── @ DefNode (location: (25,0)-(25,33)) + │ ├── name: :foo + │ ├── name_loc: (25,4)-(25,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (25,8)-(25,18)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (25,8)-(25,13)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,20)-(25,23) = "bar" + │ │ ├── opening_loc: (25,23)-(25,24) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (25,24)-(25,27)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (25,24)-(25,27)) + │ │ ├── closing_loc: (25,27)-(25,28) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:b, :"..."] + │ ├── def_keyword_loc: (25,0)-(25,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (25,30)-(25,33) = "end" + └── @ DefNode (location: (27,0)-(27,28)) + ├── name: :foo + ├── name_loc: (27,4)-(27,7) = "foo" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (27,8)-(27,14)) + │ ├── requireds: (length: 1) + │ │ └── @ RequiredParameterNode (location: (27,8)-(27,9)) + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,16)-(27,19) = "bar" + │ ├── opening_loc: (27,19)-(27,20) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,20)-(27,23)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (27,20)-(27,23)) + │ ├── closing_loc: (27,23)-(27,24) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:a, :"..."] + ├── def_keyword_loc: (27,0)-(27,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (27,7)-(27,8) = "(" + ├── rparen_loc: (27,14)-(27,15) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (27,25)-(27,28) = "end" diff --git a/test/prism/snapshots/whitequark/forward_args_legacy.txt b/test/prism/snapshots/whitequark/forward_args_legacy.txt new file mode 100644 index 00000000000000..ea271bd9ce64f9 --- /dev/null +++ b/test/prism/snapshots/whitequark/forward_args_legacy.txt @@ -0,0 +1,97 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,14)-(1,17) = "bar" + │ │ ├── opening_loc: (1,17)-(1,18) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,18)-(1,21)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ ForwardingArgumentsNode (location: (1,18)-(1,21)) + │ │ ├── closing_loc: (1,21)-(1,22) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "bar" + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (1,7)-(1,8) = "(" + │ ├── rparen_loc: (1,11)-(1,12) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,24)-(1,27) = "end" + ├── @ DefNode (location: (3,0)-(3,17)) + │ ├── name: :foo + │ ├── name_loc: (3,4)-(3,7) = "foo" + │ ├── receiver: ∅ + │ ├── parameters: + │ │ @ ParametersNode (location: (3,8)-(3,11)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: + │ │ │ @ ForwardingParameterNode (location: (3,8)-(3,11)) + │ │ └── block: ∅ + │ ├── body: ∅ + │ ├── locals: [:"..."] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: (3,7)-(3,8) = "(" + │ ├── rparen_loc: (3,11)-(3,12) = ")" + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,14)-(3,17) = "end" + └── @ DefNode (location: (5,0)-(5,29)) + ├── name: :foo + ├── name_loc: (5,4)-(5,7) = "foo" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (5,8)-(5,11)) + │ ├── requireds: (length: 0) + │ ├── optionals: (length: 0) + │ ├── rest: ∅ + │ ├── posts: (length: 0) + │ ├── keywords: (length: 0) + │ ├── keyword_rest: + │ │ @ ForwardingParameterNode (location: (5,8)-(5,11)) + │ └── block: ∅ + ├── body: + │ @ StatementsNode (location: (5,14)-(5,24)) + │ └── body: (length: 1) + │ └── @ SuperNode (location: (5,14)-(5,24)) + │ ├── keyword_loc: (5,14)-(5,19) = "super" + │ ├── lparen_loc: (5,19)-(5,20) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,20)-(5,23)) + │ │ └── arguments: (length: 1) + │ │ └── @ ForwardingArgumentsNode (location: (5,20)-(5,23)) + │ ├── rparen_loc: (5,23)-(5,24) = ")" + │ └── block: ∅ + ├── locals: [:"..."] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (5,7)-(5,8) = "(" + ├── rparen_loc: (5,11)-(5,12) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (5,26)-(5,29) = "end" diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt new file mode 100644 index 00000000000000..3a3ddaea6e7f5d --- /dev/null +++ b/test/prism/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt @@ -0,0 +1,54 @@ +@ 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: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,23)-(1,26) = "bar" + │ ├── opening_loc: (1,26)-(1,27) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,27)-(1,39)) + │ │ └── arguments: (length: 2) + │ │ ├── @ LocalVariableReadNode (location: (1,27)-(1,35)) + │ │ │ ├── name: :argument + │ │ │ └── depth: 0 + │ │ └── @ KeywordHashNode (location: (1,37)-(1,39)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (1,37)-(1,39)) + │ │ ├── value: ∅ + │ │ └── operator_loc: (1,37)-(1,39) = "**" + │ ├── closing_loc: (1,39)-(1,40) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:argument, :**] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,20)-(1,21) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,42)-(1,45) = "end" diff --git a/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt b/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt new file mode 100644 index 00000000000000..5c1d350672fd6a --- /dev/null +++ b/test/prism/snapshots/whitequark/forwarded_argument_with_restarg.txt @@ -0,0 +1,52 @@ +@ 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: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,22)-(1,25) = "bar" + │ ├── opening_loc: (1,25)-(1,26) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,26)-(1,37)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:argument, :*] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,19)-(1,20) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,40)-(1,43) = "end" diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt new file mode 100644 index 00000000000000..3690613d9ec050 --- /dev/null +++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg.txt @@ -0,0 +1,49 @@ +@ 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: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,13)-(1,16) = "bar" + │ ├── opening_loc: (1,16)-(1,17) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,17)-(1,19)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,17)-(1,19)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocSplatNode (location: (1,17)-(1,19)) + │ │ ├── value: ∅ + │ │ └── operator_loc: (1,17)-(1,19) = "**" + │ ├── closing_loc: (1,19)-(1,20) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:**] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,10)-(1,11) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,22)-(1,25) = "end" diff --git a/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt new file mode 100644 index 00000000000000..87fbc462fc26f9 --- /dev/null +++ b/test/prism/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt @@ -0,0 +1,59 @@ +@ 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: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,13)-(1,16) = "bar" + │ ├── opening_loc: (1,16)-(1,17) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,17)-(1,35)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,17)-(1,35)) + │ │ └── 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)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:**] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,10)-(1,11) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,38)-(1,41) = "end" diff --git a/test/prism/snapshots/whitequark/forwarded_restarg.txt b/test/prism/snapshots/whitequark/forwarded_restarg.txt new file mode 100644 index 00000000000000..4ff9bf55a83082 --- /dev/null +++ b/test/prism/snapshots/whitequark/forwarded_restarg.txt @@ -0,0 +1,47 @@ +@ 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: nil + │ │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,12)-(1,15) = "bar" + │ ├── opening_loc: (1,15)-(1,16) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,16)-(1,17)) + │ │ └── arguments: (length: 1) + │ │ └── @ SplatNode (location: (1,16)-(1,17)) + │ │ ├── operator_loc: (1,16)-(1,17) = "*" + │ │ └── expression: ∅ + │ ├── closing_loc: (1,17)-(1,18) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:*] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,9)-(1,10) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,20)-(1,23) = "end" diff --git a/test/prism/snapshots/whitequark/gvar.txt b/test/prism/snapshots/whitequark/gvar.txt new file mode 100644 index 00000000000000..f4401c4389b7d8 --- /dev/null +++ b/test/prism/snapshots/whitequark/gvar.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ GlobalVariableReadNode (location: (1,0)-(1,4)) + └── name: :$foo diff --git a/test/prism/snapshots/whitequark/gvasgn.txt b/test/prism/snapshots/whitequark/gvasgn.txt new file mode 100644 index 00000000000000..541a3a0fc4b23a --- /dev/null +++ b/test/prism/snapshots/whitequark/gvasgn.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..38a2c15a9aded4 --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_empty.txt @@ -0,0 +1,9 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ HashNode (location: (1,0)-(1,3)) + ├── opening_loc: (1,0)-(1,1) = "{" + ├── elements: (length: 0) + └── closing_loc: (1,2)-(1,3) = "}" diff --git a/test/prism/snapshots/whitequark/hash_hashrocket.txt b/test/prism/snapshots/whitequark/hash_hashrocket.txt new file mode 100644 index 00000000000000..5b6d1e3920bf9e --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_hashrocket.txt @@ -0,0 +1,44 @@ +@ 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)) + │ │ ├── opening_loc: (3,10)-(3,11) = ":" + │ │ ├── value_loc: (3,11)-(3,14) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── value: + │ │ @ StringNode (location: (3,18)-(3,23)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (3,18)-(3,19) = "\"" + │ │ ├── content_loc: (3,19)-(3,22) = "bar" + │ │ ├── closing_loc: (3,22)-(3,23) = "\"" + │ │ └── unescaped: "bar" + │ └── operator_loc: (3,15)-(3,17) = "=>" + └── closing_loc: (3,24)-(3,25) = "}" diff --git a/test/prism/snapshots/whitequark/hash_kwsplat.txt b/test/prism/snapshots/whitequark/hash_kwsplat.txt new file mode 100644 index 00000000000000..506f054071d481 --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_kwsplat.txt @@ -0,0 +1,33 @@ +@ 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)) + │ │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,12)-(1,15) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── operator_loc: (1,10)-(1,12) = "**" + └── closing_loc: (1,16)-(1,17) = "}" diff --git a/test/prism/snapshots/whitequark/hash_label.txt b/test/prism/snapshots/whitequark/hash_label.txt new file mode 100644 index 00000000000000..444010d4a8c6fa --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_label.txt @@ -0,0 +1,20 @@ +@ 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)) + │ │ ├── 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 new file mode 100644 index 00000000000000..dfa6eb4da514db --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_label_end.txt @@ -0,0 +1,92 @@ +@ ProgramNode (location: (1,0)-(5,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,22)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "f" + │ ├── opening_loc: (1,1)-(1,2) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ IfNode (location: (1,2)-(1,11)) + │ │ ├── if_keyword_loc: ∅ + │ │ ├── predicate: + │ │ │ @ CallNode (location: (1,2)-(1,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,2)-(1,3) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "f" + ├── @ 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)) + │ │ │ ├── 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)) + │ │ │ ├── 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)) + │ │ ├── opening_loc: (5,12)-(5,13) = "'" + │ │ ├── value_loc: (5,13)-(5,16) = "bar" + │ │ ├── closing_loc: (5,16)-(5,18) = "':" + │ │ └── unescaped: "bar" + │ ├── value: + │ │ @ HashNode (location: (5,19)-(5,21)) + │ │ ├── opening_loc: (5,19)-(5,20) = "{" + │ │ ├── elements: (length: 0) + │ │ └── closing_loc: (5,20)-(5,21) = "}" + │ └── operator_loc: ∅ + └── closing_loc: (5,21)-(5,22) = "}" diff --git a/test/prism/snapshots/whitequark/hash_pair_value_omission.txt b/test/prism/snapshots/whitequark/hash_pair_value_omission.txt new file mode 100644 index 00000000000000..37e30983690753 --- /dev/null +++ b/test/prism/snapshots/whitequark/hash_pair_value_omission.txt @@ -0,0 +1,93 @@ +@ 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)) + │ │ │ ├── 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)) + │ │ │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,1)-(3,2) = "a" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "a" + │ │ │ └── operator_loc: ∅ + │ │ └── @ AssocNode (location: (3,5)-(3,7)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (3,5)-(3,7)) + │ │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,5)-(3,6) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── 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)) + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,1)-(5,5) = "puts" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "puts" + │ └── operator_loc: ∅ + └── closing_loc: (5,6)-(5,7) = "}" diff --git a/test/prism/snapshots/whitequark/heredoc.txt b/test/prism/snapshots/whitequark/heredoc.txt new file mode 100644 index 00000000000000..35e6d8be633784 --- /dev/null +++ b/test/prism/snapshots/whitequark/heredoc.txt @@ -0,0 +1,22 @@ +@ 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)-(3,0) = "foo\nbar\n" + │ ├── closing_loc: (4,0)-(4,0) = "HERE\n" + │ └── unescaped: "foo\nbar\n" + ├── @ StringNode (location: (6,0)-(6,6)) + │ ├── flags: ∅ + │ ├── opening_loc: (6,0)-(6,6) = "<bar)" + │ │ │ └── flags: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,18) = "=~" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,19)-(1,24)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "=~" + │ └── locals: [:match] + └── @ LocalVariableReadNode (location: (1,26)-(1,31)) + ├── name: :match + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/lvasgn.txt b/test/prism/snapshots/whitequark/lvasgn.txt new file mode 100644 index 00000000000000..dfa7183840fd5e --- /dev/null +++ b/test/prism/snapshots/whitequark/lvasgn.txt @@ -0,0 +1,16 @@ +@ 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 new file mode 100644 index 00000000000000..e62f8e4ca73c39 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn.txt @@ -0,0 +1,68 @@ +@ 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (1,1)-(1,4)) + │ │ │ ├── name: :foo + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (1,6)-(1,9)) + │ │ ├── name: :bar + │ │ └── depth: 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)) + │ ├── 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)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (3,0)-(3,3)) + │ │ │ ├── name: :foo + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (3,5)-(3,8)) + │ │ ├── name: :bar + │ │ └── depth: 0 + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (3,9)-(3,10) = "=" + │ └── value: + │ @ ArrayNode (location: (3,11)-(3,15)) + │ ├── 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)) + ├── targets: (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 + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (5,14)-(5,15) = "=" + └── value: + @ ArrayNode (location: (5,16)-(5,20)) + ├── 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 new file mode 100644 index 00000000000000..c4464f01d4e0a8 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn_attr.txt @@ -0,0 +1,88 @@ +@ ProgramNode (location: (1,0)-(5,18)) +├── locals: [:foo] +└── statements: + @ StatementsNode (location: (1,0)-(5,18)) + └── body: (length: 3) + ├── @ MultiWriteNode (location: (1,0)-(1,17)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (1,0)-(1,6)) + │ │ │ ├── receiver: + │ │ │ │ @ SelfNode (location: (1,0)-(1,4)) + │ │ │ ├── call_operator_loc: (1,4)-(1,5) = "." + │ │ │ ├── message_loc: (1,5)-(1,6) = "A" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "A=" + │ │ └── @ LocalVariableTargetNode (location: (1,8)-(1,11)) + │ │ ├── name: :foo + │ │ └── depth: 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)) + │ ├── targets: (length: 2) + │ │ ├── @ CallNode (location: (3,0)-(3,6)) + │ │ │ ├── receiver: + │ │ │ │ @ SelfNode (location: (3,0)-(3,4)) + │ │ │ ├── call_operator_loc: (3,4)-(3,5) = "." + │ │ │ ├── message_loc: (3,5)-(3,6) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "a=" + │ │ └── @ CallNode (location: (3,8)-(3,18)) + │ │ ├── receiver: + │ │ │ @ SelfNode (location: (3,8)-(3,12)) + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,12)-(3,18) = "[1, 2]" + │ │ ├── opening_loc: (3,12)-(3,13) = "[" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,13)-(3,17)) + │ │ │ └── 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: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "[]=" + │ ├── 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)) + ├── targets: (length: 2) + │ ├── @ CallNode (location: (5,0)-(5,7)) + │ │ ├── receiver: + │ │ │ @ SelfNode (location: (5,0)-(5,4)) + │ │ ├── call_operator_loc: (5,4)-(5,6) = "::" + │ │ ├── message_loc: (5,6)-(5,7) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "a=" + │ └── @ LocalVariableTargetNode (location: (5,9)-(5,12)) + │ ├── name: :foo + │ └── depth: 0 + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (5,13)-(5,14) = "=" + └── value: + @ LocalVariableReadNode (location: (5,15)-(5,18)) + ├── name: :foo + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/masgn_cmd.txt b/test/prism/snapshots/whitequark/masgn_cmd.txt new file mode 100644 index 00000000000000..e2bfcffa0b95b0 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn_cmd.txt @@ -0,0 +1,32 @@ +@ 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)) + ├── targets: (length: 2) + │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8)) + │ ├── name: :bar + │ └── depth: 0 + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (1,9)-(1,10) = "=" + └── value: + @ CallNode (location: (1,11)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,11)-(1,12) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,13)-(1,16)) + │ └── arguments: (length: 1) + │ └── @ LocalVariableReadNode (location: (1,13)-(1,16)) + │ ├── name: :foo + │ └── depth: 0 + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/masgn_const.txt b/test/prism/snapshots/whitequark/masgn_const.txt new file mode 100644 index 00000000000000..3cd8f13a78d6b7 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn_const.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(3,18)) +├── locals: [:foo] +└── statements: + @ StatementsNode (location: (1,0)-(3,18)) + └── body: (length: 2) + ├── @ MultiWriteNode (location: (1,0)-(1,14)) + │ ├── targets: (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 + │ ├── 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)) + ├── targets: (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 + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (3,13)-(3,14) = "=" + └── value: + @ LocalVariableReadNode (location: (3,15)-(3,18)) + ├── name: :foo + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/masgn_nested.txt b/test/prism/snapshots/whitequark/masgn_nested.txt new file mode 100644 index 00000000000000..9fac89a3014681 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn_nested.txt @@ -0,0 +1,60 @@ +@ 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)) + │ ├── targets: (length: 1) + │ │ └── @ MultiTargetNode (location: (1,1)-(1,6)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (1,2)-(1,3)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ └── @ SplatNode (location: (1,3)-(1,4)) + │ │ │ ├── operator_loc: (1,3)-(1,4) = "," + │ │ │ └── expression: ∅ + │ │ ├── lparen_loc: (1,1)-(1,2) = "(" + │ │ └── rparen_loc: (1,5)-(1,6) = ")" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,10)-(1,13) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + └── @ MultiWriteNode (location: (3,0)-(3,15)) + ├── targets: (length: 2) + │ ├── @ LocalVariableTargetNode (location: (3,0)-(3,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ └── @ MultiTargetNode (location: (3,3)-(3,9)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (3,4)-(3,5)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (3,7)-(3,8)) + │ │ ├── name: :c + │ │ └── depth: 0 + │ ├── lparen_loc: (3,3)-(3,4) = "(" + │ └── rparen_loc: (3,8)-(3,9) = ")" + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (3,10)-(3,11) = "=" + └── value: + @ CallNode (location: (3,12)-(3,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,12)-(3,15) = "foo" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "foo" diff --git a/test/prism/snapshots/whitequark/masgn_splat.txt b/test/prism/snapshots/whitequark/masgn_splat.txt new file mode 100644 index 00000000000000..f4148d51027625 --- /dev/null +++ b/test/prism/snapshots/whitequark/masgn_splat.txt @@ -0,0 +1,270 @@ +@ 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)) + │ ├── targets: (length: 1) + │ │ └── @ SplatNode (location: (1,0)-(1,1)) + │ │ ├── operator_loc: (1,0)-(1,1) = "*" + │ │ └── expression: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (1,2)-(1,3) = "=" + │ └── value: + │ @ CallNode (location: (1,4)-(1,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,7) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (3,0)-(3,13)) + │ ├── targets: (length: 3) + │ │ ├── @ MultiTargetNode (location: (3,0)-(3,1)) + │ │ │ ├── targets: (length: 1) + │ │ │ │ └── @ SplatNode (location: (3,0)-(3,1)) + │ │ │ │ ├── operator_loc: (3,0)-(3,1) = "*" + │ │ │ │ └── expression: ∅ + │ │ │ ├── lparen_loc: ∅ + │ │ │ └── rparen_loc: ∅ + │ │ ├── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,10)-(3,13) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (5,0)-(5,8)) + │ ├── targets: (length: 1) + │ │ └── @ SplatNode (location: (5,0)-(5,2)) + │ │ ├── operator_loc: (5,0)-(5,1) = "*" + │ │ └── expression: + │ │ @ LocalVariableTargetNode (location: (5,1)-(5,2)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (5,3)-(5,4) = "=" + │ └── value: + │ @ CallNode (location: (5,5)-(5,8)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,5)-(5,8) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (7,0)-(7,11)) + │ ├── targets: (length: 2) + │ │ ├── @ MultiTargetNode (location: (7,0)-(7,2)) + │ │ │ ├── targets: (length: 1) + │ │ │ │ └── @ SplatNode (location: (7,0)-(7,2)) + │ │ │ │ ├── operator_loc: (7,0)-(7,1) = "*" + │ │ │ │ └── expression: + │ │ │ │ @ LocalVariableTargetNode (location: (7,1)-(7,2)) + │ │ │ │ ├── name: :b + │ │ │ │ └── depth: 0 + │ │ │ ├── lparen_loc: ∅ + │ │ │ └── rparen_loc: ∅ + │ │ └── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,8)-(7,11) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (9,0)-(9,18)) + │ ├── targets: (length: 2) + │ │ ├── @ InstanceVariableTargetNode (location: (9,0)-(9,4)) + │ │ │ └── name: :@foo + │ │ └── @ ClassVariableTargetNode (location: (9,6)-(9,11)) + │ │ └── name: :@@bar + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (9,12)-(9,13) = "=" + │ └── value: + │ @ ArrayNode (location: (9,14)-(9,18)) + │ ├── elements: (length: 1) + │ │ └── @ SplatNode (location: (9,14)-(9,18)) + │ │ ├── operator_loc: (9,14)-(9,15) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (9,15)-(9,18)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,15)-(9,18) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + ├── @ MultiWriteNode (location: (11,0)-(11,10)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (11,0)-(11,1)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ SplatNode (location: (11,3)-(11,4)) + │ │ ├── operator_loc: (11,3)-(11,4) = "*" + │ │ └── expression: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (11,5)-(11,6) = "=" + │ └── value: + │ @ CallNode (location: (11,7)-(11,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,7)-(11,10) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (13,0)-(13,13)) + │ ├── targets: (length: 3) + │ │ ├── @ LocalVariableTargetNode (location: (13,0)-(13,1)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── @ SplatNode (location: (13,3)-(13,4)) + │ │ │ ├── operator_loc: (13,3)-(13,4) = "*" + │ │ │ └── expression: ∅ + │ │ └── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,10)-(13,13) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (15,0)-(15,11)) + │ ├── targets: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (15,0)-(15,1)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ SplatNode (location: (15,3)-(15,5)) + │ │ ├── operator_loc: (15,3)-(15,4) = "*" + │ │ └── expression: + │ │ @ LocalVariableTargetNode (location: (15,4)-(15,5)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── operator_loc: (15,6)-(15,7) = "=" + │ └── value: + │ @ CallNode (location: (15,8)-(15,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,8)-(15,11) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── @ MultiWriteNode (location: (17,0)-(17,14)) + │ ├── targets: (length: 3) + │ │ ├── @ LocalVariableTargetNode (location: (17,0)-(17,1)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ ├── @ SplatNode (location: (17,3)-(17,5)) + │ │ │ ├── operator_loc: (17,3)-(17,4) = "*" + │ │ │ └── expression: + │ │ │ @ LocalVariableTargetNode (location: (17,4)-(17,5)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ └── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,11)-(17,14) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── @ MultiWriteNode (location: (19,0)-(19,16)) + ├── targets: (length: 2) + │ ├── @ LocalVariableTargetNode (location: (19,0)-(19,1)) + │ │ ├── name: :a + │ │ └── depth: 0 + │ └── @ LocalVariableTargetNode (location: (19,3)-(19,4)) + │ ├── name: :b + │ └── depth: 0 + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── operator_loc: (19,5)-(19,6) = "=" + └── value: + @ ArrayNode (location: (19,7)-(19,16)) + ├── elements: (length: 2) + │ ├── @ SplatNode (location: (19,7)-(19,11)) + │ │ ├── operator_loc: (19,7)-(19,8) = "*" + │ │ └── expression: + │ │ @ CallNode (location: (19,8)-(19,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,8)-(19,11) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── @ CallNode (location: (19,13)-(19,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,13)-(19,16) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── 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 new file mode 100644 index 00000000000000..2ecf554690e58f --- /dev/null +++ b/test/prism/snapshots/whitequark/method_definition_in_while_cond.txt @@ -0,0 +1,197 @@ +@ ProgramNode (location: (1,0)-(7,47)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,47)) + └── body: (length: 4) + ├── @ WhileNode (location: (1,0)-(1,45)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,18)-(1,21) = "tap" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (1,22)-(1,28)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (1,22)-(1,24) = "do" + │ │ │ │ │ └── closing_loc: (1,25)-(1,28) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "tap" + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── body: ∅ + │ │ ├── locals: [:a] + │ │ ├── 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" + │ └── flags: ∅ + ├── @ WhileNode (location: (3,0)-(3,42)) + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,15)-(3,18) = "tap" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (3,19)-(3,25)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (3,19)-(3,21) = "do" + │ │ │ │ └── closing_loc: (3,22)-(3,25) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "tap" + │ │ ├── locals: [] + │ │ ├── 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" + │ └── flags: ∅ + ├── @ WhileNode (location: (5,0)-(5,50)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,23)-(5,26) = "tap" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: + │ │ │ │ │ @ BlockNode (location: (5,27)-(5,33)) + │ │ │ │ │ ├── locals: [] + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ ├── body: ∅ + │ │ │ │ │ ├── opening_loc: (5,27)-(5,29) = "do" + │ │ │ │ │ └── closing_loc: (5,30)-(5,33) = "end" + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "tap" + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── body: ∅ + │ │ ├── locals: [:a] + │ │ ├── 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" + │ └── flags: ∅ + └── @ WhileNode (location: (7,0)-(7,47)) + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,20)-(7,23) = "tap" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (7,24)-(7,30)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (7,24)-(7,26) = "do" + │ │ │ └── closing_loc: (7,27)-(7,30) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "tap" + │ ├── locals: [] + │ ├── 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" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/module.txt b/test/prism/snapshots/whitequark/module.txt new file mode 100644 index 00000000000000..87348c4ec93176 --- /dev/null +++ b/test/prism/snapshots/whitequark/module.txt @@ -0,0 +1,14 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ ModuleNode (location: (1,0)-(1,15)) + ├── locals: [] + ├── module_keyword_loc: (1,0)-(1,6) = "module" + ├── constant_path: + │ @ ConstantReadNode (location: (1,7)-(1,10)) + │ └── name: :Foo + ├── body: ∅ + ├── end_keyword_loc: (1,12)-(1,15) = "end" + └── name: :Foo diff --git a/test/prism/snapshots/whitequark/multiple_pattern_matches.txt b/test/prism/snapshots/whitequark/multiple_pattern_matches.txt new file mode 100644 index 00000000000000..ee1cbd383851ba --- /dev/null +++ b/test/prism/snapshots/whitequark/multiple_pattern_matches.txt @@ -0,0 +1,141 @@ +@ 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (1,10)-(1,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (1,10)-(1,12)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (1,10)-(1,11) = "a" + │ │ │ │ ├── closing_loc: (1,11)-(1,12) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (2,10)-(2,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (2,10)-(2,12)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (2,10)-(2,11) = "a" + │ │ │ │ ├── closing_loc: (2,11)-(2,12) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (4,10)-(4,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (4,10)-(4,12)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (4,10)-(4,11) = "a" + │ │ │ │ ├── closing_loc: (4,11)-(4,12) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ ├── 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: ∅ + │ ├── assocs: (length: 1) + │ │ └── @ AssocNode (location: (5,10)-(5,12)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (5,10)-(5,12)) + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── value_loc: (5,10)-(5,11) = "a" + │ │ │ ├── closing_loc: (5,11)-(5,12) = ":" + │ │ │ └── unescaped: "a" + │ │ ├── value: ∅ + │ │ └── operator_loc: ∅ + │ ├── kwrest: ∅ + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + └── operator_loc: (5,7)-(5,9) = "in" diff --git a/test/prism/snapshots/whitequark/newline_in_hash_argument.txt b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt new file mode 100644 index 00000000000000..6c91492ca86e27 --- /dev/null +++ b/test/prism/snapshots/whitequark/newline_in_hash_argument.txt @@ -0,0 +1,141 @@ +@ ProgramNode (location: (1,0)-(14,1)) +├── locals: [:a, :b] +└── statements: + @ StatementsNode (location: (1,0)-(14,1)) + └── body: (length: 3) + ├── @ CaseNode (location: (1,0)-(8,3)) + │ ├── predicate: + │ │ @ CallNode (location: (1,5)-(1,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── conditions: (length: 2) + │ │ ├── @ InNode (location: (2,0)-(4,4)) + │ │ │ ├── pattern: + │ │ │ │ @ HashPatternNode (location: (2,3)-(2,5)) + │ │ │ │ ├── constant: ∅ + │ │ │ │ ├── assocs: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (2,3)-(2,5)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ SymbolNode (location: (2,3)-(2,5)) + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── value_loc: (2,3)-(2,4) = "a" + │ │ │ │ │ │ ├── closing_loc: (2,4)-(2,5) = ":" + │ │ │ │ │ │ └── unescaped: "a" + │ │ │ │ │ ├── value: ∅ + │ │ │ │ │ └── operator_loc: ∅ + │ │ │ │ ├── kwrest: ∅ + │ │ │ │ ├── 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: ∅ + │ │ │ ├── assocs: (length: 1) + │ │ │ │ └── @ AssocNode (location: (5,3)-(5,7)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (5,3)-(5,7)) + │ │ │ │ │ ├── opening_loc: (5,3)-(5,4) = "\"" + │ │ │ │ │ ├── value_loc: (5,4)-(5,5) = "b" + │ │ │ │ │ ├── closing_loc: (5,5)-(5,7) = "\":" + │ │ │ │ │ └── unescaped: "b" + │ │ │ │ ├── value: ∅ + │ │ │ │ └── operator_loc: ∅ + │ │ │ ├── kwrest: ∅ + │ │ │ ├── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (10,0)-(10,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (10,0)-(10,3) = "obj" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "obj" + │ ├── call_operator_loc: (10,3)-(10,4) = "." + │ ├── message_loc: (10,4)-(10,7) = "set" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (10,8)-(11,1)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (10,8)-(11,1)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (10,8)-(11,1)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (10,8)-(10,14)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "set" + └── @ CallNode (location: (13,0)-(14,1)) + ├── receiver: + │ @ CallNode (location: (13,0)-(13,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,3) = "obj" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "obj" + ├── call_operator_loc: (13,3)-(13,4) = "." + ├── message_loc: (13,4)-(13,7) = "set" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (13,8)-(14,1)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (13,8)-(14,1)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (13,8)-(14,1)) + │ ├── key: + │ │ @ SymbolNode (location: (13,8)-(13,12)) + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "set" diff --git a/test/prism/snapshots/whitequark/next.txt b/test/prism/snapshots/whitequark/next.txt new file mode 100644 index 00000000000000..b7d05ff9aa610d --- /dev/null +++ b/test/prism/snapshots/whitequark/next.txt @@ -0,0 +1,53 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,5)-(3,8)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,5)-(3,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── keyword_loc: (3,0)-(3,4) = "next" + ├── @ NextNode (location: (5,0)-(5,6)) + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,4)-(5,6)) + │ │ └── 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)) + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,5)-(7,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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 new file mode 100644 index 00000000000000..59cb11ac87ffda --- /dev/null +++ b/test/prism/snapshots/whitequark/next_block.txt @@ -0,0 +1,38 @@ +@ 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,5)-(1,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,9)-(1,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,9)-(1,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,13)-(1,19)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,13)-(1,15) = "do" + │ │ └── closing_loc: (1,16)-(1,19) = "end" + │ ├── flags: ∅ + │ └── name: "fun" + └── keyword_loc: (1,0)-(1,4) = "next" diff --git a/test/prism/snapshots/whitequark/nil.txt b/test/prism/snapshots/whitequark/nil.txt new file mode 100644 index 00000000000000..15774c02fd0d19 --- /dev/null +++ b/test/prism/snapshots/whitequark/nil.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ NilNode (location: (1,0)-(1,3)) diff --git a/test/prism/snapshots/whitequark/nil_expression.txt b/test/prism/snapshots/whitequark/nil_expression.txt new file mode 100644 index 00000000000000..74211156111112 --- /dev/null +++ b/test/prism/snapshots/whitequark/nil_expression.txt @@ -0,0 +1,16 @@ +@ ProgramNode (location: (1,0)-(3,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,9)) + └── body: (length: 2) + ├── @ ParenthesesNode (location: (1,0)-(1,2)) + │ ├── body: ∅ + │ ├── opening_loc: (1,0)-(1,1) = "(" + │ └── closing_loc: (1,1)-(1,2) = ")" + └── @ BeginNode (location: (3,0)-(3,9)) + ├── begin_keyword_loc: (3,0)-(3,5) = "begin" + ├── statements: ∅ + ├── rescue_clause: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (3,6)-(3,9) = "end" diff --git a/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt b/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt new file mode 100644 index 00000000000000..d31b67c6899c35 --- /dev/null +++ b/test/prism/snapshots/whitequark/non_lvar_injecting_match.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(1,28)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,28)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,28)) + ├── receiver: + │ @ InterpolatedRegularExpressionNode (location: (1,0)-(1,19)) + │ ├── 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) = "(?bar)" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "(?bar)" + │ ├── closing_loc: (1,18)-(1,19) = "/" + │ └── flags: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,20)-(1,22) = "=~" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,23)-(1,28)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "=~" diff --git a/test/prism/snapshots/whitequark/not.txt b/test/prism/snapshots/whitequark/not.txt new file mode 100644 index 00000000000000..c7706f13bab06b --- /dev/null +++ b/test/prism/snapshots/whitequark/not.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(5,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,8)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: + │ │ @ CallNode (location: (1,4)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,4)-(1,7) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "not" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + ├── @ CallNode (location: (3,0)-(3,5)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "not" + │ ├── opening_loc: (3,3)-(3,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (3,4)-(3,5) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!" + └── @ CallNode (location: (5,0)-(5,8)) + ├── receiver: + │ @ CallNode (location: (5,4)-(5,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,4)-(5,7) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,3) = "not" + ├── opening_loc: (5,3)-(5,4) = "(" + ├── arguments: ∅ + ├── closing_loc: (5,7)-(5,8) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/whitequark/not_cmd.txt b/test/prism/snapshots/whitequark/not_cmd.txt new file mode 100644 index 00000000000000..c31c06dc6bee4c --- /dev/null +++ b/test/prism/snapshots/whitequark/not_cmd.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: + │ @ CallNode (location: (1,4)-(1,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,6)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "not" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/whitequark/not_masgn__24.txt b/test/prism/snapshots/whitequark/not_masgn__24.txt new file mode 100644 index 00000000000000..971d985d11a682 --- /dev/null +++ b/test/prism/snapshots/whitequark/not_masgn__24.txt @@ -0,0 +1,43 @@ +@ 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)) + ├── receiver: + │ @ ParenthesesNode (location: (1,1)-(1,13)) + │ ├── body: + │ │ @ StatementsNode (location: (1,2)-(1,12)) + │ │ └── body: (length: 1) + │ │ └── @ MultiWriteNode (location: (1,2)-(1,12)) + │ │ ├── targets: (length: 2) + │ │ │ ├── @ LocalVariableTargetNode (location: (1,2)-(1,3)) + │ │ │ │ ├── name: :a + │ │ │ │ └── depth: 0 + │ │ │ └── @ LocalVariableTargetNode (location: (1,5)-(1,6)) + │ │ │ ├── name: :b + │ │ │ └── depth: 0 + │ │ ├── lparen_loc: ∅ + │ │ ├── rparen_loc: ∅ + │ │ ├── operator_loc: (1,7)-(1,8) = "=" + │ │ └── value: + │ │ @ CallNode (location: (1,9)-(1,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: (1,1)-(1,2) = "(" + │ └── closing_loc: (1,12)-(1,13) = ")" + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "!" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "!" diff --git a/test/prism/snapshots/whitequark/nth_ref.txt b/test/prism/snapshots/whitequark/nth_ref.txt new file mode 100644 index 00000000000000..1d386d518bab4f --- /dev/null +++ b/test/prism/snapshots/whitequark/nth_ref.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(1,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,3)) + └── body: (length: 1) + └── @ NumberedReferenceReadNode (location: (1,0)-(1,3)) + └── number: 10 diff --git a/test/prism/snapshots/whitequark/numbered_args_after_27.txt b/test/prism/snapshots/whitequark/numbered_args_after_27.txt new file mode 100644 index 00000000000000..d6dfd5e1b5b179 --- /dev/null +++ b/test/prism/snapshots/whitequark/numbered_args_after_27.txt @@ -0,0 +1,131 @@ +@ ProgramNode (location: (1,0)-(7,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,13)) + └── body: (length: 4) + ├── @ LambdaNode (location: (1,0)-(1,17)) + │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,3)-(1,5) = "do" + │ ├── closing_loc: (1,14)-(1,17) = "end" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (1,6)-(1,13)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,6)-(1,13)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (1,6)-(1,8)) + │ │ ├── name: :_1 + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,9)-(1,10) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,11)-(1,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,11)-(1,13)) + │ │ ├── name: :_9 + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ LambdaNode (location: (3,0)-(3,13)) + │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9] + │ ├── operator_loc: (3,0)-(3,2) = "->" + │ ├── opening_loc: (3,3)-(3,4) = "{" + │ ├── closing_loc: (3,12)-(3,13) = "}" + │ ├── parameters: ∅ + │ └── body: + │ @ StatementsNode (location: (3,5)-(3,12)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,5)-(3,12)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (3,5)-(3,7)) + │ │ ├── name: :_1 + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,8)-(3,9) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,10)-(3,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (3,10)-(3,12)) + │ │ ├── name: :_9 + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (5,0)-(5,16)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,2)-(5,16)) + │ │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9] + │ │ ├── parameters: ∅ + │ │ ├── body: + │ │ │ @ StatementsNode (location: (5,5)-(5,12)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (5,5)-(5,12)) + │ │ │ ├── receiver: + │ │ │ │ @ LocalVariableReadNode (location: (5,5)-(5,7)) + │ │ │ │ ├── name: :_1 + │ │ │ │ └── depth: 0 + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,8)-(5,9) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,10)-(5,12)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (5,10)-(5,12)) + │ │ │ │ ├── name: :_9 + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ ├── opening_loc: (5,2)-(5,4) = "do" + │ │ └── closing_loc: (5,13)-(5,16) = "end" + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (7,0)-(7,13)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (7,0)-(7,1) = "m" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (7,2)-(7,13)) + │ ├── locals: [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (7,4)-(7,11)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (7,4)-(7,11)) + │ │ ├── receiver: + │ │ │ @ LocalVariableReadNode (location: (7,4)-(7,6)) + │ │ │ ├── name: :_1 + │ │ │ └── depth: 0 + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,7)-(7,8) = "+" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,9)-(7,11)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ LocalVariableReadNode (location: (7,9)-(7,11)) + │ │ │ ├── name: :_9 + │ │ │ └── depth: 0 + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "+" + │ ├── opening_loc: (7,2)-(7,3) = "{" + │ └── closing_loc: (7,12)-(7,13) = "}" + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/numparam_outside_block.txt b/test/prism/snapshots/whitequark/numparam_outside_block.txt new file mode 100644 index 00000000000000..544d9c274400d9 --- /dev/null +++ b/test/prism/snapshots/whitequark/numparam_outside_block.txt @@ -0,0 +1,114 @@ +@ ProgramNode (location: (1,0)-(9,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(9,17)) + └── body: (length: 5) + ├── @ CallNode (location: (1,0)-(1,2)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,2) = "_1" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "_1" + ├── @ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,9)-(3,12) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── body: + │ │ @ StatementsNode (location: (3,14)-(3,16)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (3,14)-(3,16)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,14)-(3,16) = "_1" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "_1" + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,9)-(5,11) = "_1" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "_1" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,12)-(7,14) = "_1" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "_1" + │ ├── locals: [] + │ ├── def_keyword_loc: (7,0)-(7,3) = "def" + │ ├── operator_loc: (7,8)-(7,9) = "." + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (7,16)-(7,19) = "end" + └── @ ModuleNode (location: (9,0)-(9,17)) + ├── locals: [] + ├── module_keyword_loc: (9,0)-(9,6) = "module" + ├── constant_path: + │ @ ConstantReadNode (location: (9,7)-(9,8)) + │ └── name: :A + ├── body: + │ @ StatementsNode (location: (9,10)-(9,12)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (9,10)-(9,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,10)-(9,12) = "_1" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "_1" + ├── 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 new file mode 100644 index 00000000000000..4594c1006e4bec --- /dev/null +++ b/test/prism/snapshots/whitequark/op_asgn.txt @@ -0,0 +1,80 @@ +@ ProgramNode (location: (1,0)-(5,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,11)) + └── body: (length: 3) + ├── @ CallOperatorWriteNode (location: (1,0)-(1,10)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,5) = "A" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,4) = "." + │ ├── message_loc: (3,4)-(3,5) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + ├── receiver: + │ @ CallNode (location: (5,0)-(5,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (5,3)-(5,5) = "::" + ├── message_loc: (5,5)-(5,6) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: ∅ + ├── 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 new file mode 100644 index 00000000000000..c2af9850021f06 --- /dev/null +++ b/test/prism/snapshots/whitequark/op_asgn_cmd.txt @@ -0,0 +1,183 @@ +@ ProgramNode (location: (1,0)-(7,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,15)) + └── body: (length: 4) + ├── @ CallOperatorWriteNode (location: (1,0)-(1,14)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,5) = "A" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "A" + │ ├── write_name: "A=" + │ ├── operator: :+ + │ ├── operator_loc: (1,6)-(1,8) = "+=" + │ └── value: + │ @ CallNode (location: (1,9)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,9)-(1,10) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,11)-(1,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,11)-(1,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,11)-(1,14) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── @ CallOperatorWriteNode (location: (3,0)-(3,14)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,4) = "." + │ ├── message_loc: (3,4)-(3,5) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "a" + │ ├── write_name: "a=" + │ ├── operator: :+ + │ ├── operator_loc: (3,6)-(3,8) = "+=" + │ └── value: + │ @ CallNode (location: (3,9)-(3,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,9)-(3,10) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,11)-(3,14)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,11)-(3,14)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,11)-(3,14) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── @ ConstantPathOperatorWriteNode (location: (5,0)-(5,15)) + │ ├── target: + │ │ @ ConstantPathNode (location: (5,0)-(5,6)) + │ │ ├── parent: + │ │ │ @ CallNode (location: (5,0)-(5,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,0)-(5,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,10)-(5,11) = "m" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,12)-(5,15)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (5,12)-(5,15)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,12)-(5,15) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "m" + │ └── operator: :+ + └── @ CallOperatorWriteNode (location: (7,0)-(7,15)) + ├── receiver: + │ @ CallNode (location: (7,0)-(7,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (7,3)-(7,5) = "::" + ├── message_loc: (7,5)-(7,6) = "a" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: ∅ + ├── read_name: "a" + ├── write_name: "a=" + ├── operator: :+ + ├── operator_loc: (7,7)-(7,9) = "+=" + └── value: + @ CallNode (location: (7,10)-(7,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (7,10)-(7,11) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (7,12)-(7,15)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (7,12)-(7,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,12)-(7,15) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/op_asgn_index.txt b/test/prism/snapshots/whitequark/op_asgn_index.txt new file mode 100644 index 00000000000000..f44bd7a4c46b4b --- /dev/null +++ b/test/prism/snapshots/whitequark/op_asgn_index.txt @@ -0,0 +1,36 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallOperatorWriteNode (location: (1,0)-(1,14)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[0, 1]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ └── 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) = "]" + ├── flags: ∅ + ├── read_name: "[]" + ├── write_name: "[]=" + ├── 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 new file mode 100644 index 00000000000000..dac4a7970e08e8 --- /dev/null +++ b/test/prism/snapshots/whitequark/op_asgn_index_cmd.txt @@ -0,0 +1,56 @@ +@ ProgramNode (location: (1,0)-(1,18)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,18)) + └── body: (length: 1) + └── @ CallOperatorWriteNode (location: (1,0)-(1,18)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[0, 1]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ └── 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) = "]" + ├── flags: ∅ + ├── read_name: "[]" + ├── write_name: "[]=" + ├── operator: :+ + ├── operator_loc: (1,10)-(1,12) = "+=" + └── value: + @ CallNode (location: (1,13)-(1,18)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,13)-(1,14) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,15)-(1,18)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,15)-(1,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,15)-(1,18) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/optarg.txt b/test/prism/snapshots/whitequark/optarg.txt new file mode 100644 index 00000000000000..d0bacfdfeecdb4 --- /dev/null +++ b/test/prism/snapshots/whitequark/optarg.txt @@ -0,0 +1,68 @@ +@ 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] + │ ├── 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] + ├── def_keyword_loc: (3,0)-(3,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (3,5)-(3,6) = "(" + ├── rparen_loc: (3,18)-(3,19) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (3,21)-(3,24) = "end" diff --git a/test/prism/snapshots/whitequark/or.txt b/test/prism/snapshots/whitequark/or.txt new file mode 100644 index 00000000000000..713ca53ad73cf6 --- /dev/null +++ b/test/prism/snapshots/whitequark/or.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(3,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,10)) + └── body: (length: 2) + ├── @ OrNode (location: (1,0)-(1,10)) + │ ├── left: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── right: + │ │ @ CallNode (location: (1,7)-(1,10)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,10) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── operator_loc: (1,4)-(1,6) = "or" + └── @ OrNode (location: (3,0)-(3,10)) + ├── left: + │ @ CallNode (location: (3,0)-(3,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── right: + │ @ CallNode (location: (3,7)-(3,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,7)-(3,10) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── operator_loc: (3,4)-(3,6) = "||" diff --git a/test/prism/snapshots/whitequark/or_asgn.txt b/test/prism/snapshots/whitequark/or_asgn.txt new file mode 100644 index 00000000000000..db0b4a5adce3dd --- /dev/null +++ b/test/prism/snapshots/whitequark/or_asgn.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(3,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,15)) + └── body: (length: 2) + ├── @ CallOrWriteNode (location: (1,0)-(1,11)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,5) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "a" + │ ├── write_name: "a=" + │ ├── operator_loc: (1,6)-(1,9) = "||=" + │ └── value: + │ @ IntegerNode (location: (1,10)-(1,11)) + │ └── flags: decimal + └── @ CallOrWriteNode (location: (3,0)-(3,15)) + ├── receiver: + │ @ CallNode (location: (3,0)-(3,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (3,3)-(3,9) = "[0, 1]" + ├── opening_loc: (3,3)-(3,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (3,4)-(3,8)) + │ └── 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) = "]" + ├── flags: ∅ + ├── read_name: "[]" + ├── write_name: "[]=" + ├── 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 new file mode 100644 index 00000000000000..e60da94c2a8be1 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_272.txt @@ -0,0 +1,40 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,4)) + │ └── arguments: (length: 1) + │ └── @ InstanceVariableReadNode (location: (1,2)-(1,4)) + │ └── name: :@b + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,5)-(1,15)) + │ ├── locals: [:c] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,8)-(1,11)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,9)-(1,10)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,9)-(1,10)) + │ │ │ │ └── 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" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/whitequark/parser_bug_490.txt b/test/prism/snapshots/whitequark/parser_bug_490.txt new file mode 100644 index 00000000000000..9e4cd2bd15d98d --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_490.txt @@ -0,0 +1,106 @@ +@ ProgramNode (location: (1,0)-(5,45)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,45)) + └── body: (length: 3) + ├── @ DefNode (location: (1,0)-(1,39)) + │ ├── name: :m + │ ├── name_loc: (1,4)-(1,5) = "m" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,7)-(1,34)) + │ │ └── body: (length: 1) + │ │ └── @ SingletonClassNode (location: (1,7)-(1,34)) + │ │ ├── locals: [] + │ │ ├── class_keyword_loc: (1,7)-(1,12) = "class" + │ │ ├── operator_loc: (1,13)-(1,15) = "<<" + │ │ ├── expression: + │ │ │ @ SelfNode (location: (1,16)-(1,20)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (1,22)-(1,29)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ ConstantWriteNode (location: (1,22)-(1,29)) + │ │ │ ├── name: :A + │ │ │ ├── name_loc: (1,22)-(1,23) = "A" + │ │ │ ├── value: + │ │ │ │ @ NilNode (location: (1,26)-(1,29)) + │ │ │ └── operator_loc: (1,24)-(1,25) = "=" + │ │ └── end_keyword_loc: (1,31)-(1,34) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (1,36)-(1,39) = "end" + ├── @ DefNode (location: (3,0)-(3,44)) + │ ├── name: :m + │ ├── name_loc: (3,4)-(3,5) = "m" + │ ├── receiver: ∅ + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (3,7)-(3,39)) + │ │ └── body: (length: 1) + │ │ └── @ SingletonClassNode (location: (3,7)-(3,39)) + │ │ ├── locals: [] + │ │ ├── class_keyword_loc: (3,7)-(3,12) = "class" + │ │ ├── operator_loc: (3,13)-(3,15) = "<<" + │ │ ├── expression: + │ │ │ @ SelfNode (location: (3,16)-(3,20)) + │ │ ├── body: + │ │ │ @ StatementsNode (location: (3,22)-(3,34)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ ClassNode (location: (3,22)-(3,34)) + │ │ │ ├── locals: [] + │ │ │ ├── class_keyword_loc: (3,22)-(3,27) = "class" + │ │ │ ├── constant_path: + │ │ │ │ @ ConstantReadNode (location: (3,28)-(3,29)) + │ │ │ │ └── name: :C + │ │ │ ├── inheritance_operator_loc: ∅ + │ │ │ ├── superclass: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── end_keyword_loc: (3,31)-(3,34) = "end" + │ │ │ └── name: :C + │ │ └── end_keyword_loc: (3,36)-(3,39) = "end" + │ ├── locals: [] + │ ├── def_keyword_loc: (3,0)-(3,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,41)-(3,44) = "end" + └── @ DefNode (location: (5,0)-(5,45)) + ├── name: :m + ├── name_loc: (5,4)-(5,5) = "m" + ├── receiver: ∅ + ├── parameters: ∅ + ├── body: + │ @ StatementsNode (location: (5,7)-(5,40)) + │ └── body: (length: 1) + │ └── @ SingletonClassNode (location: (5,7)-(5,40)) + │ ├── locals: [] + │ ├── class_keyword_loc: (5,7)-(5,12) = "class" + │ ├── operator_loc: (5,13)-(5,15) = "<<" + │ ├── expression: + │ │ @ SelfNode (location: (5,16)-(5,20)) + │ ├── body: + │ │ @ StatementsNode (location: (5,22)-(5,35)) + │ │ └── body: (length: 1) + │ │ └── @ ModuleNode (location: (5,22)-(5,35)) + │ │ ├── locals: [] + │ │ ├── module_keyword_loc: (5,22)-(5,28) = "module" + │ │ ├── constant_path: + │ │ │ @ ConstantReadNode (location: (5,29)-(5,30)) + │ │ │ └── name: :M + │ │ ├── body: ∅ + │ │ ├── end_keyword_loc: (5,32)-(5,35) = "end" + │ │ └── name: :M + │ └── end_keyword_loc: (5,37)-(5,40) = "end" + ├── locals: [] + ├── def_keyword_loc: (5,0)-(5,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (5,42)-(5,45) = "end" diff --git a/test/prism/snapshots/whitequark/parser_bug_507.txt b/test/prism/snapshots/whitequark/parser_bug_507.txt new file mode 100644 index 00000000000000..d2a3d3cba81fdd --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_507.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [:m] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ LocalVariableWriteNode (location: (1,0)-(1,19)) + ├── name: :m + ├── depth: 0 + ├── name_loc: (1,0)-(1,1) = "m" + ├── value: + │ @ LambdaNode (location: (1,4)-(1,19)) + │ ├── locals: [:args] + │ ├── operator_loc: (1,4)-(1,6) = "->" + │ ├── opening_loc: (1,13)-(1,15) = "do" + │ ├── closing_loc: (1,16)-(1,19) = "end" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,7)-(1,12)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,7)-(1,12)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (1,7)-(1,12)) + │ │ │ │ ├── name: :args + │ │ │ │ ├── name_loc: (1,8)-(1,12) = "args" + │ │ │ │ └── operator_loc: (1,7)-(1,8) = "*" + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── body: ∅ + └── operator_loc: (1,2)-(1,3) = "=" diff --git a/test/prism/snapshots/whitequark/parser_bug_518.txt b/test/prism/snapshots/whitequark/parser_bug_518.txt new file mode 100644 index 00000000000000..b63fbb8284ec89 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_518.txt @@ -0,0 +1,18 @@ +@ ProgramNode (location: (1,0)-(2,3)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,3)) + └── body: (length: 1) + └── @ ClassNode (location: (1,0)-(2,3)) + ├── locals: [] + ├── class_keyword_loc: (1,0)-(1,5) = "class" + ├── constant_path: + │ @ ConstantReadNode (location: (1,6)-(1,7)) + │ └── name: :A + ├── inheritance_operator_loc: (1,8)-(1,9) = "<" + ├── superclass: + │ @ ConstantReadNode (location: (1,10)-(1,11)) + │ └── name: :B + ├── body: ∅ + ├── end_keyword_loc: (2,0)-(2,3) = "end" + └── name: :A diff --git a/test/prism/snapshots/whitequark/parser_bug_525.txt b/test/prism/snapshots/whitequark/parser_bug_525.txt new file mode 100644 index 00000000000000..9b85fcb7857fb4 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_525.txt @@ -0,0 +1,62 @@ +@ ProgramNode (location: (1,0)-(1,32)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,32)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,32)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,2) = "m1" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,3)-(1,11)) + │ └── arguments: (length: 1) + │ └── @ KeywordHashNode (location: (1,3)-(1,11)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,3)-(1,11)) + │ ├── key: + │ │ @ SymbolNode (location: (1,3)-(1,5)) + │ │ ├── opening_loc: (1,3)-(1,4) = ":" + │ │ ├── value_loc: (1,4)-(1,5) = "k" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "k" + │ ├── value: + │ │ @ CallNode (location: (1,9)-(1,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,11) = "m2" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "m2" + │ └── operator_loc: (1,6)-(1,8) = "=>" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,12)-(1,32)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,16)-(1,27)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,16)-(1,27)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,18) = "m3" + │ │ ├── opening_loc: (1,18)-(1,19) = "(" + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: (1,19)-(1,20) = ")" + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,21)-(1,27)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,21)-(1,23) = "do" + │ │ │ └── closing_loc: (1,24)-(1,27) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "m3" + │ ├── opening_loc: (1,12)-(1,14) = "do" + │ └── closing_loc: (1,29)-(1,32) = "end" + ├── flags: ∅ + └── name: "m1" diff --git a/test/prism/snapshots/whitequark/parser_bug_604.txt b/test/prism/snapshots/whitequark/parser_bug_604.txt new file mode 100644 index 00000000000000..3e03983f6efa7a --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_604.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,14)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,7)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,2)-(1,7)) + │ ├── receiver: + │ │ @ CallNode (location: (1,2)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "a" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "a" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,6)-(1,7)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,7) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "b" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,8)-(1,14)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,8)-(1,10) = "do" + │ └── closing_loc: (1,11)-(1,14) = "end" + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/parser_bug_640.txt b/test/prism/snapshots/whitequark/parser_bug_640.txt new file mode 100644 index 00000000000000..3ddfb52d9867a9 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_640.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,6)) + └── body: (length: 1) + └── @ StringNode (location: (1,0)-(1,6)) + ├── flags: ∅ + ├── opening_loc: (1,0)-(1,6) = "<<~FOO" + ├── content_loc: (2,0)-(3,0) = " baz\\\n qux\n" + ├── closing_loc: (4,0)-(4,0) = "FOO\n" + └── unescaped: "bazqux\n" diff --git a/test/prism/snapshots/whitequark/parser_bug_645.txt b/test/prism/snapshots/whitequark/parser_bug_645.txt new file mode 100644 index 00000000000000..4eee6234c1cb5f --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_645.txt @@ -0,0 +1,34 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,14)) + ├── locals: [:arg] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,12)-(1,13) = "{" + ├── closing_loc: (1,13)-(1,14) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,3)-(1,11)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,4)-(1,10)) + │ │ ├── requireds: (length: 0) + │ │ ├── optionals: (length: 1) + │ │ │ └── @ OptionalParameterNode (location: (1,4)-(1,10)) + │ │ │ ├── name: :arg + │ │ │ ├── name_loc: (1,4)-(1,7) = "arg" + │ │ │ ├── operator_loc: (1,7)-(1,8) = "=" + │ │ │ └── value: + │ │ │ @ HashNode (location: (1,8)-(1,10)) + │ │ │ ├── opening_loc: (1,8)-(1,9) = "{" + │ │ │ ├── elements: (length: 0) + │ │ │ └── closing_loc: (1,9)-(1,10) = "}" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (1,3)-(1,4) = "(" + │ └── closing_loc: (1,10)-(1,11) = ")" + └── body: ∅ diff --git a/test/prism/snapshots/whitequark/parser_bug_830.txt b/test/prism/snapshots/whitequark/parser_bug_830.txt new file mode 100644 index 00000000000000..f19fffbba0f122 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_bug_830.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ RegularExpressionNode (location: (1,0)-(1,4)) + ├── opening_loc: (1,0)-(1,1) = "/" + ├── content_loc: (1,1)-(1,3) = "\\(" + ├── closing_loc: (1,3)-(1,4) = "/" + ├── unescaped: "(" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt b/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt new file mode 100644 index 00000000000000..8a041058b8cb13 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt @@ -0,0 +1,19 @@ +@ 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)-(2,0)) + │ ├── flags: ∅ + │ ├── opening_loc: ∅ + │ ├── content_loc: (2,5)-(2,0) = "\n" + │ ├── closing_loc: ∅ + │ └── unescaped: "\n" + └── closing_loc: (3,0)-(3,0) = "HERE\n" diff --git a/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt new file mode 100644 index 00000000000000..a527c36f62d667 --- /dev/null +++ b/test/prism/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt @@ -0,0 +1,127 @@ +@ 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)) + │ ├── elements: (length: 1) + │ │ └── @ SymbolNode (location: (4,3)-(5,1)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (4,3)-(5,1) = "a\\\nb" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "ab" + │ ├── 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)) + │ ├── elements: (length: 1) + │ │ └── @ StringNode (location: (10,3)-(11,1)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: ∅ + │ │ ├── content_loc: (10,3)-(11,1) = "a\\\nb" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "ab" + │ ├── opening_loc: (10,0)-(10,3) = "%W{" + │ └── closing_loc: (11,1)-(11,2) = "}" + ├── @ ArrayNode (location: (13,0)-(14,2)) + │ ├── elements: (length: 1) + │ │ └── @ SymbolNode (location: (13,3)-(14,1)) + │ │ ├── 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)) + │ ├── opening_loc: (19,0)-(19,3) = "%r{" + │ ├── content_loc: (19,3)-(20,1) = "a\\\nb" + │ ├── closing_loc: (20,1)-(20,2) = "}" + │ ├── unescaped: "ab" + │ └── flags: ∅ + ├── @ SymbolNode (location: (22,0)-(23,2)) + │ ├── opening_loc: (22,0)-(22,3) = "%s{" + │ ├── value_loc: (22,3)-(23,1) = "a\\\nb" + │ ├── closing_loc: (23,1)-(23,2) = "}" + │ └── unescaped: "ab" + ├── @ ArrayNode (location: (25,0)-(26,2)) + │ ├── 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)) + │ ├── 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)) + │ ├── opening_loc: (37,0)-(37,1) = "/" + │ ├── content_loc: (37,1)-(38,1) = "a\\\nb" + │ ├── closing_loc: (38,1)-(38,2) = "/" + │ ├── unescaped: "ab" + │ └── flags: ∅ + ├── @ SymbolNode (location: (40,0)-(41,2)) + │ ├── 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)) + │ ├── opening_loc: (43,0)-(43,2) = ":'" + │ ├── value_loc: (43,2)-(44,1) = "a\\\nb" + │ ├── closing_loc: (44,1)-(44,2) = "'" + │ └── unescaped: "ab" + ├── @ StringNode (location: (46,0)-(46,9)) + │ ├── flags: ∅ + │ ├── opening_loc: (46,0)-(46,9) = "<<-\"HERE\"" + │ ├── content_loc: (47,0)-(48,0) = "a\\\nb\n" + │ ├── closing_loc: (49,0)-(49,0) = "HERE\n" + │ └── unescaped: "ab\n" + ├── @ StringNode (location: (51,0)-(51,9)) + │ ├── flags: ∅ + │ ├── opening_loc: (51,0)-(51,9) = "<<-'HERE'" + │ ├── content_loc: (52,0)-(53,0) = "a\\\nb\n" + │ ├── closing_loc: (54,0)-(54,0) = "HERE\n" + │ └── unescaped: "a\\\nb\n" + ├── @ XStringNode (location: (56,0)-(56,9)) + │ ├── opening_loc: (56,0)-(56,9) = "<<-`HERE`" + │ ├── content_loc: (57,0)-(58,0) = "a\\\nb\n" + │ ├── closing_loc: (59,0)-(59,0) = "HERE\n" + │ └── unescaped: "ab\n" + └── @ XStringNode (location: (61,0)-(62,2)) + ├── opening_loc: (61,0)-(61,1) = "`" + ├── content_loc: (61,1)-(62,1) = "a\\\nb" + ├── closing_loc: (62,1)-(62,2) = "`" + └── unescaped: "ab" diff --git a/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt new file mode 100644 index 00000000000000..1fc938e1ed96e3 --- /dev/null +++ b/test/prism/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,8)-(3,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,8)-(3,11)) + └── body: (length: 1) + └── @ CaseNode (location: (1,8)-(3,11)) + ├── predicate: + │ @ ArrayNode (location: (1,13)-(1,51)) + │ ├── elements: (length: 3) + │ │ ├── @ SourceFileNode (location: (1,14)-(1,22)) + │ │ │ └── filepath: "whitequark/pattern_matching__FILE__LINE_literals.txt" + │ │ ├── @ CallNode (location: (1,24)-(1,36)) + │ │ │ ├── receiver: + │ │ │ │ @ SourceLineNode (location: (1,24)-(1,32)) + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,33)-(1,34) = "+" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,35)-(1,36)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ IntegerNode (location: (1,35)-(1,36)) + │ │ │ │ └── flags: decimal + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "+" + │ │ └── @ 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 new file mode 100644 index 00000000000000..f6b212c8b2e62f --- /dev/null +++ b/test/prism/snapshots/whitequark/pattern_matching_blank_else.txt @@ -0,0 +1,28 @@ +@ ProgramNode (location: (1,0)-(1,26)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,26)) + └── body: (length: 1) + └── @ CaseNode (location: (1,0)-(1,26)) + ├── predicate: + │ @ 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 new file mode 100644 index 00000000000000..358a556947b218 --- /dev/null +++ b/test/prism/snapshots/whitequark/pattern_matching_else.txt @@ -0,0 +1,32 @@ +@ ProgramNode (location: (1,0)-(1,29)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,29)) + └── body: (length: 1) + └── @ CaseNode (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 new file mode 100644 index 00000000000000..4cda50acb1c553 --- /dev/null +++ b/test/prism/snapshots/whitequark/pattern_matching_single_line.txt @@ -0,0 +1,43 @@ +@ 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 new file mode 100644 index 00000000000000..faf1c957ea8139 --- /dev/null +++ b/test/prism/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt @@ -0,0 +1,221 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (5,10)-(5,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (5,10)-(5,12)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (5,10)-(5,11) = "a" + │ │ │ │ ├── closing_loc: (5,11)-(5,12) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (7,10)-(7,12)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (7,10)-(7,12)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (7,10)-(7,11) = "a" + │ │ │ │ ├── closing_loc: (7,11)-(7,12) = ":" + │ │ │ │ └── unescaped: "a" + │ │ │ ├── value: ∅ + │ │ │ └── operator_loc: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (9,1)-(9,4) = "key" + │ │ │ │ ├── closing_loc: (9,4)-(9,5) = ":" + │ │ │ │ └── unescaped: "key" + │ │ │ ├── value: + │ │ │ │ @ SymbolNode (location: (9,6)-(9,12)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (9,17)-(9,27)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (9,17)-(9,21)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── 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)) + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── value_loc: (11,1)-(11,4) = "key" + │ │ │ │ ├── closing_loc: (11,4)-(11,5) = ":" + │ │ │ │ └── unescaped: "key" + │ │ │ ├── value: + │ │ │ │ @ SymbolNode (location: (11,6)-(11,12)) + │ │ │ │ ├── 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: ∅ + │ │ ├── assocs: (length: 1) + │ │ │ └── @ AssocNode (location: (11,17)-(11,27)) + │ │ │ ├── key: + │ │ │ │ @ SymbolNode (location: (11,17)-(11,21)) + │ │ │ │ ├── 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: ∅ + │ │ ├── kwrest: ∅ + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── operator_loc: (11,14)-(11,16) = "in" + └── @ LocalVariableReadNode (location: (11,29)-(11,34)) + ├── name: :value + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/postexe.txt b/test/prism/snapshots/whitequark/postexe.txt new file mode 100644 index 00000000000000..1c833ffaa48a88 --- /dev/null +++ b/test/prism/snapshots/whitequark/postexe.txt @@ -0,0 +1,14 @@ +@ 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 new file mode 100644 index 00000000000000..955ba6d44426e1 --- /dev/null +++ b/test/prism/snapshots/whitequark/preexe.txt @@ -0,0 +1,14 @@ +@ 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 new file mode 100644 index 00000000000000..8518cbf811f1fa --- /dev/null +++ b/test/prism/snapshots/whitequark/procarg0.txt @@ -0,0 +1,73 @@ +@ ProgramNode (location: (1,0)-(3,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,11)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,2)-(1,18)) + │ │ ├── locals: [:foo, :bar] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (1,5)-(1,15)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredDestructuredParameterNode (location: (1,5)-(1,15)) + │ │ │ │ │ ├── parameters: (length: 2) + │ │ │ │ │ │ ├── @ RequiredParameterNode (location: (1,6)-(1,9)) + │ │ │ │ │ │ │ └── name: :foo + │ │ │ │ │ │ └── @ RequiredParameterNode (location: (1,11)-(1,14)) + │ │ │ │ │ │ └── name: :bar + │ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ │ └── closing_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) = "}" + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (3,0)-(3,11)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,0)-(3,1) = "m" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (3,2)-(3,11)) + │ ├── locals: [:foo] + │ ├── parameters: + │ │ @ BlockParametersNode (location: (3,4)-(3,9)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (3,5)-(3,8)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (3,5)-(3,8)) + │ │ │ │ └── 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) = "}" + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/range_exclusive.txt b/test/prism/snapshots/whitequark/range_exclusive.txt new file mode 100644 index 00000000000000..7e134a3004b416 --- /dev/null +++ b/test/prism/snapshots/whitequark/range_exclusive.txt @@ -0,0 +1,14 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,5)) + ├── left: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── right: + │ @ IntegerNode (location: (1,4)-(1,5)) + │ └── flags: decimal + ├── operator_loc: (1,1)-(1,4) = "..." + └── flags: exclude_end diff --git a/test/prism/snapshots/whitequark/range_inclusive.txt b/test/prism/snapshots/whitequark/range_inclusive.txt new file mode 100644 index 00000000000000..b6fe0458347eb3 --- /dev/null +++ b/test/prism/snapshots/whitequark/range_inclusive.txt @@ -0,0 +1,14 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ RangeNode (location: (1,0)-(1,4)) + ├── left: + │ @ IntegerNode (location: (1,0)-(1,1)) + │ └── flags: decimal + ├── right: + │ @ IntegerNode (location: (1,3)-(1,4)) + │ └── flags: decimal + ├── operator_loc: (1,1)-(1,3) = ".." + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/rational.txt b/test/prism/snapshots/whitequark/rational.txt new file mode 100644 index 00000000000000..260a5d2efc5f02 --- /dev/null +++ b/test/prism/snapshots/whitequark/rational.txt @@ -0,0 +1,12 @@ +@ 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 new file mode 100644 index 00000000000000..48d3da9d52d181 --- /dev/null +++ b/test/prism/snapshots/whitequark/redo.txt @@ -0,0 +1,6 @@ +@ 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 new file mode 100644 index 00000000000000..71d88cae70ada0 --- /dev/null +++ b/test/prism/snapshots/whitequark/regex_interp.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ InterpolatedRegularExpressionNode (location: (1,0)-(1,14)) + ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,6)-(1,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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) = "/" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/regex_plain.txt b/test/prism/snapshots/whitequark/regex_plain.txt new file mode 100644 index 00000000000000..e4c80c53eaa561 --- /dev/null +++ b/test/prism/snapshots/whitequark/regex_plain.txt @@ -0,0 +1,11 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ RegularExpressionNode (location: (1,0)-(1,10)) + ├── opening_loc: (1,0)-(1,1) = "/" + ├── content_loc: (1,1)-(1,7) = "source" + ├── closing_loc: (1,7)-(1,10) = "/im" + ├── unescaped: "source" + └── flags: ignore_case, multi_line diff --git a/test/prism/snapshots/whitequark/resbody_list.txt b/test/prism/snapshots/whitequark/resbody_list.txt new file mode 100644 index 00000000000000..2611c028cbdae8 --- /dev/null +++ b/test/prism/snapshots/whitequark/resbody_list.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,39)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,39)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,39)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,31)-(1,34) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,36)-(1,39) = "end" diff --git a/test/prism/snapshots/whitequark/resbody_list_mrhs.txt b/test/prism/snapshots/whitequark/resbody_list_mrhs.txt new file mode 100644 index 00000000000000..72758b6c97be56 --- /dev/null +++ b/test/prism/snapshots/whitequark/resbody_list_mrhs.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(1,44)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,44)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,44)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,31)-(1,34) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── operator_loc: ∅ + │ ├── reference: ∅ + │ ├── statements: + │ │ @ StatementsNode (location: (1,36)-(1,39)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,36)-(1,39)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,36)-(1,39) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,41)-(1,44) = "end" diff --git a/test/prism/snapshots/whitequark/resbody_list_var.txt b/test/prism/snapshots/whitequark/resbody_list_var.txt new file mode 100644 index 00000000000000..27798cd6104389 --- /dev/null +++ b/test/prism/snapshots/whitequark/resbody_list_var.txt @@ -0,0 +1,56 @@ +@ ProgramNode (location: (1,0)-(1,39)) +├── locals: [:ex] +└── statements: + @ StatementsNode (location: (1,0)-(1,39)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,39)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── rescue_clause: + │ @ RescueNode (location: (1,13)-(1,34)) + │ ├── keyword_loc: (1,13)-(1,19) = "rescue" + │ ├── exceptions: (length: 1) + │ │ └── @ CallNode (location: (1,20)-(1,23)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,20)-(1,23) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,31)-(1,34) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,36)-(1,39) = "end" diff --git a/test/prism/snapshots/whitequark/resbody_var.txt b/test/prism/snapshots/whitequark/resbody_var.txt new file mode 100644 index 00000000000000..1428a7e6c3d8a2 --- /dev/null +++ b/test/prism/snapshots/whitequark/resbody_var.txt @@ -0,0 +1,86 @@ +@ ProgramNode (location: (1,0)-(3,35)) +├── locals: [:ex] +└── statements: + @ StatementsNode (location: (1,0)-(3,35)) + └── body: (length: 2) + ├── @ BeginNode (location: (1,0)-(1,36)) + │ ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + │ ├── statements: + │ │ @ StatementsNode (location: (1,7)-(1,11)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,7)-(1,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,11) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,28)-(1,31) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,7)-(3,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,27)-(3,30) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (3,32)-(3,35) = "end" diff --git a/test/prism/snapshots/whitequark/rescue.txt b/test/prism/snapshots/whitequark/rescue.txt new file mode 100644 index 00000000000000..8bf45b892e8315 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(1,29)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,29)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,29)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,21)-(1,24) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── consequent: ∅ + ├── else_clause: ∅ + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,26)-(1,29) = "end" diff --git a/test/prism/snapshots/whitequark/rescue_else.txt b/test/prism/snapshots/whitequark/rescue_else.txt new file mode 100644 index 00000000000000..9d39f38aef5916 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_else.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(1,40)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,40)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,40)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,21)-(1,24) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,32)-(1,35) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── end_keyword_loc: (1,37)-(1,40) = "end" + ├── ensure_clause: ∅ + └── end_keyword_loc: (1,37)-(1,40) = "end" diff --git a/test/prism/snapshots/whitequark/rescue_else_ensure.txt b/test/prism/snapshots/whitequark/rescue_else_ensure.txt new file mode 100644 index 00000000000000..f3d59057e7c0e4 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_else_ensure.txt @@ -0,0 +1,75 @@ +@ ProgramNode (location: (1,0)-(1,51)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,51)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,51)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,21)-(1,24) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,31)-(1,34) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,44)-(1,47) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── end_keyword_loc: (1,48)-(1,51) = "end" + └── end_keyword_loc: (1,48)-(1,51) = "end" diff --git a/test/prism/snapshots/whitequark/rescue_ensure.txt b/test/prism/snapshots/whitequark/rescue_ensure.txt new file mode 100644 index 00000000000000..f709474a7cc5de --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_ensure.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(1,42)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,42)) + └── body: (length: 1) + └── @ BeginNode (location: (1,0)-(1,42)) + ├── begin_keyword_loc: (1,0)-(1,5) = "begin" + ├── statements: + │ @ StatementsNode (location: (1,7)-(1,11)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,7)-(1,11)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,11) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,21)-(1,24) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,34)-(1,37) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── end_keyword_loc: (1,39)-(1,42) = "end" + └── end_keyword_loc: (1,39)-(1,42) = "end" diff --git a/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt b/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt new file mode 100644 index 00000000000000..72b6842f4258bc --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_in_lambda_block.txt @@ -0,0 +1,26 @@ +@ ProgramNode (location: (1,0)-(1,17)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,17)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,17)) + ├── locals: [] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,3)-(1,5) = "do" + ├── closing_loc: (1,14)-(1,17) = "end" + ├── parameters: ∅ + └── body: + @ BeginNode (location: (1,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 new file mode 100644 index 00000000000000..a0d9cc6ceb655a --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_mod.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ RescueModifierNode (location: (1,0)-(1,15)) + ├── expression: + │ @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── keyword_loc: (1,5)-(1,11) = "rescue" + └── rescue_expression: + @ CallNode (location: (1,12)-(1,15)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,12)-(1,15) = "bar" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: variable_call + └── name: "bar" diff --git a/test/prism/snapshots/whitequark/rescue_mod_asgn.txt b/test/prism/snapshots/whitequark/rescue_mod_asgn.txt new file mode 100644 index 00000000000000..85c68e719bc31f --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_mod_asgn.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(1,21)) +├── locals: [:foo] +└── statements: + @ StatementsNode (location: (1,0)-(1,21)) + └── body: (length: 1) + └── @ LocalVariableWriteNode (location: (1,0)-(1,21)) + ├── name: :foo + ├── depth: 0 + ├── name_loc: (1,0)-(1,3) = "foo" + ├── value: + │ @ RescueModifierNode (location: (1,6)-(1,21)) + │ ├── expression: + │ │ @ CallNode (location: (1,6)-(1,10)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,10) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ ├── keyword_loc: (1,11)-(1,17) = "rescue" + │ └── rescue_expression: + │ @ CallNode (location: (1,18)-(1,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,18)-(1,21) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + └── operator_loc: (1,4)-(1,5) = "=" diff --git a/test/prism/snapshots/whitequark/rescue_mod_masgn.txt b/test/prism/snapshots/whitequark/rescue_mod_masgn.txt new file mode 100644 index 00000000000000..bf2db50258f763 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_mod_masgn.txt @@ -0,0 +1,39 @@ +@ 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)) + ├── targets: (length: 2) + │ ├── @ LocalVariableTargetNode (location: (1,0)-(1,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ └── @ LocalVariableTargetNode (location: (1,5)-(1,8)) + │ ├── name: :bar + │ └── depth: 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,15) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── keyword_loc: (1,16)-(1,22) = "rescue" + └── rescue_expression: + @ ArrayNode (location: (1,23)-(1,29)) + ├── 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 new file mode 100644 index 00000000000000..32aa9d38805889 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_mod_op_assign.txt @@ -0,0 +1,36 @@ +@ ProgramNode (location: (1,0)-(1,22)) +├── locals: [:foo] +└── statements: + @ StatementsNode (location: (1,0)-(1,22)) + └── body: (length: 1) + └── @ LocalVariableOperatorWriteNode (location: (1,0)-(1,22)) + ├── name_loc: (1,0)-(1,3) = "foo" + ├── operator_loc: (1,4)-(1,6) = "+=" + ├── value: + │ @ RescueModifierNode (location: (1,7)-(1,22)) + │ ├── expression: + │ │ @ CallNode (location: (1,7)-(1,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,11) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ ├── keyword_loc: (1,12)-(1,18) = "rescue" + │ └── rescue_expression: + │ @ CallNode (location: (1,19)-(1,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,19)-(1,22) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── name: :foo + ├── operator: :+ + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/rescue_without_begin_end.txt b/test/prism/snapshots/whitequark/rescue_without_begin_end.txt new file mode 100644 index 00000000000000..250b63fdda7d55 --- /dev/null +++ b/test/prism/snapshots/whitequark/rescue_without_begin_end.txt @@ -0,0 +1,59 @@ +@ ProgramNode (location: (1,0)-(1,30)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,30)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,30)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,4) = "meth" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,5)-(1,30)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ BeginNode (location: (1,9)-(1,30)) + │ │ ├── begin_keyword_loc: ∅ + │ │ ├── statements: + │ │ │ @ StatementsNode (location: (1,9)-(1,12)) + │ │ │ └── body: (length: 1) + │ │ │ └── @ CallNode (location: (1,9)-(1,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,9)-(1,12) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,22)-(1,25) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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" + ├── flags: ∅ + └── name: "meth" diff --git a/test/prism/snapshots/whitequark/restarg_named.txt b/test/prism/snapshots/whitequark/restarg_named.txt new file mode 100644 index 00000000000000..3255609cdde618 --- /dev/null +++ b/test/prism/snapshots/whitequark/restarg_named.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,16)) + ├── name: :f + ├── name_loc: (1,4)-(1,5) = "f" + ├── receiver: ∅ + ├── parameters: + │ @ ParametersNode (location: (1,6)-(1,10)) + │ ├── requireds: (length: 0) + │ ├── optionals: (length: 0) + │ ├── rest: + │ │ @ 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] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,10)-(1,11) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,13)-(1,16) = "end" diff --git a/test/prism/snapshots/whitequark/restarg_unnamed.txt b/test/prism/snapshots/whitequark/restarg_unnamed.txt new file mode 100644 index 00000000000000..82e8f3f7abcf5c --- /dev/null +++ b/test/prism/snapshots/whitequark/restarg_unnamed.txt @@ -0,0 +1,30 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ DefNode (location: (1,0)-(1,13)) + ├── name: :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: nil + │ │ ├── name_loc: ∅ + │ │ └── operator_loc: (1,6)-(1,7) = "*" + │ ├── posts: (length: 0) + │ ├── keywords: (length: 0) + │ ├── keyword_rest: ∅ + │ └── block: ∅ + ├── body: ∅ + ├── locals: [:*] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,5)-(1,6) = "(" + ├── rparen_loc: (1,7)-(1,8) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,10)-(1,13) = "end" diff --git a/test/prism/snapshots/whitequark/retry.txt b/test/prism/snapshots/whitequark/retry.txt new file mode 100644 index 00000000000000..671c36951469ce --- /dev/null +++ b/test/prism/snapshots/whitequark/retry.txt @@ -0,0 +1,6 @@ +@ 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 new file mode 100644 index 00000000000000..5bf8d4ca10782b --- /dev/null +++ b/test/prism/snapshots/whitequark/return.txt @@ -0,0 +1,53 @@ +@ 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (3,7)-(3,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,7)-(3,10) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── @ ReturnNode (location: (5,0)-(5,8)) + │ ├── keyword_loc: (5,0)-(5,6) = "return" + │ └── arguments: + │ @ ArgumentsNode (location: (5,6)-(5,8)) + │ └── 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)) + └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,7)-(7,10) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── opening_loc: (7,6)-(7,7) = "(" + └── closing_loc: (7,10)-(7,11) = ")" diff --git a/test/prism/snapshots/whitequark/return_block.txt b/test/prism/snapshots/whitequark/return_block.txt new file mode 100644 index 00000000000000..91cd334f06e194 --- /dev/null +++ b/test/prism/snapshots/whitequark/return_block.txt @@ -0,0 +1,38 @@ +@ 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)) + └── arguments: (length: 1) + └── @ CallNode (location: (1,7)-(1,21)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,7)-(1,10) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,11)-(1,14)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,11)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,15)-(1,21)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,15)-(1,17) = "do" + │ └── closing_loc: (1,18)-(1,21) = "end" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/ruby_bug_10279.txt b/test/prism/snapshots/whitequark/ruby_bug_10279.txt new file mode 100644 index 00000000000000..be4105fff31124 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_10279.txt @@ -0,0 +1,29 @@ +@ 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)) + │ │ ├── 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)) + │ │ ├── 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 new file mode 100644 index 00000000000000..edd326980423cd --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_10653.txt @@ -0,0 +1,166 @@ +@ 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)) + │ ├── statements: + │ │ @ StatementsNode (location: (1,8)-(1,20)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,8)-(1,20)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,8)-(1,13) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,14)-(1,20)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,14)-(1,16) = "do" + │ │ │ └── closing_loc: (1,17)-(1,20) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,23)-(1,26) = "tap" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (1,27)-(1,33)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (1,27)-(1,29) = "do" + │ │ │ │ └── closing_loc: (1,30)-(1,33) = "end" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "tap" + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + ├── @ IfNode (location: (3,0)-(3,25)) + │ ├── if_keyword_loc: ∅ + │ ├── predicate: + │ │ @ FalseNode (location: (3,0)-(3,5)) + │ ├── statements: + │ │ @ StatementsNode (location: (3,8)-(3,16)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (3,8)-(3,16)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,8)-(3,13) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (3,14)-(3,16)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (3,14)-(3,15) = "{" + │ │ │ └── closing_loc: (3,15)-(3,16) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,19)-(3,22) = "tap" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (3,23)-(3,25)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: ∅ + │ │ │ │ ├── opening_loc: (3,23)-(3,24) = "{" + │ │ │ │ └── closing_loc: (3,24)-(3,25) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "tap" + │ │ └── end_keyword_loc: ∅ + │ └── end_keyword_loc: ∅ + └── @ IfNode (location: (5,0)-(5,31)) + ├── if_keyword_loc: ∅ + ├── predicate: + │ @ TrueNode (location: (5,0)-(5,4)) + ├── statements: + │ @ StatementsNode (location: (5,7)-(5,27)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (5,7)-(5,27)) + │ ├── receiver: + │ │ @ IntegerNode (location: (5,7)-(5,8)) + │ │ └── flags: decimal + │ ├── call_operator_loc: (5,8)-(5,9) = "." + │ ├── message_loc: (5,9)-(5,12) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,13)-(5,27)) + │ │ ├── locals: [:n] + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (5,16)-(5,19)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (5,17)-(5,18)) + │ │ │ │ ├── requireds: (length: 1) + │ │ │ │ │ └── @ RequiredParameterNode (location: (5,17)-(5,18)) + │ │ │ │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,20)-(5,21) = "p" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,22)-(5,23)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ LocalVariableReadNode (location: (5,22)-(5,23)) + │ │ │ │ ├── name: :n + │ │ │ │ └── depth: 0 + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "p" + │ │ ├── opening_loc: (5,13)-(5,15) = "do" + │ │ └── closing_loc: (5,24)-(5,27) = "end" + │ ├── flags: ∅ + │ └── name: "tap" + ├── 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 new file mode 100644 index 00000000000000..28aa66ee5af9e5 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11107.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(1,24)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,24)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,24)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,24)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (1,2)-(1,24)) + │ ├── locals: [] + │ ├── operator_loc: (1,2)-(1,4) = "->" + │ ├── opening_loc: (1,7)-(1,9) = "do" + │ ├── closing_loc: (1,21)-(1,24) = "end" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,4)-(1,6)) + │ │ ├── parameters: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,4)-(1,5) = "(" + │ │ └── closing_loc: (1,5)-(1,6) = ")" + │ └── body: + │ @ StatementsNode (location: (1,10)-(1,20)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,10)-(1,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,10)-(1,11) = "a" + │ ├── opening_loc: (1,11)-(1,12) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (1,12)-(1,13) = ")" + │ ├── block: + │ │ @ BlockNode (location: (1,14)-(1,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,14)-(1,16) = "do" + │ │ └── closing_loc: (1,17)-(1,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11380.txt b/test/prism/snapshots/whitequark/ruby_bug_11380.txt new file mode 100644 index 00000000000000..4453caa63d62a0 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11380.txt @@ -0,0 +1,50 @@ +@ ProgramNode (location: (1,0)-(1,28)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,28)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,28)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,21)) + │ └── arguments: (length: 2) + │ ├── @ LambdaNode (location: (1,2)-(1,15)) + │ │ ├── locals: [] + │ │ ├── operator_loc: (1,2)-(1,4) = "->" + │ │ ├── opening_loc: (1,5)-(1,6) = "{" + │ │ ├── closing_loc: (1,14)-(1,15) = "}" + │ │ ├── parameters: ∅ + │ │ └── body: + │ │ @ StatementsNode (location: (1,7)-(1,13)) + │ │ └── body: (length: 1) + │ │ └── @ SymbolNode (location: (1,7)-(1,13)) + │ │ ├── opening_loc: (1,7)-(1,8) = ":" + │ │ ├── value_loc: (1,8)-(1,13) = "hello" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "hello" + │ └── @ KeywordHashNode (location: (1,17)-(1,21)) + │ └── elements: (length: 1) + │ └── @ AssocNode (location: (1,17)-(1,21)) + │ ├── key: + │ │ @ SymbolNode (location: (1,17)-(1,19)) + │ │ ├── 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: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,22)-(1,24) = "do" + │ └── closing_loc: (1,25)-(1,28) = "end" + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873.txt b/test/prism/snapshots/whitequark/ruby_bug_11873.txt new file mode 100644 index 00000000000000..e7fdb64e9e9019 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11873.txt @@ -0,0 +1,737 @@ +@ ProgramNode (location: (1,0)-(23,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(23,22)) + └── body: (length: 12) + ├── @ CallNode (location: (1,0)-(1,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (1,2)-(1,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,2)-(1,3) = "b" + │ │ │ ├── opening_loc: (1,3)-(1,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (1,4)-(1,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (1,7)-(1,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ StringNode (location: (1,10)-(1,13)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,10)-(1,11) = "\"" + │ │ ├── content_loc: (1,11)-(1,12) = "x" + │ │ ├── closing_loc: (1,12)-(1,13) = "\"" + │ │ └── unescaped: "x" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,14)-(1,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,14)-(1,16) = "do" + │ │ └── closing_loc: (1,17)-(1,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (3,0)-(3,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,2)-(3,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (3,2)-(3,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,2)-(3,3) = "b" + │ │ │ ├── opening_loc: (3,3)-(3,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (3,4)-(3,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (3,4)-(3,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,4)-(3,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (3,6)-(3,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (3,6)-(3,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (3,6)-(3,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (3,7)-(3,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (3,10)-(3,13)) + │ │ ├── opening_loc: (3,10)-(3,11) = "/" + │ │ ├── content_loc: (3,11)-(3,12) = "x" + │ │ ├── closing_loc: (3,12)-(3,13) = "/" + │ │ ├── unescaped: "x" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,14)-(3,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,14)-(3,16) = "do" + │ │ └── closing_loc: (3,17)-(3,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (5,0)-(5,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,2)-(5,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (5,2)-(5,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,2)-(5,3) = "b" + │ │ │ ├── opening_loc: (5,3)-(5,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,4)-(5,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (5,4)-(5,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,4)-(5,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (5,6)-(5,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (5,6)-(5,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (5,6)-(5,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (5,7)-(5,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (5,10)-(5,14)) + │ │ ├── opening_loc: (5,10)-(5,11) = "/" + │ │ ├── content_loc: (5,11)-(5,12) = "x" + │ │ ├── closing_loc: (5,12)-(5,14) = "/m" + │ │ ├── unescaped: "x" + │ │ └── flags: multi_line + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,15)-(5,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (5,15)-(5,17) = "do" + │ │ └── closing_loc: (5,18)-(5,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (7,0)-(7,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,2)-(7,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (7,2)-(7,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,2)-(7,3) = "b" + │ │ │ ├── opening_loc: (7,3)-(7,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (7,4)-(7,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (7,4)-(7,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (7,4)-(7,5) = "c" + │ │ │ │ ├── opening_loc: (7,5)-(7,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (7,6)-(7,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (7,6)-(7,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (7,7)-(7,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (7,8)-(7,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ StringNode (location: (7,11)-(7,14)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (7,11)-(7,12) = "\"" + │ │ ├── content_loc: (7,12)-(7,13) = "x" + │ │ ├── closing_loc: (7,13)-(7,14) = "\"" + │ │ └── unescaped: "x" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (7,15)-(7,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (7,15)-(7,17) = "do" + │ │ └── closing_loc: (7,18)-(7,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (9,0)-(9,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,0)-(9,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,2)-(9,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (9,2)-(9,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,3) = "b" + │ │ │ ├── opening_loc: (9,3)-(9,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (9,4)-(9,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (9,4)-(9,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,4)-(9,5) = "c" + │ │ │ │ ├── opening_loc: (9,5)-(9,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (9,6)-(9,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (9,6)-(9,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (9,6)-(9,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (9,7)-(9,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (9,8)-(9,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (9,11)-(9,14)) + │ │ ├── opening_loc: (9,11)-(9,12) = "/" + │ │ ├── content_loc: (9,12)-(9,13) = "x" + │ │ ├── closing_loc: (9,13)-(9,14) = "/" + │ │ ├── unescaped: "x" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (9,15)-(9,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (9,15)-(9,17) = "do" + │ │ └── closing_loc: (9,18)-(9,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (11,0)-(11,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,2)-(11,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (11,2)-(11,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,2)-(11,3) = "b" + │ │ │ ├── opening_loc: (11,3)-(11,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (11,4)-(11,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (11,4)-(11,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (11,4)-(11,5) = "c" + │ │ │ │ ├── opening_loc: (11,5)-(11,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (11,6)-(11,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (11,6)-(11,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (11,6)-(11,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (11,8)-(11,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (11,11)-(11,15)) + │ │ ├── opening_loc: (11,11)-(11,12) = "/" + │ │ ├── content_loc: (11,12)-(11,13) = "x" + │ │ ├── closing_loc: (11,13)-(11,15) = "/m" + │ │ ├── unescaped: "x" + │ │ └── flags: multi_line + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (11,16)-(11,22)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (11,16)-(11,18) = "do" + │ │ └── closing_loc: (11,19)-(11,22) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (13,0)-(13,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,2)-(13,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (13,2)-(13,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,2)-(13,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (13,3)-(13,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (13,4)-(13,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (13,4)-(13,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (13,4)-(13,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (13,6)-(13,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (13,6)-(13,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (13,6)-(13,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (13,3)-(13,4) = "{" + │ │ │ │ └── closing_loc: (13,7)-(13,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ StringNode (location: (13,10)-(13,13)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (13,10)-(13,11) = "\"" + │ │ ├── content_loc: (13,11)-(13,12) = "x" + │ │ ├── closing_loc: (13,12)-(13,13) = "\"" + │ │ └── unescaped: "x" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,14)-(13,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (13,14)-(13,16) = "do" + │ │ └── closing_loc: (13,17)-(13,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (15,0)-(15,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,2)-(15,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (15,2)-(15,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,2)-(15,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (15,3)-(15,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (15,4)-(15,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (15,4)-(15,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (15,4)-(15,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (15,6)-(15,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (15,6)-(15,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (15,6)-(15,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (15,3)-(15,4) = "{" + │ │ │ │ └── closing_loc: (15,7)-(15,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (15,10)-(15,13)) + │ │ ├── opening_loc: (15,10)-(15,11) = "/" + │ │ ├── content_loc: (15,11)-(15,12) = "x" + │ │ ├── closing_loc: (15,12)-(15,13) = "/" + │ │ ├── unescaped: "x" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (15,14)-(15,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (15,14)-(15,16) = "do" + │ │ └── closing_loc: (15,17)-(15,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (17,0)-(17,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,2)-(17,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (17,2)-(17,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (17,2)-(17,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (17,3)-(17,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (17,4)-(17,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (17,4)-(17,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (17,4)-(17,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (17,6)-(17,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (17,6)-(17,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (17,6)-(17,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (17,3)-(17,4) = "{" + │ │ │ │ └── closing_loc: (17,7)-(17,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (17,10)-(17,14)) + │ │ ├── opening_loc: (17,10)-(17,11) = "/" + │ │ ├── content_loc: (17,11)-(17,12) = "x" + │ │ ├── closing_loc: (17,12)-(17,14) = "/m" + │ │ ├── unescaped: "x" + │ │ └── flags: multi_line + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (17,15)-(17,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (17,15)-(17,17) = "do" + │ │ └── closing_loc: (17,18)-(17,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (19,0)-(19,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,0)-(19,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (19,2)-(19,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (19,2)-(19,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,2)-(19,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (19,3)-(19,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (19,4)-(19,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (19,4)-(19,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (19,4)-(19,5) = "c" + │ │ │ │ │ ├── opening_loc: (19,5)-(19,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (19,3)-(19,4) = "{" + │ │ │ │ └── closing_loc: (19,8)-(19,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ StringNode (location: (19,11)-(19,14)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (19,11)-(19,12) = "\"" + │ │ ├── content_loc: (19,12)-(19,13) = "x" + │ │ ├── closing_loc: (19,13)-(19,14) = "\"" + │ │ └── unescaped: "x" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (19,15)-(19,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (19,15)-(19,17) = "do" + │ │ └── closing_loc: (19,18)-(19,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (21,0)-(21,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,0)-(21,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,2)-(21,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (21,2)-(21,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,2)-(21,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (21,3)-(21,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (21,4)-(21,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (21,4)-(21,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (21,4)-(21,5) = "c" + │ │ │ │ │ ├── opening_loc: (21,5)-(21,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (21,6)-(21,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (21,6)-(21,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (21,6)-(21,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (21,7)-(21,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (21,3)-(21,4) = "{" + │ │ │ │ └── closing_loc: (21,8)-(21,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RegularExpressionNode (location: (21,11)-(21,14)) + │ │ ├── opening_loc: (21,11)-(21,12) = "/" + │ │ ├── content_loc: (21,12)-(21,13) = "x" + │ │ ├── closing_loc: (21,13)-(21,14) = "/" + │ │ ├── unescaped: "x" + │ │ └── flags: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (21,15)-(21,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (21,15)-(21,17) = "do" + │ │ └── closing_loc: (21,18)-(21,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (23,0)-(23,22)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (23,0)-(23,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (23,2)-(23,15)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (23,2)-(23,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,2)-(23,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (23,3)-(23,9)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (23,4)-(23,8)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (23,4)-(23,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (23,4)-(23,5) = "c" + │ │ │ │ ├── opening_loc: (23,5)-(23,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (23,6)-(23,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (23,6)-(23,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (23,6)-(23,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (23,7)-(23,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── opening_loc: (23,3)-(23,4) = "{" + │ │ │ └── closing_loc: (23,8)-(23,9) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ └── @ RegularExpressionNode (location: (23,11)-(23,15)) + │ ├── opening_loc: (23,11)-(23,12) = "/" + │ ├── content_loc: (23,12)-(23,13) = "x" + │ ├── closing_loc: (23,13)-(23,15) = "/m" + │ ├── unescaped: "x" + │ └── flags: multi_line + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (23,16)-(23,22)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (23,16)-(23,18) = "do" + │ └── closing_loc: (23,19)-(23,22) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt new file mode 100644 index 00000000000000..c5d24ac5f76e1b --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11873_a.txt @@ -0,0 +1,1161 @@ +@ ProgramNode (location: (1,0)-(39,20)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(39,20)) + └── body: (length: 20) + ├── @ CallNode (location: (1,0)-(1,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,11)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (1,2)-(1,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,2)-(1,3) = "b" + │ │ │ ├── opening_loc: (1,3)-(1,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (1,4)-(1,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,4)-(1,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (1,7)-(1,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ IntegerNode (location: (1,10)-(1,11)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,12)-(1,18)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,12)-(1,14) = "do" + │ │ └── closing_loc: (1,15)-(1,18) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (3,0)-(3,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,2)-(3,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (3,2)-(3,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,2)-(3,3) = "b" + │ │ │ ├── opening_loc: (3,3)-(3,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (3,4)-(3,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (3,4)-(3,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,4)-(3,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (3,6)-(3,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (3,6)-(3,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (3,6)-(3,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (3,7)-(3,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ FloatNode (location: (3,10)-(3,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,14)-(3,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,14)-(3,16) = "do" + │ │ └── closing_loc: (3,17)-(3,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (5,0)-(5,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,2)-(5,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (5,2)-(5,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,2)-(5,3) = "b" + │ │ │ ├── opening_loc: (5,3)-(5,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,4)-(5,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (5,4)-(5,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,4)-(5,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (5,6)-(5,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (5,6)-(5,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (5,6)-(5,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (5,7)-(5,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ ImaginaryNode (location: (5,10)-(5,14)) + │ │ └── numeric: + │ │ @ FloatNode (location: (5,10)-(5,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,15)-(5,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (5,15)-(5,17) = "do" + │ │ └── closing_loc: (5,18)-(5,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (7,0)-(7,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,2)-(7,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (7,2)-(7,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,2)-(7,3) = "b" + │ │ │ ├── opening_loc: (7,3)-(7,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (7,4)-(7,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (7,4)-(7,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (7,4)-(7,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (7,6)-(7,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (7,6)-(7,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (7,6)-(7,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (7,7)-(7,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RationalNode (location: (7,10)-(7,14)) + │ │ └── numeric: + │ │ @ FloatNode (location: (7,10)-(7,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (7,15)-(7,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (7,15)-(7,17) = "do" + │ │ └── closing_loc: (7,18)-(7,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (9,0)-(9,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,0)-(9,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,2)-(9,12)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (9,2)-(9,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,2)-(9,3) = "b" + │ │ │ ├── opening_loc: (9,3)-(9,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (9,4)-(9,7)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (9,4)-(9,7)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (9,4)-(9,5) = "c" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (9,6)-(9,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (9,6)-(9,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (9,6)-(9,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (9,7)-(9,8) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ SymbolNode (location: (9,10)-(9,12)) + │ │ ├── opening_loc: (9,10)-(9,11) = ":" + │ │ ├── value_loc: (9,11)-(9,12) = "e" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "e" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (9,13)-(9,19)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (9,13)-(9,15) = "do" + │ │ └── closing_loc: (9,16)-(9,19) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (11,0)-(11,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,0)-(11,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,2)-(11,12)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (11,2)-(11,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,2)-(11,3) = "b" + │ │ │ ├── opening_loc: (11,3)-(11,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (11,4)-(11,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (11,4)-(11,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (11,4)-(11,5) = "c" + │ │ │ │ ├── opening_loc: (11,5)-(11,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (11,6)-(11,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (11,6)-(11,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (11,6)-(11,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (11,7)-(11,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (11,8)-(11,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ IntegerNode (location: (11,11)-(11,12)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (11,13)-(11,19)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (11,13)-(11,15) = "do" + │ │ └── closing_loc: (11,16)-(11,19) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (13,0)-(13,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,2)-(13,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (13,2)-(13,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,2)-(13,3) = "b" + │ │ │ ├── opening_loc: (13,3)-(13,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (13,4)-(13,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (13,4)-(13,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (13,4)-(13,5) = "c" + │ │ │ │ ├── opening_loc: (13,5)-(13,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (13,6)-(13,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (13,6)-(13,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (13,6)-(13,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (13,7)-(13,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (13,8)-(13,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ FloatNode (location: (13,11)-(13,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,15)-(13,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (13,15)-(13,17) = "do" + │ │ └── closing_loc: (13,18)-(13,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (15,0)-(15,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,0)-(15,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,2)-(15,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (15,2)-(15,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,2)-(15,3) = "b" + │ │ │ ├── opening_loc: (15,3)-(15,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (15,4)-(15,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (15,4)-(15,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (15,4)-(15,5) = "c" + │ │ │ │ ├── opening_loc: (15,5)-(15,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (15,6)-(15,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (15,6)-(15,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (15,6)-(15,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (15,7)-(15,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (15,8)-(15,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ ImaginaryNode (location: (15,11)-(15,15)) + │ │ └── numeric: + │ │ @ FloatNode (location: (15,11)-(15,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (15,16)-(15,22)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (15,16)-(15,18) = "do" + │ │ └── closing_loc: (15,19)-(15,22) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (17,0)-(17,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,0)-(17,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,2)-(17,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (17,2)-(17,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (17,2)-(17,3) = "b" + │ │ │ ├── opening_loc: (17,3)-(17,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (17,4)-(17,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (17,4)-(17,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (17,4)-(17,5) = "c" + │ │ │ │ ├── opening_loc: (17,5)-(17,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (17,6)-(17,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (17,6)-(17,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (17,6)-(17,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (17,7)-(17,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (17,8)-(17,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RationalNode (location: (17,11)-(17,15)) + │ │ └── numeric: + │ │ @ FloatNode (location: (17,11)-(17,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (17,16)-(17,22)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (17,16)-(17,18) = "do" + │ │ └── closing_loc: (17,19)-(17,22) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (19,0)-(19,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,0)-(19,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (19,2)-(19,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (19,2)-(19,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,2)-(19,3) = "b" + │ │ │ ├── opening_loc: (19,3)-(19,4) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (19,4)-(19,8)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (19,4)-(19,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (19,4)-(19,5) = "c" + │ │ │ │ ├── opening_loc: (19,5)-(19,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (19,6)-(19,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (19,6)-(19,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (19,6)-(19,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (19,7)-(19,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── closing_loc: (19,8)-(19,9) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ SymbolNode (location: (19,11)-(19,13)) + │ │ ├── opening_loc: (19,11)-(19,12) = ":" + │ │ ├── value_loc: (19,12)-(19,13) = "e" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "e" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (19,14)-(19,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (19,14)-(19,16) = "do" + │ │ └── closing_loc: (19,17)-(19,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (21,0)-(21,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,0)-(21,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,2)-(21,11)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (21,2)-(21,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,2)-(21,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (21,3)-(21,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (21,4)-(21,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (21,4)-(21,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (21,4)-(21,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (21,6)-(21,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (21,6)-(21,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (21,6)-(21,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (21,3)-(21,4) = "{" + │ │ │ │ └── closing_loc: (21,7)-(21,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ IntegerNode (location: (21,10)-(21,11)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (21,12)-(21,18)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (21,12)-(21,14) = "do" + │ │ └── closing_loc: (21,15)-(21,18) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (23,0)-(23,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,0)-(23,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (23,2)-(23,13)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (23,2)-(23,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,2)-(23,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (23,3)-(23,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (23,4)-(23,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (23,4)-(23,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (23,4)-(23,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (23,6)-(23,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (23,6)-(23,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (23,6)-(23,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (23,3)-(23,4) = "{" + │ │ │ │ └── closing_loc: (23,7)-(23,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ FloatNode (location: (23,10)-(23,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (23,14)-(23,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (23,14)-(23,16) = "do" + │ │ └── closing_loc: (23,17)-(23,20) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (25,0)-(25,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,0)-(25,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (25,2)-(25,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (25,2)-(25,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (25,2)-(25,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (25,3)-(25,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (25,4)-(25,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (25,4)-(25,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (25,4)-(25,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (25,6)-(25,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (25,6)-(25,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (25,6)-(25,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (25,3)-(25,4) = "{" + │ │ │ │ └── closing_loc: (25,7)-(25,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ ImaginaryNode (location: (25,10)-(25,14)) + │ │ └── numeric: + │ │ @ FloatNode (location: (25,10)-(25,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (25,15)-(25,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (25,15)-(25,17) = "do" + │ │ └── closing_loc: (25,18)-(25,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (27,0)-(27,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,0)-(27,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,2)-(27,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (27,2)-(27,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (27,2)-(27,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (27,3)-(27,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (27,4)-(27,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (27,4)-(27,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (27,4)-(27,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (27,6)-(27,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (27,6)-(27,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (27,6)-(27,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (27,3)-(27,4) = "{" + │ │ │ │ └── closing_loc: (27,7)-(27,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RationalNode (location: (27,10)-(27,14)) + │ │ └── numeric: + │ │ @ FloatNode (location: (27,10)-(27,13)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (27,15)-(27,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (27,15)-(27,17) = "do" + │ │ └── closing_loc: (27,18)-(27,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (29,0)-(29,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (29,0)-(29,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (29,2)-(29,12)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (29,2)-(29,8)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (29,2)-(29,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (29,3)-(29,8)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (29,4)-(29,7)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (29,4)-(29,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (29,4)-(29,5) = "c" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (29,6)-(29,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (29,6)-(29,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (29,6)-(29,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (29,3)-(29,4) = "{" + │ │ │ │ └── closing_loc: (29,7)-(29,8) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ SymbolNode (location: (29,10)-(29,12)) + │ │ ├── opening_loc: (29,10)-(29,11) = ":" + │ │ ├── value_loc: (29,11)-(29,12) = "e" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "e" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (29,13)-(29,19)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (29,13)-(29,15) = "do" + │ │ └── closing_loc: (29,16)-(29,19) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (31,0)-(31,19)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,0)-(31,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,2)-(31,12)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (31,2)-(31,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (31,2)-(31,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (31,3)-(31,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (31,4)-(31,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (31,4)-(31,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (31,4)-(31,5) = "c" + │ │ │ │ │ ├── opening_loc: (31,5)-(31,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (31,6)-(31,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (31,6)-(31,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (31,6)-(31,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (31,7)-(31,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (31,3)-(31,4) = "{" + │ │ │ │ └── closing_loc: (31,8)-(31,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ IntegerNode (location: (31,11)-(31,12)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (31,13)-(31,19)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (31,13)-(31,15) = "do" + │ │ └── closing_loc: (31,16)-(31,19) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (33,0)-(33,21)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,0)-(33,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (33,2)-(33,14)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (33,2)-(33,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (33,2)-(33,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (33,3)-(33,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (33,4)-(33,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (33,4)-(33,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (33,4)-(33,5) = "c" + │ │ │ │ │ ├── opening_loc: (33,5)-(33,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (33,6)-(33,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (33,6)-(33,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (33,6)-(33,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (33,7)-(33,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (33,3)-(33,4) = "{" + │ │ │ │ └── closing_loc: (33,8)-(33,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ FloatNode (location: (33,11)-(33,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (33,15)-(33,21)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (33,15)-(33,17) = "do" + │ │ └── closing_loc: (33,18)-(33,21) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (35,0)-(35,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,0)-(35,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,2)-(35,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (35,2)-(35,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (35,2)-(35,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (35,3)-(35,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (35,4)-(35,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (35,4)-(35,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (35,4)-(35,5) = "c" + │ │ │ │ │ ├── opening_loc: (35,5)-(35,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (35,6)-(35,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (35,6)-(35,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (35,6)-(35,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (35,7)-(35,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (35,3)-(35,4) = "{" + │ │ │ │ └── closing_loc: (35,8)-(35,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ ImaginaryNode (location: (35,11)-(35,15)) + │ │ └── numeric: + │ │ @ FloatNode (location: (35,11)-(35,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (35,16)-(35,22)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (35,16)-(35,18) = "do" + │ │ └── closing_loc: (35,19)-(35,22) = "end" + │ ├── flags: ∅ + │ └── name: "a" + ├── @ CallNode (location: (37,0)-(37,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,0)-(37,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,2)-(37,15)) + │ │ └── arguments: (length: 2) + │ │ ├── @ CallNode (location: (37,2)-(37,9)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (37,2)-(37,3) = "b" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: + │ │ │ │ @ BlockNode (location: (37,3)-(37,9)) + │ │ │ │ ├── locals: [] + │ │ │ │ ├── parameters: ∅ + │ │ │ │ ├── body: + │ │ │ │ │ @ StatementsNode (location: (37,4)-(37,8)) + │ │ │ │ │ └── body: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (37,4)-(37,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (37,4)-(37,5) = "c" + │ │ │ │ │ ├── opening_loc: (37,5)-(37,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (37,6)-(37,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (37,6)-(37,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (37,6)-(37,7) = "d" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "d" + │ │ │ │ │ ├── closing_loc: (37,7)-(37,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "c" + │ │ │ │ ├── opening_loc: (37,3)-(37,4) = "{" + │ │ │ │ └── closing_loc: (37,8)-(37,9) = "}" + │ │ │ ├── flags: ∅ + │ │ │ └── name: "b" + │ │ └── @ RationalNode (location: (37,11)-(37,15)) + │ │ └── numeric: + │ │ @ FloatNode (location: (37,11)-(37,14)) + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (37,16)-(37,22)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (37,16)-(37,18) = "do" + │ │ └── closing_loc: (37,19)-(37,22) = "end" + │ ├── flags: ∅ + │ └── name: "a" + └── @ CallNode (location: (39,0)-(39,20)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (39,0)-(39,1) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (39,2)-(39,13)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (39,2)-(39,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,2)-(39,3) = "b" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (39,3)-(39,9)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (39,4)-(39,8)) + │ │ │ │ └── body: (length: 1) + │ │ │ │ └── @ CallNode (location: (39,4)-(39,8)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (39,4)-(39,5) = "c" + │ │ │ │ ├── opening_loc: (39,5)-(39,6) = "(" + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (39,6)-(39,7)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (39,6)-(39,7)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (39,6)-(39,7) = "d" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "d" + │ │ │ │ ├── closing_loc: (39,7)-(39,8) = ")" + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "c" + │ │ │ ├── opening_loc: (39,3)-(39,4) = "{" + │ │ │ └── closing_loc: (39,8)-(39,9) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "b" + │ └── @ SymbolNode (location: (39,11)-(39,13)) + │ ├── opening_loc: (39,11)-(39,12) = ":" + │ ├── value_loc: (39,12)-(39,13) = "e" + │ ├── closing_loc: ∅ + │ └── unescaped: "e" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (39,14)-(39,20)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (39,14)-(39,16) = "do" + │ └── closing_loc: (39,17)-(39,20) = "end" + ├── flags: ∅ + └── name: "a" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt b/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt new file mode 100644 index 00000000000000..89323d477893bd --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11873_b.txt @@ -0,0 +1,95 @@ +@ ProgramNode (location: (1,0)-(1,25)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,25)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,25)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,18)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (1,2)-(1,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,2)-(1,3) = "p" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,3)-(1,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: + │ │ │ │ @ StatementsNode (location: (1,4)-(1,12)) + │ │ │ │ └── body: (length: 2) + │ │ │ │ ├── @ CallNode (location: (1,4)-(1,8)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,4)-(1,5) = "p" + │ │ │ │ │ ├── opening_loc: (1,5)-(1,6) = "(" + │ │ │ │ │ ├── arguments: + │ │ │ │ │ │ @ ArgumentsNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ │ └── @ CallNode (location: (1,6)-(1,7)) + │ │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ │ ├── message_loc: (1,6)-(1,7) = "p" + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ │ └── name: "p" + │ │ │ │ │ ├── closing_loc: (1,7)-(1,8) = ")" + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: ∅ + │ │ │ │ │ └── name: "p" + │ │ │ │ └── @ CallNode (location: (1,9)-(1,12)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,9)-(1,10) = "p" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: + │ │ │ │ │ @ ArgumentsNode (location: (1,11)-(1,12)) + │ │ │ │ │ └── arguments: (length: 1) + │ │ │ │ │ └── @ CallNode (location: (1,11)-(1,12)) + │ │ │ │ │ ├── receiver: ∅ + │ │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ │ ├── message_loc: (1,11)-(1,12) = "p" + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── arguments: ∅ + │ │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ │ ├── block: ∅ + │ │ │ │ │ ├── flags: variable_call + │ │ │ │ │ └── name: "p" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: ∅ + │ │ │ │ └── name: "p" + │ │ │ ├── opening_loc: (1,3)-(1,4) = "{" + │ │ │ └── closing_loc: (1,12)-(1,13) = "}" + │ │ ├── flags: ∅ + │ │ └── name: "p" + │ └── @ CallNode (location: (1,15)-(1,18)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,15)-(1,18) = "tap" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "tap" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,19)-(1,25)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,19)-(1,21) = "do" + │ └── closing_loc: (1,22)-(1,25) = "end" + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11989.txt b/test/prism/snapshots/whitequark/ruby_bug_11989.txt new file mode 100644 index 00000000000000..b271785d1333ab --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11989.txt @@ -0,0 +1,23 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,8)) + │ └── arguments: (length: 1) + │ └── @ StringNode (location: (1,2)-(1,8)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,2)-(1,8) = "<<~\"E\"" + │ ├── content_loc: (2,0)-(2,0) = " x\\n y\n" + │ ├── closing_loc: (3,0)-(3,0) = "E\n" + │ └── unescaped: "x\n y\n" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/ruby_bug_11990.txt b/test/prism/snapshots/whitequark/ruby_bug_11990.txt new file mode 100644 index 00000000000000..08179b6c765494 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_11990.txt @@ -0,0 +1,32 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "p" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,12)) + │ └── arguments: (length: 1) + │ └── @ StringConcatNode (location: (1,2)-(1,12)) + │ ├── left: + │ │ @ StringNode (location: (1,2)-(1,6)) + │ │ ├── flags: ∅ + │ │ ├── opening_loc: (1,2)-(1,6) = "<<~E" + │ │ ├── content_loc: (2,0)-(2,0) = " x\n" + │ │ ├── closing_loc: (3,0)-(3,0) = "E\n" + │ │ └── unescaped: "x\n" + │ └── right: + │ @ 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: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "p" diff --git a/test/prism/snapshots/whitequark/ruby_bug_12073.txt b/test/prism/snapshots/whitequark/ruby_bug_12073.txt new file mode 100644 index 00000000000000..8d87e2ff0d7f12 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_12073.txt @@ -0,0 +1,89 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,8) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,9)-(1,13)) + │ │ └── arguments: (length: 1) + │ │ └── @ KeywordHashNode (location: (1,9)-(1,13)) + │ │ └── elements: (length: 1) + │ │ └── @ AssocNode (location: (1,9)-(1,13)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (1,9)-(1,11)) + │ │ │ ├── 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: ∅ + │ ├── flags: ∅ + │ └── name: "a" + └── @ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,15)-(3,20) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,21)-(3,29)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── locals: [:raise] + ├── def_keyword_loc: (3,0)-(3,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (3,31)-(3,34) = "end" diff --git a/test/prism/snapshots/whitequark/ruby_bug_12402.txt b/test/prism/snapshots/whitequark/ruby_bug_12402.txt new file mode 100644 index 00000000000000..8b3ca598278387 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_12402.txt @@ -0,0 +1,571 @@ +@ 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: + │ │ @ CallNode (location: (1,7)-(1,27)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,12) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,13)-(1,27)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ RescueModifierNode (location: (1,13)-(1,27)) + │ │ │ ├── expression: + │ │ │ │ @ CallNode (location: (1,13)-(1,16)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (1,13)-(1,16) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── keyword_loc: (1,17)-(1,23) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ NilNode (location: (1,24)-(1,27)) + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,7)-(3,12) = "raise" + │ │ │ ├── opening_loc: (3,12)-(3,13) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (3,13)-(3,16)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (3,13)-(3,16)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,13)-(3,16) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── closing_loc: (3,16)-(3,17) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ ├── 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: + │ │ @ CallNode (location: (5,6)-(5,26)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,6)-(5,11) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,12)-(5,26)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ RescueModifierNode (location: (5,12)-(5,26)) + │ │ │ ├── expression: + │ │ │ │ @ CallNode (location: (5,12)-(5,15)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (5,12)-(5,15) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── keyword_loc: (5,16)-(5,22) = "rescue" + │ │ │ └── rescue_expression: + │ │ │ @ NilNode (location: (5,23)-(5,26)) + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (7,6)-(7,11) = "raise" + │ │ │ ├── opening_loc: (7,11)-(7,12) = "(" + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (7,12)-(7,15)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ CallNode (location: (7,12)-(7,15)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (7,12)-(7,15) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ ├── closing_loc: (7,15)-(7,16) = ")" + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ ├── 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)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "C" + │ ├── write_name: "C=" + │ ├── operator: :+ + │ ├── operator_loc: (9,6)-(9,8) = "+=" + │ └── value: + │ @ CallNode (location: (9,9)-(9,29)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,9)-(9,14) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,15)-(9,29)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (9,15)-(9,29)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (9,15)-(9,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (9,15)-(9,18) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_loc: (9,19)-(9,25) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (9,26)-(9,29)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── @ CallOperatorWriteNode (location: (11,0)-(11,30)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,9)-(11,14) = "raise" + │ │ ├── opening_loc: (11,14)-(11,15) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (11,15)-(11,18)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (11,15)-(11,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (11,15)-(11,18) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (11,18)-(11,19) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── keyword_loc: (11,20)-(11,26) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (11,27)-(11,30)) + ├── @ CallOperatorWriteNode (location: (13,0)-(13,29)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "m" + │ ├── write_name: "m=" + │ ├── operator: :+ + │ ├── operator_loc: (13,6)-(13,8) = "+=" + │ └── value: + │ @ CallNode (location: (13,9)-(13,29)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,9)-(13,14) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,15)-(13,29)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (13,15)-(13,29)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (13,15)-(13,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (13,15)-(13,18) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_loc: (13,19)-(13,25) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (13,26)-(13,29)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── @ CallOperatorWriteNode (location: (15,0)-(15,30)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,9)-(15,14) = "raise" + │ │ ├── opening_loc: (15,14)-(15,15) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (15,15)-(15,18)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (15,15)-(15,18)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (15,15)-(15,18) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (15,18)-(15,19) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── 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: + │ @ CallNode (location: (17,11)-(17,31)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,11)-(17,16) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,17)-(17,31)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (17,17)-(17,31)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (17,17)-(17,20)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (17,17)-(17,20) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_loc: (17,21)-(17,27) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (17,28)-(17,31)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── @ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,11)-(19,16) = "raise" + │ │ ├── opening_loc: (19,16)-(19,17) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (19,17)-(19,20)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (19,17)-(19,20)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (19,17)-(19,20) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (19,20)-(19,21) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── keyword_loc: (19,22)-(19,28) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (19,29)-(19,32)) + ├── @ CallOperatorWriteNode (location: (21,0)-(21,30)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── read_name: "m" + │ ├── write_name: "m=" + │ ├── operator: :+ + │ ├── operator_loc: (21,7)-(21,9) = "+=" + │ └── value: + │ @ CallNode (location: (21,10)-(21,30)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,10)-(21,15) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,16)-(21,30)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (21,16)-(21,30)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (21,16)-(21,19)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (21,16)-(21,19) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_loc: (21,20)-(21,26) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (21,27)-(21,30)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── @ CallOperatorWriteNode (location: (23,0)-(23,31)) + │ ├── 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" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── flags: ∅ + │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,10)-(23,15) = "raise" + │ │ ├── opening_loc: (23,15)-(23,16) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (23,16)-(23,19)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (23,16)-(23,19)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (23,16)-(23,19) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: (23,19)-(23,20) = ")" + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ ├── keyword_loc: (23,21)-(23,27) = "rescue" + │ └── rescue_expression: + │ @ NilNode (location: (23,28)-(23,31)) + ├── @ CallOperatorWriteNode (location: (25,0)-(25,30)) + │ ├── receiver: + │ │ @ LocalVariableReadNode (location: (25,0)-(25,3)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,3)-(25,6) = "[0]" + │ ├── opening_loc: (25,3)-(25,4) = "[" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (25,4)-(25,5)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (25,4)-(25,5)) + │ │ └── flags: decimal + │ ├── closing_loc: (25,5)-(25,6) = "]" + │ ├── flags: ∅ + │ ├── read_name: "[]" + │ ├── write_name: "[]=" + │ ├── operator: :+ + │ ├── operator_loc: (25,7)-(25,9) = "+=" + │ └── value: + │ @ CallNode (location: (25,10)-(25,30)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,10)-(25,15) = "raise" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (25,16)-(25,30)) + │ │ └── arguments: (length: 1) + │ │ └── @ RescueModifierNode (location: (25,16)-(25,30)) + │ │ ├── expression: + │ │ │ @ CallNode (location: (25,16)-(25,19)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (25,16)-(25,19) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── keyword_loc: (25,20)-(25,26) = "rescue" + │ │ └── rescue_expression: + │ │ @ NilNode (location: (25,27)-(25,30)) + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + └── @ CallOperatorWriteNode (location: (27,0)-(27,31)) + ├── receiver: + │ @ LocalVariableReadNode (location: (27,0)-(27,3)) + │ ├── name: :foo + │ └── depth: 0 + ├── call_operator_loc: ∅ + ├── message_loc: (27,3)-(27,6) = "[0]" + ├── opening_loc: (27,3)-(27,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (27,4)-(27,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (27,4)-(27,5)) + │ └── flags: decimal + ├── closing_loc: (27,5)-(27,6) = "]" + ├── flags: ∅ + ├── read_name: "[]" + ├── write_name: "[]=" + ├── operator: :+ + ├── operator_loc: (27,7)-(27,9) = "+=" + └── value: + @ RescueModifierNode (location: (27,10)-(27,31)) + ├── expression: + │ @ CallNode (location: (27,10)-(27,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,10)-(27,15) = "raise" + │ ├── opening_loc: (27,15)-(27,16) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,16)-(27,19)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (27,16)-(27,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (27,16)-(27,19) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (27,19)-(27,20) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "raise" + ├── keyword_loc: (27,21)-(27,27) = "rescue" + └── rescue_expression: + @ NilNode (location: (27,28)-(27,31)) diff --git a/test/prism/snapshots/whitequark/ruby_bug_12669.txt b/test/prism/snapshots/whitequark/ruby_bug_12669.txt new file mode 100644 index 00000000000000..f9380994e914d4 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_12669.txt @@ -0,0 +1,125 @@ +@ 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,10)-(1,15) = "raise" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (1,16)-(1,18)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (1,16)-(1,18)) + │ │ │ │ ├── opening_loc: (1,16)-(1,17) = ":" + │ │ │ │ ├── value_loc: (1,17)-(1,18) = "x" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "x" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (3,9)-(3,14) = "raise" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (3,15)-(3,17)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (3,15)-(3,17)) + │ │ │ │ ├── opening_loc: (3,15)-(3,16) = ":" + │ │ │ │ ├── value_loc: (3,16)-(3,17) = "x" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "x" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,9)-(5,14) = "raise" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: + │ │ │ │ @ ArgumentsNode (location: (5,15)-(5,17)) + │ │ │ │ └── arguments: (length: 1) + │ │ │ │ └── @ SymbolNode (location: (5,15)-(5,17)) + │ │ │ │ ├── opening_loc: (5,15)-(5,16) = ":" + │ │ │ │ ├── value_loc: (5,16)-(5,17) = "x" + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ └── unescaped: "x" + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: ∅ + │ │ │ └── name: "raise" + │ │ ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,8)-(7,13) = "raise" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,14)-(7,16)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ SymbolNode (location: (7,14)-(7,16)) + │ │ │ ├── opening_loc: (7,14)-(7,15) = ":" + │ │ │ ├── value_loc: (7,15)-(7,16) = "x" + │ │ │ ├── closing_loc: ∅ + │ │ │ └── unescaped: "x" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "raise" + │ └── operator_loc: (7,6)-(7,7) = "=" + └── operator_loc: (7,2)-(7,3) = "=" diff --git a/test/prism/snapshots/whitequark/ruby_bug_12686.txt b/test/prism/snapshots/whitequark/ruby_bug_12686.txt new file mode 100644 index 00000000000000..c5d14532cba262 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_12686.txt @@ -0,0 +1,38 @@ +@ ProgramNode (location: (1,0)-(1,16)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,16)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,16)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,1) = "f" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,2)-(1,16)) + │ └── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,3)-(1,4) = "g" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "g" + │ │ ├── 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: ∅ + ├── flags: ∅ + └── name: "f" diff --git a/test/prism/snapshots/whitequark/ruby_bug_13547.txt b/test/prism/snapshots/whitequark/ruby_bug_13547.txt new file mode 100644 index 00000000000000..e370f583678070 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_13547.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + ├── call_operator_loc: ∅ + ├── message_loc: (1,4)-(1,6) = "[]" + ├── opening_loc: (1,4)-(1,5) = "[" + ├── arguments: ∅ + ├── closing_loc: (1,5)-(1,6) = "]" + ├── block: + │ @ BlockNode (location: (1,7)-(1,9)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,7)-(1,8) = "{" + │ └── closing_loc: (1,8)-(1,9) = "}" + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/whitequark/ruby_bug_14690.txt b/test/prism/snapshots/whitequark/ruby_bug_14690.txt new file mode 100644 index 00000000000000..949de2297aef1e --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_14690.txt @@ -0,0 +1,57 @@ +@ ProgramNode (location: (1,0)-(1,23)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,23)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,23)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "let" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ ParenthesesNode (location: (1,4)-(1,6)) + │ ├── body: ∅ + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ └── closing_loc: (1,5)-(1,6) = ")" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,7)-(1,23)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (1,9)-(1,21)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,9)-(1,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,9)-(1,10) = "m" + │ │ ├── opening_loc: (1,10)-(1,11) = "(" + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,11)-(1,12)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (1,11)-(1,12)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,11)-(1,12) = "a" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "a" + │ │ ├── closing_loc: (1,12)-(1,13) = ")" + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,14)-(1,21)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,14)-(1,16) = "do" + │ │ │ └── closing_loc: (1,18)-(1,21) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "m" + │ ├── opening_loc: (1,7)-(1,8) = "{" + │ └── closing_loc: (1,22)-(1,23) = "}" + ├── flags: ∅ + └── name: "let" diff --git a/test/prism/snapshots/whitequark/ruby_bug_15789.txt b/test/prism/snapshots/whitequark/ruby_bug_15789.txt new file mode 100644 index 00000000000000..2de0b0f7a987e5 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_15789.txt @@ -0,0 +1,112 @@ +@ ProgramNode (location: (1,0)-(3,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,19)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,20)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,2)-(1,20)) + │ │ └── arguments: (length: 1) + │ │ └── @ LambdaNode (location: (1,2)-(1,20)) + │ │ ├── locals: [:a] + │ │ ├── operator_loc: (1,2)-(1,4) = "->" + │ │ ├── opening_loc: (1,17)-(1,18) = "{" + │ │ ├── closing_loc: (1,19)-(1,20) = "}" + │ │ ├── parameters: + │ │ │ @ BlockParametersNode (location: (1,4)-(1,16)) + │ │ │ ├── parameters: + │ │ │ │ @ ParametersNode (location: (1,5)-(1,15)) + │ │ │ │ ├── requireds: (length: 0) + │ │ │ │ ├── optionals: (length: 1) + │ │ │ │ │ └── @ OptionalParameterNode (location: (1,5)-(1,15)) + │ │ │ │ │ ├── name: :a + │ │ │ │ │ ├── name_loc: (1,5)-(1,6) = "a" + │ │ │ │ │ ├── operator_loc: (1,7)-(1,8) = "=" + │ │ │ │ │ └── value: + │ │ │ │ │ @ LambdaNode (location: (1,9)-(1,15)) + │ │ │ │ │ ├── locals: [:_1] + │ │ │ │ │ ├── operator_loc: (1,9)-(1,11) = "->" + │ │ │ │ │ ├── opening_loc: (1,11)-(1,12) = "{" + │ │ │ │ │ ├── closing_loc: (1,14)-(1,15) = "}" + │ │ │ │ │ ├── parameters: ∅ + │ │ │ │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "m" + └── @ CallNode (location: (3,0)-(3,19)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (3,0)-(3,1) = "m" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (3,2)-(3,19)) + │ └── arguments: (length: 1) + │ └── @ LambdaNode (location: (3,2)-(3,19)) + │ ├── locals: [:a] + │ ├── operator_loc: (3,2)-(3,4) = "->" + │ ├── opening_loc: (3,16)-(3,17) = "{" + │ ├── closing_loc: (3,18)-(3,19) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (3,4)-(3,15)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (3,5)-(3,14)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (location: (3,5)-(3,14)) + │ │ │ │ ├── name: :a + │ │ │ │ ├── name_loc: (3,5)-(3,7) = "a:" + │ │ │ │ └── value: + │ │ │ │ @ LambdaNode (location: (3,8)-(3,14)) + │ │ │ │ ├── locals: [:_1] + │ │ │ │ ├── operator_loc: (3,8)-(3,10) = "->" + │ │ │ │ ├── opening_loc: (3,10)-(3,11) = "{" + │ │ │ │ ├── closing_loc: (3,13)-(3,14) = "}" + │ │ │ │ ├── parameters: ∅ + │ │ │ │ └── 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: ∅ + ├── flags: ∅ + └── name: "m" diff --git a/test/prism/snapshots/whitequark/ruby_bug_9669.txt b/test/prism/snapshots/whitequark/ruby_bug_9669.txt new file mode 100644 index 00000000000000..62a25ef2ce2137 --- /dev/null +++ b/test/prism/snapshots/whitequark/ruby_bug_9669.txt @@ -0,0 +1,56 @@ +@ 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) + │ │ │ └── @ KeywordParameterNode (location: (1,6)-(1,8)) + │ │ │ ├── name: :b + │ │ │ ├── name_loc: (1,6)-(1,8) = "b:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── body: + │ │ @ StatementsNode (location: (2,0)-(2,6)) + │ │ └── body: (length: 1) + │ │ └── @ ReturnNode (location: (2,0)-(2,6)) + │ │ ├── keyword_loc: (2,0)-(2,6) = "return" + │ │ └── arguments: ∅ + │ ├── locals: [:b] + │ ├── def_keyword_loc: (1,0)-(1,3) = "def" + │ ├── operator_loc: ∅ + │ ├── lparen_loc: ∅ + │ ├── rparen_loc: ∅ + │ ├── equal_loc: ∅ + │ └── end_keyword_loc: (3,0)-(3,3) = "end" + └── @ LocalVariableWriteNode (location: (5,0)-(8,1)) + ├── name: :o + ├── depth: 0 + ├── name_loc: (5,0)-(5,1) = "o" + ├── value: + │ @ HashNode (location: (5,4)-(8,1)) + │ ├── opening_loc: (5,4)-(5,5) = "{" + │ ├── elements: (length: 1) + │ │ └── @ AssocNode (location: (6,0)-(7,1)) + │ │ ├── key: + │ │ │ @ SymbolNode (location: (6,0)-(6,2)) + │ │ │ ├── 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 new file mode 100644 index 00000000000000..81584a8ca60924 --- /dev/null +++ b/test/prism/snapshots/whitequark/sclass.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,22)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,22)) + └── body: (length: 1) + └── @ SingletonClassNode (location: (1,0)-(1,22)) + ├── locals: [] + ├── class_keyword_loc: (1,0)-(1,5) = "class" + ├── operator_loc: (1,6)-(1,8) = "<<" + ├── expression: + │ @ CallNode (location: (1,9)-(1,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,9)-(1,12) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── body: + │ @ StatementsNode (location: (1,14)-(1,17)) + │ └── body: (length: 1) + │ └── @ NilNode (location: (1,14)-(1,17)) + └── end_keyword_loc: (1,19)-(1,22) = "end" diff --git a/test/prism/snapshots/whitequark/self.txt b/test/prism/snapshots/whitequark/self.txt new file mode 100644 index 00000000000000..c69f8fa8c595ef --- /dev/null +++ b/test/prism/snapshots/whitequark/self.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ SelfNode (location: (1,0)-(1,4)) diff --git a/test/prism/snapshots/whitequark/send_attr_asgn.txt b/test/prism/snapshots/whitequark/send_attr_asgn.txt new file mode 100644 index 00000000000000..2f005fb4dce78a --- /dev/null +++ b/test/prism/snapshots/whitequark/send_attr_asgn.txt @@ -0,0 +1,99 @@ +@ ProgramNode (location: (1,0)-(7,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,10)) + └── body: (length: 4) + ├── @ CallNode (location: (1,0)-(1,9)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,5) = "A" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,8)-(1,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "A=" + ├── @ CallNode (location: (3,0)-(3,9)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,4) = "." + │ ├── message_loc: (3,4)-(3,5) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,8)-(3,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (3,8)-(3,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "a=" + ├── @ ConstantPathWriteNode (location: (5,0)-(5,10)) + │ ├── target: + │ │ @ ConstantPathNode (location: (5,0)-(5,6)) + │ │ ├── parent: + │ │ │ @ CallNode (location: (5,0)-(5,3)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (5,0)-(5,3) = "foo" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "foo" + │ │ ├── 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)) + ├── receiver: + │ @ CallNode (location: (7,0)-(7,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,0)-(7,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (7,3)-(7,5) = "::" + ├── message_loc: (7,5)-(7,6) = "a" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (7,9)-(7,10)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (7,9)-(7,10)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "a=" diff --git a/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt b/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt new file mode 100644 index 00000000000000..e6ea102a269771 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_attr_asgn_conditional.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,8)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "&." + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,7)-(1,8)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (1,7)-(1,8)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: safe_navigation + └── name: "b=" diff --git a/test/prism/snapshots/whitequark/send_binary_op.txt b/test/prism/snapshots/whitequark/send_binary_op.txt new file mode 100644 index 00000000000000..d0b3aedae813fc --- /dev/null +++ b/test/prism/snapshots/whitequark/send_binary_op.txt @@ -0,0 +1,509 @@ +@ ProgramNode (location: (1,0)-(41,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(41,7)) + └── body: (length: 21) + ├── @ CallNode (location: (1,0)-(1,8)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,6) = "!=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,7)-(1,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,7)-(1,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!=" + ├── @ CallNode (location: (3,0)-(3,8)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,4)-(3,6) = "!~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,7)-(3,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (3,7)-(3,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "!~" + ├── @ CallNode (location: (5,0)-(5,7)) + │ ├── receiver: + │ │ @ CallNode (location: (5,0)-(5,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,4)-(5,5) = "%" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,6)-(5,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (5,6)-(5,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "%" + ├── @ CallNode (location: (7,0)-(7,7)) + │ ├── receiver: + │ │ @ CallNode (location: (7,0)-(7,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,4)-(7,5) = "&" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,6)-(7,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (7,6)-(7,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "&" + ├── @ CallNode (location: (9,0)-(9,7)) + │ ├── receiver: + │ │ @ CallNode (location: (9,0)-(9,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,0)-(9,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (9,4)-(9,5) = "*" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,6)-(9,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (9,6)-(9,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "*" + ├── @ CallNode (location: (11,0)-(11,8)) + │ ├── receiver: + │ │ @ CallNode (location: (11,0)-(11,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (11,4)-(11,6) = "**" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,7)-(11,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (11,7)-(11,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "**" + ├── @ CallNode (location: (13,0)-(13,7)) + │ ├── receiver: + │ │ @ CallNode (location: (13,0)-(13,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (13,0)-(13,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,4)-(13,5) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,6)-(13,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (13,6)-(13,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+" + ├── @ CallNode (location: (15,0)-(15,7)) + │ ├── receiver: + │ │ @ CallNode (location: (15,0)-(15,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (15,0)-(15,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (15,4)-(15,5) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (15,6)-(15,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (15,6)-(15,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-" + ├── @ CallNode (location: (17,0)-(17,7)) + │ ├── receiver: + │ │ @ CallNode (location: (17,0)-(17,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (17,0)-(17,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (17,4)-(17,5) = "/" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (17,6)-(17,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (17,6)-(17,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "/" + ├── @ CallNode (location: (19,0)-(19,7)) + │ ├── receiver: + │ │ @ CallNode (location: (19,0)-(19,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (19,0)-(19,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (19,4)-(19,5) = "<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (19,6)-(19,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (19,6)-(19,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<" + ├── @ CallNode (location: (21,0)-(21,8)) + │ ├── receiver: + │ │ @ CallNode (location: (21,0)-(21,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (21,0)-(21,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (21,4)-(21,6) = "<<" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (21,7)-(21,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (21,7)-(21,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<<" + ├── @ CallNode (location: (23,0)-(23,8)) + │ ├── receiver: + │ │ @ CallNode (location: (23,0)-(23,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (23,0)-(23,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (23,4)-(23,6) = "<=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (23,7)-(23,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (23,7)-(23,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<=" + ├── @ CallNode (location: (25,0)-(25,9)) + │ ├── receiver: + │ │ @ CallNode (location: (25,0)-(25,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (25,0)-(25,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (25,4)-(25,7) = "<=>" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (25,8)-(25,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (25,8)-(25,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "<=>" + ├── @ CallNode (location: (27,0)-(27,8)) + │ ├── receiver: + │ │ @ CallNode (location: (27,0)-(27,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (27,0)-(27,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (27,4)-(27,6) = "==" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (27,7)-(27,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (27,7)-(27,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "==" + ├── @ CallNode (location: (29,0)-(29,9)) + │ ├── receiver: + │ │ @ CallNode (location: (29,0)-(29,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (29,0)-(29,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (29,4)-(29,7) = "===" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (29,8)-(29,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (29,8)-(29,9)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "===" + ├── @ CallNode (location: (31,0)-(31,8)) + │ ├── receiver: + │ │ @ CallNode (location: (31,0)-(31,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (31,0)-(31,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (31,4)-(31,6) = "=~" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (31,7)-(31,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (31,7)-(31,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "=~" + ├── @ CallNode (location: (33,0)-(33,7)) + │ ├── receiver: + │ │ @ CallNode (location: (33,0)-(33,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (33,0)-(33,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (33,4)-(33,5) = ">" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (33,6)-(33,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (33,6)-(33,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">" + ├── @ CallNode (location: (35,0)-(35,8)) + │ ├── receiver: + │ │ @ CallNode (location: (35,0)-(35,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (35,0)-(35,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (35,4)-(35,6) = ">=" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (35,7)-(35,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (35,7)-(35,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">=" + ├── @ CallNode (location: (37,0)-(37,8)) + │ ├── receiver: + │ │ @ CallNode (location: (37,0)-(37,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (37,0)-(37,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (37,4)-(37,6) = ">>" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (37,7)-(37,8)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (37,7)-(37,8)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: ">>" + ├── @ CallNode (location: (39,0)-(39,7)) + │ ├── receiver: + │ │ @ CallNode (location: (39,0)-(39,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (39,0)-(39,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (39,4)-(39,5) = "^" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (39,6)-(39,7)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (39,6)-(39,7)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "^" + └── @ CallNode (location: (41,0)-(41,7)) + ├── receiver: + │ @ CallNode (location: (41,0)-(41,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (41,0)-(41,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (41,4)-(41,5) = "|" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (41,6)-(41,7)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (41,6)-(41,7)) + │ └── flags: decimal + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "|" diff --git a/test/prism/snapshots/whitequark/send_block_chain_cmd.txt b/test/prism/snapshots/whitequark/send_block_chain_cmd.txt new file mode 100644 index 00000000000000..c82d388037bab4 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_block_chain_cmd.txt @@ -0,0 +1,305 @@ +@ ProgramNode (location: (1,0)-(13,23)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(13,23)) + └── body: (length: 7) + ├── @ CallNode (location: (1,0)-(1,21)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (1,7)-(1,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (1,7)-(1,9) = "do" + │ │ │ └── closing_loc: (1,10)-(1,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (1,13)-(1,14) = "." + │ ├── message_loc: (1,14)-(1,17) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,18)-(1,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,18)-(1,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,18)-(1,21) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,28)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,5)-(3,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (3,5)-(3,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (3,7)-(3,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (3,7)-(3,9) = "do" + │ │ │ └── closing_loc: (3,10)-(3,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (3,13)-(3,14) = "." + │ ├── message_loc: (3,14)-(3,17) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,18)-(3,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,18)-(3,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,18)-(3,21) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,22)-(3,28)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,22)-(3,24) = "do" + │ │ └── closing_loc: (3,25)-(3,28) = "end" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (5,0)-(5,20)) + │ ├── receiver: + │ │ @ CallNode (location: (5,0)-(5,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (5,0)-(5,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (5,5)-(5,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (5,5)-(5,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (5,7)-(5,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (5,7)-(5,9) = "do" + │ │ │ └── closing_loc: (5,10)-(5,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (5,13)-(5,14) = "." + │ ├── message_loc: (5,14)-(5,17) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (5,18)-(5,20)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (5,18)-(5,19) = "{" + │ │ └── closing_loc: (5,19)-(5,20) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (7,0)-(7,22)) + │ ├── receiver: + │ │ @ CallNode (location: (7,0)-(7,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,0)-(7,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (7,5)-(7,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (7,5)-(7,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (7,7)-(7,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (7,7)-(7,9) = "do" + │ │ │ └── closing_loc: (7,10)-(7,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (7,13)-(7,14) = "." + │ ├── message_loc: (7,14)-(7,17) = "fun" + │ ├── opening_loc: (7,17)-(7,18) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (7,18)-(7,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (7,18)-(7,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (7,18)-(7,21) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (7,21)-(7,22) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (9,0)-(9,25)) + │ ├── receiver: + │ │ @ CallNode (location: (9,0)-(9,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,0)-(9,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (9,5)-(9,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (9,5)-(9,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (9,7)-(9,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (9,7)-(9,9) = "do" + │ │ │ └── closing_loc: (9,10)-(9,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (9,13)-(9,14) = "." + │ ├── message_loc: (9,14)-(9,17) = "fun" + │ ├── opening_loc: (9,17)-(9,18) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (9,18)-(9,21)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (9,18)-(9,21)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (9,18)-(9,21) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: (9,21)-(9,22) = ")" + │ ├── block: + │ │ @ BlockNode (location: (9,23)-(9,25)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (9,23)-(9,24) = "{" + │ │ └── closing_loc: (9,24)-(9,25) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (11,0)-(11,22)) + │ ├── receiver: + │ │ @ CallNode (location: (11,0)-(11,13)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,0)-(11,4) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (11,5)-(11,6)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (11,5)-(11,6)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: + │ │ │ @ BlockNode (location: (11,7)-(11,13)) + │ │ │ ├── locals: [] + │ │ │ ├── parameters: ∅ + │ │ │ ├── body: ∅ + │ │ │ ├── opening_loc: (11,7)-(11,9) = "do" + │ │ │ └── closing_loc: (11,10)-(11,13) = "end" + │ │ ├── flags: ∅ + │ │ └── name: "meth" + │ ├── call_operator_loc: (11,13)-(11,15) = "::" + │ ├── message_loc: (11,15)-(11,18) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (11,19)-(11,22)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (11,19)-(11,22)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (11,19)-(11,22) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + └── @ CallNode (location: (13,0)-(13,23)) + ├── receiver: + │ @ CallNode (location: (13,0)-(13,13)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,0)-(13,4) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (13,5)-(13,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (13,5)-(13,6)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (13,7)-(13,13)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (13,7)-(13,9) = "do" + │ │ └── closing_loc: (13,10)-(13,13) = "end" + │ ├── flags: ∅ + │ └── name: "meth" + ├── call_operator_loc: (13,13)-(13,15) = "::" + ├── message_loc: (13,15)-(13,18) = "fun" + ├── opening_loc: (13,18)-(13,19) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (13,19)-(13,22)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (13,19)-(13,22)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (13,19)-(13,22) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── closing_loc: (13,22)-(13,23) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/send_block_conditional.txt b/test/prism/snapshots/whitequark/send_block_conditional.txt new file mode 100644 index 00000000000000..5fc2660cf75797 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_block_conditional.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,11)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (1,3)-(1,5) = "&." + ├── message_loc: (1,5)-(1,8) = "bar" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,9)-(1,11)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,9)-(1,10) = "{" + │ └── closing_loc: (1,10)-(1,11) = "}" + ├── flags: safe_navigation + └── name: "bar" diff --git a/test/prism/snapshots/whitequark/send_call.txt b/test/prism/snapshots/whitequark/send_call.txt new file mode 100644 index 00000000000000..639381d9e53373 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_call.txt @@ -0,0 +1,53 @@ +@ ProgramNode (location: (1,0)-(3,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,8)) + └── body: (length: 2) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: ∅ + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,5)-(1,6)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,5)-(1,6)) + │ │ └── flags: decimal + │ ├── closing_loc: (1,6)-(1,7) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "call" + └── @ CallNode (location: (3,0)-(3,8)) + ├── receiver: + │ @ CallNode (location: (3,0)-(3,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (3,3)-(3,5) = "::" + ├── message_loc: ∅ + ├── opening_loc: (3,5)-(3,6) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (3,6)-(3,7)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (3,6)-(3,7)) + │ └── flags: decimal + ├── closing_loc: (3,7)-(3,8) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "call" diff --git a/test/prism/snapshots/whitequark/send_conditional.txt b/test/prism/snapshots/whitequark/send_conditional.txt new file mode 100644 index 00000000000000..cf7412a9fa79d6 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_conditional.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,4)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "&." + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: safe_navigation + └── name: "b" diff --git a/test/prism/snapshots/whitequark/send_index.txt b/test/prism/snapshots/whitequark/send_index.txt new file mode 100644 index 00000000000000..1689635083cbaf --- /dev/null +++ b/test/prism/snapshots/whitequark/send_index.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[1, 2]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/whitequark/send_index_asgn.txt b/test/prism/snapshots/whitequark/send_index_asgn.txt new file mode 100644 index 00000000000000..190b6b4eb4642a --- /dev/null +++ b/test/prism/snapshots/whitequark/send_index_asgn.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[1, 2]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,13)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "[]=" diff --git a/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt b/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt new file mode 100644 index 00000000000000..190b6b4eb4642a --- /dev/null +++ b/test/prism/snapshots/whitequark/send_index_asgn_legacy.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,13)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,13)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,13)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[1, 2]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,13)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "[]=" diff --git a/test/prism/snapshots/whitequark/send_index_cmd.txt b/test/prism/snapshots/whitequark/send_index_cmd.txt new file mode 100644 index 00000000000000..a5a4f9586fd506 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_index_cmd.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,10)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,10) = "[m bar]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,9)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,4)-(1,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,4)-(1,5) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,6)-(1,9)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── closing_loc: (1,9)-(1,10) = "]" + ├── block: ∅ + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/whitequark/send_index_legacy.txt b/test/prism/snapshots/whitequark/send_index_legacy.txt new file mode 100644 index 00000000000000..1689635083cbaf --- /dev/null +++ b/test/prism/snapshots/whitequark/send_index_legacy.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (1,3)-(1,9) = "[1, 2]" + ├── opening_loc: (1,3)-(1,4) = "[" + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,8)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "[]" diff --git a/test/prism/snapshots/whitequark/send_lambda.txt b/test/prism/snapshots/whitequark/send_lambda.txt new file mode 100644 index 00000000000000..aa21442971d0c7 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_lambda.txt @@ -0,0 +1,43 @@ +@ ProgramNode (location: (1,0)-(5,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,5)) + └── body: (length: 3) + ├── @ LambdaNode (location: (1,0)-(1,8)) + │ ├── locals: [:*] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,5)-(1,6) = "{" + │ ├── closing_loc: (1,7)-(1,8) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,3)-(1,4)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,3)-(1,4)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: + │ │ │ │ @ RestParameterNode (location: (1,3)-(1,4)) + │ │ │ │ ├── name: nil + │ │ │ │ ├── name_loc: ∅ + │ │ │ │ └── operator_loc: (1,3)-(1,4) = "*" + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: ∅ + │ │ └── closing_loc: ∅ + │ └── body: ∅ + ├── @ LambdaNode (location: (3,0)-(3,9)) + │ ├── locals: [] + │ ├── operator_loc: (3,0)-(3,2) = "->" + │ ├── opening_loc: (3,3)-(3,5) = "do" + │ ├── closing_loc: (3,6)-(3,9) = "end" + │ ├── parameters: ∅ + │ └── body: ∅ + └── @ LambdaNode (location: (5,0)-(5,5)) + ├── locals: [] + ├── operator_loc: (5,0)-(5,2) = "->" + ├── opening_loc: (5,2)-(5,3) = "{" + ├── closing_loc: (5,4)-(5,5) = "}" + ├── parameters: ∅ + └── body: ∅ diff --git a/test/prism/snapshots/whitequark/send_lambda_args.txt b/test/prism/snapshots/whitequark/send_lambda_args.txt new file mode 100644 index 00000000000000..0e5dd9a7c0a007 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_lambda_args.txt @@ -0,0 +1,49 @@ +@ ProgramNode (location: (1,0)-(3,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,9)) + └── body: (length: 2) + ├── @ LambdaNode (location: (1,0)-(1,10)) + │ ├── locals: [:a] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,7)-(1,8) = "{" + │ ├── closing_loc: (1,9)-(1,10) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,3)-(1,6)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,4)-(1,5)) + │ │ │ ├── requireds: (length: 1) + │ │ │ │ └── @ RequiredParameterNode (location: (1,4)-(1,5)) + │ │ │ │ └── name: :a + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 0) + │ │ │ ├── keyword_rest: ∅ + │ │ │ └── block: ∅ + │ │ ├── locals: (length: 0) + │ │ ├── opening_loc: (1,3)-(1,4) = "(" + │ │ └── closing_loc: (1,5)-(1,6) = ")" + │ └── body: ∅ + └── @ LambdaNode (location: (3,0)-(3,9)) + ├── locals: [:a] + ├── operator_loc: (3,0)-(3,2) = "->" + ├── opening_loc: (3,6)-(3,7) = "{" + ├── closing_loc: (3,8)-(3,9) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (3,2)-(3,5)) + │ ├── parameters: + │ │ @ ParametersNode (location: (3,3)-(3,4)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (3,3)-(3,4)) + │ │ │ └── name: :a + │ │ ├── optionals: (length: 0) + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── keywords: (length: 0) + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: (3,2)-(3,3) = "(" + │ └── closing_loc: (3,4)-(3,5) = ")" + └── body: ∅ diff --git a/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt b/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt new file mode 100644 index 00000000000000..f28ed889a83154 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_lambda_args_noparen.txt @@ -0,0 +1,55 @@ +@ ProgramNode (location: (1,0)-(3,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,9)) + └── body: (length: 2) + ├── @ LambdaNode (location: (1,0)-(1,11)) + │ ├── locals: [:a] + │ ├── operator_loc: (1,0)-(1,2) = "->" + │ ├── opening_loc: (1,8)-(1,9) = "{" + │ ├── closing_loc: (1,10)-(1,11) = "}" + │ ├── parameters: + │ │ @ BlockParametersNode (location: (1,3)-(1,7)) + │ │ ├── parameters: + │ │ │ @ ParametersNode (location: (1,3)-(1,7)) + │ │ │ ├── requireds: (length: 0) + │ │ │ ├── optionals: (length: 0) + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── keywords: (length: 1) + │ │ │ │ └── @ KeywordParameterNode (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] + ├── 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) + │ │ │ └── @ KeywordParameterNode (location: (3,3)-(3,5)) + │ │ │ ├── name: :a + │ │ │ ├── name_loc: (3,3)-(3,5) = "a:" + │ │ │ └── value: ∅ + │ │ ├── keyword_rest: ∅ + │ │ └── block: ∅ + │ ├── locals: (length: 0) + │ ├── opening_loc: ∅ + │ └── closing_loc: ∅ + └── body: ∅ diff --git a/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt b/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt new file mode 100644 index 00000000000000..2e1160427cc7bf --- /dev/null +++ b/test/prism/snapshots/whitequark/send_lambda_args_shadow.txt @@ -0,0 +1,31 @@ +@ ProgramNode (location: (1,0)-(1,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,19)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,19)) + ├── locals: [:a, :foo, :bar] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,16)-(1,17) = "{" + ├── closing_loc: (1,18)-(1,19) = "}" + ├── parameters: + │ @ BlockParametersNode (location: (1,2)-(1,15)) + │ ├── parameters: + │ │ @ ParametersNode (location: (1,3)-(1,4)) + │ │ ├── requireds: (length: 1) + │ │ │ └── @ RequiredParameterNode (location: (1,3)-(1,4)) + │ │ │ └── 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 new file mode 100644 index 00000000000000..3a64e941b6c25d --- /dev/null +++ b/test/prism/snapshots/whitequark/send_lambda_legacy.txt @@ -0,0 +1,12 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ LambdaNode (location: (1,0)-(1,5)) + ├── locals: [] + ├── operator_loc: (1,0)-(1,2) = "->" + ├── opening_loc: (1,2)-(1,3) = "{" + ├── closing_loc: (1,4)-(1,5) = "}" + ├── parameters: ∅ + └── body: ∅ diff --git a/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt b/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt new file mode 100644 index 00000000000000..2507dfa904fd86 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_op_asgn_conditional.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,10)) + └── body: (length: 1) + └── @ CallAndWriteNode (location: (1,0)-(1,10)) + ├── receiver: + │ @ CallNode (location: (1,0)-(1,1)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "a" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "a" + ├── call_operator_loc: (1,1)-(1,3) = "&." + ├── message_loc: (1,3)-(1,4) = "b" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── flags: safe_navigation + ├── 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 new file mode 100644 index 00000000000000..de49cba3c301c2 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_plain.txt @@ -0,0 +1,65 @@ +@ ProgramNode (location: (1,0)-(5,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,8)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,7)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,7) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,10)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,5) = "::" + │ ├── message_loc: (3,5)-(3,8) = "Fun" + │ ├── opening_loc: (3,8)-(3,9) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (3,9)-(3,10) = ")" + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Fun" + └── @ CallNode (location: (5,0)-(5,8)) + ├── receiver: + │ @ CallNode (location: (5,0)-(5,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (5,3)-(5,5) = "::" + ├── message_loc: (5,5)-(5,8) = "fun" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/send_plain_cmd.txt b/test/prism/snapshots/whitequark/send_plain_cmd.txt new file mode 100644 index 00000000000000..1ddca9e15ee9d1 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_plain_cmd.txt @@ -0,0 +1,101 @@ +@ ProgramNode (location: (1,0)-(5,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,12)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,11)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,7) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,11)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,8)-(1,11)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,8)-(1,11) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,12)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,5) = "::" + │ ├── message_loc: (3,5)-(3,8) = "Fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,9)-(3,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,9)-(3,12)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,9)-(3,12) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "Fun" + └── @ CallNode (location: (5,0)-(5,12)) + ├── receiver: + │ @ CallNode (location: (5,0)-(5,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: (5,3)-(5,5) = "::" + ├── message_loc: (5,5)-(5,8) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (5,9)-(5,12)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (5,9)-(5,12)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,9)-(5,12) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/send_self.txt b/test/prism/snapshots/whitequark/send_self.txt new file mode 100644 index 00000000000000..aa1de85d59c611 --- /dev/null +++ b/test/prism/snapshots/whitequark/send_self.txt @@ -0,0 +1,39 @@ +@ ProgramNode (location: (1,0)-(5,6)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,6)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,4) = "fun!" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "fun!" + └── @ CallNode (location: (5,0)-(5,6)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,3) = "fun" + ├── opening_loc: (5,3)-(5,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (5,4)-(5,5)) + │ └── arguments: (length: 1) + │ └── @ IntegerNode (location: (5,4)-(5,5)) + │ └── flags: decimal + ├── closing_loc: (5,5)-(5,6) = ")" + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/send_self_block.txt b/test/prism/snapshots/whitequark/send_self_block.txt new file mode 100644 index 00000000000000..929f3ecaf2370c --- /dev/null +++ b/test/prism/snapshots/whitequark/send_self_block.txt @@ -0,0 +1,73 @@ +@ ProgramNode (location: (1,0)-(7,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,10)) + └── body: (length: 4) + ├── @ CallNode (location: (1,0)-(1,10)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (1,4)-(1,10)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,4)-(1,6) = "do" + │ │ └── closing_loc: (1,7)-(1,10) = "end" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,7)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,3) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: + │ │ @ BlockNode (location: (3,4)-(3,7)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,4)-(3,5) = "{" + │ │ └── closing_loc: (3,6)-(3,7) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (5,0)-(5,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,0)-(5,3) = "fun" + │ ├── opening_loc: (5,3)-(5,4) = "(" + │ ├── arguments: ∅ + │ ├── closing_loc: (5,4)-(5,5) = ")" + │ ├── block: + │ │ @ BlockNode (location: (5,6)-(5,9)) + │ │ ├── locals: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (5,6)-(5,7) = "{" + │ │ └── closing_loc: (5,8)-(5,9) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + └── @ CallNode (location: (7,0)-(7,10)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (7,0)-(7,3) = "fun" + ├── opening_loc: (7,3)-(7,4) = "(" + ├── arguments: + │ @ ArgumentsNode (location: (7,4)-(7,5)) + │ └── 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: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (7,7)-(7,8) = "{" + │ └── closing_loc: (7,9)-(7,10) = "}" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/send_unary_op.txt b/test/prism/snapshots/whitequark/send_unary_op.txt new file mode 100644 index 00000000000000..6b1f4a383bd87b --- /dev/null +++ b/test/prism/snapshots/whitequark/send_unary_op.txt @@ -0,0 +1,65 @@ +@ ProgramNode (location: (1,0)-(5,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,4)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: + │ │ @ CallNode (location: (1,1)-(1,4)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,1)-(1,4) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,1) = "+" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "+@" + ├── @ CallNode (location: (3,0)-(3,4)) + │ ├── receiver: + │ │ @ CallNode (location: (3,1)-(3,4)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,1)-(3,4) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-@" + └── @ CallNode (location: (5,0)-(5,4)) + ├── receiver: + │ @ CallNode (location: (5,1)-(5,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,1)-(5,4) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,1) = "~" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "~" diff --git a/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt b/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt new file mode 100644 index 00000000000000..2a63c8cb0bca0f --- /dev/null +++ b/test/prism/snapshots/whitequark/slash_newline_in_heredocs.txt @@ -0,0 +1,17 @@ +@ 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)-(4,0) = " 1 \\\n 2\n 3\n" + │ ├── closing_loc: (5,0)-(5,0) = "E\n" + │ └── unescaped: " 1 2\n 3\n" + └── @ StringNode (location: (8,0)-(8,4)) + ├── flags: ∅ + ├── opening_loc: (8,0)-(8,4) = "<<~E" + ├── content_loc: (9,0)-(11,0) = " 1 \\\n 2\n 3\n" + ├── closing_loc: (12,0)-(12,0) = "E\n" + └── unescaped: "1 2\n3\n" diff --git a/test/prism/snapshots/whitequark/space_args_arg.txt b/test/prism/snapshots/whitequark/space_args_arg.txt new file mode 100644 index 00000000000000..78e19335373a07 --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_arg.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(1,7)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,7)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,7)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,7)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/space_args_arg_block.txt b/test/prism/snapshots/whitequark/space_args_arg_block.txt new file mode 100644 index 00000000000000..f16e0991478261 --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_arg_block.txt @@ -0,0 +1,103 @@ +@ ProgramNode (location: (1,0)-(5,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,10)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,14)) + │ ├── receiver: + │ │ @ CallNode (location: (1,0)-(1,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,0)-(1,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (1,3)-(1,4) = "." + │ ├── message_loc: (1,4)-(1,7) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,11)) + │ │ └── 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: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (1,12)-(1,13) = "{" + │ │ └── closing_loc: (1,13)-(1,14) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + ├── @ CallNode (location: (3,0)-(3,15)) + │ ├── receiver: + │ │ @ CallNode (location: (3,0)-(3,3)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,0)-(3,3) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── call_operator_loc: (3,3)-(3,5) = "::" + │ ├── message_loc: (3,5)-(3,8) = "fun" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (3,9)-(3,12)) + │ │ └── 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: [] + │ │ ├── parameters: ∅ + │ │ ├── body: ∅ + │ │ ├── opening_loc: (3,13)-(3,14) = "{" + │ │ └── closing_loc: (3,14)-(3,15) = "}" + │ ├── flags: ∅ + │ └── name: "fun" + └── @ CallNode (location: (5,0)-(5,10)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (5,4)-(5,7)) + │ └── 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: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (5,8)-(5,9) = "{" + │ └── closing_loc: (5,9)-(5,10) = "}" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/space_args_arg_call.txt b/test/prism/snapshots/whitequark/space_args_arg_call.txt new file mode 100644 index 00000000000000..5de0873d9a849f --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_arg_call.txt @@ -0,0 +1,35 @@ +@ ProgramNode (location: (1,0)-(1,12)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,12)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,12)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,12)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (1,4)-(1,12)) + │ ├── 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) = "." + │ ├── message_loc: (1,8)-(1,12) = "to_i" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "to_i" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/space_args_arg_newline.txt b/test/prism/snapshots/whitequark/space_args_arg_newline.txt new file mode 100644 index 00000000000000..edc8183494065a --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_arg_newline.txt @@ -0,0 +1,25 @@ +@ ProgramNode (location: (1,0)-(2,1)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(2,1)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(2,1)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(2,1)) + │ └── 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: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/space_args_block.txt b/test/prism/snapshots/whitequark/space_args_block.txt new file mode 100644 index 00000000000000..b8e35e9d2083f1 --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_block.txt @@ -0,0 +1,27 @@ +@ ProgramNode (location: (1,0)-(1,9)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,9)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,9)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,6)) + │ └── arguments: (length: 1) + │ └── @ ParenthesesNode (location: (1,4)-(1,6)) + │ ├── body: ∅ + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ └── closing_loc: (1,5)-(1,6) = ")" + ├── closing_loc: ∅ + ├── block: + │ @ BlockNode (location: (1,7)-(1,9)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,7)-(1,8) = "{" + │ └── closing_loc: (1,8)-(1,9) = "}" + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/space_args_cmd.txt b/test/prism/snapshots/whitequark/space_args_cmd.txt new file mode 100644 index 00000000000000..ef1ed11ec0dbe1 --- /dev/null +++ b/test/prism/snapshots/whitequark/space_args_cmd.txt @@ -0,0 +1,45 @@ +@ ProgramNode (location: (1,0)-(1,11)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,11)) + └── body: (length: 1) + └── @ CallNode (location: (1,0)-(1,11)) + ├── receiver: ∅ + ├── call_operator_loc: ∅ + ├── message_loc: (1,0)-(1,3) = "fun" + ├── opening_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (1,4)-(1,11)) + │ └── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,6) = "f" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (1,7)-(1,10)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ CallNode (location: (1,7)-(1,10)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,7)-(1,10) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "f" + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ └── closing_loc: (1,10)-(1,11) = ")" + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "fun" diff --git a/test/prism/snapshots/whitequark/string___FILE__.txt b/test/prism/snapshots/whitequark/string___FILE__.txt new file mode 100644 index 00000000000000..c6ce21be5fc88a --- /dev/null +++ b/test/prism/snapshots/whitequark/string___FILE__.txt @@ -0,0 +1,7 @@ +@ 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 new file mode 100644 index 00000000000000..2c15895d7ea288 --- /dev/null +++ b/test/prism/snapshots/whitequark/string_concat.txt @@ -0,0 +1,29 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ StringConcatNode (location: (1,0)-(1,14)) + ├── left: + │ @ 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) = "\"" + └── right: + @ 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" diff --git a/test/prism/snapshots/whitequark/string_dvar.txt b/test/prism/snapshots/whitequark/string_dvar.txt new file mode 100644 index 00000000000000..123b36e01d9aa4 --- /dev/null +++ b/test/prism/snapshots/whitequark/string_dvar.txt @@ -0,0 +1,36 @@ +@ 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 new file mode 100644 index 00000000000000..9c372473fea46b --- /dev/null +++ b/test/prism/snapshots/whitequark/string_interp.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ InterpolatedStringNode (location: (1,0)-(1,14)) + ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,6)-(1,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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 new file mode 100644 index 00000000000000..7534ac1844bff0 --- /dev/null +++ b/test/prism/snapshots/whitequark/string_plain.txt @@ -0,0 +1,17 @@ +@ ProgramNode (location: (1,0)-(3,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,8)) + └── body: (length: 2) + ├── @ StringNode (location: (1,0)-(1,10)) + │ ├── flags: ∅ + │ ├── opening_loc: (1,0)-(1,3) = "%q(" + │ ├── content_loc: (1,3)-(1,9) = "foobar" + │ ├── closing_loc: (1,9)-(1,10) = ")" + │ └── unescaped: "foobar" + └── @ StringNode (location: (3,0)-(3,8)) + ├── flags: ∅ + ├── opening_loc: (3,0)-(3,1) = "'" + ├── content_loc: (3,1)-(3,7) = "foobar" + ├── closing_loc: (3,7)-(3,8) = "'" + └── unescaped: "foobar" diff --git a/test/prism/snapshots/whitequark/super.txt b/test/prism/snapshots/whitequark/super.txt new file mode 100644 index 00000000000000..694b4c796d35ed --- /dev/null +++ b/test/prism/snapshots/whitequark/super.txt @@ -0,0 +1,47 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (5,6)-(5,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,6)-(5,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── rparen_loc: (5,9)-(5,10) = ")" + └── block: ∅ diff --git a/test/prism/snapshots/whitequark/super_block.txt b/test/prism/snapshots/whitequark/super_block.txt new file mode 100644 index 00000000000000..ffb07e77157fa9 --- /dev/null +++ b/test/prism/snapshots/whitequark/super_block.txt @@ -0,0 +1,47 @@ +@ ProgramNode (location: (1,0)-(3,21)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,21)) + └── body: (length: 2) + ├── @ ForwardingSuperNode (location: (1,0)-(1,12)) + │ └── block: + │ @ BlockNode (location: (1,6)-(1,12)) + │ ├── locals: [] + │ ├── parameters: ∅ + │ ├── body: ∅ + │ ├── opening_loc: (1,6)-(1,8) = "do" + │ └── closing_loc: (1,9)-(1,12) = "end" + └── @ SuperNode (location: (3,0)-(3,21)) + ├── keyword_loc: (3,0)-(3,5) = "super" + ├── lparen_loc: ∅ + ├── arguments: + │ @ ArgumentsNode (location: (3,6)-(3,14)) + │ └── arguments: (length: 2) + │ ├── @ CallNode (location: (3,6)-(3,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,6)-(3,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── @ CallNode (location: (3,11)-(3,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,11)-(3,14) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── rparen_loc: ∅ + └── block: + @ BlockNode (location: (3,15)-(3,21)) + ├── locals: [] + ├── parameters: ∅ + ├── body: ∅ + ├── opening_loc: (3,15)-(3,17) = "do" + └── closing_loc: (3,18)-(3,21) = "end" diff --git a/test/prism/snapshots/whitequark/symbol_interp.txt b/test/prism/snapshots/whitequark/symbol_interp.txt new file mode 100644 index 00000000000000..fae980d98a7ead --- /dev/null +++ b/test/prism/snapshots/whitequark/symbol_interp.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,15)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,15)) + └── body: (length: 1) + └── @ InterpolatedSymbolNode (location: (1,0)-(1,15)) + ├── opening_loc: (1,0)-(1,2) = ":\"" + ├── parts: (length: 3) + │ ├── @ StringNode (location: (1,2)-(1,5)) + │ │ ├── flags: ∅ + │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,7)-(1,10) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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 new file mode 100644 index 00000000000000..95b1246d419576 --- /dev/null +++ b/test/prism/snapshots/whitequark/symbol_plain.txt @@ -0,0 +1,15 @@ +@ ProgramNode (location: (1,0)-(3,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,4)) + └── body: (length: 2) + ├── @ SymbolNode (location: (1,0)-(1,6)) + │ ├── 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)) + ├── opening_loc: (3,0)-(3,1) = ":" + ├── value_loc: (3,1)-(3,4) = "foo" + ├── closing_loc: ∅ + └── unescaped: "foo" diff --git a/test/prism/snapshots/whitequark/ternary.txt b/test/prism/snapshots/whitequark/ternary.txt new file mode 100644 index 00000000000000..ce65ca09ec3e31 --- /dev/null +++ b/test/prism/snapshots/whitequark/ternary.txt @@ -0,0 +1,33 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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 new file mode 100644 index 00000000000000..3b9457d47157c7 --- /dev/null +++ b/test/prism/snapshots/whitequark/ternary_ambiguous_symbol.txt @@ -0,0 +1,48 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,5)-(1,8) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── opening_loc: (1,4)-(1,5) = "(" + │ └── closing_loc: (1,8)-(1,9) = ")" + ├── statements: + │ @ StatementsNode (location: (1,10)-(1,11)) + │ └── body: (length: 1) + │ └── @ LocalVariableReadNode (location: (1,10)-(1,11)) + │ ├── name: :t + │ └── depth: 0 + ├── consequent: + │ @ ElseNode (location: (1,11)-(1,13)) + │ ├── else_keyword_loc: (1,11)-(1,12) = ":" + │ ├── statements: + │ │ @ StatementsNode (location: (1,12)-(1,13)) + │ │ └── body: (length: 1) + │ │ └── @ ConstantReadNode (location: (1,12)-(1,13)) + │ │ └── name: :T + │ └── end_keyword_loc: ∅ + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/trailing_forward_arg.txt b/test/prism/snapshots/whitequark/trailing_forward_arg.txt new file mode 100644 index 00000000000000..a67b8552b51f03 --- /dev/null +++ b/test/prism/snapshots/whitequark/trailing_forward_arg.txt @@ -0,0 +1,51 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,20)-(1,23) = "bar" + │ ├── opening_loc: (1,23)-(1,24) = "(" + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,24)-(1,34)) + │ │ └── 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: ∅ + │ ├── flags: ∅ + │ └── name: "bar" + ├── locals: [:a, :b, :"..."] + ├── def_keyword_loc: (1,0)-(1,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: (1,7)-(1,8) = "(" + ├── rparen_loc: (1,17)-(1,18) = ")" + ├── equal_loc: ∅ + └── end_keyword_loc: (1,37)-(1,40) = "end" diff --git a/test/prism/snapshots/whitequark/true.txt b/test/prism/snapshots/whitequark/true.txt new file mode 100644 index 00000000000000..3e1ceef586d71c --- /dev/null +++ b/test/prism/snapshots/whitequark/true.txt @@ -0,0 +1,6 @@ +@ ProgramNode (location: (1,0)-(1,4)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,4)) + └── body: (length: 1) + └── @ TrueNode (location: (1,0)-(1,4)) diff --git a/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt b/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt new file mode 100644 index 00000000000000..e0efa7e17c19fb --- /dev/null +++ b/test/prism/snapshots/whitequark/unary_num_pow_precedence.txt @@ -0,0 +1,71 @@ +@ ProgramNode (location: (1,0)-(5,10)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(5,10)) + └── body: (length: 3) + ├── @ CallNode (location: (1,0)-(1,10)) + │ ├── receiver: + │ │ @ FloatNode (location: (1,0)-(1,4)) + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,7) = "**" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,8)-(1,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (1,8)-(1,10)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "**" + ├── @ CallNode (location: (3,0)-(3,8)) + │ ├── receiver: + │ │ @ CallNode (location: (3,1)-(3,8)) + │ │ ├── receiver: + │ │ │ @ IntegerNode (location: (3,1)-(3,2)) + │ │ │ └── flags: decimal + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,3)-(3,5) = "**" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: + │ │ │ @ ArgumentsNode (location: (3,6)-(3,8)) + │ │ │ └── arguments: (length: 1) + │ │ │ └── @ IntegerNode (location: (3,6)-(3,8)) + │ │ │ └── flags: decimal + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: ∅ + │ │ └── name: "**" + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,0)-(3,1) = "-" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "-@" + └── @ CallNode (location: (5,0)-(5,10)) + ├── receiver: + │ @ CallNode (location: (5,1)-(5,10)) + │ ├── receiver: + │ │ @ FloatNode (location: (5,1)-(5,4)) + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (5,5)-(5,7) = "**" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (5,8)-(5,10)) + │ │ └── arguments: (length: 1) + │ │ └── @ IntegerNode (location: (5,8)-(5,10)) + │ │ └── flags: decimal + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "**" + ├── call_operator_loc: ∅ + ├── message_loc: (5,0)-(5,1) = "-" + ├── opening_loc: ∅ + ├── arguments: ∅ + ├── closing_loc: ∅ + ├── block: ∅ + ├── flags: ∅ + └── name: "-@" diff --git a/test/prism/snapshots/whitequark/undef.txt b/test/prism/snapshots/whitequark/undef.txt new file mode 100644 index 00000000000000..1012a03c574cec --- /dev/null +++ b/test/prism/snapshots/whitequark/undef.txt @@ -0,0 +1,36 @@ +@ 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)) + │ │ ├── opening_loc: ∅ + │ │ ├── value_loc: (1,6)-(1,9) = "foo" + │ │ ├── closing_loc: ∅ + │ │ └── unescaped: "foo" + │ ├── @ SymbolNode (location: (1,11)-(1,15)) + │ │ ├── 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 new file mode 100644 index 00000000000000..8f34c0f21f41fd --- /dev/null +++ b/test/prism/snapshots/whitequark/unless.txt @@ -0,0 +1,61 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,10) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── statements: + │ │ @ StatementsNode (location: (1,16)-(1,19)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,16)-(1,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,19) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,7)-(3,10) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (3,12)-(3,15)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,12)-(3,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,12)-(3,15) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── consequent: ∅ + └── end_keyword_loc: (3,17)-(3,20) = "end" diff --git a/test/prism/snapshots/whitequark/unless_else.txt b/test/prism/snapshots/whitequark/unless_else.txt new file mode 100644 index 00000000000000..77ca14355c0f5b --- /dev/null +++ b/test/prism/snapshots/whitequark/unless_else.txt @@ -0,0 +1,93 @@ +@ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,7)-(1,10) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── statements: + │ │ @ StatementsNode (location: (1,16)-(1,19)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,16)-(1,19)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,16)-(1,19) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,26)-(1,29) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,7)-(3,10) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (3,12)-(3,15)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,12)-(3,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,12)-(3,15) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,22)-(3,25) = "baz" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "baz" + │ └── end_keyword_loc: (3,27)-(3,30) = "end" + └── end_keyword_loc: (3,27)-(3,30) = "end" diff --git a/test/prism/snapshots/whitequark/unless_mod.txt b/test/prism/snapshots/whitequark/unless_mod.txt new file mode 100644 index 00000000000000..923b4d3cc0aad9 --- /dev/null +++ b/test/prism/snapshots/whitequark/unless_mod.txt @@ -0,0 +1,33 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (1,0)-(1,3)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,0)-(1,3)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,3) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── consequent: ∅ + └── end_keyword_loc: ∅ diff --git a/test/prism/snapshots/whitequark/until.txt b/test/prism/snapshots/whitequark/until.txt new file mode 100644 index 00000000000000..a00febb20a3931 --- /dev/null +++ b/test/prism/snapshots/whitequark/until.txt @@ -0,0 +1,61 @@ +@ ProgramNode (location: (1,0)-(3,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,19)) + └── body: (length: 2) + ├── @ UntilNode (location: (1,0)-(1,21)) + │ ├── keyword_loc: (1,0)-(1,5) = "until" + │ ├── closing_loc: (1,18)-(1,21) = "end" + │ ├── predicate: + │ │ @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── statements: + │ │ @ StatementsNode (location: (1,13)-(1,17)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,13)-(1,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,13)-(1,17) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ └── flags: ∅ + └── @ UntilNode (location: (3,0)-(3,19)) + ├── keyword_loc: (3,0)-(3,5) = "until" + ├── closing_loc: (3,16)-(3,19) = "end" + ├── predicate: + │ @ CallNode (location: (3,6)-(3,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,6)-(3,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (3,11)-(3,15)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,11)-(3,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,11)-(3,15) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/until_mod.txt b/test/prism/snapshots/whitequark/until_mod.txt new file mode 100644 index 00000000000000..56cc47b9d7c914 --- /dev/null +++ b/test/prism/snapshots/whitequark/until_mod.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ UntilNode (location: (1,0)-(1,14)) + ├── keyword_loc: (1,5)-(1,10) = "until" + ├── closing_loc: ∅ + ├── predicate: + │ @ CallNode (location: (1,11)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (1,0)-(1,4)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/until_post.txt b/test/prism/snapshots/whitequark/until_post.txt new file mode 100644 index 00000000000000..7bcfd2678b9281 --- /dev/null +++ b/test/prism/snapshots/whitequark/until_post.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(1,24)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,24)) + └── body: (length: 1) + └── @ UntilNode (location: (1,0)-(1,24)) + ├── keyword_loc: (1,15)-(1,20) = "until" + ├── closing_loc: ∅ + ├── predicate: + │ @ CallNode (location: (1,21)-(1,24)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,21)-(1,24) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,10) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ ├── rescue_clause: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (1,11)-(1,14) = "end" + └── flags: begin_modifier diff --git a/test/prism/snapshots/whitequark/var_and_asgn.txt b/test/prism/snapshots/whitequark/var_and_asgn.txt new file mode 100644 index 00000000000000..fc746a93506104 --- /dev/null +++ b/test/prism/snapshots/whitequark/var_and_asgn.txt @@ -0,0 +1,13 @@ +@ 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 new file mode 100644 index 00000000000000..7160141b07549a --- /dev/null +++ b/test/prism/snapshots/whitequark/var_op_asgn.txt @@ -0,0 +1,53 @@ +@ 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: [] + ├── def_keyword_loc: (7,0)-(7,3) = "def" + ├── operator_loc: ∅ + ├── lparen_loc: ∅ + ├── rparen_loc: ∅ + ├── equal_loc: ∅ + └── end_keyword_loc: (7,20)-(7,23) = "end" diff --git a/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt new file mode 100644 index 00000000000000..9f9750cedd5b1f --- /dev/null +++ b/test/prism/snapshots/whitequark/var_op_asgn_cmd.txt @@ -0,0 +1,27 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,7)-(1,8) = "m" + │ ├── opening_loc: ∅ + │ ├── arguments: + │ │ @ ArgumentsNode (location: (1,9)-(1,12)) + │ │ └── arguments: (length: 1) + │ │ └── @ LocalVariableReadNode (location: (1,9)-(1,12)) + │ │ ├── name: :foo + │ │ └── depth: 0 + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: ∅ + │ └── name: "m" + ├── name: :foo + ├── operator: :+ + └── depth: 0 diff --git a/test/prism/snapshots/whitequark/var_or_asgn.txt b/test/prism/snapshots/whitequark/var_or_asgn.txt new file mode 100644 index 00000000000000..d5064bc55b5d50 --- /dev/null +++ b/test/prism/snapshots/whitequark/var_or_asgn.txt @@ -0,0 +1,13 @@ +@ 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 new file mode 100644 index 00000000000000..499369644d6fdb --- /dev/null +++ b/test/prism/snapshots/whitequark/when_multi.txt @@ -0,0 +1,49 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,29)-(1,32) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,34)-(1,37) = "end" diff --git a/test/prism/snapshots/whitequark/when_splat.txt b/test/prism/snapshots/whitequark/when_splat.txt new file mode 100644 index 00000000000000..d09637b1a10c41 --- /dev/null +++ b/test/prism/snapshots/whitequark/when_splat.txt @@ -0,0 +1,69 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,19)-(1,22) = "baz" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "baz" + │ │ └── statements: + │ │ @ StatementsNode (location: (1,24)-(1,27)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,24)-(1,27)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,24)-(1,27) = "bar" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "bar" + │ └── @ 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,35)-(1,38) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── statements: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,40)-(1,43) = "end" diff --git a/test/prism/snapshots/whitequark/when_then.txt b/test/prism/snapshots/whitequark/when_then.txt new file mode 100644 index 00000000000000..01feb88737b39b --- /dev/null +++ b/test/prism/snapshots/whitequark/when_then.txt @@ -0,0 +1,43 @@ +@ 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,5)-(1,8) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,26)-(1,29) = "bar" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "bar" + ├── consequent: ∅ + ├── case_keyword_loc: (1,0)-(1,4) = "case" + └── end_keyword_loc: (1,31)-(1,34) = "end" diff --git a/test/prism/snapshots/whitequark/while.txt b/test/prism/snapshots/whitequark/while.txt new file mode 100644 index 00000000000000..2fae4e412fccf9 --- /dev/null +++ b/test/prism/snapshots/whitequark/while.txt @@ -0,0 +1,61 @@ +@ ProgramNode (location: (1,0)-(3,19)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(3,19)) + └── body: (length: 2) + ├── @ WhileNode (location: (1,0)-(1,21)) + │ ├── keyword_loc: (1,0)-(1,5) = "while" + │ ├── closing_loc: (1,18)-(1,21) = "end" + │ ├── predicate: + │ │ @ CallNode (location: (1,6)-(1,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ ├── statements: + │ │ @ StatementsNode (location: (1,13)-(1,17)) + │ │ └── body: (length: 1) + │ │ └── @ CallNode (location: (1,13)-(1,17)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,13)-(1,17) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ └── flags: ∅ + └── @ WhileNode (location: (3,0)-(3,19)) + ├── keyword_loc: (3,0)-(3,5) = "while" + ├── closing_loc: (3,16)-(3,19) = "end" + ├── predicate: + │ @ CallNode (location: (3,6)-(3,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,6)-(3,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (3,11)-(3,15)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (3,11)-(3,15)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (3,11)-(3,15) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/while_mod.txt b/test/prism/snapshots/whitequark/while_mod.txt new file mode 100644 index 00000000000000..46b1d20033015a --- /dev/null +++ b/test/prism/snapshots/whitequark/while_mod.txt @@ -0,0 +1,33 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ WhileNode (location: (1,0)-(1,14)) + ├── keyword_loc: (1,5)-(1,10) = "while" + ├── closing_loc: ∅ + ├── predicate: + │ @ CallNode (location: (1,11)-(1,14)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,11)-(1,14) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── statements: + │ @ StatementsNode (location: (1,0)-(1,4)) + │ └── body: (length: 1) + │ └── @ CallNode (location: (1,0)-(1,4)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,0)-(1,4) = "meth" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "meth" + └── flags: ∅ diff --git a/test/prism/snapshots/whitequark/while_post.txt b/test/prism/snapshots/whitequark/while_post.txt new file mode 100644 index 00000000000000..7ec16db0a16c14 --- /dev/null +++ b/test/prism/snapshots/whitequark/while_post.txt @@ -0,0 +1,42 @@ +@ ProgramNode (location: (1,0)-(1,24)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,24)) + └── body: (length: 1) + └── @ WhileNode (location: (1,0)-(1,24)) + ├── keyword_loc: (1,15)-(1,20) = "while" + ├── closing_loc: ∅ + ├── predicate: + │ @ CallNode (location: (1,21)-(1,24)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (1,21)-(1,24) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + ├── 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)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (1,6)-(1,10) = "meth" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "meth" + │ ├── rescue_clause: ∅ + │ ├── else_clause: ∅ + │ ├── ensure_clause: ∅ + │ └── end_keyword_loc: (1,11)-(1,14) = "end" + └── flags: begin_modifier diff --git a/test/prism/snapshots/whitequark/xstring_interp.txt b/test/prism/snapshots/whitequark/xstring_interp.txt new file mode 100644 index 00000000000000..53844dfbe2d3dd --- /dev/null +++ b/test/prism/snapshots/whitequark/xstring_interp.txt @@ -0,0 +1,37 @@ +@ ProgramNode (location: (1,0)-(1,14)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,14)) + └── body: (length: 1) + └── @ InterpolatedXStringNode (location: (1,0)-(1,14)) + ├── opening_loc: (1,0)-(1,1) = "`" + ├── parts: (length: 3) + │ ├── @ StringNode (location: (1,1)-(1,4)) + │ │ ├── flags: ∅ + │ │ ├── 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)) + │ │ │ ├── receiver: ∅ + │ │ │ ├── call_operator_loc: ∅ + │ │ │ ├── message_loc: (1,6)-(1,9) = "bar" + │ │ │ ├── opening_loc: ∅ + │ │ │ ├── arguments: ∅ + │ │ │ ├── closing_loc: ∅ + │ │ │ ├── block: ∅ + │ │ │ ├── flags: variable_call + │ │ │ └── name: "bar" + │ │ └── 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 new file mode 100644 index 00000000000000..2546f9829f7712 --- /dev/null +++ b/test/prism/snapshots/whitequark/xstring_plain.txt @@ -0,0 +1,10 @@ +@ ProgramNode (location: (1,0)-(1,8)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,8)) + └── body: (length: 1) + └── @ XStringNode (location: (1,0)-(1,8)) + ├── opening_loc: (1,0)-(1,1) = "`" + ├── content_loc: (1,1)-(1,7) = "foobar" + ├── closing_loc: (1,7)-(1,8) = "`" + └── unescaped: "foobar" diff --git a/test/prism/snapshots/whitequark/yield.txt b/test/prism/snapshots/whitequark/yield.txt new file mode 100644 index 00000000000000..4d1ca051ccc2d9 --- /dev/null +++ b/test/prism/snapshots/whitequark/yield.txt @@ -0,0 +1,49 @@ +@ 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)) + │ │ └── arguments: (length: 1) + │ │ └── @ CallNode (location: (3,6)-(3,9)) + │ │ ├── receiver: ∅ + │ │ ├── call_operator_loc: ∅ + │ │ ├── message_loc: (3,6)-(3,9) = "foo" + │ │ ├── opening_loc: ∅ + │ │ ├── arguments: ∅ + │ │ ├── closing_loc: ∅ + │ │ ├── block: ∅ + │ │ ├── flags: variable_call + │ │ └── name: "foo" + │ └── 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)) + │ └── arguments: (length: 1) + │ └── @ CallNode (location: (7,6)-(7,9)) + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── message_loc: (7,6)-(7,9) = "foo" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ ├── block: ∅ + │ ├── flags: variable_call + │ └── name: "foo" + └── rparen_loc: (7,9)-(7,10) = ")" diff --git a/test/prism/snapshots/whitequark/zsuper.txt b/test/prism/snapshots/whitequark/zsuper.txt new file mode 100644 index 00000000000000..9c28128d06f1d1 --- /dev/null +++ b/test/prism/snapshots/whitequark/zsuper.txt @@ -0,0 +1,7 @@ +@ ProgramNode (location: (1,0)-(1,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(1,5)) + └── body: (length: 1) + └── @ ForwardingSuperNode (location: (1,0)-(1,5)) + └── block: ∅ diff --git a/test/prism/snapshots/xstring.txt b/test/prism/snapshots/xstring.txt new file mode 100644 index 00000000000000..5cea973e4fa06a --- /dev/null +++ b/test/prism/snapshots/xstring.txt @@ -0,0 +1,52 @@ +@ ProgramNode (location: (1,0)-(7,5)) +├── locals: [] +└── statements: + @ StatementsNode (location: (1,0)-(7,5)) + └── body: (length: 4) + ├── @ XStringNode (location: (1,0)-(1,7)) + │ ├── 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)) + │ │ │ │ ├── receiver: ∅ + │ │ │ │ ├── call_operator_loc: ∅ + │ │ │ │ ├── message_loc: (3,7)-(3,10) = "bar" + │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ ├── arguments: ∅ + │ │ │ │ ├── closing_loc: ∅ + │ │ │ │ ├── block: ∅ + │ │ │ │ ├── flags: variable_call + │ │ │ │ └── name: "bar" + │ │ │ └── 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)) + │ ├── 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)) + ├── 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 new file mode 100644 index 00000000000000..ecdf48f026ec12 --- /dev/null +++ b/test/prism/snapshots/yield.txt @@ -0,0 +1,37 @@ +@ 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)) + │ │ └── 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)) + │ └── 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/yarp/test_helper.rb b/test/prism/test_helper.rb similarity index 96% rename from test/yarp/test_helper.rb rename to test/prism/test_helper.rb index 086b73dd563a6c..a16de14cbeb802 100644 --- a/test/yarp/test_helper.rb +++ b/test/prism/test_helper.rb @@ -1,12 +1,12 @@ # frozen_string_literal: true -require "yarp" +require "prism" require "ripper" require "pp" require "test/unit" require "tempfile" -puts "Using YARP backend: #{YARP::BACKEND}" if ENV["YARP_FFI_BACKEND"] +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 @@ -15,7 +15,7 @@ Test::Unit::Assertions::AssertionMessage.max_diff_target_string_size = 5000 end -module YARP +module Prism class TestCase < ::Test::Unit::TestCase private diff --git a/test/yarp/unescape_test.rb b/test/prism/unescape_test.rb similarity index 91% rename from test/yarp/unescape_test.rb rename to test/prism/unescape_test.rb index f39bdd0e394ee3..c2129051ec4dad 100644 --- a/test/yarp/unescape_test.rb +++ b/test/prism/unescape_test.rb @@ -2,9 +2,9 @@ require_relative "test_helper" -return if YARP::BACKEND == :FFI +return if Prism::BACKEND == :FFI -module YARP +module Prism class UnescapeNoneTest < TestCase def test_backslash assert_unescape_none("\\") @@ -136,6 +136,13 @@ def test_escaping_normal_characters assert_unescape_all("g", "\\g") end + def test_whitespace_escaping_string_list + assert_equal("a b", Debug.unescape_whitespace("a\\ b")) + assert_equal("a\tb", Debug.unescape_whitespace("a\\\tb")) + assert_equal("a\nb", Debug.unescape_whitespace("a\\\nb")) + assert_equal("a\nb", Debug.unescape_whitespace("a\\\r\nb")) + end + private def unescape_all(source) diff --git a/test/yarp/version_test.rb b/test/prism/version_test.rb similarity index 92% rename from test/yarp/version_test.rb rename to test/prism/version_test.rb index 6011eb695d7267..29ee6b224cc735 100644 --- a/test/yarp/version_test.rb +++ b/test/prism/version_test.rb @@ -2,7 +2,7 @@ require_relative "test_helper" -module YARP +module Prism class VersionTest < TestCase def test_version_is_set refute_nil VERSION diff --git a/test/reline/helper.rb b/test/reline/helper.rb index bb2389318739aa..fb2262e7f5047a 100644 --- a/test/reline/helper.rb +++ b/test/reline/helper.rb @@ -21,21 +21,23 @@ module Reline class <{#{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 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_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 diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb new file mode 100644 index 00000000000000..9c2f232396f2f6 --- /dev/null +++ b/test/ruby/test_compile_prism.rb @@ -0,0 +1,435 @@ +# frozen_string_literal: true + +module Prism + class TestCompilePrism < Test::Unit::TestCase + def test_empty_program + test_prism_eval("") + end + + ############################################################################ + # Literals # + ############################################################################ + + def test_FalseNode + test_prism_eval("false") + end + + def test_FloatNode + test_prism_eval("1.2") + test_prism_eval("1.2e3") + test_prism_eval("+1.2e+3") + test_prism_eval("-1.2e-3") + end + + def test_ImaginaryNode + test_prism_eval("1i") + test_prism_eval("+1.0i") + test_prism_eval("1ri") + end + + def test_IntegerNode + test_prism_eval("1") + test_prism_eval("+1") + test_prism_eval("-1") + test_prism_eval("0x10") + test_prism_eval("0b10") + test_prism_eval("0o10") + test_prism_eval("010") + end + + def test_MatchLastLineNode + test_prism_eval("if /foo/; end") + test_prism_eval("if /foo/i; end") + test_prism_eval("if /foo/x; end") + test_prism_eval("if /foo/m; end") + test_prism_eval("if /foo/im; end") + test_prism_eval("if /foo/mx; end") + test_prism_eval("if /foo/xi; end") + test_prism_eval("if /foo/ixm; end") + end + + def test_NilNode + test_prism_eval("nil") + end + + def test_RationalNode + test_prism_eval("1.2r") + test_prism_eval("+1.2r") + end + + def test_SelfNode + test_prism_eval("self") + end + + def test_TrueNode + test_prism_eval("true") + end + + ############################################################################ + # Reads # + ############################################################################ + + def test_ClassVariableReadNode + test_prism_eval("class Prism::TestCompilePrism; @@pit = 1; @@pit; end") + end + + def test_ConstantPathNode + test_prism_eval("Prism::TestCompilePrism") + end + + def test_ConstantReadNode + test_prism_eval("Prism") + end + + def test_GlobalVariableReadNode + test_prism_eval("$pit = 1; $pit") + end + + def test_InstanceVariableReadNode + test_prism_eval("class Prism::TestCompilePrism; @pit = 1; @pit; end") + end + + def test_LocalVariableReadNode + test_prism_eval("pit = 1; pit") + end + + ############################################################################ + # Writes # + ############################################################################ + + def test_ClassVariableTargetNode + test_prism_eval("class Prism::TestCompilePrism; @@pit, @@pit1 = 1; end") + end + + def test_ClassVariableWriteNode + test_prism_eval("class Prism::TestCompilePrism; @@pit = 1; end") + end + + def test_ClassVariableAndWriteNode + test_prism_eval("class Prism::TestCompilePrism; @@pit = 0; @@pit &&= 1; end") + end + + def test_ClassVariableOrWriteNode + test_prism_eval("class Prism::TestCompilePrism; @@pit = 1; @@pit ||= 0; end") + test_prism_eval("class Prism::TestCompilePrism; @@pit = nil; @@pit ||= 1; end") + end + + def test_ClassVariableOperatorWriteNode + test_prism_eval("class Prism::TestCompilePrism; @@pit = 0; @@pit += 1; end") + end + + def test_ConstantTargetNode + # We don't call test_prism_eval directly in this case becuase we + # don't want to assign the constant mutliple 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_ConstantWriteNode + # We don't call test_prism_eval directly in this case becuase we + # don't want to assign the constant mutliple 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_ConstantPathTargetNode + 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 + + ensure + ## Teardown temp constants + Object.const_get("MyFoo").send(:remove_const, "Bar") + Object.send(:remove_const, "MyFoo") + Object.send(:remove_const, "MyBar") + $VERBOSE = verbose + end + + def test_ConstantPathWriteNode + # test_prism_eval("Prism::YCT = 1") + end + + def test_GlobalVariableTargetNode + test_prism_eval("$pit, $pit1 = 1") + end + + def test_GlobalVariableWriteNode + test_prism_eval("$pit = 1") + end + + def test_GlobalVariableAndWriteNode + test_prism_eval("$pit = 0; $pit &&= 1") + end + + def test_GlobalVariableOrWriteNode + test_prism_eval("$pit ||= 1") + end + + def test_GlobalVariableOperatorWriteNode + test_prism_eval("$pit = 0; $pit += 1") + end + + def test_InstanceVariableTargetNode + test_prism_eval("class Prism::TestCompilePrism; @pit, @pit1 = 1; end") + end + + def test_InstanceVariableWriteNode + test_prism_eval("class Prism::TestCompilePrism; @pit = 1; end") + end + + def test_InstanceVariableAndWriteNode + test_prism_eval("@pit = 0; @pit &&= 1") + end + + def test_InstanceVariableOrWriteNode + test_prism_eval("@pit ||= 1") + end + + def test_InstanceVariableOperatorWriteNode + test_prism_eval("@pit = 0; @pit += 1") + end + + def test_LocalVariableTargetNode + test_prism_eval("pit, pit1 = 1") + end + + def test_LocalVariableWriteNode + test_prism_eval("pit = 1") + end + + def test_LocalVariableAndWriteNode + test_prism_eval("pit = 0; pit &&= 1") + end + + def test_LocalVariableOrWriteNode + test_prism_eval("pit ||= 1") + end + + def test_LocalVariableOperatorWriteNode + test_prism_eval("pit = 0; pit += 1") + end + + def test_MatchWriteNode + test_prism_eval("/(?bar)(?bar>)/ =~ 'barbar'") + test_prism_eval("/(?bar)/ =~ 'barbar'") + end + + ############################################################################ + # String-likes # + ############################################################################ + + def test_EmbeddedVariableNode + # test_prism_eval('class Prism::TestCompilePrism; @pit = 1; "#@pit"; end') + # test_prism_eval('class Prism::TestCompilePrism; @@pit = 1; "#@@pit"; end') + test_prism_eval('$pit = 1; "#$pit"') + end + + def test_InterpolatedMatchLastLineNode + test_prism_eval("$pit = '.oo'; if /\#$pit/mix; end") + end + + def test_InterpolatedRegularExpressionNode + test_prism_eval('$pit = 1; /1 #$pit 1/') + test_prism_eval('$pit = 1; /#$pit/i') + test_prism_eval('/1 #{1 + 2} 1/') + test_prism_eval('/1 #{"2"} #{1 + 2} 1/') + end + + def test_InterpolatedStringNode + test_prism_eval('$pit = 1; "1 #$pit 1"') + test_prism_eval('"1 #{1 + 2} 1"') + end + + def test_InterpolatedSymbolNode + test_prism_eval('$pit = 1; :"1 #$pit 1"') + test_prism_eval(':"1 #{1 + 2} 1"') + end + + def test_InterpolatedXStringNode + test_prism_eval('`echo #{1}`') + test_prism_eval('`printf #{"100"}`') + end + + def test_RegularExpressionNode + test_prism_eval('/pit/') + test_prism_eval('/pit/i') + test_prism_eval('/pit/x') + test_prism_eval('/pit/m') + test_prism_eval('/pit/im') + test_prism_eval('/pit/mx') + test_prism_eval('/pit/xi') + test_prism_eval('/pit/ixm') + end + + def test_StringConcatNode + # test_prism_eval('"Prism" "::" "TestCompilePrism"') + end + + def test_StringNode + test_prism_eval('"pit"') + end + + def test_SymbolNode + test_prism_eval(":pit") + end + + def test_XStringNode + # test_prism_eval(<<~RUBY) + # class Prism::TestCompilePrism + # def self.`(command) = command * 2 + # `pit` + # end + # RUBY + end + + ############################################################################ + # Structures # + ############################################################################ + + def test_ArrayNode + test_prism_eval("[]") + test_prism_eval("[1, 2, 3]") + test_prism_eval("%i[foo bar baz]") + test_prism_eval("%w[foo bar baz]") + end + + def test_HashNode + test_prism_eval("{}") + test_prism_eval("{ a: :a }") + test_prism_eval("{ a: :a, b: :b }") + test_prism_eval("a = 1; { a: a }") + test_prism_eval("a = 1; { a: }") + test_prism_eval("{ to_s: }") + test_prism_eval("{ Prism: }") + end + + ############################################################################ + # Jumps # + ############################################################################ + + def test_AndNode + test_prism_eval("true && 1") + test_prism_eval("false && 1") + end + + def test_OrNode + test_prism_eval("true || 1") + test_prism_eval("false || 1") + end + + ############################################################################ + # Calls / arugments # + ############################################################################ + + def test_BlockArgumentNode + test_prism_eval("1.then(&:to_s)") + end + + ############################################################################ + # Scopes/statements # + ############################################################################ + + def test_ParenthesesNode + test_prism_eval("()") + test_prism_eval("(1)") + end + + ############################################################################ + # Pattern matching # + ############################################################################ + + def test_AlternationPatternNode + test_prism_eval("1 in 1 | 2") + test_prism_eval("1 in 2 | 1") + test_prism_eval("1 in 2 | 3 | 4 | 1") + test_prism_eval("1 in 2 | 3") + end + + def test_MatchPredicateNode + test_prism_eval("1 in 1") + test_prism_eval("1.0 in 1.0") + test_prism_eval("1i in 1i") + test_prism_eval("1r in 1r") + + test_prism_eval("\"foo\" in \"foo\"") + test_prism_eval("\"foo \#{1}\" in \"foo \#{1}\"") + + test_prism_eval("false in false") + test_prism_eval("nil in nil") + test_prism_eval("self in self") + test_prism_eval("true in true") + + test_prism_eval("5 in 0..10") + test_prism_eval("5 in 0...10") + + test_prism_eval("[\"5\"] in %w[5]") + + test_prism_eval("Prism in Prism") + test_prism_eval("Prism in ::Prism") + + test_prism_eval(":prism in :prism") + test_prism_eval("%s[prism\#{1}] in %s[prism\#{1}]") + test_prism_eval("\"foo\" in /.../") + test_prism_eval("\"foo1\" in /...\#{1}/") + test_prism_eval("4 in ->(v) { v.even? }") + + test_prism_eval("5 in foo") + + test_prism_eval("1 in 2") + end + + def test_PinnedExpressionNode + test_prism_eval("4 in ^(4)") + end + + def test_PinnedVariableNode + test_prism_eval("module Prism; @@prism = 1; 1 in ^@@prism; end") + test_prism_eval("module Prism; @prism = 1; 1 in ^@prism; end") + test_prism_eval("$prism = 1; 1 in ^$prism") + test_prism_eval("prism = 1; 1 in ^prism") + end + + private + + def compare_eval(source) + ruby_eval = RubyVM::InstructionSequence.compile(source).eval + prism_eval = RubyVM::InstructionSequence.compile_prism(source).eval + + assert_equal ruby_eval, prism_eval + end + + def test_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_hash.rb b/test/ruby/test_hash.rb index 9121f3539eac72..f95876d85575c3 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -744,6 +744,21 @@ def test_rehash assert_equal(100, h[a]) 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_reject assert_equal({3=>4,5=>6}, @cls[1=>2,3=>4,5=>6].reject {|k, v| k + v < 7 }) diff --git a/test/ruby/test_io.rb b/test/ruby/test_io.rb index 7689b52e231fb6..476d9f882fc579 100644 --- a/test/ruby/test_io.rb +++ b/test/ruby/test_io.rb @@ -1898,6 +1898,110 @@ def test_set_lineno_gets end) end + def test_readline_bad_param_raises + File.open(__FILE__) do |f| + assert_raise(TypeError) do + f.readline Object.new + end + end + + File.open(__FILE__) do |f| + assert_raise(TypeError) do + f.readline 1, 2 + end + end + end + + def test_readline_raises + File.open(__FILE__) do |f| + assert_equal File.read(__FILE__), f.readline(nil) + assert_raise(EOFError) do + f.readline + end + end + end + + def test_readline_separators + File.open(__FILE__) do |f| + line = f.readline("def") + assert_equal File.read(__FILE__)[/\A.*?def/m], line + end + + File.open(__FILE__) do |f| + line = f.readline("def", chomp: true) + assert_equal File.read(__FILE__)[/\A.*?(?=def)/m], line + end + end + + def test_readline_separators_limits + t = Tempfile.open("readline_limit") + str = "#" * 50 + sep = "def" + + t.write str + t.write sep + t.write str + t.flush + + # over limit + File.open(t.path) do |f| + line = f.readline sep, str.bytesize + assert_equal(str, line) + end + + # under limit + File.open(t.path) do |f| + line = f.readline(sep, str.bytesize + 5) + assert_equal(str + sep, line) + end + + # under limit + chomp + File.open(t.path) do |f| + line = f.readline(sep, str.bytesize + 5, chomp: true) + assert_equal(str, line) + end + ensure + t&.close! + end + + def test_readline_limit_without_separator + t = Tempfile.open("readline_limit") + str = "#" * 50 + sep = "\n" + + t.write str + t.write sep + t.write str + t.flush + + # over limit + File.open(t.path) do |f| + line = f.readline str.bytesize + assert_equal(str, line) + end + + # under limit + File.open(t.path) do |f| + line = f.readline(str.bytesize + 5) + assert_equal(str + sep, line) + end + + # under limit + chomp + File.open(t.path) do |f| + line = f.readline(str.bytesize + 5, chomp: true) + assert_equal(str, line) + end + ensure + t&.close! + end + + def test_readline_chomp_true + File.open(__FILE__) do |f| + line = f.readline(chomp: true) + assert_equal File.readlines(__FILE__).first.chomp, line + end + end + def test_set_lineno_readline pipe(proc do |w| w.puts "foo" diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb index 75ec4016fa6793..d5ba3266c7de4a 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -251,6 +251,18 @@ def test_get_string chunk = buffer.get_string(0, message.bytesize, Encoding::BINARY) assert_equal Encoding::BINARY, chunk.encoding + + assert_raise_with_message(ArgumentError, /bigger than the buffer size/) do + buffer.get_string(0, 129) + end + + assert_raise_with_message(ArgumentError, /bigger than the buffer size/) do + buffer.get_string(129) + end + + assert_raise_with_message(ArgumentError, /Offset can't be negative/) do + buffer.get_string(-1) + end end # We check that values are correctly round tripped. diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 4ff808418ffa04..80fe9b0f060984 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -770,4 +770,15 @@ def test_unreachable_syntax_error assert_syntax_error("false and break", mesg) assert_syntax_error("if false and break; end", mesg) end + + def test_unreachable_pattern_matching + assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", %w[1]) + begin; + if true or {a: 0} in {a:} + p 1 + else + p a + end + end; + end end diff --git a/test/ruby/test_lambda.rb b/test/ruby/test_lambda.rb index 9949fab8c76498..7738034240497d 100644 --- a/test/ruby/test_lambda.rb +++ b/test/ruby/test_lambda.rb @@ -177,32 +177,6 @@ def test_proc_inside_lambda_toplevel 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_math.rb b/test/ruby/test_math.rb index bc2172d6805919..6e67099c6b063f 100644 --- a/test/ruby/test_math.rb +++ b/test/ruby/test_math.rb @@ -168,6 +168,7 @@ def test_log 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 diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 81c5345a5f541e..ca157460020caa 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -3292,6 +3292,47 @@ def test_iclass_memory_leak CODE end + def test_complemented_method_entry_memory_leak + # [Bug #19894] [Bug #19896] + assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true) + code = proc do + $c = Class.new do + def foo; end + end + + $m = Module.new do + refine $c do + def foo; end + end + end + + Class.new do + using $m + + def initialize + o = $c.new + o.method(:foo).unbind + end + end.new + end + 1_000.times(&code) + PREP + 300_000.times(&code) + CODE + end + + def test_module_clone_memory_leak + # [Bug #19901] + assert_no_memory_leak([], <<~PREP, <<~CODE, rss: true) + code = proc do + Module.new.clone + end + 1_000.times(&code) + PREP + 1_000_000.times(&code) + CODE + end + private def assert_top_method_is_private(method) diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 957a37eb81bb8a..6a9f7150a027c6 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -453,10 +453,35 @@ def foo(a, a); end end def test_define_singleton_error - assert_syntax_error("#{<<~"begin;"}\n#{<<~'end;'}", /singleton method for literals/) do - begin; - def ("foo").foo; end - end; + msg = /singleton method for literals/ + assert_parse_error(%q[def ("foo").foo; end], msg) + assert_parse_error(%q[def (1).foo; end], msg) + assert_parse_error(%q[def ((1;1)).foo; end], msg) + assert_parse_error(%q[def ((;1)).foo; end], msg) + assert_parse_error(%q[def ((1+1;1)).foo; end], msg) + assert_parse_error(%q[def ((%s();1)).foo; end], msg) + assert_parse_error(%q[def ((%w();1)).foo; end], msg) + assert_parse_error(%q[def ("#{42}").foo; end], msg) + assert_parse_error(%q[def (:"#{42}").foo; end], msg) + end + + def test_flip_flop + [ + '((cond1..cond2))', + '(; cond1..cond2)', + '(1; cond1..cond2)', + '(%s(); cond1..cond2)', + '(%w(); cond1..cond2)', + '(1; (2; (3; 4; cond1..cond2)))', + '(1+1; cond1..cond2)', + ].each do |code| + code = code.sub("cond1", "n==4").sub("cond2", "n==5") + begin + $VERBOSE, verbose_bak = nil, $VERBOSE + assert_equal([4,5], eval("(1..9).select {|n| true if #{code}}")) + ensure + $VERBOSE = verbose_bak + end end end @@ -641,6 +666,7 @@ def test_symbol 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 @@ -965,6 +991,25 @@ def test_named_capture_conflict assert_warning('') {eval("#{a} = 1; /(?<#{a}>)/ =~ ''")} end + def test_named_capture_in_block + [ + '(/(?.*)/)', + '(;/(?.*)/)', + '(%s();/(?.*)/)', + '(%w();/(?.*)/)', + '(1; (2; 3; (4; /(?.*)/)))', + '(1+1; /(?.*)/)', + ].each do |code| + token = Random.bytes(4).unpack1("H*") + begin + $VERBOSE, verbose_bak = nil, $VERBOSE + assert_equal(token, eval("#{code} =~ #{token.dump}; a")) + ensure + $VERBOSE = verbose_bak + end + end + end + def test_rescue_in_command_assignment bug = '[ruby-core:75621] [Bug #12402]' all_assertions(bug) do |a| @@ -1444,8 +1489,8 @@ def set(arg) end def test_ungettable_gvar - assert_syntax_error('$01234', /not valid to get/) - assert_syntax_error('"#$01234"', /not valid to get/) + assert_syntax_error('$01234', /not allowed/) + assert_syntax_error('"#$01234"', /not allowed/) end =begin @@ -1453,4 +1498,19 @@ 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_proc.rb b/test/ruby/test_proc.rb index 2b3590d4d0627d..4245a7b7857c17 100644 --- a/test/ruby/test_proc.rb +++ b/test/ruby/test_proc.rb @@ -289,7 +289,6 @@ def test_lambda? assert_equal(false, l.lambda?) assert_equal(false, l.curry.lambda?, '[ruby-core:24127]') assert_equal(false, proc(&l).lambda?) - assert_equal(false, assert_deprecated_warning {lambda(&l)}.lambda?) assert_equal(false, Proc.new(&l).lambda?) l = lambda {} assert_equal(true, l.lambda?) @@ -299,47 +298,21 @@ def test_lambda? assert_equal(true, Proc.new(&l).lambda?) end - def self.helper_test_warn_lamda_with_passed_block &b + def helper_test_warn_lambda_with_passed_block &b lambda(&b) end - def self.def_lambda_warning name, warn - define_method(name, proc do - prev = Warning[:deprecated] - assert_warn warn do - Warning[:deprecated] = true - yield - end - ensure - Warning[:deprecated] = prev - end) - end - - def_lambda_warning 'test_lambda_warning_normal', '' do - lambda{} - end - - def_lambda_warning 'test_lambda_warning_pass_lambda', '' do - b = lambda{} - lambda(&b) - end - - def_lambda_warning 'test_lambda_warning_pass_symbol_proc', '' do - lambda(&:to_s) - end - - def_lambda_warning 'test_lambda_warning_pass_proc', /deprecated/ do - b = proc{} - lambda(&b) - end - - def_lambda_warning 'test_lambda_warning_pass_block', /deprecated/ do - helper_test_warn_lamda_with_passed_block{} + def test_lambda_warning_pass_proc + assert_raise(ArgumentError) do + b = proc{} + lambda(&b) + end end - def_lambda_warning 'test_lambda_warning_pass_block_symbol_proc', '' do - # Symbol#to_proc returns lambda - helper_test_warn_lamda_with_passed_block(&:to_s) + def test_lambda_warning_pass_block + assert_raise(ArgumentError) do + helper_test_warn_lambda_with_passed_block{} + end end def test_curry_ski_fib diff --git a/test/ruby/test_process.rb b/test/ruby/test_process.rb index dc0ccd1f770cd6..f180b6368d8718 100644 --- a/test/ruby/test_process.rb +++ b/test/ruby/test_process.rb @@ -665,6 +665,7 @@ def test_execopts_redirect_open_fifo end unless windows? # does not support fifo def test_execopts_redirect_open_fifo_interrupt_raise + pid = nil with_tmpchdir {|d| begin File.mkfifo("fifo") @@ -682,15 +683,21 @@ class E < StandardError; end 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") @@ -703,14 +710,25 @@ def test_execopts_redirect_open_fifo_interrupt_print 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 @@ -1437,8 +1455,15 @@ def test_status assert_equal(s, s) assert_equal(s, s.to_i) - assert_equal(s.to_i & 0x55555555, s & 0x55555555) - assert_equal(s.to_i >> 1, s >> 1) + assert_deprecated_warn(/\buse .*Process::Status/) do + assert_equal(s.to_i & 0x55555555, s & 0x55555555) + end + assert_deprecated_warn(/\buse .*Process::Status/) do + assert_equal(s.to_i >> 1, s >> 1) + end + assert_raise(ArgumentError) do + s >> -1 + end assert_equal(false, s.stopped?) assert_equal(nil, s.stopsig) diff --git a/test/ruby/test_random_formatter.rb b/test/ruby/test_random_formatter.rb index 2c01d99b3dbe78..7c3003e02d1db3 100644 --- a/test/ruby/test_random_formatter.rb +++ b/test/ruby/test_random_formatter.rb @@ -75,6 +75,54 @@ def test_uuid assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid) end + def test_uuid_v7 + t1 = current_uuid7_time + uuid = @it.uuid_v7 + t3 = current_uuid7_time + + assert_match(/\A\h{8}-\h{4}-7\h{3}-[89ab]\h{3}-\h{12}\z/, uuid) + + t2 = get_uuid7_time(uuid) + assert_operator(t1, :<=, t2) + assert_operator(t2, :<=, t3) + end + + def test_uuid_v7_extra_timestamp_bits + 0.upto(12) do |extra_timestamp_bits| + t1 = current_uuid7_time extra_timestamp_bits: extra_timestamp_bits + uuid = @it.uuid_v7 extra_timestamp_bits: extra_timestamp_bits + t3 = current_uuid7_time extra_timestamp_bits: extra_timestamp_bits + + assert_match(/\A\h{8}-\h{4}-7\h{3}-[89ab]\h{3}-\h{12}\z/, uuid) + + t2 = get_uuid7_time uuid, extra_timestamp_bits: extra_timestamp_bits + assert_operator(t1, :<=, t2) + assert_operator(t2, :<=, t3) + 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) diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 820ca9e9c23454..4d2b6294ed323b 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 'date' require 'rbconfig/sizeof' class TestRange < Test::Unit::TestCase @@ -624,6 +625,28 @@ def <=>(other) assert_operator(c.new(0)..c.new(10), :===, c.new(5), bug12003) end + def test_eqq_unbounded_ruby_bug_19864 + t1 = Date.today + t2 = t1 + 1 + assert_equal(true, (..t1) === t1) + assert_equal(false, (..t1) === t2) + assert_equal(true, (..t2) === t1) + assert_equal(true, (..t2) === t2) + assert_equal(false, (...t1) === t1) + assert_equal(false, (...t1) === t2) + assert_equal(true, (...t2) === t1) + assert_equal(false, (...t2) === t2) + + assert_equal(true, (t1..) === t1) + assert_equal(true, (t1..) === t2) + assert_equal(false, (t2..) === t1) + assert_equal(true, (t2..) === t2) + assert_equal(true, (t1...) === t1) + assert_equal(true, (t1...) === t2) + assert_equal(false, (t2...) === t1) + assert_equal(true, (t2...) === t2) + end + def test_eqq_non_iteratable k = Class.new do include Comparable @@ -1024,7 +1047,10 @@ def test_bsearch_for_bignum 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 {} } @@ -1051,4 +1077,67 @@ def test_beginless_range_iteration def test_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_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_require_lib.rb b/test/ruby/test_require_lib.rb index 3615d88a1110dd..a88279727e896d 100644 --- a/test/ruby/test_require_lib.rb +++ b/test/ruby/test_require_lib.rb @@ -1,25 +1,26 @@ -# frozen_string_literal: false +# frozen_string_literal: true require 'test/unit' class TestRequireLib < Test::Unit::TestCase - TEST_RATIO = ENV["TEST_REQUIRE_THREAD_RATIO"]&.tap {|s|break s.to_f} || 0.05 # testing all files needs too long time... + libdir = __dir__ + '/../../lib' - Dir.glob(File.expand_path('../../lib/**/*.rb', __dir__)).each do |lib| - # skip some problems - next if %r!/lib/(?:bundler|rubygems)\b! =~ lib - next if %r!/lib/(?:debug|mkmf)\.rb\z! =~ lib - next if %r!/lib/irb/ext/tracer\.rb\z! =~ lib - # skip many files that almost use no threads - next if TEST_RATIO < rand(0.0..1.0) + # .rb files at lib + scripts = Dir.glob('*.rb', base: libdir).map {|f| f.chomp('.rb')} + + # .rb files in subdirectories of lib without same name script + dirs = Dir.glob('*/', base: libdir).map {|d| d.chomp('/')} + dirs -= scripts + scripts.concat(Dir.glob(dirs.map {|d| d + '/*.rb'}, base: libdir).map {|f| f.chomp('.rb')}) + + # skip some problems + scripts -= %w[bundler bundled_gems rubygems mkmf] + + scripts.each do |lib| define_method "test_thread_size:#{lib}" do assert_separately(['-W0'], "#{<<~"begin;"}\n#{<<~"end;"}") begin; n = Thread.list.size - begin - require #{lib.dump} - rescue Exception - omit $! - end + require #{lib.dump} assert_equal n, Thread.list.size end; end diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index 20fa15604db9d1..191c0c22784308 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -99,8 +99,7 @@ def test_backtrace_limit end def test_warning - save_rubyopt = ENV['RUBYOPT'] - ENV['RUBYOPT'] = nil + save_rubyopt = ENV.delete('RUBYOPT') assert_in_out_err(%w(-W0 -e) + ['p $-W'], "", %w(0), []) assert_in_out_err(%w(-W1 -e) + ['p $-W'], "", %w(1), []) assert_in_out_err(%w(-Wx -e) + ['p $-W'], "", %w(2), []) @@ -369,7 +368,25 @@ def test_encoding end def test_syntax_check - assert_in_out_err(%w(-c -e a=1+1 -e !a), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e a=1+1 -e !a), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e break), "", [], ["-e:1: Invalid break", :*]) + assert_in_out_err(%w(-cw -e next), "", [], ["-e:1: Invalid next", :*]) + assert_in_out_err(%w(-cw -e redo), "", [], ["-e:1: Invalid redo", :*]) + assert_in_out_err(%w(-cw -e retry), "", [], ["-e:1: Invalid retry", :*]) + assert_in_out_err(%w(-cw -e yield), "", [], ["-e:1: Invalid yield", :*]) + assert_in_out_err(%w(-cw -e begin -e break -e end), "", [], ["-e:2: Invalid break", :*]) + assert_in_out_err(%w(-cw -e begin -e next -e end), "", [], ["-e:2: Invalid next", :*]) + assert_in_out_err(%w(-cw -e begin -e redo -e end), "", [], ["-e:2: Invalid redo", :*]) + assert_in_out_err(%w(-cw -e begin -e retry -e end), "", [], ["-e:2: Invalid retry", :*]) + assert_in_out_err(%w(-cw -e begin -e yield -e end), "", [], ["-e:2: Invalid yield", :*]) + assert_in_out_err(%w(-cw -e !defined?(break)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e !defined?(next)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e !defined?(redo)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e !defined?(retry)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-cw -e !defined?(yield)), "", ["Syntax OK"], []) + assert_in_out_err(%w(-n -cw -e break), "", ["Syntax OK"], []) + assert_in_out_err(%w(-n -cw -e next), "", ["Syntax OK"], []) + assert_in_out_err(%w(-n -cw -e redo), "", ["Syntax OK"], []) end def test_invalid_option @@ -417,12 +434,11 @@ def test_rubyopt 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 - if rubyopt_orig - ENV['RUBYOPT'] = rubyopt_orig - else - ENV.delete('RUBYOPT') - end + ENV['RUBYOPT'] = rubyopt_orig end def test_search @@ -795,29 +811,32 @@ module SEGVTest )? )x, ] + + KILL_SELF = "Process.kill :SEGV, $$" end - def assert_segv(args, message=nil) + def assert_segv(args, message=nil, list: SEGVTest::ExpectedStderrList, **opt) # 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? - args.unshift({'RUBY_ON_BUG' => nil}) + 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", **opt) + assert_in_out_err(args, test_stdin, //, list, encoding: "ASCII-8BIT", + **SEGVTest::ExecOptions, **opt) end def test_segv_test - assert_segv(["--disable-gems", "-e", "Process.kill :SEGV, $$"]) + assert_segv(["--disable-gems", "-e", SEGVTest::KILL_SELF]) end def test_segv_loaded_features bug7402 = '[ruby-core:49573]' - status = assert_segv(['-e', 'END {Process.kill :SEGV, $$}', + status = assert_segv(['-e', "END {#{SEGVTest::KILL_SELF}}", '-e', 'class Bogus; def to_str; exit true; end; end', '-e', '$".clear', '-e', '$".unshift Bogus.new', @@ -831,10 +850,70 @@ def test_segv_setproctitle Tempfile.create(["test_ruby_test_bug7597", ".rb"]) {|t| t.write "f" * 100 t.flush - assert_segv(["--disable-gems", "-e", "$0=ARGV[0]; Process.kill :SEGV, $$", t.path], bug7597) + assert_segv(["--disable-gems", "-e", "$0=ARGV[0]; #{SEGVTest::KILL_SELF}", t.path], bug7597) } end + def assert_crash_report(path, cmd = nil) + 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" diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 703373b11ea75a..bcd65909032ccb 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -3,6 +3,7 @@ require 'test/unit' require "rbconfig/sizeof" require "timeout" +require "fiddle" class TestThread < Test::Unit::TestCase class Thread < ::Thread @@ -1443,6 +1444,35 @@ def test_thread_native_thread_id 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 } diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb index fd77853f0ec3ec..545bf98888bf55 100644 --- a/test/ruby/test_thread_queue.rb +++ b/test/ruby/test_thread_queue.rb @@ -19,6 +19,15 @@ def test_sized_queue_initialized } end + def test_freeze + assert_raise(TypeError) { + Queue.new.freeze + } + assert_raise(TypeError) { + SizedQueue.new(5).freeze + } + end + def test_queue grind(5, 1000, 15, Queue) end diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb index 2519a20883ebf6..d9e518048ca8e6 100644 --- a/test/rubygems/test_gem_commands_open_command.rb +++ b/test/rubygems/test_gem_commands_open_command.rb @@ -22,20 +22,23 @@ def gem(name, version = "1.0") def test_execute @cmd.options[:args] = %w[foo] - @cmd.options[:editor] = "#{ruby_with_rubygems_in_load_path} -eexit --" + @cmd.options[:editor] = (ruby_with_rubygems_in_load_path + ["-e", "puts(ARGV,Dir.pwd)", "--"]).join(" ") gem "foo", "1.0.0" spec = gem "foo", "1.0.1" assert_nothing_raised Gem::MockGemUi::TermError do - Dir.stub(:chdir, spec.full_gem_path) do + stdout, stderr = capture_subprocess_io do use_ui @ui do @cmd.execute end end + assert_equal [spec.full_gem_path, spec.full_gem_path], stdout.split("\n") + assert_equal "", stderr end assert_equal "", @ui.error + assert_equal "", @ui.output end def test_wrong_version 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 3953d5924ddba9..59612c4e04ef76 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 @@ -152,18 +152,18 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.81" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57240b308b155b09dce81e32829966a99f52d1088b45957e4283e526c5317a1" +checksum = "a3e6bf79bf4c711917cacfaf46dfab4314dbfdd89a8ee3ec4b98336cd23f1ebf" dependencies = [ "rb-sys-build", ] [[package]] name = "rb-sys-build" -version = "0.9.81" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24ce877a4c5d07f06f6aa6fec3ac95e4b357b9f73b0f5445d8cbb7266d410e8" +checksum = "5482a1ed4cde58dddaf162b6aebcb5c25645822547832b8be101f2acd40bcdd6" dependencies = [ "bindgen", "lazy_static", 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 a6dde068b2ade7..38382cfc66f594 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.81" +rb-sys = "0.9.82" 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 c3db0d95c2e58f..44db761b40a17d 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 @@ -145,18 +145,18 @@ dependencies = [ [[package]] name = "rb-sys" -version = "0.9.81" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a57240b308b155b09dce81e32829966a99f52d1088b45957e4283e526c5317a1" +checksum = "a3e6bf79bf4c711917cacfaf46dfab4314dbfdd89a8ee3ec4b98336cd23f1ebf" dependencies = [ "rb-sys-build", ] [[package]] name = "rb-sys-build" -version = "0.9.81" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f24ce877a4c5d07f06f6aa6fec3ac95e4b357b9f73b0f5445d8cbb7266d410e8" +checksum = "5482a1ed4cde58dddaf162b6aebcb5c25645822547832b8be101f2acd40bcdd6" dependencies = [ "bindgen", "lazy_static", 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 ecdc1d2d5d508d..285ac3e88d5c70 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.81" +rb-sys = "0.9.82" diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 6161e81f62df75..68dbf119a45f02 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -574,6 +574,32 @@ def test_extract_tar_gz_symlink_relative_path 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 diff --git a/test/rubygems/test_gem_safe_marshal.rb b/test/rubygems/test_gem_safe_marshal.rb new file mode 100644 index 00000000000000..dc7ce362c4ec1c --- /dev/null +++ b/test/rubygems/test_gem_safe_marshal.rb @@ -0,0 +1,364 @@ +# frozen_string_literal: true + +require_relative "helper" + +require "date" +require "rubygems/safe_marshal" + +class TestGemSafeMarshal < Gem::TestCase + define_method("test_safe_load_marshal Date #") { 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 #") { 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: (RUBY_ENGINE != "truffleruby" || RUBY_ENGINE_VERSION >= "23") } + + 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: (RUBY_ENGINE != "truffleruby" || RUBY_ENGINE_VERSION >= "23") + 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), + ].tap do |times| + unless RUBY_ENGINE == "truffleruby" && RUBY_ENGINE_VERSION < "23" || RUBY_VERSION < "2.7" + times.concat [ + Time.at(secs, in: "UTC"), + Time.at(secs, in: "Z"), + ] + end + end.each_with_index do |t, i| + define_method("test_time_#{i} #{t.inspect}") do + pend "Marshal.load of Time with custom zone is broken before Truffleruby 23" if t.zone.nil? && RUBY_ENGINE == "truffleruby" && RUBY_ENGINE_VERSION < "23" + + 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 + pend "`read_user_class` not yet implemented" + + assert_safe_load_as Hash.new.compare_by_identity + 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 + pend "truffleruby dumps rationals with ivars set on array, see https://github.com/oracle/truffleruby/issues/3228" if RUBY_ENGINE == "truffleruby" + + 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 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_specification.rb b/test/rubygems/test_gem_specification.rb index 25b72c587f05f8..6657d77b07f76e 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -2291,7 +2291,7 @@ def test_to_ruby Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze, "other".freeze] @@ -2306,7 +2306,7 @@ def test_to_ruby s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - s.add_runtime_dependency(%q.freeze, [\"= 1\"]) + s.add_runtime_dependency(%q.freeze, [\"= 1\".freeze]) end SPEC @@ -2331,7 +2331,7 @@ def test_to_ruby_with_rsa_key Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -2364,7 +2364,7 @@ def test_to_ruby_for_cache Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -2376,11 +2376,11 @@ def test_to_ruby_for_cache s.rubygems_version = "#{Gem::VERSION}".freeze s.summary = "this is a summary".freeze - s.installed_by_version = "#{Gem::VERSION}" if s.respond_to? :installed_by_version + s.installed_by_version = "#{Gem::VERSION}".freeze if s.respond_to? :installed_by_version s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - s.add_runtime_dependency(%q.freeze, [\"= 1\"]) + s.add_runtime_dependency(%q.freeze, ["= 1".freeze]) end SPEC @@ -2400,7 +2400,7 @@ def test_to_ruby_fancy ruby_code = @c1.to_ruby local = Gem::Platform.local - expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]" + expected_platform = "[#{local.cpu.inspect}.freeze, #{local.os.inspect}.freeze, #{local.version.inspect}.freeze]" stub_require_paths = @c1.instance_variable_get(:@require_paths).join "\u0000" extensions = @c1.extensions.join "\u0000" @@ -2412,7 +2412,7 @@ def test_to_ruby_fancy Gem::Specification.new do |s| s.name = "a".freeze - s.version = "1" + s.version = "1".freeze s.platform = Gem::Platform.new(#{expected_platform}) s.required_rubygems_version = Gem::Requirement.new(\">= 0\".freeze) if s.respond_to? :required_rubygems_version= @@ -2433,9 +2433,9 @@ def test_to_ruby_fancy s.specification_version = 4 - s.add_runtime_dependency(%q.freeze, [\"> 0.4\"]) - s.add_runtime_dependency(%q.freeze, [\"> 0.0.0\"]) - s.add_runtime_dependency(%q.freeze, [\"> 0.4\", \"<= 0.6\"]) + s.add_runtime_dependency(%q.freeze, [\"> 0.4\".freeze]) + s.add_runtime_dependency(%q.freeze, [\"> 0.0.0\".freeze]) + s.add_runtime_dependency(%q.freeze, [\"> 0.4\".freeze, \"<= 0.6\".freeze]) end SPEC @@ -2451,7 +2451,7 @@ def test_to_ruby_keeps_requirements_as_originally_specified s.add_dependency "b", ["~> 1.0", ">= 1.0.0"] end - assert_includes spec.to_ruby, '"~> 1.0", ">= 1.0.0"' + assert_includes spec.to_ruby, '"~> 1.0".freeze, ">= 1.0.0".freeze' end def test_to_ruby_legacy @@ -3665,7 +3665,7 @@ def test_metadata_specs Gem::Specification.new do |s| s.name = "m".freeze - s.version = "1" + s.version = "1".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "one" => "two", "two" => "three" } if s.respond_to? :metadata= diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb index ab4563dce244b0..56457235580c54 100644 --- a/test/socket/test_socket.rb +++ b/test/socket/test_socket.rb @@ -447,13 +447,12 @@ def test_udp_server omit "UDP server is no response: #{$!}" ensure if th - if skipped - Thread.kill th unless th.join(10) - else + unless skipped Addrinfo.udp("127.0.0.1", port).connect {|s| s.sendmsg "exit" } - unless th.join(10) - Thread.kill th - th.join(10) + end + unless th.join(10) + th.kill.join(10) + unless skipped raise "thread killed" end end @@ -497,6 +496,7 @@ def timestamp_retry_rw(s1, s2, t1, type) 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,6 +505,10 @@ def timestamp_retry_rw(s1, s2, t1, type) 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 diff --git a/test/yarp/comments_test.rb b/test/yarp/comments_test.rb deleted file mode 100644 index ec419a9fffdcb1..00000000000000 --- a/test/yarp/comments_test.rb +++ /dev/null @@ -1,92 +0,0 @@ -# frozen_string_literal: true - -require_relative "test_helper" - -module YARP - class CommentsTest < TestCase - def test_comment_inline - source = "# comment" - - assert_comment source, :inline, 0..9 - assert_equal [0], Debug.newlines(source) - end - - def test_comment_inline_def - source = <<~RUBY - def foo - # a comment - end - RUBY - - assert_comment source, :inline, 10..22 - end - - def test_comment___END__ - source = <<~RUBY - __END__ - comment - RUBY - - assert_comment source, :__END__, 0..16 - end - - def test_comment___END__crlf - source = "__END__\r\ncomment\r\n" - - assert_comment source, :__END__, 0..18 - end - - def test_comment_embedded_document - source = <<~RUBY - =begin - comment - =end - RUBY - - assert_comment source, :embdoc, 0..20 - end - - def test_comment_embedded_document_with_content_on_same_line - source = <<~RUBY - =begin other stuff - =end - RUBY - - assert_comment source, :embdoc, 0..24 - 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 = YARP.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\n", class_node.location.comments.map { |c| c.location.slice }.join) - assert_equal("# bar method\n# bar end\n", method_node.location.comments.map { |c| c.location.slice }.join) - assert_equal("# baz invocation\n", call_node.location.comments.map { |c| c.location.slice }.join) - end - - private - - def assert_comment(source, type, location) - result = YARP.parse(source) - assert result.errors.empty?, result.errors.map(&:message).join("\n") - assert_equal result.comments.first.type, type - assert_equal result.comments.first.location.start_offset, location.begin - assert_equal result.comments.first.location.end_offset, location.end - end - end -end diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb deleted file mode 100644 index 862fc0cc1febe1..00000000000000 --- a/test/yarp/compiler_test.rb +++ /dev/null @@ -1,251 +0,0 @@ -# frozen_string_literal: true - -module YARP - class CompilerTest < Test::Unit::TestCase - def test_empty_program - assert_nil compile("") - end - - ############################################################################ - # Literals # - ############################################################################ - - def test_FalseNode - assert_equal false, compile("false") - end - - def test_FloatNode - assert_equal 1.2, compile("1.2") - assert_equal 1.2e3, compile("1.2e3") - assert_equal(+1.2e+3, compile("+1.2e+3")) - assert_equal(-1.2e-3, compile("-1.2e-3")) - end - - def test_ImaginaryNode - assert_equal 1i, compile("1i") - assert_equal +1.0i, compile("+1.0i") - assert_equal 1ri, compile("1ri") - end - - def test_IntegerNode - assert_equal 1, compile("1") - assert_equal(+1, compile("+1")) - assert_equal(-1, compile("-1")) - assert_equal 0x10, compile("0x10") - assert_equal 0b10, compile("0b10") - assert_equal 0o10, compile("0o10") - assert_equal 010, compile("010") - end - - def test_NilNode - assert_nil compile("nil") - end - - def test_RationalNode - assert_equal 1.2r, compile("1.2r") - assert_equal +1.2r, compile("+1.2r") - end - - def test_SelfNode - assert_equal TOPLEVEL_BINDING.eval("self"), compile("self") - end - - def test_TrueNode - assert_equal true, compile("true") - end - - ############################################################################ - # Reads # - ############################################################################ - - def test_ClassVariableReadNode - assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; @@yct; end") - end - - def test_ConstantPathNode - assert_equal YARP::CompilerTest, compile("YARP::CompilerTest") - end - - def test_ConstantReadNode - assert_equal YARP, compile("YARP") - end - - def test_GlobalVariableReadNode - assert_equal 1, compile("$yct = 1; $yct") - end - - def test_InstanceVariableReadNode - assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; @yct; end") - end - - def test_LocalVariableReadNode - assert_equal 1, compile("yct = 1; yct") - end - - ############################################################################ - # Writes # - ############################################################################ - - def test_ClassVariableWriteNode - assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; end") - end - - def test_ClassVariableAndWriteNode - assert_equal 1, compile("class YARP::CompilerTest; @@yct = 0; @@yct &&= 1; end") - end - - def test_ClassVariableOrWriteNode - assert_equal 1, compile("class YARP::CompilerTest; @@yct = 1; @@yct ||= 0; end") - assert_equal 1, compile("class YARP::CompilerTest; @@yct = nil; @@yct ||= 1; end") - end - - def test_ClassVariableOperatorWriteNode - assert_equal 1, compile("class YARP::CompilerTest; @@yct = 0; @@yct += 1; end") - end - - def test_ConstantWriteNode - constant_name = "YCT" - assert_equal 1, compile("#{constant_name} = 1") - # We remove the constant to avoid assigning it mutliple - # times if we run with `--repeat_count` - Object.send(:remove_const, constant_name) - end - - def test_ConstantPathWriteNode - # assert_equal 1, compile("YARP::YCT = 1") - end - - def test_GlobalVariableWriteNode - assert_equal 1, compile("$yct = 1") - end - - def test_GlobalVariableAndWriteNode - assert_equal 1, compile("$yct = 0; $yct &&= 1") - end - - def test_GlobalVariableOrWriteNode - assert_equal 1, compile("$yct ||= 1") - end - - def test_GlobalVariableOperatorWriteNode - assert_equal 1, compile("$yct = 0; $yct += 1") - end - - def test_InstanceVariableWriteNode - assert_equal 1, compile("class YARP::CompilerTest; @yct = 1; end") - end - - def test_InstanceVariableAndWriteNode - assert_equal 1, compile("@yct = 0; @yct &&= 1") - end - - def test_InstanceVariableOrWriteNode - assert_equal 1, compile("@yct ||= 1") - end - - def test_InstanceVariableOperatorWriteNode - assert_equal 1, compile("@yct = 0; @yct += 1") - end - - def test_LocalVariableWriteNode - assert_equal 1, compile("yct = 1") - end - - def test_LocalVariableAndWriteNode - assert_equal 1, compile("yct = 0; yct &&= 1") - end - - def test_LocalVariableOrWriteNode - assert_equal 1, compile("yct ||= 1") - end - - def test_LocalVariableOperatorWriteNode - assert_equal 1, compile("yct = 0; yct += 1") - end - - ############################################################################ - # String-likes # - ############################################################################ - - def test_EmbeddedVariableNode - # assert_equal "1", compile('class YARP::CompilerTest; @yct = 1; "#@yct"; end') - # assert_equal "1", compile('class YARP::CompilerTest; @@yct = 1; "#@@yct"; end') - assert_equal "1", compile('$yct = 1; "#$yct"') - end - - def test_InterpolatedRegularExpressionNode - assert_equal /1 1 1/, compile('$yct = 1; /1 #$yct 1/') - assert_equal /1 3 1/, compile('/1 #{1 + 2} 1/') - assert_equal /1 2 3 1/, compile('/1 #{"2"} #{1 + 2} 1/') - end - - def test_InterpolatedStringNode - assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"') - assert_equal "1 3 1", compile('"1 #{1 + 2} 1"') - end - - def test_InterpolatedSymbolNode - assert_equal :"1 1 1", compile('$yct = 1; :"1 #$yct 1"') - assert_equal :"1 3 1", compile(':"1 #{1 + 2} 1"') - end - - def test_InterpolatedXStringNode - assert_equal "1\n", compile('`echo #{1}`') - assert_equal "100", compile('`printf "100"`') - end - - def test_RegularExpressionNode - assert_equal /yct/, compile('/yct/') - end - - def test_StringConcatNode - # assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"') - end - - def test_StringNode - assert_equal "yct", compile('"yct"') - end - - def test_SymbolNode - assert_equal :yct, compile(":yct") - end - - def test_XStringNode - # assert_equal "yctyct", compile(<<~RUBY) - # class YARP::CompilerTest - # def self.`(command) = command * 2 - # `yct` - # end - # RUBY - end - - ############################################################################ - # Jumps # - ############################################################################ - - def test_AndNode - assert_equal 1, compile("true && 1") - assert_equal false, compile("false && 1") - end - - def test_OrNode - assert_equal true, compile("true || 1") - assert_equal 1, compile("false || 1") - end - - ############################################################################ - # Scopes/statements # - ############################################################################ - - def test_ParenthesesNode - assert_equal (), compile("()") - assert_equal (1), compile("(1)") - end - - private - - def compile(source) - RubyVM::InstructionSequence.compile_yarp(source).eval - end - end -end diff --git a/test/yarp/desugar_visitor_test.rb b/test/yarp/desugar_visitor_test.rb deleted file mode 100644 index 3966d7bfcb6078..00000000000000 --- a/test/yarp/desugar_visitor_test.rb +++ /dev/null @@ -1,86 +0,0 @@ -# frozen_string_literal: true - -require_relative "test_helper" - -module YARP - class DesugarVisitorTest < 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 = YARP.parse(source).value.accept(DesugarVisitor.new) - assert_equal expected, ast_inspect(ast.statements.body.last) - - ast.accept(EnsureEveryNodeOnceInAST.new) - end - - def assert_not_desugared(source, reason) - ast = YARP.parse(source).value - assert_equal_nodes(ast, ast.accept(DesugarVisitor.new)) - end - end -end diff --git a/test/yarp/fixtures/arithmetic.txt b/test/yarp/fixtures/arithmetic.txt deleted file mode 100644 index 6f86f92d47c95e..00000000000000 --- a/test/yarp/fixtures/arithmetic.txt +++ /dev/null @@ -1,8 +0,0 @@ -foo !bar - --foo*bar - -+foo**bar - -foo ~bar - diff --git a/test/yarp/fixtures/case.txt b/test/yarp/fixtures/case.txt deleted file mode 100644 index 76d11313ee0de1..00000000000000 --- a/test/yarp/fixtures/case.txt +++ /dev/null @@ -1,30 +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 diff --git a/test/yarp/fixtures/hashes.txt b/test/yarp/fixtures/hashes.txt deleted file mode 100644 index 42c430e43ed369..00000000000000 --- a/test/yarp/fixtures/hashes.txt +++ /dev/null @@ -1,20 +0,0 @@ -{} - -{ -} - -{ a => b, c => d } - -{ a => b, **c } - -{ - a: b, - c: d - - - - } - -{ a: b, c: d, **e, f: g } - -{ "a": !b? } diff --git a/test/yarp/fixtures/methods.txt b/test/yarp/fixtures/methods.txt deleted file mode 100644 index de17645bb553a1..00000000000000 --- a/test/yarp/fixtures/methods.txt +++ /dev/null @@ -1,165 +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 diff --git a/test/yarp/fixtures/spanning_heredoc.txt b/test/yarp/fixtures/spanning_heredoc.txt deleted file mode 100644 index a52a4c3c27b37a..00000000000000 --- a/test/yarp/fixtures/spanning_heredoc.txt +++ /dev/null @@ -1,51 +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: yarp 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 YARP does ... -# TODO: yarp does not include the "\n" in "p\np" in the AST like ruby does -pp <<-A, %I[p\ -o -A -p] diff --git a/test/yarp/fixtures/strings.txt b/test/yarp/fixtures/strings.txt deleted file mode 100644 index 947c535aed53f5..00000000000000 --- a/test/yarp/fixtures/strings.txt +++ /dev/null @@ -1,99 +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 - -%Q{abc} diff --git a/test/yarp/heredoc_dedent_test.rb b/test/yarp/heredoc_dedent_test.rb deleted file mode 100644 index 975232889f488e..00000000000000 --- a/test/yarp/heredoc_dedent_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -require_relative "test_helper" - -module YARP - class HeredocDedentTest < TestCase - filepath = File.expand_path("fixtures/tilde_heredocs.txt", __dir__) - - File.read(filepath).split(/(?=\n)\n(?=<)/).each_with_index do |heredoc, index| - define_method "test_heredoc_#{index}" do - parts = YARP.parse(heredoc).value.statements.body.first.parts - actual = parts.map { |part| part.is_a?(StringNode) ? part.unescaped : "1" }.join - - assert_equal(eval(heredoc), actual, "Expected heredocs to match.") - end - end - end -end diff --git a/test/yarp/snapshots/alias.txt b/test/yarp/snapshots/alias.txt deleted file mode 100644 index 224c2069a58f35..00000000000000 --- a/test/yarp/snapshots/alias.txt +++ /dev/null @@ -1,74 +0,0 @@ -ProgramNode(0...199)( - [], - StatementsNode(0...199)( - [AliasNode(0...15)( - SymbolNode(6...10)((6...7), (7...10), nil, "foo"), - SymbolNode(11...15)((11...12), (12...15), nil, "bar"), - (0...5) - ), - AliasNode(17...38)( - SymbolNode(23...30)((23...26), (26...29), (29...30), "abc"), - SymbolNode(31...38)((31...34), (34...37), (37...38), "def"), - (17...22) - ), - AliasNode(40...59)( - SymbolNode(46...52)((46...48), (48...51), (51...52), "abc"), - SymbolNode(53...59)((53...55), (55...58), (58...59), "def"), - (40...45) - ), - AliasNode(61...84)( - InterpolatedSymbolNode(67...77)( - (67...69), - [StringNode(69...72)(nil, (69...72), nil, "abc"), - EmbeddedStatementsNode(72...76)( - (72...74), - StatementsNode(74...75)([IntegerNode(74...75)()]), - (75...76) - )], - (76...77) - ), - SymbolNode(78...84)((78...80), (80...83), (83...84), "def"), - (61...66) - ), - AliasNode(86...97)( - GlobalVariableReadNode(92...94)(:$a), - BackReferenceReadNode(95...97)(), - (86...91) - ), - AliasNode(99...112)( - SymbolNode(105...108)(nil, (105...108), nil, "foo"), - SymbolNode(109...112)(nil, (109...112), nil, "bar"), - (99...104) - ), - AliasNode(114...129)( - GlobalVariableReadNode(120...124)(:$foo), - GlobalVariableReadNode(125...129)(:$bar), - (114...119) - ), - AliasNode(131...143)( - SymbolNode(137...140)(nil, (137...140), nil, "foo"), - SymbolNode(141...143)(nil, (141...143), nil, "if"), - (131...136) - ), - AliasNode(145...158)( - SymbolNode(151...154)(nil, (151...154), nil, "foo"), - SymbolNode(155...158)(nil, (155...158), nil, "<=>"), - (145...150) - ), - AliasNode(160...175)( - SymbolNode(166...169)((166...167), (167...169), nil, "=="), - SymbolNode(170...175)((170...171), (171...175), nil, "eql?"), - (160...165) - ), - AliasNode(177...186)( - SymbolNode(183...184)(nil, (183...184), nil, "A"), - SymbolNode(185...186)(nil, (185...186), nil, "B"), - (177...182) - ), - AliasNode(188...199)( - SymbolNode(194...196)((194...195), (195...196), nil, "A"), - SymbolNode(197...199)((197...198), (198...199), nil, "B"), - (188...193) - )] - ) -) diff --git a/test/yarp/snapshots/arithmetic.txt b/test/yarp/snapshots/arithmetic.txt deleted file mode 100644 index c82760a7e39826..00000000000000 --- a/test/yarp/snapshots/arithmetic.txt +++ /dev/null @@ -1,107 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [CallNode(0...8)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...8)( - [CallNode(4...8)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "bar"), - nil, - (4...5), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(10...18)( - CallNode(10...14)( - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - nil, - (10...11), - nil, - nil, - nil, - nil, - 0, - "-@" - ), - nil, - (14...15), - nil, - ArgumentsNode(15...18)( - [CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "*" - ), - CallNode(20...29)( - CallNode(20...24)( - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"), - nil, - (20...21), - nil, - nil, - nil, - nil, - 0, - "+@" - ), - nil, - (24...26), - nil, - ArgumentsNode(26...29)( - [CallNode(26...29)(nil, nil, (26...29), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "**" - ), - CallNode(31...39)( - nil, - nil, - (31...34), - nil, - ArgumentsNode(35...39)( - [CallNode(35...39)( - CallNode(36...39)( - nil, - nil, - (36...39), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (35...36), - nil, - nil, - nil, - nil, - 0, - "~" - )] - ), - nil, - nil, - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/arrays.txt b/test/yarp/snapshots/arrays.txt deleted file mode 100644 index a29cbeecb56433..00000000000000 --- a/test/yarp/snapshots/arrays.txt +++ /dev/null @@ -1,701 +0,0 @@ -ProgramNode(0...511)( - [], - StatementsNode(0...511)( - [ArrayNode(0...4)( - [SplatNode(1...3)( - (1...2), - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a") - )], - (0...1), - (3...4) - ), - CallNode(6...29)( - CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo"), - nil, - (9...19), - (9...10), - ArgumentsNode(10...29)( - [CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "bar"), - CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "baz"), - ArrayNode(22...29)( - [IntegerNode(22...23)(), - IntegerNode(25...26)(), - IntegerNode(28...29)()], - nil, - nil - )] - ), - (18...19), - nil, - 0, - "[]=" - ), - ArrayNode(31...44)( - [KeywordHashNode(32...43)( - [AssocNode(32...43)( - SymbolNode(32...34)(nil, (32...33), (33...34), "a"), - ArrayNode(35...43)( - [SymbolNode(36...38)((36...37), (37...38), nil, "b"), - SymbolNode(40...42)((40...41), (41...42), nil, "c")], - (35...36), - (42...43) - ), - nil - )] - )], - (31...32), - (43...44) - ), - ArrayNode(48...71)( - [SymbolNode(49...51)((49...50), (50...51), nil, "a"), - SymbolNode(53...55)((53...54), (54...55), nil, "b"), - SymbolNode(57...59)((57...58), (58...59), nil, "c"), - IntegerNode(60...61)(), - SymbolNode(66...68)((66...67), (67...68), nil, "d")], - (48...49), - (70...71) - ), - ArrayNode(74...98)( - [SymbolNode(75...77)((75...76), (76...77), nil, "a"), - SymbolNode(79...81)((79...80), (80...81), nil, "b"), - SymbolNode(83...85)((83...84), (84...85), nil, "c"), - IntegerNode(86...87)(), - SymbolNode(92...94)((92...93), (93...94), nil, "d")], - (74...75), - (97...98) - ), - ArrayNode(100...112)( - [KeywordHashNode(101...111)( - [AssocNode(101...111)( - CallNode(101...104)( - nil, - nil, - (101...104), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(108...111)( - nil, - nil, - (108...111), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (105...107) - )] - )], - (100...101), - (111...112) - ), - CallNode(114...133)( - CallNode(114...122)( - CallNode(114...117)( - nil, - nil, - (114...117), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (117...122), - (117...118), - ArgumentsNode(118...121)( - [CallNode(118...121)( - nil, - nil, - (118...121), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (121...122), - nil, - 0, - "[]" - ), - nil, - (122...127), - (122...123), - ArgumentsNode(123...133)( - [CallNode(123...126)( - nil, - nil, - (123...126), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - CallNode(130...133)( - nil, - nil, - (130...133), - nil, - nil, - nil, - nil, - 2, - "qux" - )] - ), - (126...127), - nil, - 0, - "[]=" - ), - CallNode(135...148)( - CallNode(135...143)( - CallNode(135...138)( - nil, - nil, - (135...138), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (138...143), - (138...139), - ArgumentsNode(139...142)( - [CallNode(139...142)( - nil, - nil, - (139...142), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (142...143), - nil, - 0, - "[]" - ), - nil, - (143...148), - (143...144), - ArgumentsNode(144...147)( - [CallNode(144...147)( - nil, - nil, - (144...147), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (147...148), - nil, - 0, - "[]" - ), - ArrayNode(150...153)([], (150...151), (152...153)), - CallNode(155...168)( - CallNode(155...158)( - nil, - nil, - (155...158), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (158...168), - (158...159), - ArgumentsNode(159...167)( - [CallNode(159...162)( - nil, - nil, - (159...162), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - CallNode(164...167)( - nil, - nil, - (164...167), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (167...168), - nil, - 0, - "[]" - ), - CallNode(170...189)( - CallNode(170...173)( - nil, - nil, - (170...173), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (173...183), - (173...174), - ArgumentsNode(174...189)( - [CallNode(174...177)( - nil, - nil, - (174...177), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - CallNode(179...182)( - nil, - nil, - (179...182), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - CallNode(186...189)( - nil, - nil, - (186...189), - nil, - nil, - nil, - nil, - 2, - "qux" - )] - ), - (182...183), - nil, - 0, - "[]=" - ), - MultiWriteNode(191...212)( - [CallNode(191...197)( - CallNode(191...194)( - nil, - nil, - (191...194), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (194...197), - (194...195), - ArgumentsNode(195...196)([IntegerNode(195...196)()]), - (196...197), - nil, - 0, - "[]=" - ), - CallNode(199...205)( - CallNode(199...202)( - nil, - nil, - (199...202), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (202...205), - (202...203), - ArgumentsNode(203...204)([IntegerNode(203...204)()]), - (204...205), - nil, - 0, - "[]=" - )], - nil, - nil, - (206...207), - ArrayNode(208...212)( - [IntegerNode(208...209)(), IntegerNode(211...212)()], - nil, - nil - ) - ), - CallNode(214...233)( - CallNode(214...217)( - nil, - nil, - (214...217), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (217...233), - (217...218), - ArgumentsNode(218...232)( - [CallNode(218...232)( - CallNode(218...221)( - nil, - nil, - (218...221), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (221...226), - (221...222), - ArgumentsNode(222...232)( - [CallNode(222...225)( - nil, - nil, - (222...225), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - CallNode(229...232)( - nil, - nil, - (229...232), - nil, - nil, - nil, - nil, - 2, - "qux" - )] - ), - (225...226), - nil, - 0, - "[]=" - )] - ), - (232...233), - nil, - 0, - "[]" - ), - CallNode(235...243)( - CallNode(235...238)( - nil, - nil, - (235...238), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (238...243), - (238...239), - ArgumentsNode(239...242)( - [CallNode(239...242)( - nil, - nil, - (239...242), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (242...243), - nil, - 0, - "[]" - ), - CallNode(245...259)( - CallNode(245...248)( - nil, - nil, - (245...248), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (248...253), - (248...249), - ArgumentsNode(249...259)( - [CallNode(249...252)( - nil, - nil, - (249...252), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - CallNode(256...259)( - nil, - nil, - (256...259), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (252...253), - nil, - 0, - "[]=" - ), - ArrayNode(261...267)( - [KeywordHashNode(262...266)( - [AssocSplatNode(262...266)( - HashNode(264...266)((264...265), [], (265...266)), - (262...264) - )] - )], - (261...262), - (266...267) - ), - ArrayNode(269...275)( - [KeywordHashNode(270...274)( - [AssocSplatNode(270...274)( - CallNode(272...274)( - nil, - nil, - (272...274), - nil, - nil, - nil, - nil, - 2, - "kw" - ), - (270...272) - )] - )], - (269...270), - (274...275) - ), - ArrayNode(277...286)( - [IntegerNode(278...279)(), - KeywordHashNode(281...285)( - [AssocSplatNode(281...285)( - CallNode(283...285)( - nil, - nil, - (283...285), - nil, - nil, - nil, - nil, - 2, - "kw" - ), - (281...283) - )] - )], - (277...278), - (285...286) - ), - ArrayNode(288...309)( - [IntegerNode(289...290)(), - KeywordHashNode(292...308)( - [AssocSplatNode(292...296)( - CallNode(294...296)( - nil, - nil, - (294...296), - nil, - nil, - nil, - nil, - 2, - "kw" - ), - (292...294) - ), - AssocSplatNode(298...302)( - HashNode(300...302)((300...301), [], (301...302)), - (298...300) - ), - AssocSplatNode(304...308)( - CallNode(306...308)( - nil, - nil, - (306...308), - nil, - nil, - nil, - nil, - 2, - "kw" - ), - (304...306) - )] - )], - (288...289), - (308...309) - ), - ArrayNode(311...328)( - [KeywordHashNode(315...325)( - [AssocNode(315...325)( - CallNode(315...318)( - nil, - nil, - (315...318), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(322...325)( - nil, - nil, - (322...325), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (319...321) - )] - )], - (311...312), - (327...328) - ), - ArrayNode(331...348)( - [SymbolNode(334...337)(nil, (334...337), nil, "one"), - SymbolNode(338...341)(nil, (338...341), nil, "two"), - SymbolNode(342...347)(nil, (342...347), nil, "three")], - (331...334), - (347...348) - ), - ArrayNode(350...367)( - [StringNode(353...356)(nil, (353...356), nil, "one"), - StringNode(357...360)(nil, (357...360), nil, "two"), - StringNode(361...366)(nil, (361...366), nil, "three")], - (350...353), - (366...367) - ), - XStringNode(369...386)( - (369...372), - (372...385), - (385...386), - "one two three" - ), - ArrayNode(389...406)( - [SymbolNode(392...395)(nil, (392...395), nil, "one"), - SymbolNode(396...399)(nil, (396...399), nil, "two"), - SymbolNode(400...405)(nil, (400...405), nil, "three")], - (389...392), - (405...406) - ), - ArrayNode(408...425)( - [StringNode(411...414)(nil, (411...414), nil, "one"), - StringNode(415...418)(nil, (415...418), nil, "two"), - StringNode(419...424)(nil, (419...424), nil, "three")], - (408...411), - (424...425) - ), - XStringNode(427...444)( - (427...430), - (430...443), - (443...444), - "one two three" - ), - ArrayNode(447...464)( - [SymbolNode(450...453)(nil, (450...453), nil, "one"), - SymbolNode(454...457)(nil, (454...457), nil, "two"), - SymbolNode(458...463)(nil, (458...463), nil, "three")], - (447...450), - (463...464) - ), - ArrayNode(466...483)( - [StringNode(469...472)(nil, (469...472), nil, "one"), - StringNode(473...476)(nil, (473...476), nil, "two"), - StringNode(477...482)(nil, (477...482), nil, "three")], - (466...469), - (482...483) - ), - XStringNode(485...502)( - (485...488), - (488...501), - (501...502), - "one two three" - ), - ArrayNode(504...511)( - [StringNode(507...510)(nil, (507...510), nil, "\\C:")], - (504...507), - (510...511) - )] - ) -) diff --git a/test/yarp/snapshots/begin_ensure.txt b/test/yarp/snapshots/begin_ensure.txt deleted file mode 100644 index a842d8f07ffef6..00000000000000 --- a/test/yarp/snapshots/begin_ensure.txt +++ /dev/null @@ -1,164 +0,0 @@ -ProgramNode(0...211)( - [], - StatementsNode(0...211)( - [BeginNode(0...20)( - (0...5), - StatementsNode(6...7)( - [CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - EnsureNode(8...20)( - (8...14), - StatementsNode(15...16)( - [CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "b")] - ), - (17...20) - ), - (17...20) - ), - BeginNode(22...46)( - (22...27), - StatementsNode(29...30)( - [CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - EnsureNode(32...46)( - (32...38), - StatementsNode(40...41)( - [CallNode(40...41)(nil, nil, (40...41), nil, nil, nil, nil, 2, "b")] - ), - (43...46) - ), - (43...46) - ), - BeginNode(48...70)( - (48...53), - StatementsNode(54...55)( - [CallNode(54...55)(nil, nil, (54...55), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - EnsureNode(57...70)( - (57...63), - StatementsNode(64...65)( - [CallNode(64...65)(nil, nil, (64...65), nil, nil, nil, nil, 2, "b")] - ), - (67...70) - ), - (67...70) - ), - BeginNode(72...94)( - (72...77), - StatementsNode(78...79)( - [CallNode(78...79)(nil, nil, (78...79), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - EnsureNode(81...94)( - (81...87), - StatementsNode(88...89)( - [CallNode(88...89)(nil, nil, (88...89), nil, nil, nil, nil, 2, "b")] - ), - (91...94) - ), - (91...94) - ), - BeginNode(96...211)( - (96...101), - StatementsNode(102...207)( - [BeginNode(102...207)( - (102...107), - StatementsNode(107...203)( - [CallNode(107...203)( - SymbolNode(107...109)((107...108), (108...109), nil, "s"), - (109...110), - (110...111), - nil, - ArgumentsNode(112...203)( - [BeginNode(112...203)( - (112...117), - nil, - nil, - nil, - EnsureNode(118...203)( - (118...124), - StatementsNode(125...199)( - [CallNode(125...199)( - ConstantReadNode(125...131)(:Module), - (131...132), - (132...135), - nil, - nil, - nil, - BlockNode(136...199)( - [], - nil, - StatementsNode(141...195)( - [BeginNode(141...195)( - (141...146), - StatementsNode(151...156)( - [BreakNode(151...156)(nil, (151...156))] - ), - nil, - nil, - EnsureNode(161...195)( - (161...167), - StatementsNode(168...189)( - [CallNode(168...189)( - ConstantReadNode(168...174)( - :Module - ), - (174...175), - (175...178), - nil, - nil, - nil, - BlockNode(179...189)( - [], - nil, - nil, - (179...181), - (186...189) - ), - 0, - "new" - )] - ), - (192...195) - ), - (192...195) - )] - ), - (136...138), - (196...199) - ), - 0, - "new" - )] - ), - (200...203) - ), - (200...203) - )] - ), - nil, - nil, - 0, - "l" - )] - ), - nil, - nil, - nil, - (204...207) - )] - ), - nil, - nil, - nil, - (208...211) - )] - ) -) diff --git a/test/yarp/snapshots/begin_rescue.txt b/test/yarp/snapshots/begin_rescue.txt deleted file mode 100644 index ac0592054a0c9d..00000000000000 --- a/test/yarp/snapshots/begin_rescue.txt +++ /dev/null @@ -1,598 +0,0 @@ -ProgramNode(0...578)( - [:ex], - StatementsNode(0...578)( - [BeginNode(0...33)( - (0...5), - StatementsNode(7...8)( - [CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(10...19)( - (10...16), - [], - nil, - nil, - StatementsNode(18...19)( - [CallNode(18...19)(nil, nil, (18...19), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - ElseNode(21...33)( - (21...25), - StatementsNode(27...28)( - [CallNode(27...28)(nil, nil, (27...28), nil, nil, nil, nil, 2, "c")] - ), - (30...33) - ), - nil, - (30...33) - ), - BeginNode(35...79)( - (35...40), - StatementsNode(42...43)( - [CallNode(42...43)(nil, nil, (42...43), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(45...54)( - (45...51), - [], - nil, - nil, - StatementsNode(53...54)( - [CallNode(53...54)(nil, nil, (53...54), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - ElseNode(56...71)( - (56...60), - StatementsNode(62...63)( - [CallNode(62...63)(nil, nil, (62...63), nil, nil, nil, nil, 2, "c")] - ), - (65...71) - ), - EnsureNode(65...79)( - (65...71), - StatementsNode(73...74)( - [CallNode(73...74)(nil, nil, (73...74), nil, nil, nil, nil, 2, "d")] - ), - (76...79) - ), - (76...79) - ), - BeginNode(81...92)( - (81...86), - StatementsNode(87...88)( - [CallNode(87...88)(nil, nil, (87...88), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - nil, - (89...92) - ), - BeginNode(94...107)( - (94...99), - StatementsNode(101...102)( - [CallNode(101...102)( - nil, - nil, - (101...102), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - nil, - nil, - nil, - (104...107) - ), - BeginNode(109...121)( - (109...114), - StatementsNode(115...116)( - [CallNode(115...116)( - nil, - nil, - (115...116), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - nil, - nil, - nil, - (118...121) - ), - BeginNode(123...135)( - (123...128), - StatementsNode(129...130)( - [CallNode(129...130)( - nil, - nil, - (129...130), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - nil, - nil, - nil, - (132...135) - ), - BeginNode(137...175)( - (137...142), - StatementsNode(143...144)( - [CallNode(143...144)( - nil, - nil, - (143...144), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(145...171)( - (145...151), - [], - nil, - nil, - StatementsNode(152...153)( - [CallNode(152...153)( - nil, - nil, - (152...153), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - RescueNode(154...171)( - (154...160), - [], - nil, - nil, - StatementsNode(161...162)( - [CallNode(161...162)( - nil, - nil, - (161...162), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - RescueNode(163...171)( - (163...169), - [], - nil, - nil, - StatementsNode(170...171)( - [CallNode(170...171)( - nil, - nil, - (170...171), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil - ) - ) - ), - nil, - nil, - (172...175) - ), - BeginNode(177...269)( - (177...182), - StatementsNode(185...186)( - [CallNode(185...186)( - nil, - nil, - (185...186), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(187...265)( - (187...193), - [ConstantReadNode(194...203)(:Exception)], - (204...206), - LocalVariableTargetNode(207...209)(:ex, 0), - StatementsNode(212...213)( - [CallNode(212...213)( - nil, - nil, - (212...213), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - RescueNode(214...265)( - (214...220), - [ConstantReadNode(221...237)(:AnotherException), - ConstantReadNode(239...255)(:OneMoreException)], - (256...258), - LocalVariableTargetNode(259...261)(:ex, 0), - StatementsNode(264...265)( - [CallNode(264...265)( - nil, - nil, - (264...265), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - nil - ) - ), - nil, - nil, - (266...269) - ), - BeginNode(271...322)( - (271...276), - StatementsNode(279...280)( - [CallNode(279...280)( - nil, - nil, - (279...280), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(281...307)( - (281...287), - [ConstantReadNode(288...297)(:Exception)], - (298...300), - LocalVariableTargetNode(301...303)(:ex, 0), - StatementsNode(306...307)( - [CallNode(306...307)( - nil, - nil, - (306...307), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - EnsureNode(308...322)( - (308...314), - StatementsNode(317...318)( - [CallNode(317...318)( - nil, - nil, - (317...318), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (319...322) - ), - (319...322) - ), - StringNode(324...330)((324...326), (326...329), (329...330), "abc"), - BeginNode(332...352)( - (332...337), - StatementsNode(338...339)( - [CallNode(338...339)( - nil, - nil, - (338...339), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(340...348)( - (340...346), - [], - nil, - nil, - StatementsNode(347...348)( - [CallNode(347...348)( - nil, - nil, - (347...348), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (349...352) - ), - BeginNode(354...374)( - (354...359), - StatementsNode(360...361)( - [CallNode(360...361)( - nil, - nil, - (360...361), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(362...370)( - (362...368), - [], - nil, - nil, - StatementsNode(369...370)( - [CallNode(369...370)( - nil, - nil, - (369...370), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (371...374) - ), - BeginNode(376...396)( - (376...381), - StatementsNode(382...383)( - [CallNode(382...383)( - nil, - nil, - (382...383), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(384...392)( - (384...390), - [], - nil, - nil, - StatementsNode(391...392)( - [CallNode(391...392)( - nil, - nil, - (391...392), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (393...396) - ), - BeginNode(398...428)( - (398...403), - StatementsNode(404...405)( - [CallNode(404...405)( - nil, - nil, - (404...405), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(406...424)( - (406...412), - [ConstantReadNode(413...422)(:Exception)], - nil, - nil, - StatementsNode(423...424)( - [CallNode(423...424)( - nil, - nil, - (423...424), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (425...428) - ), - BeginNode(430...477)( - (430...435), - StatementsNode(436...437)( - [CallNode(436...437)( - nil, - nil, - (436...437), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(438...473)( - (438...444), - [ConstantReadNode(445...454)(:Exception), - ConstantReadNode(456...471)(:CustomException)], - nil, - nil, - StatementsNode(472...473)( - [CallNode(472...473)( - nil, - nil, - (472...473), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (474...477) - ), - BeginNode(479...536)( - (479...484), - StatementsNode(487...488)( - [CallNode(487...488)( - nil, - nil, - (487...488), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(489...532)( - (489...495), - [ConstantReadNode(496...505)(:Exception), - ConstantReadNode(507...522)(:CustomException)], - (523...525), - LocalVariableTargetNode(526...528)(:ex, 0), - StatementsNode(531...532)( - [CallNode(531...532)( - nil, - nil, - (531...532), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (533...536) - ), - BeginNode(538...578)( - (538...543), - StatementsNode(546...547)( - [CallNode(546...547)( - nil, - nil, - (546...547), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(548...574)( - (548...554), - [ConstantReadNode(555...564)(:Exception)], - (565...567), - LocalVariableTargetNode(568...570)(:ex, 0), - StatementsNode(573...574)( - [CallNode(573...574)( - nil, - nil, - (573...574), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (575...578) - )] - ) -) diff --git a/test/yarp/snapshots/blocks.txt b/test/yarp/snapshots/blocks.txt deleted file mode 100644 index b23965960afcdf..00000000000000 --- a/test/yarp/snapshots/blocks.txt +++ /dev/null @@ -1,624 +0,0 @@ -ProgramNode(0...402)( - [:fork], - StatementsNode(0...402)( - [CallNode(0...16)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...8), - (3...4), - ArgumentsNode(4...7)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar")] - ), - (7...8), - BlockNode(9...16)( - [], - nil, - StatementsNode(11...14)( - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (9...10), - (15...16) - ), - 0, - "[]" - ), - CallNode(18...37)( - CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "foo"), - nil, - (21...26), - (21...22), - ArgumentsNode(22...25)( - [CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "bar")] - ), - (25...26), - BlockNode(27...37)( - [], - nil, - StatementsNode(30...33)( - [CallNode(30...33)( - nil, - nil, - (30...33), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (27...29), - (34...37) - ), - 0, - "[]" - ), - CallNode(39...74)( - CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 2, "x"), - (40...41), - (41...47), - (47...48), - ArgumentsNode(48...49)([IntegerNode(48...49)()]), - (49...50), - BlockNode(51...74)( - [:x, :memo], - BlockParametersNode(53...62)( - ParametersNode(54...61)( - [RequiredParameterNode(54...55)(:x), - RequiredParameterNode(57...61)(:memo)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (53...54), - (61...62) - ), - StatementsNode(63...72)( - [LocalVariableOperatorWriteNode(63...72)( - (63...67), - (68...70), - LocalVariableReadNode(71...72)(:x, 0), - :memo, - :+, - 0 - )] - ), - (51...52), - (73...74) - ), - 0, - "reduce" - ), - CallNode(76...86)( - nil, - nil, - (76...79), - nil, - nil, - nil, - BlockNode(80...86)([], nil, nil, (80...82), (83...86)), - 0, - "foo" - ), - CallNode(88...109)( - nil, - nil, - (88...91), - nil, - ArgumentsNode(92...109)( - [CallNode(92...95)(nil, nil, (92...95), nil, nil, nil, nil, 2, "bar"), - ParenthesesNode(97...109)( - StatementsNode(98...108)( - [CallNode(98...108)( - nil, - nil, - (98...101), - nil, - nil, - nil, - BlockNode(102...108)([], nil, nil, (102...104), (105...108)), - 0, - "baz" - )] - ), - (97...98), - (108...109) - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(111...125)( - nil, - nil, - (111...114), - nil, - ArgumentsNode(115...118)( - [CallNode(115...118)( - nil, - nil, - (115...118), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - BlockNode(119...125)([], nil, nil, (119...121), (122...125)), - 0, - "foo" - ), - CallNode(127...145)( - nil, - nil, - (127...130), - nil, - ArgumentsNode(131...138)( - [CallNode(131...138)( - nil, - nil, - (131...134), - nil, - ArgumentsNode(135...138)( - [CallNode(135...138)( - nil, - nil, - (135...138), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil, - nil, - 0, - "bar" - )] - ), - nil, - BlockNode(139...145)([], nil, nil, (139...141), (142...145)), - 0, - "foo" - ), - CallNode(147...168)( - nil, - nil, - (147...150), - nil, - nil, - nil, - BlockNode(151...168)( - [:a], - BlockParametersNode(154...164)( - ParametersNode(155...163)( - [], - [OptionalParameterNode(155...163)( - :a, - (155...156), - (157...158), - CallNode(159...163)( - CallNode(159...160)( - nil, - nil, - (159...160), - nil, - nil, - nil, - nil, - 2, - "b" - ), - nil, - (160...163), - (160...161), - ArgumentsNode(161...162)([IntegerNode(161...162)()]), - (162...163), - nil, - 0, - "[]" - ) - )], - [], - nil, - [], - nil, - nil - ), - [], - (154...155), - (163...164) - ), - nil, - (151...153), - (165...168) - ), - 0, - "foo" - ), - CallNode(170...187)( - nil, - nil, - (170...173), - nil, - nil, - nil, - BlockNode(174...187)( - [], - nil, - BeginNode(177...187)( - nil, - nil, - RescueNode(177...183)((177...183), [], nil, nil, nil, nil), - nil, - nil, - (184...187) - ), - (174...176), - (184...187) - ), - 0, - "foo" - ), - CallNode(189...233)( - nil, - nil, - (189...192), - nil, - nil, - nil, - BlockNode(193...233)( - [], - nil, - StatementsNode(198...229)( - [CallNode(198...229)( - nil, - nil, - (198...201), - nil, - nil, - nil, - BlockNode(202...229)( - [], - nil, - StatementsNode(209...223)( - [CallNode(209...223)( - nil, - nil, - (209...212), - nil, - nil, - nil, - BlockNode(213...223)( - [], - nil, - nil, - (213...215), - (220...223) - ), - 0, - "baz" - )] - ), - (202...204), - (226...229) - ), - 0, - "bar" - )] - ), - (193...195), - (230...233) - ), - 0, - "foo" - ), - CallNode(235...251)( - CallNode(235...238)( - nil, - nil, - (235...238), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (238...243), - (238...239), - ArgumentsNode(239...242)( - [CallNode(239...242)( - nil, - nil, - (239...242), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (242...243), - BlockNode(244...251)( - [], - nil, - StatementsNode(246...249)( - [CallNode(246...249)( - nil, - nil, - (246...249), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (244...245), - (250...251) - ), - 0, - "[]" - ), - CallNode(253...277)( - nil, - nil, - (253...256), - nil, - nil, - nil, - BlockNode(257...277)( - [:x, :y, :z], - BlockParametersNode(259...273)( - ParametersNode(260...272)( - [RequiredParameterNode(260...261)(:x)], - [OptionalParameterNode(263...268)( - :y, - (263...264), - (265...266), - IntegerNode(267...268)() - )], - [], - nil, - [KeywordParameterNode(270...272)(:z, (270...272), nil)], - nil, - nil - ), - [], - (259...260), - (272...273) - ), - StatementsNode(274...275)([LocalVariableReadNode(274...275)(:x, 0)]), - (257...258), - (276...277) - ), - 0, - "foo" - ), - CallNode(279...290)( - nil, - nil, - (279...282), - nil, - nil, - nil, - BlockNode(283...290)( - [:x], - BlockParametersNode(285...288)( - ParametersNode(286...287)( - [RequiredParameterNode(286...287)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (285...286), - (287...288) - ), - nil, - (283...284), - (289...290) - ), - 0, - "foo" - ), - LocalVariableWriteNode(292...300)( - :fork, - 0, - (292...296), - IntegerNode(299...300)(), - (297...298) - ), - CallNode(301...316)( - nil, - nil, - (301...305), - nil, - nil, - nil, - BlockNode(306...316)( - [:a], - BlockParametersNode(309...312)( - ParametersNode(310...311)( - [RequiredParameterNode(310...311)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (309...310), - (311...312) - ), - nil, - (306...308), - (313...316) - ), - 0, - "fork" - ), - CallNode(318...330)( - nil, - nil, - (318...322), - nil, - nil, - nil, - BlockNode(323...330)( - [:a], - BlockParametersNode(325...328)( - ParametersNode(326...327)( - [RequiredParameterNode(326...327)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (325...326), - (327...328) - ), - nil, - (323...324), - (329...330) - ), - 0, - "fork" - ), - CallNode(332...340)( - nil, - nil, - (332...333), - nil, - nil, - nil, - BlockNode(334...340)([], nil, nil, (334...336), (337...340)), - 0, - "C" - ), - CallNode(342...346)( - nil, - nil, - (342...343), - nil, - nil, - nil, - BlockNode(344...346)([], nil, nil, (344...345), (345...346)), - 0, - "C" - ), - CallNode(348...383)( - nil, - nil, - (348...351), - nil, - ArgumentsNode(352...383)( - [CallNode(352...383)( - nil, - nil, - (352...358), - nil, - nil, - nil, - BlockNode(359...383)( - [:a, :b], - BlockParametersNode(361...381)( - ParametersNode(365...377)( - [], - [], - [], - nil, - [KeywordParameterNode(365...369)( - :a, - (365...367), - IntegerNode(368...369)() - ), - KeywordParameterNode(373...377)( - :b, - (373...375), - IntegerNode(376...377)() - )], - nil, - nil - ), - [], - (361...362), - (380...381) - ), - nil, - (359...360), - (382...383) - ), - 0, - "lambda" - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(385...402)( - nil, - nil, - (385...388), - nil, - nil, - nil, - BlockNode(389...402)( - [:bar], - BlockParametersNode(392...398)( - ParametersNode(393...397)( - [RequiredParameterNode(393...396)(:bar)], - [], - [], - RestParameterNode(396...397)(nil, nil, (396...397)), - [], - nil, - nil - ), - [], - (392...393), - (397...398) - ), - nil, - (389...391), - (399...402) - ), - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/boolean_operators.txt b/test/yarp/snapshots/boolean_operators.txt deleted file mode 100644 index f1fc5cd4b29472..00000000000000 --- a/test/yarp/snapshots/boolean_operators.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...24)( - [:a], - StatementsNode(0...24)( - [LocalVariableAndWriteNode(0...7)( - (0...1), - (2...5), - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"), - :a, - 0 - ), - LocalVariableOperatorWriteNode(9...15)( - (9...10), - (11...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "b"), - :a, - :+, - 0 - ), - LocalVariableOrWriteNode(17...24)( - (17...18), - (19...22), - CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "b"), - :a, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/booleans.txt b/test/yarp/snapshots/booleans.txt deleted file mode 100644 index f4e609652c3c57..00000000000000 --- a/test/yarp/snapshots/booleans.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)([FalseNode(0...5)(), TrueNode(7...11)()]) -) diff --git a/test/yarp/snapshots/break.txt b/test/yarp/snapshots/break.txt deleted file mode 100644 index b8ae8ffe815edb..00000000000000 --- a/test/yarp/snapshots/break.txt +++ /dev/null @@ -1,158 +0,0 @@ -ProgramNode(0...168)( - [], - StatementsNode(0...168)( - [BreakNode(0...5)(nil, (0...5)), - BreakNode(7...26)( - ArgumentsNode(13...26)( - [ParenthesesNode(13...16)( - StatementsNode(14...15)([IntegerNode(14...15)()]), - (13...14), - (15...16) - ), - ParenthesesNode(18...21)( - StatementsNode(19...20)([IntegerNode(19...20)()]), - (18...19), - (20...21) - ), - ParenthesesNode(23...26)( - StatementsNode(24...25)([IntegerNode(24...25)()]), - (23...24), - (25...26) - )] - ), - (7...12) - ), - BreakNode(28...35)( - ArgumentsNode(34...35)([IntegerNode(34...35)()]), - (28...33) - ), - BreakNode(37...50)( - ArgumentsNode(43...50)( - [IntegerNode(43...44)(), - IntegerNode(46...47)(), - IntegerNode(49...50)()] - ), - (37...42) - ), - BreakNode(52...65)( - ArgumentsNode(58...65)( - [IntegerNode(58...59)(), - IntegerNode(61...62)(), - IntegerNode(64...65)()] - ), - (52...57) - ), - BreakNode(67...82)( - ArgumentsNode(73...82)( - [ArrayNode(73...82)( - [IntegerNode(74...75)(), - IntegerNode(77...78)(), - IntegerNode(80...81)()], - (73...74), - (81...82) - )] - ), - (67...72) - ), - BreakNode(84...100)( - ArgumentsNode(89...100)( - [ParenthesesNode(89...100)( - StatementsNode(93...98)( - [IntegerNode(93...94)(), IntegerNode(97...98)()] - ), - (89...90), - (99...100) - )] - ), - (84...89) - ), - BreakNode(102...109)( - ArgumentsNode(107...109)( - [ParenthesesNode(107...109)(nil, (107...108), (108...109))] - ), - (102...107) - ), - BreakNode(111...119)( - ArgumentsNode(116...119)( - [ParenthesesNode(116...119)( - StatementsNode(117...118)([IntegerNode(117...118)()]), - (116...117), - (118...119) - )] - ), - (111...116) - ), - CallNode(121...143)( - CallNode(121...137)( - nil, - nil, - (121...124), - nil, - nil, - nil, - BlockNode(125...137)( - [], - nil, - StatementsNode(127...135)( - [BreakNode(127...135)( - ArgumentsNode(133...135)([IntegerNode(133...135)()]), - (127...132) - )] - ), - (125...126), - (136...137) - ), - 0, - "foo" - ), - nil, - (138...140), - nil, - ArgumentsNode(141...143)([IntegerNode(141...143)()]), - nil, - nil, - 0, - "==" - ), - CallNode(145...168)( - CallNode(145...162)( - nil, - nil, - (145...148), - nil, - nil, - nil, - BlockNode(149...162)( - [:a], - BlockParametersNode(151...154)( - ParametersNode(152...153)( - [RequiredParameterNode(152...153)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (151...152), - (153...154) - ), - StatementsNode(155...160)([BreakNode(155...160)(nil, (155...160))]), - (149...150), - (161...162) - ), - 0, - "foo" - ), - nil, - (163...165), - nil, - ArgumentsNode(166...168)([IntegerNode(166...168)()]), - nil, - nil, - 0, - "==" - )] - ) -) diff --git a/test/yarp/snapshots/case.txt b/test/yarp/snapshots/case.txt deleted file mode 100644 index 346b466a5e2d37..00000000000000 --- a/test/yarp/snapshots/case.txt +++ /dev/null @@ -1,208 +0,0 @@ -ProgramNode(0...272)( - [], - StatementsNode(0...272)( - [CaseNode(0...21)( - SymbolNode(5...8)((5...6), (6...8), nil, "hi"), - [WhenNode(9...17)( - (9...13), - [SymbolNode(14...17)((14...15), (15...17), nil, "hi")], - nil - )], - nil, - (0...4), - (18...21) - ), - CaseNode(23...81)( - TrueNode(28...32)(), - [WhenNode(34...53)( - (34...38), - [TrueNode(39...43)()], - StatementsNode(45...53)( - [CallNode(45...53)( - nil, - nil, - (45...49), - nil, - ArgumentsNode(50...53)( - [SymbolNode(50...53)((50...51), (51...53), nil, "hi")] - ), - nil, - nil, - 0, - "puts" - )] - ) - ), - WhenNode(55...76)( - (55...59), - [FalseNode(60...65)()], - StatementsNode(67...76)( - [CallNode(67...76)( - nil, - nil, - (67...71), - nil, - ArgumentsNode(72...76)( - [SymbolNode(72...76)((72...73), (73...76), nil, "bye")] - ), - nil, - nil, - 0, - "puts" - )] - ) - )], - nil, - (23...27), - (78...81) - ), - CaseNode(83...103)( - nil, - [WhenNode(89...98)( - (89...93), - [SplatNode(94...98)( - (94...95), - CallNode(95...98)( - nil, - nil, - (95...98), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )], - nil - )], - nil, - (83...87), - (100...103) - ), - CaseNode(105...134)( - SymbolNode(110...113)((110...111), (111...113), nil, "hi"), - [WhenNode(114...122)( - (114...118), - [SymbolNode(119...122)((119...120), (120...122), nil, "hi")], - nil - )], - ElseNode(123...134)( - (123...127), - StatementsNode(128...130)( - [SymbolNode(128...130)((128...129), (129...130), nil, "b")] - ), - (131...134) - ), - (105...109), - (131...134) - ), - CaseNode(136...172)( - CallNode(141...145)( - nil, - nil, - (141...145), - nil, - nil, - nil, - nil, - 2, - "this" - ), - [WhenNode(147...167)( - (147...151), - [ConstantReadNode(152...158)(:FooBar), - ConstantReadNode(160...167)(:BazBonk)], - nil - )], - nil, - (136...140), - (169...172) - ), - CaseNode(174...198)( - nil, - [WhenNode(179...194)( - (179...183), - [CallNode(184...194)( - CallNode(184...187)( - nil, - nil, - (184...187), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (188...190), - nil, - ArgumentsNode(191...194)( - [CallNode(191...194)( - nil, - nil, - (191...194), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "==" - )], - nil - )], - nil, - (174...178), - (195...198) - ), - CaseNode(200...230)( - nil, - [WhenNode(205...211)( - (205...209), - [CallNode(210...211)( - nil, - nil, - (210...211), - nil, - nil, - nil, - nil, - 2, - "a" - )], - nil - )], - ElseNode(212...230)((212...216), nil, (227...230)), - (200...204), - (227...230) - ), - CaseNode(232...272)( - CallNode(237...241)( - nil, - nil, - (237...241), - nil, - nil, - nil, - nil, - 2, - "type" - ), - [WhenNode(246...253)( - (246...250), - [SymbolNode(251...253)((251...252), (252...253), nil, "b")], - nil - )], - ElseNode(260...272)((260...264), nil, (269...272)), - (232...236), - (269...272) - )] - ) -) diff --git a/test/yarp/snapshots/classes.txt b/test/yarp/snapshots/classes.txt deleted file mode 100644 index 0679fe957fb3a8..00000000000000 --- a/test/yarp/snapshots/classes.txt +++ /dev/null @@ -1,287 +0,0 @@ -ProgramNode(0...370)( - [], - StatementsNode(0...370)( - [ClassNode(0...17)( - [:a], - (0...5), - ConstantReadNode(6...7)(:A), - nil, - nil, - StatementsNode(8...13)( - [LocalVariableWriteNode(8...13)( - :a, - 0, - (8...9), - IntegerNode(12...13)(), - (10...11) - )] - ), - (14...17), - :A - ), - ClassNode(19...39)( - [], - (19...24), - ConstantReadNode(25...26)(:A), - nil, - nil, - BeginNode(28...39)( - nil, - nil, - nil, - nil, - EnsureNode(28...39)((28...34), nil, (36...39)), - (36...39) - ), - (36...39), - :A - ), - ClassNode(41...75)( - [], - (41...46), - ConstantReadNode(47...48)(:A), - nil, - nil, - BeginNode(50...75)( - nil, - nil, - RescueNode(50...56)((50...56), [], nil, nil, nil, nil), - ElseNode(58...70)((58...62), nil, (64...70)), - EnsureNode(64...75)((64...70), nil, (72...75)), - (72...75) - ), - (72...75), - :A - ), - ClassNode(77...98)( - [:a], - (77...82), - ConstantReadNode(83...84)(:A), - (85...86), - ConstantReadNode(87...88)(:B), - StatementsNode(89...94)( - [LocalVariableWriteNode(89...94)( - :a, - 0, - (89...90), - IntegerNode(93...94)(), - (91...92) - )] - ), - (95...98), - :A - ), - SingletonClassNode(100...120)( - [], - (100...105), - (106...108), - CallNode(109...116)( - CallNode(113...116)( - nil, - nil, - (113...116), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (109...112), - nil, - nil, - nil, - nil, - 0, - "!" - ), - nil, - (117...120) - ), - ClassNode(122...162)( - [], - (122...127), - ConstantReadNode(128...129)(:A), - nil, - nil, - StatementsNode(131...157)( - [SingletonClassNode(131...157)( - [], - (131...136), - (137...139), - SelfNode(140...144)(), - BeginNode(146...157)( - nil, - nil, - nil, - nil, - EnsureNode(146...157)((146...152), nil, (154...157)), - (154...157) - ), - (154...157) - )] - ), - (159...162), - :A - ), - ClassNode(164...218)( - [], - (164...169), - ConstantReadNode(170...171)(:A), - nil, - nil, - StatementsNode(173...213)( - [SingletonClassNode(173...213)( - [], - (173...178), - (179...181), - SelfNode(182...186)(), - BeginNode(188...213)( - nil, - nil, - RescueNode(188...194)((188...194), [], nil, nil, nil, nil), - ElseNode(196...208)((196...200), nil, (202...208)), - EnsureNode(202...213)((202...208), nil, (210...213)), - (210...213) - ), - (210...213) - )] - ), - (215...218), - :A - ), - SingletonClassNode(220...240)( - [], - (220...225), - (226...228), - CallNode(229...236)( - CallNode(229...232)( - nil, - nil, - (229...232), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (232...233), - (233...236), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - nil, - (237...240) - ), - SingletonClassNode(242...262)( - [], - (242...247), - (248...250), - CallNode(251...258)( - CallNode(251...254)( - nil, - nil, - (251...254), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (254...255), - (255...258), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - nil, - (259...262) - ), - SingletonClassNode(264...281)( - [], - (264...269), - (270...272), - SelfNode(273...277)(), - nil, - (278...281) - ), - SingletonClassNode(283...300)( - [], - (283...288), - (289...291), - SelfNode(292...296)(), - nil, - (297...300) - ), - SingletonClassNode(302...325)( - [], - (302...307), - (308...310), - SelfNode(311...315)(), - StatementsNode(316...321)( - [CallNode(316...321)( - IntegerNode(316...317)(), - nil, - (318...319), - nil, - ArgumentsNode(320...321)([IntegerNode(320...321)()]), - nil, - nil, - 0, - "+" - )] - ), - (322...325) - ), - SingletonClassNode(327...350)( - [], - (327...332), - (333...335), - SelfNode(336...340)(), - StatementsNode(341...346)( - [CallNode(341...346)( - IntegerNode(341...342)(), - nil, - (343...344), - nil, - ArgumentsNode(345...346)([IntegerNode(345...346)()]), - nil, - nil, - 0, - "+" - )] - ), - (347...350) - ), - ClassNode(352...370)( - [], - (352...357), - ConstantReadNode(358...359)(:A), - (360...361), - CallNode(362...366)( - ConstantReadNode(362...363)(:B), - nil, - (363...366), - (363...364), - ArgumentsNode(364...365)([IntegerNode(364...365)()]), - (365...366), - nil, - 0, - "[]" - ), - nil, - (367...370), - :A - )] - ) -) diff --git a/test/yarp/snapshots/comments.txt b/test/yarp/snapshots/comments.txt deleted file mode 100644 index e24df47bc83170..00000000000000 --- a/test/yarp/snapshots/comments.txt +++ /dev/null @@ -1,64 +0,0 @@ -ProgramNode(0...118)( - [], - StatementsNode(0...118)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "b"), - CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "c"), - CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 2, "d"), - CallNode(31...47)( - CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 2, "e"), - (45...46), - (46...47), - nil, - nil, - nil, - nil, - 0, - "f" - ), - CallNode(49...64)( - CallNode(49...50)(nil, nil, (49...50), nil, nil, nil, nil, 2, "g"), - (62...63), - (63...64), - nil, - nil, - nil, - nil, - 0, - "h" - ), - CallNode(66...80)( - CallNode(66...67)(nil, nil, (66...67), nil, nil, nil, nil, 2, "i"), - (78...79), - (79...80), - nil, - nil, - nil, - nil, - 0, - "j" - ), - CallNode(82...98)( - CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "k"), - (96...97), - (97...98), - nil, - nil, - nil, - nil, - 0, - "l" - ), - CallNode(100...118)( - CallNode(100...101)(nil, nil, (100...101), nil, nil, nil, nil, 2, "m"), - (115...117), - (117...118), - nil, - nil, - nil, - nil, - 1, - "n" - )] - ) -) diff --git a/test/yarp/snapshots/constants.txt b/test/yarp/snapshots/constants.txt deleted file mode 100644 index bf4564c46d02fa..00000000000000 --- a/test/yarp/snapshots/constants.txt +++ /dev/null @@ -1,1095 +0,0 @@ -ProgramNode(0...792)( - [], - StatementsNode(0...792)( - [ConstantPathNode(0...4)( - ConstantReadNode(0...1)(:A), - ConstantReadNode(3...4)(:B), - (1...3) - ), - ConstantPathNode(6...13)( - ConstantPathNode(6...10)( - ConstantReadNode(6...7)(:A), - ConstantReadNode(9...10)(:B), - (7...9) - ), - ConstantReadNode(12...13)(:C), - (10...12) - ), - ConstantPathNode(15...19)( - CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "a"), - ConstantReadNode(18...19)(:B), - (16...18) - ), - ConstantPathWriteNode(21...29)( - ConstantPathNode(21...25)( - ConstantReadNode(21...22)(:A), - ConstantReadNode(24...25)(:B), - (22...24) - ), - (26...27), - IntegerNode(28...29)() - ), - ConstantWriteNode(31...36)( - :A, - (31...32), - IntegerNode(35...36)(), - (33...34) - ), - ConstantReadNode(38...41)(:ABC), - CallNode(43...48)( - nil, - nil, - (43...46), - nil, - ArgumentsNode(47...48)([IntegerNode(47...48)()]), - nil, - nil, - 0, - "Foo" - ), - CallNode(50...58)( - nil, - nil, - (50...53), - nil, - ArgumentsNode(54...58)( - [SplatNode(54...58)( - (54...55), - CallNode(55...58)( - nil, - nil, - (55...58), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )] - ), - nil, - nil, - 0, - "Foo" - ), - CallNode(60...69)( - nil, - nil, - (60...63), - nil, - ArgumentsNode(64...69)( - [KeywordHashNode(64...69)( - [AssocSplatNode(64...69)( - CallNode(66...69)( - nil, - nil, - (66...69), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (64...66) - )] - )] - ), - nil, - nil, - 0, - "Foo" - ), - CallNode(71...79)( - nil, - nil, - (71...74), - nil, - ArgumentsNode(75...79)( - [BlockArgumentNode(75...79)( - CallNode(76...79)( - nil, - nil, - (76...79), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (75...76) - )] - ), - nil, - nil, - 0, - "Foo" - ), - CallNode(81...94)( - ConstantReadNode(81...84)(:Foo), - (84...86), - (86...89), - nil, - ArgumentsNode(90...94)( - [SplatNode(90...94)( - (90...91), - CallNode(91...94)( - nil, - nil, - (91...94), - nil, - nil, - nil, - nil, - 2, - "baz" - ) - )] - ), - nil, - nil, - 0, - "Bar" - ), - CallNode(96...110)( - ConstantReadNode(96...99)(:Foo), - (99...101), - (101...104), - nil, - ArgumentsNode(105...110)( - [KeywordHashNode(105...110)( - [AssocSplatNode(105...110)( - CallNode(107...110)( - nil, - nil, - (107...110), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (105...107) - )] - )] - ), - nil, - nil, - 0, - "Bar" - ), - CallNode(112...125)( - ConstantReadNode(112...115)(:Foo), - (115...117), - (117...120), - nil, - ArgumentsNode(121...125)( - [BlockArgumentNode(121...125)( - CallNode(122...125)( - nil, - nil, - (122...125), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (121...122) - )] - ), - nil, - nil, - 0, - "Bar" - ), - CallNode(127...135)( - ConstantPathNode(127...130)( - nil, - ConstantReadNode(129...130)(:A), - (127...129) - ), - (130...132), - (132...135), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - ConstantPathWriteNode(137...144)( - ConstantPathNode(137...140)( - nil, - ConstantReadNode(139...140)(:A), - (137...139) - ), - (141...142), - IntegerNode(143...144)() - ), - ConstantPathWriteNode(146...156)( - ConstantPathNode(146...152)( - ConstantPathNode(146...149)( - nil, - ConstantReadNode(148...149)(:A), - (146...148) - ), - ConstantReadNode(151...152)(:B), - (149...151) - ), - (153...154), - IntegerNode(155...156)() - ), - ConstantPathNode(158...164)( - ConstantPathNode(158...161)( - nil, - ConstantReadNode(160...161)(:A), - (158...160) - ), - ConstantReadNode(163...164)(:B), - (161...163) - ), - ConstantPathNode(166...169)( - nil, - ConstantReadNode(168...169)(:A), - (166...168) - ), - CallNode(171...179)( - ConstantReadNode(171...172)(:A), - (172...174), - (174...179), - nil, - nil, - nil, - nil, - 0, - "false" - ), - CallNode(181...191)( - ConstantPathNode(181...185)( - ConstantReadNode(181...182)(:A), - ConstantReadNode(184...185)(:B), - (182...184) - ), - (185...187), - (187...191), - nil, - nil, - nil, - nil, - 0, - "true" - ), - CallNode(193...197)( - ConstantReadNode(193...194)(:A), - (194...196), - (196...197), - nil, - nil, - nil, - nil, - 0, - "&" - ), - CallNode(199...203)( - ConstantReadNode(199...200)(:A), - (200...202), - (202...203), - nil, - nil, - nil, - nil, - 0, - "`" - ), - CallNode(205...209)( - ConstantReadNode(205...206)(:A), - (206...208), - (208...209), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(211...216)( - ConstantReadNode(211...212)(:A), - (212...214), - (214...216), - nil, - nil, - nil, - nil, - 0, - "!=" - ), - CallNode(218...222)( - ConstantReadNode(218...219)(:A), - (219...221), - (221...222), - nil, - nil, - nil, - nil, - 0, - "^" - ), - CallNode(224...229)( - ConstantReadNode(224...225)(:A), - (225...227), - (227...229), - nil, - nil, - nil, - nil, - 0, - "==" - ), - CallNode(231...237)( - ConstantReadNode(231...232)(:A), - (232...234), - (234...237), - nil, - nil, - nil, - nil, - 0, - "===" - ), - CallNode(239...244)( - ConstantReadNode(239...240)(:A), - (240...242), - (242...244), - nil, - nil, - nil, - nil, - 0, - "=~" - ), - CallNode(246...250)( - ConstantReadNode(246...247)(:A), - (247...249), - (249...250), - nil, - nil, - nil, - nil, - 0, - ">" - ), - CallNode(252...257)( - ConstantReadNode(252...253)(:A), - (253...255), - (255...257), - nil, - nil, - nil, - nil, - 0, - ">=" - ), - CallNode(259...264)( - ConstantReadNode(259...260)(:A), - (260...262), - (262...264), - nil, - nil, - nil, - nil, - 0, - ">>" - ), - CallNode(266...271)( - ConstantReadNode(266...267)(:A), - (267...269), - (269...271), - nil, - nil, - nil, - nil, - 0, - "<<" - ), - ConstantPathNode(273...281)( - ConstantReadNode(273...274)(:A), - ConstantReadNode(280...281)(:C), - (274...276) - ), - CallNode(283...291)( - ConstantReadNode(283...284)(:A), - (284...286), - (286...291), - nil, - nil, - nil, - nil, - 0, - "alias" - ), - CallNode(293...299)( - ConstantReadNode(293...294)(:A), - (294...296), - (296...299), - nil, - nil, - nil, - nil, - 0, - "and" - ), - CallNode(301...309)( - ConstantReadNode(301...302)(:A), - (302...304), - (304...309), - nil, - nil, - nil, - nil, - 0, - "begin" - ), - ConstantPathNode(311...319)( - ConstantReadNode(311...312)(:A), - ConstantReadNode(314...319)(:BEGIN), - (312...314) - ), - CallNode(321...329)( - ConstantReadNode(321...322)(:A), - (322...324), - (324...329), - nil, - nil, - nil, - nil, - 0, - "break" - ), - CallNode(331...339)( - ConstantReadNode(331...332)(:A), - (332...334), - (334...339), - nil, - nil, - nil, - nil, - 0, - "class" - ), - CallNode(341...347)( - ConstantReadNode(341...342)(:A), - (342...344), - (344...347), - nil, - nil, - nil, - nil, - 0, - "def" - ), - CallNode(349...359)( - ConstantReadNode(349...350)(:A), - (350...352), - (352...359), - nil, - nil, - nil, - nil, - 0, - "defined" - ), - CallNode(361...366)( - ConstantReadNode(361...362)(:A), - (362...364), - (364...366), - nil, - nil, - nil, - nil, - 0, - "do" - ), - CallNode(368...375)( - ConstantReadNode(368...369)(:A), - (369...371), - (371...375), - nil, - nil, - nil, - nil, - 0, - "else" - ), - CallNode(377...385)( - ConstantReadNode(377...378)(:A), - (378...380), - (380...385), - nil, - nil, - nil, - nil, - 0, - "elsif" - ), - CallNode(387...393)( - ConstantReadNode(387...388)(:A), - (388...390), - (390...393), - nil, - nil, - nil, - nil, - 0, - "end" - ), - ConstantPathNode(395...401)( - ConstantReadNode(395...396)(:A), - ConstantReadNode(398...401)(:END), - (396...398) - ), - CallNode(403...412)( - ConstantReadNode(403...404)(:A), - (404...406), - (406...412), - nil, - nil, - nil, - nil, - 0, - "ensure" - ), - CallNode(414...422)( - ConstantReadNode(414...415)(:A), - (415...417), - (417...422), - nil, - nil, - nil, - nil, - 0, - "false" - ), - CallNode(424...430)( - ConstantReadNode(424...425)(:A), - (425...427), - (427...430), - nil, - nil, - nil, - nil, - 0, - "for" - ), - CallNode(432...437)( - ConstantReadNode(432...433)(:A), - (433...435), - (435...437), - nil, - nil, - nil, - nil, - 0, - "if" - ), - CallNode(439...444)( - ConstantReadNode(439...440)(:A), - (440...442), - (442...444), - nil, - nil, - nil, - nil, - 0, - "in" - ), - CallNode(446...453)( - ConstantReadNode(446...447)(:A), - (447...449), - (449...453), - nil, - nil, - nil, - nil, - 0, - "next" - ), - CallNode(455...461)( - ConstantReadNode(455...456)(:A), - (456...458), - (458...461), - nil, - nil, - nil, - nil, - 0, - "nil" - ), - CallNode(463...469)( - ConstantReadNode(463...464)(:A), - (464...466), - (466...469), - nil, - nil, - nil, - nil, - 0, - "not" - ), - CallNode(471...476)( - ConstantReadNode(471...472)(:A), - (472...474), - (474...476), - nil, - nil, - nil, - nil, - 0, - "or" - ), - CallNode(478...485)( - ConstantReadNode(478...479)(:A), - (479...481), - (481...485), - nil, - nil, - nil, - nil, - 0, - "redo" - ), - CallNode(487...496)( - ConstantReadNode(487...488)(:A), - (488...490), - (490...496), - nil, - nil, - nil, - nil, - 0, - "rescue" - ), - CallNode(498...506)( - ConstantReadNode(498...499)(:A), - (499...501), - (501...506), - nil, - nil, - nil, - nil, - 0, - "retry" - ), - CallNode(508...517)( - ConstantReadNode(508...509)(:A), - (509...511), - (511...517), - nil, - nil, - nil, - nil, - 0, - "return" - ), - CallNode(519...526)( - ConstantReadNode(519...520)(:A), - (520...522), - (522...526), - nil, - nil, - nil, - nil, - 0, - "self" - ), - CallNode(528...536)( - ConstantReadNode(528...529)(:A), - (529...531), - (531...536), - nil, - nil, - nil, - nil, - 0, - "super" - ), - CallNode(538...545)( - ConstantReadNode(538...539)(:A), - (539...541), - (541...545), - nil, - nil, - nil, - nil, - 0, - "then" - ), - CallNode(547...554)( - ConstantReadNode(547...548)(:A), - (548...550), - (550...554), - nil, - nil, - nil, - nil, - 0, - "true" - ), - CallNode(556...564)( - ConstantReadNode(556...557)(:A), - (557...559), - (559...564), - nil, - nil, - nil, - nil, - 0, - "undef" - ), - CallNode(566...575)( - ConstantReadNode(566...567)(:A), - (567...569), - (569...575), - nil, - nil, - nil, - nil, - 0, - "unless" - ), - CallNode(577...585)( - ConstantReadNode(577...578)(:A), - (578...580), - (580...585), - nil, - nil, - nil, - nil, - 0, - "until" - ), - CallNode(587...594)( - ConstantReadNode(587...588)(:A), - (588...590), - (590...594), - nil, - nil, - nil, - nil, - 0, - "when" - ), - CallNode(596...604)( - ConstantReadNode(596...597)(:A), - (597...599), - (599...604), - nil, - nil, - nil, - nil, - 0, - "while" - ), - CallNode(606...614)( - ConstantReadNode(606...607)(:A), - (607...609), - (609...614), - nil, - nil, - nil, - nil, - 0, - "yield" - ), - CallNode(616...631)( - ConstantReadNode(616...617)(:A), - (617...619), - (619...631), - nil, - nil, - nil, - nil, - 0, - "__ENCODING__" - ), - CallNode(633...644)( - ConstantReadNode(633...634)(:A), - (634...636), - (636...644), - nil, - nil, - nil, - nil, - 0, - "__FILE__" - ), - CallNode(646...657)( - ConstantReadNode(646...647)(:A), - (647...649), - (649...657), - nil, - nil, - nil, - nil, - 0, - "__LINE__" - ), - CallNode(659...663)( - ConstantReadNode(659...660)(:A), - (660...662), - (662...663), - nil, - nil, - nil, - nil, - 0, - "<" - ), - CallNode(665...671)( - ConstantReadNode(665...666)(:A), - (666...668), - (668...671), - nil, - nil, - nil, - nil, - 0, - "<=>" - ), - CallNode(673...678)( - ConstantReadNode(673...674)(:A), - (674...676), - (676...678), - nil, - nil, - nil, - nil, - 0, - "<<" - ), - CallNode(680...684)( - ConstantReadNode(680...681)(:A), - (681...683), - (683...684), - nil, - nil, - nil, - nil, - 0, - "-" - ), - CallNode(686...690)( - ConstantReadNode(686...687)(:A), - (687...689), - (689...690), - nil, - nil, - nil, - nil, - 0, - "%" - ), - CallNode(692...697)( - ConstantReadNode(692...693)(:A), - (693...695), - (695...696), - nil, - ArgumentsNode(696...697)( - [CallNode(696...697)( - nil, - nil, - (696...697), - nil, - nil, - nil, - nil, - 2, - "i" - )] - ), - nil, - nil, - 0, - "%" - ), - CallNode(699...704)( - ConstantReadNode(699...700)(:A), - (700...702), - (702...703), - nil, - ArgumentsNode(703...704)( - [CallNode(703...704)( - nil, - nil, - (703...704), - nil, - nil, - nil, - nil, - 2, - "w" - )] - ), - nil, - nil, - 0, - "%" - ), - CallNode(706...711)( - ConstantReadNode(706...707)(:A), - (707...709), - (709...710), - nil, - ArgumentsNode(710...711)( - [CallNode(710...711)( - nil, - nil, - (710...711), - nil, - nil, - nil, - nil, - 2, - "x" - )] - ), - nil, - nil, - 0, - "%" - ), - CallNode(713...718)( - ConstantReadNode(713...714)(:A), - (714...716), - (716...717), - nil, - ArgumentsNode(717...718)([ConstantReadNode(717...718)(:I)]), - nil, - nil, - 0, - "%" - ), - CallNode(720...725)( - ConstantReadNode(720...721)(:A), - (721...723), - (723...724), - nil, - ArgumentsNode(724...725)([ConstantReadNode(724...725)(:W)]), - nil, - nil, - 0, - "%" - ), - CallNode(727...731)( - ConstantReadNode(727...728)(:A), - (728...730), - (730...731), - nil, - nil, - nil, - nil, - 0, - "|" - ), - CallNode(733...737)( - ConstantReadNode(733...734)(:A), - (734...736), - (736...737), - nil, - nil, - nil, - nil, - 0, - "+" - ), - CallNode(739...743)( - ConstantReadNode(739...740)(:A), - (740...742), - (742...743), - nil, - nil, - nil, - nil, - 0, - "/" - ), - CallNode(745...749)( - ConstantReadNode(745...746)(:A), - (746...748), - (748...749), - nil, - nil, - nil, - nil, - 0, - "*" - ), - CallNode(751...756)( - ConstantReadNode(751...752)(:A), - (752...754), - (754...756), - nil, - nil, - nil, - nil, - 0, - "**" - ), - CallNode(758...762)( - ConstantReadNode(758...759)(:A), - (759...761), - (761...762), - nil, - nil, - nil, - nil, - 0, - "~" - ), - ConstantPathNode(764...772)( - CallNode(764...768)( - ConstantReadNode(764...765)(:A), - (765...767), - (767...768), - nil, - nil, - nil, - nil, - 0, - "_" - ), - ConstantReadNode(771...772)(:C), - (768...770) - ), - RangeNode(774...792)( - CallNode(774...778)( - ConstantReadNode(774...775)(:A), - (775...777), - (777...778), - nil, - nil, - nil, - nil, - 0, - "_" - ), - CallNode(782...792)( - ConstantReadNode(782...783)(:A), - (783...785), - (785...792), - nil, - nil, - nil, - nil, - 0, - "__END__" - ), - (778...780), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/dash_heredocs.txt b/test/yarp/snapshots/dash_heredocs.txt deleted file mode 100644 index e2eea3c2a53666..00000000000000 --- a/test/yarp/snapshots/dash_heredocs.txt +++ /dev/null @@ -1,176 +0,0 @@ -ProgramNode(0...278)( - [], - StatementsNode(0...278)( - [InterpolatedStringNode(0...6)( - (0...6), - [StringNode(7...11)(nil, (7...11), nil, " a\n")], - (11...15) - ), - CallNode(16...36)( - InterpolatedStringNode(16...24)( - (16...24), - [StringNode(37...41)(nil, (37...41), nil, " a\n")], - (41...47) - ), - nil, - (25...26), - nil, - ArgumentsNode(27...36)( - [InterpolatedStringNode(27...36)( - (27...36), - [StringNode(47...51)(nil, (47...51), nil, " b\n")], - (51...58) - )] - ), - nil, - nil, - 0, - "+" - ), - InterpolatedXStringNode(59...67)( - (59...67), - [StringNode(68...72)(nil, (68...72), nil, " a\n"), - EmbeddedStatementsNode(72...76)( - (72...74), - StatementsNode(74...75)( - [CallNode(74...75)( - nil, - nil, - (74...75), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (75...76) - ), - StringNode(76...77)(nil, (76...77), nil, "\n")], - (77...81) - ), - InterpolatedStringNode(82...88)( - (82...88), - [StringNode(98...102)(nil, (98...102), nil, " a\n")], - (102...106) - ), - InterpolatedStringNode(107...113)( - (107...113), - [StringNode(114...122)(nil, (114...122), nil, " a\n" + " b\n")], - (122...128) - ), - InterpolatedStringNode(129...137)( - (129...137), - [StringNode(138...142)(nil, (138...142), nil, " a\n"), - EmbeddedStatementsNode(142...146)( - (142...144), - StatementsNode(144...145)( - [CallNode(144...145)( - nil, - nil, - (144...145), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (145...146) - ), - StringNode(146...147)(nil, (146...147), nil, "\n")], - (147...151) - ), - InterpolatedStringNode(152...158)( - (152...158), - [StringNode(159...163)(nil, (159...163), nil, " a\n"), - EmbeddedStatementsNode(163...167)( - (163...165), - StatementsNode(165...166)( - [CallNode(165...166)( - nil, - nil, - (165...166), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (166...167) - ), - StringNode(167...168)(nil, (167...168), nil, "\n")], - (168...172) - ), - StringNode(173...179)((173...175), (175...178), (178...179), "abc"), - InterpolatedStringNode(181...187)( - (181...187), - [StringNode(188...196)(nil, (188...196), nil, " a\n" + " b\n")], - (196...200) - ), - InterpolatedStringNode(201...206)((201...206), [], (207...208)), - InterpolatedStringNode(209...217)( - (209...217), - [StringNode(218...227)(nil, (218...227), nil, " a \#{1}\n")], - (227...231) - ), - CallNode(232...243)( - InterpolatedStringNode(232...236)( - (232...236), - [StringNode(244...248)(nil, (244...248), nil, " a\n")], - (248...250) - ), - nil, - (237...238), - nil, - ArgumentsNode(239...243)( - [InterpolatedStringNode(239...243)( - (239...243), - [StringNode(250...256)(nil, (250...256), nil, " b\n" + " "), - EmbeddedStatementsNode(256...263)( - (256...258), - StatementsNode(258...259)([IntegerNode(258...259)()]), - (262...263) - ), - StringNode(263...264)(nil, (263...264), nil, "\n")], - (264...266) - )] - ), - nil, - nil, - 0, - "+" - ), - CallNode(267...278)( - InterpolatedStringNode(267...271)( - (267...271), - [StringNode(279...283)(nil, (279...283), nil, " a\n")], - (283...285) - ), - nil, - (272...273), - nil, - ArgumentsNode(274...278)( - [InterpolatedStringNode(274...278)( - (274...278), - [StringNode(285...291)(nil, (285...291), nil, " b\n" + " "), - EmbeddedStatementsNode(291...298)( - (291...293), - StatementsNode(296...297)([IntegerNode(296...297)()]), - (297...298) - ), - StringNode(298...299)(nil, (298...299), nil, "\n")], - (299...301) - )] - ), - nil, - nil, - 0, - "+" - )] - ) -) diff --git a/test/yarp/snapshots/defined.txt b/test/yarp/snapshots/defined.txt deleted file mode 100644 index 1d4b5a5502e876..00000000000000 --- a/test/yarp/snapshots/defined.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...78)( - [:x], - StatementsNode(0...78)( - [AndNode(0...25)( - DefinedNode(0...10)(nil, IntegerNode(9...10)(), nil, (0...8)), - DefinedNode(15...25)(nil, IntegerNode(24...25)(), nil, (15...23)), - (11...14) - ), - DefinedNode(27...43)( - (35...36), - LocalVariableOperatorWriteNode(36...42)( - (36...37), - (38...40), - IntegerNode(41...42)(), - :x, - :%, - 0 - ), - (42...43), - (27...35) - ), - DefinedNode(45...66)( - (53...54), - AndNode(54...65)( - CallNode(54...57)(nil, nil, (54...57), nil, nil, nil, nil, 2, "foo"), - CallNode(62...65)(nil, nil, (62...65), nil, nil, nil, nil, 2, "bar"), - (58...61) - ), - (65...66), - (45...53) - ), - DefinedNode(68...78)(nil, IntegerNode(77...78)(), nil, (68...76))] - ) -) diff --git a/test/yarp/snapshots/dos_endings.txt b/test/yarp/snapshots/dos_endings.txt deleted file mode 100644 index 7048028b2a193b..00000000000000 --- a/test/yarp/snapshots/dos_endings.txt +++ /dev/null @@ -1,81 +0,0 @@ -ProgramNode(0...108)( - [:x, :a], - StatementsNode(0...108)( - [CallNode(0...24)( - nil, - nil, - (0...4), - nil, - ArgumentsNode(5...24)( - [StringConcatNode(5...24)( - StringNode(5...9)((5...6), (6...8), (8...9), "hi"), - StringNode(17...24)((17...18), (18...23), (23...24), "there") - )] - ), - nil, - nil, - 0, - "puts" - ), - ArrayNode(28...37)( - [SymbolNode(31...36)(nil, (31...36), nil, "ab")], - (28...31), - (36...37) - ), - InterpolatedStringNode(41...45)( - (41...45), - [StringNode(47...70)( - nil, - (47...70), - nil, - " 1 2\r\n" + " 3\r\n" - )], - (70...73) - ), - LocalVariableWriteNode(75...84)( - :x, - 0, - (75...76), - StringNode(79...84)((79...82), (82...82), (82...84), ""), - (77...78) - ), - LocalVariableWriteNode(88...108)( - :a, - 0, - (88...89), - CallNode(92...108)( - nil, - nil, - (92...95), - (95...96), - ArgumentsNode(96...107)( - [CallNode(96...107)( - InterpolatedStringNode(96...102)( - (96...102), - [StringNode(110...121)( - nil, - (110...121), - nil, - "\n" + "baz\r\n" - )], - (121...128) - ), - (102...103), - (103...107), - nil, - nil, - nil, - nil, - 0, - "chop" - )] - ), - (107...108), - nil, - 0, - "foo" - ), - (90...91) - )] - ) -) diff --git a/test/yarp/snapshots/embdoc_no_newline_at_end.txt b/test/yarp/snapshots/embdoc_no_newline_at_end.txt deleted file mode 100644 index bd3eaf5ff49bc2..00000000000000 --- a/test/yarp/snapshots/embdoc_no_newline_at_end.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...0)([], StatementsNode(0...0)([])) diff --git a/test/yarp/snapshots/endless_methods.txt b/test/yarp/snapshots/endless_methods.txt deleted file mode 100644 index 61b7493847957d..00000000000000 --- a/test/yarp/snapshots/endless_methods.txt +++ /dev/null @@ -1,83 +0,0 @@ -ProgramNode(0...51)( - [], - StatementsNode(0...51)( - [DefNode(0...11)( - :foo, - (4...7), - nil, - nil, - StatementsNode(10...11)([IntegerNode(10...11)()]), - [], - (0...3), - nil, - nil, - nil, - (8...9), - nil - ), - DefNode(13...27)( - :bar, - (17...20), - nil, - nil, - StatementsNode(23...27)( - [CallNode(23...27)( - nil, - nil, - (23...24), - nil, - ArgumentsNode(25...27)( - [StringNode(25...27)((25...26), (26...26), (26...27), "")] - ), - nil, - nil, - 0, - "A" - )] - ), - [], - (13...16), - nil, - nil, - nil, - (21...22), - nil - ), - DefNode(29...51)( - :method, - (33...39), - nil, - nil, - StatementsNode(42...51)( - [CallNode(42...51)( - CallNode(42...47)( - IntegerNode(42...43)(), - nil, - (44...45), - nil, - ArgumentsNode(46...47)([IntegerNode(46...47)()]), - nil, - nil, - 0, - "+" - ), - nil, - (48...49), - nil, - ArgumentsNode(50...51)([IntegerNode(50...51)()]), - nil, - nil, - 0, - "+" - )] - ), - [], - (29...32), - nil, - nil, - nil, - (40...41), - nil - )] - ) -) diff --git a/test/yarp/snapshots/endless_range_in_conditional.txt b/test/yarp/snapshots/endless_range_in_conditional.txt deleted file mode 100644 index 4360818e40de56..00000000000000 --- a/test/yarp/snapshots/endless_range_in_conditional.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [IfNode(0...13)( - (0...2), - FlipFlopNode(3...7)( - IntegerNode(3...4)(), - IntegerNode(6...7)(), - (4...6), - 0 - ), - nil, - nil, - (10...13) - ), - IfNode(14...26)( - (14...16), - FlipFlopNode(17...20)(nil, IntegerNode(19...20)(), (17...19), 0), - nil, - nil, - (23...26) - ), - IfNode(27...39)( - (27...29), - FlipFlopNode(30...33)(IntegerNode(30...31)(), nil, (31...33), 0), - nil, - nil, - (36...39) - )] - ) -) diff --git a/test/yarp/snapshots/for.txt b/test/yarp/snapshots/for.txt deleted file mode 100644 index 77f85312e389b9..00000000000000 --- a/test/yarp/snapshots/for.txt +++ /dev/null @@ -1,116 +0,0 @@ -ProgramNode(0...143)( - [:i, :j, :k], - StatementsNode(0...143)( - [ForNode(0...20)( - MultiTargetNode(4...5)( - [LocalVariableTargetNode(4...5)(:i, 0)], - nil, - nil - ), - RangeNode(9...14)( - IntegerNode(9...10)(), - IntegerNode(12...14)(), - (10...12), - 0 - ), - StatementsNode(15...16)([LocalVariableReadNode(15...16)(:i, 0)]), - (0...3), - (6...8), - nil, - (17...20) - ), - ForNode(22...44)( - MultiTargetNode(26...27)( - [LocalVariableTargetNode(26...27)(:i, 0)], - nil, - nil - ), - RangeNode(31...36)( - IntegerNode(31...32)(), - IntegerNode(34...36)(), - (32...34), - 0 - ), - StatementsNode(38...39)([LocalVariableReadNode(38...39)(:i, 0)]), - (22...25), - (28...30), - nil, - (41...44) - ), - ForNode(46...68)( - MultiTargetNode(50...53)( - [LocalVariableTargetNode(50...51)(:i, 0), - LocalVariableTargetNode(52...53)(:j, 0)], - nil, - nil - ), - RangeNode(57...62)( - IntegerNode(57...58)(), - IntegerNode(60...62)(), - (58...60), - 0 - ), - StatementsNode(63...64)([LocalVariableReadNode(63...64)(:i, 0)]), - (46...49), - (54...56), - nil, - (65...68) - ), - ForNode(70...94)( - MultiTargetNode(74...79)( - [LocalVariableTargetNode(74...75)(:i, 0), - LocalVariableTargetNode(76...77)(:j, 0), - LocalVariableTargetNode(78...79)(:k, 0)], - nil, - nil - ), - RangeNode(83...88)( - IntegerNode(83...84)(), - IntegerNode(86...88)(), - (84...86), - 0 - ), - StatementsNode(89...90)([LocalVariableReadNode(89...90)(:i, 0)]), - (70...73), - (80...82), - nil, - (91...94) - ), - ForNode(96...119)( - MultiTargetNode(100...101)( - [LocalVariableTargetNode(100...101)(:i, 0)], - nil, - nil - ), - RangeNode(105...110)( - IntegerNode(105...106)(), - IntegerNode(108...110)(), - (106...108), - 0 - ), - StatementsNode(114...115)([LocalVariableReadNode(114...115)(:i, 0)]), - (96...99), - (102...104), - (111...113), - (116...119) - ), - ForNode(121...143)( - MultiTargetNode(125...126)( - [LocalVariableTargetNode(125...126)(:i, 0)], - nil, - nil - ), - RangeNode(130...135)( - IntegerNode(130...131)(), - IntegerNode(133...135)(), - (131...133), - 0 - ), - StatementsNode(137...138)([LocalVariableReadNode(137...138)(:i, 0)]), - (121...124), - (127...129), - nil, - (140...143) - )] - ) -) diff --git a/test/yarp/snapshots/global_variables.txt b/test/yarp/snapshots/global_variables.txt deleted file mode 100644 index 578f02e9b81519..00000000000000 --- a/test/yarp/snapshots/global_variables.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...349)( - [], - StatementsNode(0...349)( - [GlobalVariableReadNode(0...16)(:$global_variable), - GlobalVariableReadNode(18...20)(:$_), - GlobalVariableReadNode(22...25)(:$-w), - GlobalVariableReadNode(27...37)(:$LOAD_PATH), - GlobalVariableReadNode(39...45)(:$stdin), - GlobalVariableReadNode(47...54)(:$stdout), - GlobalVariableReadNode(56...63)(:$stderr), - GlobalVariableReadNode(65...67)(:$!), - GlobalVariableReadNode(69...71)(:$?), - GlobalVariableReadNode(73...75)(:$~), - BackReferenceReadNode(77...79)(), - BackReferenceReadNode(81...83)(), - BackReferenceReadNode(85...87)(), - BackReferenceReadNode(89...91)(), - GlobalVariableReadNode(93...95)(:$:), - GlobalVariableReadNode(97...99)(:$;), - GlobalVariableReadNode(101...103)(:$,), - GlobalVariableReadNode(105...111)(:$DEBUG), - GlobalVariableReadNode(113...122)(:$FILENAME), - GlobalVariableReadNode(124...126)(:$0), - GlobalVariableReadNode(128...131)(:$-0), - GlobalVariableReadNode(133...149)(:$LOADED_FEATURES), - GlobalVariableReadNode(151...159)(:$VERBOSE), - GlobalVariableReadNode(161...164)(:$-K), - SymbolNode(166...183)((166...167), (167...183), nil, "$global_variable"), - SymbolNode(185...188)((185...186), (186...188), nil, "$_"), - SymbolNode(190...194)((190...191), (191...194), nil, "$-w"), - SymbolNode(196...207)((196...197), (197...207), nil, "$LOAD_PATH"), - SymbolNode(209...216)((209...210), (210...216), nil, "$stdin"), - SymbolNode(218...226)((218...219), (219...226), nil, "$stdout"), - SymbolNode(228...236)((228...229), (229...236), nil, "$stderr"), - SymbolNode(238...241)((238...239), (239...241), nil, "$!"), - SymbolNode(243...246)((243...244), (244...246), nil, "$?"), - SymbolNode(248...251)((248...249), (249...251), nil, "$~"), - SymbolNode(253...256)((253...254), (254...256), nil, "$&"), - SymbolNode(258...261)((258...259), (259...261), nil, "$`"), - SymbolNode(263...266)((263...264), (264...266), nil, "$'"), - SymbolNode(268...271)((268...269), (269...271), nil, "$+"), - SymbolNode(273...276)((273...274), (274...276), nil, "$:"), - SymbolNode(278...281)((278...279), (279...281), nil, "$;"), - SymbolNode(283...290)((283...284), (284...290), nil, "$DEBUG"), - SymbolNode(292...302)((292...293), (293...302), nil, "$FILENAME"), - SymbolNode(304...307)((304...305), (305...307), nil, "$0"), - SymbolNode(309...313)((309...310), (310...313), nil, "$-0"), - SymbolNode(315...332)((315...316), (316...332), nil, "$LOADED_FEATURES"), - SymbolNode(334...343)((334...335), (335...343), nil, "$VERBOSE"), - SymbolNode(345...349)((345...346), (346...349), nil, "$-K")] - ) -) diff --git a/test/yarp/snapshots/hashes.txt b/test/yarp/snapshots/hashes.txt deleted file mode 100644 index cfd3e04f163653..00000000000000 --- a/test/yarp/snapshots/hashes.txt +++ /dev/null @@ -1,110 +0,0 @@ -ProgramNode(0...120)( - [], - StatementsNode(0...120)( - [HashNode(0...2)((0...1), [], (1...2)), - HashNode(4...7)((4...5), [], (6...7)), - HashNode(9...27)( - (9...10), - [AssocNode(11...17)( - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"), - CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "b"), - (13...15) - ), - AssocNode(19...25)( - CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "c"), - CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "d"), - (21...23) - )], - (26...27) - ), - HashNode(29...44)( - (29...30), - [AssocNode(31...37)( - CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 2, "a"), - CallNode(36...37)(nil, nil, (36...37), nil, nil, nil, nil, 2, "b"), - (33...35) - ), - AssocSplatNode(39...42)( - CallNode(41...42)(nil, nil, (41...42), nil, nil, nil, nil, 2, "c"), - (39...41) - )], - (43...44) - ), - HashNode(46...79)( - (46...47), - [AssocNode(54...58)( - SymbolNode(54...56)(nil, (54...55), (55...56), "a"), - CallNode(57...58)(nil, nil, (57...58), nil, nil, nil, nil, 2, "b"), - nil - ), - AssocNode(66...70)( - SymbolNode(66...68)(nil, (66...67), (67...68), "c"), - CallNode(69...70)(nil, nil, (69...70), nil, nil, nil, nil, 2, "d"), - nil - )], - (78...79) - ), - HashNode(81...106)( - (81...82), - [AssocNode(83...87)( - SymbolNode(83...85)(nil, (83...84), (84...85), "a"), - CallNode(86...87)(nil, nil, (86...87), nil, nil, nil, nil, 2, "b"), - nil - ), - AssocNode(89...93)( - SymbolNode(89...91)(nil, (89...90), (90...91), "c"), - CallNode(92...93)(nil, nil, (92...93), nil, nil, nil, nil, 2, "d"), - nil - ), - AssocSplatNode(95...98)( - CallNode(97...98)(nil, nil, (97...98), nil, nil, nil, nil, 2, "e"), - (95...97) - ), - AssocNode(100...104)( - SymbolNode(100...102)(nil, (100...101), (101...102), "f"), - CallNode(103...104)( - nil, - nil, - (103...104), - nil, - nil, - nil, - nil, - 2, - "g" - ), - nil - )], - (105...106) - ), - HashNode(108...120)( - (108...109), - [AssocNode(110...118)( - SymbolNode(110...114)((110...111), (111...112), (112...114), "a"), - CallNode(115...118)( - CallNode(116...118)( - nil, - nil, - (116...118), - nil, - nil, - nil, - nil, - 0, - "b?" - ), - nil, - (115...116), - nil, - nil, - nil, - nil, - 0, - "!" - ), - nil - )], - (119...120) - )] - ) -) diff --git a/test/yarp/snapshots/heredoc_with_escaped_newline_at_start.txt b/test/yarp/snapshots/heredoc_with_escaped_newline_at_start.txt deleted file mode 100644 index 43fa751526de80..00000000000000 --- a/test/yarp/snapshots/heredoc_with_escaped_newline_at_start.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...62)( - [], - StatementsNode(0...62)( - [CallNode(0...25)( - InterpolatedStringNode(0...9)((0...9), [], (27...34)), - (9...10), - (10...14), - nil, - ArgumentsNode(15...25)( - [RegularExpressionNode(15...21)( - (15...16), - (16...20), - (20...21), - "^ {", - 0 - ), - StringNode(23...25)((23...24), (24...24), (24...25), "")] - ), - nil, - nil, - 0, - "gsub" - ), - CallNode(37...62)( - InterpolatedStringNode(37...46)((37...46), [], (65...73)), - (46...47), - (47...51), - nil, - ArgumentsNode(52...62)( - [RegularExpressionNode(52...58)( - (52...53), - (53...57), - (57...58), - "^ {", - 0 - ), - StringNode(60...62)((60...61), (61...61), (61...62), "")] - ), - nil, - nil, - 0, - "gsub" - )] - ) -) diff --git a/test/yarp/snapshots/heredoc_with_trailing_newline.txt b/test/yarp/snapshots/heredoc_with_trailing_newline.txt deleted file mode 100644 index adaa524dda59f7..00000000000000 --- a/test/yarp/snapshots/heredoc_with_trailing_newline.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)([InterpolatedStringNode(0...6)((0...6), [], (7...10))]) -) diff --git a/test/yarp/snapshots/heredocs_nested.txt b/test/yarp/snapshots/heredocs_nested.txt deleted file mode 100644 index 750e5e4473fa36..00000000000000 --- a/test/yarp/snapshots/heredocs_nested.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [InterpolatedStringNode(0...7)( - (0...7), - [StringNode(8...12)(nil, (8...12), nil, "pre\n"), - EmbeddedStatementsNode(12...36)( - (12...14), - StatementsNode(15...21)( - [InterpolatedStringNode(15...21)( - (15...21), - [StringNode(22...30)(nil, (22...30), nil, " hello\n")], - (30...35) - )] - ), - (35...36) - ), - StringNode(36...42)(nil, (36...42), nil, "\n" + "post\n")], - (42...47) - )] - ) -) diff --git a/test/yarp/snapshots/heredocs_with_ignored_newlines.txt b/test/yarp/snapshots/heredocs_with_ignored_newlines.txt deleted file mode 100644 index 3fd8c7accb8386..00000000000000 --- a/test/yarp/snapshots/heredocs_with_ignored_newlines.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [InterpolatedStringNode(0...7)((0...7), [], (9...14)), - InterpolatedStringNode(15...23)( - (15...23), - [StringNode(25...100)( - nil, - (25...100), - nil, - "way over\n" + - "<" - ), - CallNode(111...117)( - IntegerNode(111...112)(), - nil, - (113...115), - nil, - ArgumentsNode(116...117)([IntegerNode(116...117)()]), - nil, - nil, - 0, - "==" - ), - CallNode(119...126)( - IntegerNode(119...120)(), - nil, - (121...124), - nil, - ArgumentsNode(125...126)([IntegerNode(125...126)()]), - nil, - nil, - 0, - "===" - ), - CallNode(128...134)( - IntegerNode(128...129)(), - nil, - (130...132), - nil, - ArgumentsNode(133...134)([IntegerNode(133...134)()]), - nil, - nil, - 0, - "=~" - ), - CallNode(136...141)( - IntegerNode(136...137)(), - nil, - (138...139), - nil, - ArgumentsNode(140...141)([IntegerNode(140...141)()]), - nil, - nil, - 0, - ">" - ), - CallNode(143...149)( - IntegerNode(143...144)(), - nil, - (145...147), - nil, - ArgumentsNode(148...149)([IntegerNode(148...149)()]), - nil, - nil, - 0, - ">=" - ), - CallNode(151...157)( - IntegerNode(151...152)(), - nil, - (153...155), - nil, - ArgumentsNode(156...157)([IntegerNode(156...157)()]), - nil, - nil, - 0, - ">>" - ), - CallNode(159...164)( - IntegerNode(159...160)(), - nil, - (161...162), - nil, - ArgumentsNode(163...164)([IntegerNode(163...164)()]), - nil, - nil, - 0, - "^" - ), - CallNode(166...171)( - IntegerNode(166...167)(), - nil, - (168...169), - nil, - ArgumentsNode(170...171)([IntegerNode(170...171)()]), - nil, - nil, - 0, - "|" - ), - AndNode(173...179)( - IntegerNode(173...174)(), - IntegerNode(178...179)(), - (175...177) - ), - AndNode(181...188)( - IntegerNode(181...182)(), - IntegerNode(187...188)(), - (183...186) - ), - CallNode(190...200)( - IntegerNode(190...191)(), - nil, - (192...193), - nil, - ArgumentsNode(194...200)( - [CallNode(194...200)( - IntegerNode(194...195)(), - nil, - (196...198), - nil, - ArgumentsNode(199...200)([IntegerNode(199...200)()]), - nil, - nil, - 0, - "**" - )] - ), - nil, - nil, - 0, - "*" - ), - CallNode(202...211)( - CallNode(202...207)( - IntegerNode(202...203)(), - nil, - (204...205), - nil, - ArgumentsNode(206...207)([IntegerNode(206...207)()]), - nil, - nil, - 0, - "*" - ), - nil, - (208...209), - nil, - ArgumentsNode(210...211)([IntegerNode(210...211)()]), - nil, - nil, - 0, - "+" - ), - OrNode(213...219)( - IntegerNode(213...214)(), - IntegerNode(218...219)(), - (215...217) - ), - OrNode(221...227)( - IntegerNode(221...222)(), - IntegerNode(226...227)(), - (223...225) - ), - CallNode(229...238)( - IntegerNode(229...230)(), - nil, - (231...232), - nil, - ArgumentsNode(233...238)( - [CallNode(233...238)( - IntegerNode(233...234)(), - nil, - (235...236), - nil, - ArgumentsNode(237...238)([IntegerNode(237...238)()]), - nil, - nil, - 0, - "*" - )] - ), - nil, - nil, - 0, - "+" - ), - ParenthesesNode(240...247)( - StatementsNode(241...246)( - [CallNode(241...246)( - IntegerNode(241...242)(), - nil, - (243...244), - nil, - ArgumentsNode(245...246)([IntegerNode(245...246)()]), - nil, - nil, - 0, - "+" - )] - ), - (240...241), - (246...247) - )] - ) -) diff --git a/test/yarp/snapshots/keyword_method_names.txt b/test/yarp/snapshots/keyword_method_names.txt deleted file mode 100644 index 293164bb1e8371..00000000000000 --- a/test/yarp/snapshots/keyword_method_names.txt +++ /dev/null @@ -1,151 +0,0 @@ -ProgramNode(0...185)( - [], - StatementsNode(0...185)( - [DefNode(0...11)( - :def, - (4...7), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (8...11) - ), - DefNode(13...32)( - :ensure, - (22...28), - SelfNode(17...21)(), - nil, - nil, - [], - (13...16), - (21...22), - nil, - nil, - nil, - (29...32) - ), - CallNode(34...68)( - nil, - nil, - (34...41), - nil, - ArgumentsNode(42...68)( - [DefNode(42...68)( - :foo, - (46...49), - nil, - nil, - StatementsNode(52...64)( - [CallNode(52...64)( - nil, - nil, - (52...55), - nil, - nil, - nil, - BlockNode(56...64)([], nil, nil, (56...58), (61...64)), - 0, - "bar" - )] - ), - [], - (42...45), - nil, - nil, - nil, - nil, - (65...68) - )] - ), - nil, - nil, - 0, - "private" - ), - DefNode(70...89)( - :m, - (74...75), - nil, - ParametersNode(76...84)( - [RequiredParameterNode(76...77)(:a)], - [], - [], - nil, - [], - NoKeywordsParameterNode(79...84)((79...81), (81...84)), - nil - ), - nil, - [:a], - (70...73), - nil, - (75...76), - (84...85), - nil, - (86...89) - ), - DefNode(91...113)( - :a, - (108...109), - SourceEncodingNode(95...107)(), - nil, - nil, - [], - (91...94), - (107...108), - nil, - nil, - nil, - (110...113) - ), - StringNode(115...121)((115...117), (117...120), (120...121), "abc"), - StringNode(123...129)((123...125), (125...128), (128...129), "abc"), - DefNode(131...149)( - :a, - (144...145), - SourceFileNode(135...143)("keyword_method_names.txt"), - nil, - nil, - [], - (131...134), - (143...144), - nil, - nil, - nil, - (146...149) - ), - DefNode(151...169)( - :a, - (164...165), - SourceLineNode(155...163)(), - nil, - nil, - [], - (151...154), - (163...164), - nil, - nil, - nil, - (166...169) - ), - DefNode(171...185)( - :a, - (180...181), - NilNode(175...178)(), - nil, - nil, - [], - (171...174), - (178...180), - nil, - nil, - nil, - (182...185) - )] - ) -) diff --git a/test/yarp/snapshots/keywords.txt b/test/yarp/snapshots/keywords.txt deleted file mode 100644 index c949b291aa2d9b..00000000000000 --- a/test/yarp/snapshots/keywords.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...51)( - [], - StatementsNode(0...51)( - [RedoNode(0...4)(), - RetryNode(6...11)(), - SelfNode(13...17)(), - SourceEncodingNode(19...31)(), - SourceFileNode(33...41)("keywords.txt"), - SourceLineNode(43...51)()] - ) -) diff --git a/test/yarp/snapshots/lambda.txt b/test/yarp/snapshots/lambda.txt deleted file mode 100644 index 01846d7c147d46..00000000000000 --- a/test/yarp/snapshots/lambda.txt +++ /dev/null @@ -1,188 +0,0 @@ -ProgramNode(0...92)( - [], - StatementsNode(0...92)( - [LambdaNode(0...14)( - [:foo], - (0...2), - (12...13), - (13...14), - BlockParametersNode(2...11)( - ParametersNode(6...9)( - [RequiredParameterNode(6...9)(:foo)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (2...3), - (10...11) - ), - nil - ), - LambdaNode(16...34)( - [:x], - (16...18), - (31...32), - (33...34), - BlockParametersNode(18...30)( - ParametersNode(19...29)( - [], - [], - [], - nil, - [KeywordParameterNode(19...29)( - :x, - (19...21), - InterpolatedStringNode(22...29)( - (22...23), - [StringNode(23...24)(nil, (23...24), nil, "b"), - EmbeddedStatementsNode(24...28)( - (24...26), - StatementsNode(26...27)( - [CallNode(26...27)( - nil, - nil, - (26...27), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - (27...28) - )], - (28...29) - ) - )], - nil, - nil - ), - [], - (18...19), - (29...30) - ), - nil - ), - LambdaNode(36...51)( - [:a], - (36...38), - (49...50), - (50...51), - BlockParametersNode(38...48)( - ParametersNode(39...47)( - [], - [], - [], - nil, - [KeywordParameterNode(39...47)( - :a, - (39...41), - CallNode(42...47)( - CallNode(42...43)( - nil, - nil, - (42...43), - nil, - nil, - nil, - nil, - 2, - "b" - ), - nil, - (44...45), - nil, - ArgumentsNode(46...47)([IntegerNode(46...47)()]), - nil, - nil, - 0, - "*" - ) - )], - nil, - nil - ), - [], - (38...39), - (47...48) - ), - nil - ), - LambdaNode(53...72)( - [:foo], - (53...55), - (66...68), - (69...72), - BlockParametersNode(56...65)( - ParametersNode(56...65)( - [], - [OptionalParameterNode(56...65)( - :foo, - (56...59), - (60...61), - CallNode(62...65)( - nil, - nil, - (62...65), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - [], - nil, - [], - nil, - nil - ), - [], - nil, - nil - ), - nil - ), - LambdaNode(74...92)( - [:foo], - (74...76), - (86...88), - (89...92), - BlockParametersNode(77...85)( - ParametersNode(77...85)( - [], - [], - [], - nil, - [KeywordParameterNode(77...85)( - :foo, - (77...81), - CallNode(82...85)( - nil, - nil, - (82...85), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - nil, - nil - ), - [], - nil, - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/method_calls.txt b/test/yarp/snapshots/method_calls.txt deleted file mode 100644 index 37f03ef25f572c..00000000000000 --- a/test/yarp/snapshots/method_calls.txt +++ /dev/null @@ -1,1656 +0,0 @@ -ProgramNode(0...1237)( - [], - StatementsNode(0...1237)( - [CallNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...7), - nil, - ArgumentsNode(8...14)( - [StringNode(8...14)((8...10), (10...13), (13...14), "baz")] - ), - nil, - nil, - 0, - "bar" - ), - CallNode(16...25)( - CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "a"), - (17...18), - (18...19), - (19...20), - ArgumentsNode(20...24)( - [CallNode(20...21)(nil, nil, (20...21), nil, nil, nil, nil, 2, "c"), - CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "d")] - ), - (24...25), - nil, - 0, - "b" - ), - CallNode(27...32)( - CallNode(27...28)(nil, nil, (27...28), nil, nil, nil, nil, 2, "a"), - (28...29), - (29...30), - (30...31), - nil, - (31...32), - nil, - 0, - "b" - ), - CallNode(34...52)( - CallNode(34...44)( - CallNode(34...37)(nil, nil, (34...37), nil, nil, nil, nil, 2, "foo"), - (40...41), - (41...44), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - (47...49), - (49...52), - nil, - nil, - nil, - nil, - 1, - "baz" - ), - CallNode(54...56)(nil, nil, (54...56), nil, nil, nil, nil, 0, "a!"), - CallNode(58...62)( - CallNode(58...59)(nil, nil, (58...59), nil, nil, nil, nil, 2, "a"), - (59...60), - nil, - (60...61), - nil, - (61...62), - nil, - 0, - "call" - ), - CallNode(64...75)( - CallNode(64...65)(nil, nil, (64...65), nil, nil, nil, nil, 2, "a"), - (65...66), - nil, - (66...67), - ArgumentsNode(67...74)( - [IntegerNode(67...68)(), - IntegerNode(70...71)(), - IntegerNode(73...74)()] - ), - (74...75), - nil, - 0, - "call" - ), - CallNode(77...81)( - CallNode(77...78)(nil, nil, (77...78), nil, nil, nil, nil, 2, "a"), - (78...80), - (80...81), - nil, - nil, - nil, - nil, - 0, - "b" - ), - CallNode(83...89)( - CallNode(83...84)(nil, nil, (83...84), nil, nil, nil, nil, 2, "a"), - (84...86), - (86...87), - nil, - ArgumentsNode(88...89)( - [CallNode(88...89)(nil, nil, (88...89), nil, nil, nil, nil, 2, "c")] - ), - nil, - nil, - 0, - "b" - ), - CallNode(91...102)( - CallNode(91...94)(nil, nil, (91...94), nil, nil, nil, nil, 2, "foo"), - (94...95), - (95...98), - nil, - ArgumentsNode(101...102)([IntegerNode(101...102)()]), - nil, - nil, - 0, - "bar=" - ), - CallNode(104...106)(nil, nil, (104...106), nil, nil, nil, nil, 0, "a?"), - CallNode(108...117)( - nil, - nil, - (108...109), - (109...110), - ArgumentsNode(110...116)( - [BlockArgumentNode(110...116)( - CallNode(111...116)( - nil, - nil, - (111...116), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (110...111) - )] - ), - (116...117), - nil, - 0, - "a" - ), - CallNode(119...130)( - nil, - nil, - (119...120), - (120...121), - ArgumentsNode(121...129)( - [KeywordHashNode(121...129)( - [AssocSplatNode(121...129)( - CallNode(123...129)( - nil, - nil, - (123...129), - nil, - nil, - nil, - nil, - 2, - "kwargs" - ), - (121...123) - )] - )] - ), - (129...130), - nil, - 0, - "a" - ), - CallNode(132...137)( - CallNode(132...135)( - CallNode(132...133)( - nil, - nil, - (132...133), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (133...134), - (134...135), - nil, - nil, - nil, - nil, - 0, - "b" - ), - (135...136), - (136...137), - nil, - nil, - nil, - nil, - 0, - "c" - ), - CallNode(139...146)( - nil, - nil, - (139...140), - (140...141), - ArgumentsNode(141...145)( - [CallNode(141...142)( - nil, - nil, - (141...142), - nil, - nil, - nil, - nil, - 2, - "b" - ), - CallNode(144...145)( - nil, - nil, - (144...145), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (145...146), - nil, - 0, - "a" - ), - CallNode(148...151)( - nil, - nil, - (148...149), - (149...150), - nil, - (150...151), - nil, - 0, - "a" - ), - CallNode(153...161)( - nil, - nil, - (153...154), - (154...155), - ArgumentsNode(155...160)( - [SplatNode(155...160)( - (155...156), - CallNode(156...160)( - nil, - nil, - (156...160), - nil, - nil, - nil, - nil, - 2, - "args" - ) - )] - ), - (160...161), - nil, - 0, - "a" - ), - CallNode(163...169)( - nil, - nil, - (163...164), - nil, - ArgumentsNode(165...169)( - [CallNode(165...166)( - nil, - nil, - (165...166), - nil, - nil, - nil, - nil, - 2, - "b" - ), - CallNode(168...169)( - nil, - nil, - (168...169), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - nil, - nil, - 0, - "a" - ), - CallNode(171...179)( - CallNode(171...172)(nil, nil, (171...172), nil, nil, nil, nil, 2, "a"), - (172...173), - (173...174), - nil, - ArgumentsNode(175...179)( - [CallNode(175...176)( - nil, - nil, - (175...176), - nil, - nil, - nil, - nil, - 2, - "c" - ), - CallNode(178...179)( - nil, - nil, - (178...179), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "b" - ), - MultiWriteNode(181...204)( - [CallNode(181...188)( - CallNode(181...184)( - nil, - nil, - (181...184), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (184...185), - (185...188), - nil, - nil, - nil, - nil, - 0, - "foo=" - ), - CallNode(190...197)( - CallNode(190...193)( - nil, - nil, - (190...193), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (193...194), - (194...197), - nil, - nil, - nil, - nil, - 0, - "bar=" - )], - nil, - nil, - (198...199), - ArrayNode(200...204)( - [IntegerNode(200...201)(), IntegerNode(203...204)()], - nil, - nil - ) - ), - CallNode(206...210)( - CallNode(206...207)(nil, nil, (206...207), nil, nil, nil, nil, 2, "a"), - (207...209), - (209...210), - nil, - nil, - nil, - nil, - 1, - "b" - ), - CallNode(212...217)( - CallNode(212...213)(nil, nil, (212...213), nil, nil, nil, nil, 2, "a"), - (213...215), - nil, - (215...216), - nil, - (216...217), - nil, - 1, - "call" - ), - CallNode(219...226)( - CallNode(219...220)(nil, nil, (219...220), nil, nil, nil, nil, 2, "a"), - (220...222), - (222...223), - (223...224), - ArgumentsNode(224...225)( - [CallNode(224...225)( - nil, - nil, - (224...225), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (225...226), - nil, - 1, - "b" - ), - CallNode(228...234)( - CallNode(228...229)(nil, nil, (228...229), nil, nil, nil, nil, 2, "a"), - (229...231), - (231...232), - (232...233), - nil, - (233...234), - nil, - 1, - "b" - ), - IfNode(236...269)( - (247...249), - AndNode(250...269)( - OrNode(250...261)( - CallNode(250...254)( - nil, - nil, - (250...254), - nil, - nil, - nil, - nil, - 0, - "bar?" - ), - CallNode(258...261)( - nil, - nil, - (258...261), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (255...257) - ), - CallNode(266...269)( - nil, - nil, - (266...269), - nil, - nil, - nil, - nil, - 2, - "qux" - ), - (262...265) - ), - StatementsNode(236...246)( - [CallNode(236...246)( - nil, - nil, - (236...239), - nil, - ArgumentsNode(240...246)( - [SymbolNode(240...242)((240...241), (241...242), nil, "a"), - SymbolNode(244...246)((244...245), (245...246), nil, "b")] - ), - nil, - nil, - 0, - "foo" - )] - ), - nil, - nil - ), - CallNode(271...286)( - nil, - nil, - (271...274), - (274...275), - ArgumentsNode(275...284)( - [SymbolNode(275...277)((275...276), (276...277), nil, "a"), - SymbolNode(282...284)((282...283), (283...284), nil, "b")] - ), - (285...286), - nil, - 0, - "foo" - ), - CallNode(288...298)( - nil, - nil, - (288...291), - (291...292), - ArgumentsNode(292...297)( - [SplatNode(292...297)( - (292...293), - CallNode(293...297)( - nil, - nil, - (293...297), - nil, - nil, - nil, - nil, - 2, - "rest" - ) - )] - ), - (297...298), - nil, - 0, - "foo" - ), - CallNode(300...340)( - nil, - nil, - (300...303), - (303...304), - ArgumentsNode(304...339)( - [SymbolNode(304...306)((304...305), (305...306), nil, "a"), - KeywordHashNode(308...332)( - [AssocNode(308...322)( - SymbolNode(308...310)((308...309), (309...310), nil, "h"), - ArrayNode(314...322)( - [SymbolNode(315...317)((315...316), (316...317), nil, "x"), - SymbolNode(319...321)((319...320), (320...321), nil, "y")], - (314...315), - (321...322) - ), - (311...313) - ), - AssocNode(324...332)( - SymbolNode(324...326)((324...325), (325...326), nil, "a"), - SymbolNode(330...332)((330...331), (331...332), nil, "b"), - (327...329) - )] - ), - BlockArgumentNode(334...339)( - SymbolNode(335...339)((335...336), (336...339), nil, "bar"), - (334...335) - )] - ), - (339...340), - nil, - 0, - "foo" - ), - CallNode(342...391)( - nil, - nil, - (342...344), - nil, - ArgumentsNode(345...391)( - [IntegerNode(345...348)(), - HashNode(350...391)( - (350...351), - [AssocNode(352...369)( - SymbolNode(352...358)((352...353), (353...358), nil, "there"), - SymbolNode(362...369)((362...363), (363...369), nil, "friend"), - (359...361) - ), - AssocSplatNode(371...375)( - HashNode(373...375)((373...374), [], (374...375)), - (371...373) - ), - AssocNode(377...389)( - SymbolNode(377...384)(nil, (377...383), (383...384), "whatup"), - SymbolNode(385...389)((385...386), (386...389), nil, "dog"), - nil - )], - (390...391) - )] - ), - nil, - nil, - 0, - "hi" - ), - CallNode(393...429)( - nil, - nil, - (393...396), - nil, - ArgumentsNode(397...408)( - [SymbolNode(397...399)((397...398), (398...399), nil, "a"), - KeywordHashNode(401...408)( - [AssocNode(401...408)( - SymbolNode(401...403)(nil, (401...402), (402...403), "b"), - TrueNode(404...408)(), - nil - )] - )] - ), - nil, - BlockNode(409...429)( - [:a, :b], - BlockParametersNode(412...418)( - ParametersNode(413...417)( - [RequiredParameterNode(413...414)(:a), - RequiredParameterNode(416...417)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (412...413), - (417...418) - ), - StatementsNode(419...425)( - [CallNode(419...425)( - nil, - nil, - (419...423), - nil, - ArgumentsNode(424...425)( - [LocalVariableReadNode(424...425)(:a, 0)] - ), - nil, - nil, - 0, - "puts" - )] - ), - (409...411), - (426...429) - ), - 0, - "foo" - ), - CallNode(431...448)( - nil, - nil, - (431...433), - nil, - ArgumentsNode(434...448)( - [KeywordHashNode(434...448)( - [AssocNode(434...448)( - SymbolNode(434...440)(nil, (434...439), (439...440), "there"), - SymbolNode(441...448)((441...442), (442...448), nil, "friend"), - nil - )] - )] - ), - nil, - nil, - 0, - "hi" - ), - CallNode(450...490)( - nil, - nil, - (450...452), - nil, - ArgumentsNode(453...490)( - [KeywordHashNode(453...490)( - [AssocNode(453...470)( - SymbolNode(453...459)((453...454), (454...459), nil, "there"), - SymbolNode(463...470)((463...464), (464...470), nil, "friend"), - (460...462) - ), - AssocSplatNode(472...476)( - HashNode(474...476)((474...475), [], (475...476)), - (472...474) - ), - AssocNode(478...490)( - SymbolNode(478...485)(nil, (478...484), (484...485), "whatup"), - SymbolNode(486...490)((486...487), (487...490), nil, "dog"), - nil - )] - )] - ), - nil, - nil, - 0, - "hi" - ), - CallNode(492...533)( - nil, - nil, - (492...494), - (494...495), - ArgumentsNode(495...532)( - [KeywordHashNode(495...532)( - [AssocNode(495...512)( - SymbolNode(495...501)((495...496), (496...501), nil, "there"), - SymbolNode(505...512)((505...506), (506...512), nil, "friend"), - (502...504) - ), - AssocSplatNode(514...518)( - HashNode(516...518)((516...517), [], (517...518)), - (514...516) - ), - AssocNode(520...532)( - SymbolNode(520...527)(nil, (520...526), (526...527), "whatup"), - SymbolNode(528...532)((528...529), (529...532), nil, "dog"), - nil - )] - )] - ), - (532...533), - nil, - 0, - "hi" - ), - CallNode(535...571)( - nil, - nil, - (535...538), - (538...539), - ArgumentsNode(539...570)( - [HashNode(539...561)( - (539...540), - [AssocNode(541...548)( - SymbolNode(541...543)(nil, (541...542), (542...543), "a"), - TrueNode(544...548)(), - nil - ), - AssocNode(550...558)( - SymbolNode(550...552)(nil, (550...551), (551...552), "b"), - FalseNode(553...558)(), - nil - )], - (560...561) - ), - BlockArgumentNode(563...570)( - SymbolNode(564...570)((564...565), (565...570), nil, "block"), - (563...564) - )] - ), - (570...571), - nil, - 0, - "foo" - ), - CallNode(573...593)( - nil, - nil, - (573...575), - nil, - ArgumentsNode(576...593)( - [KeywordHashNode(576...593)( - [AssocNode(576...593)( - SymbolNode(576...582)((576...577), (577...582), nil, "there"), - SymbolNode(586...593)((586...587), (587...593), nil, "friend"), - (583...585) - )] - )] - ), - nil, - nil, - 0, - "hi" - ), - CallNode(595...608)( - nil, - nil, - (595...598), - (598...599), - ArgumentsNode(599...605)( - [SymbolNode(599...601)((599...600), (600...601), nil, "a"), - SymbolNode(603...605)((603...604), (604...605), nil, "b")] - ), - (607...608), - nil, - 0, - "foo" - ), - CallNode(610...627)( - nil, - nil, - (610...613), - (613...614), - ArgumentsNode(615...624)( - [SymbolNode(615...617)((615...616), (616...617), nil, "a"), - KeywordHashNode(619...624)( - [AssocNode(619...624)( - SymbolNode(619...621)(nil, (619...620), (620...621), "b"), - SymbolNode(622...624)((622...623), (623...624), nil, "c"), - nil - )] - )] - ), - (626...627), - nil, - 0, - "foo" - ), - CallNode(629...640)( - nil, - nil, - (629...632), - nil, - ArgumentsNode(633...640)( - [BlockArgumentNode(633...640)( - SymbolNode(634...640)((634...635), (635...640), nil, "block"), - (633...634) - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(642...672)( - nil, - nil, - (642...645), - nil, - ArgumentsNode(646...672)( - [KeywordHashNode(646...663)( - [AssocNode(646...653)( - SymbolNode(646...648)(nil, (646...647), (647...648), "a"), - TrueNode(649...653)(), - nil - ), - AssocNode(655...663)( - SymbolNode(655...657)(nil, (655...656), (656...657), "b"), - FalseNode(658...663)(), - nil - )] - ), - BlockArgumentNode(665...672)( - SymbolNode(666...672)((666...667), (667...672), nil, "block"), - (665...666) - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(674...695)( - nil, - nil, - (674...683), - nil, - ArgumentsNode(684...695)( - [IntegerNode(684...685)(), - KeywordHashNode(687...695)( - [AssocNode(687...695)( - SymbolNode(687...693)(nil, (687...692), (692...693), "kwarg"), - IntegerNode(694...695)(), - nil - )] - )] - ), - nil, - nil, - 0, - "some_func" - ), - CallNode(697...715)( - ConstantReadNode(697...703)(:Kernel), - (703...704), - (704...711), - (711...712), - ArgumentsNode(712...714)([IntegerNode(712...714)()]), - (714...715), - nil, - 0, - "Integer" - ), - CallNode(717...727)( - CallNode(717...718)(nil, nil, (717...718), nil, nil, nil, nil, 2, "x"), - (718...719), - (719...723), - nil, - nil, - nil, - BlockNode(724...727)([], nil, nil, (724...725), (726...727)), - 0, - "each" - ), - CallNode(729...743)( - CallNode(729...732)( - nil, - nil, - (729...732), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (732...733), - (733...736), - nil, - nil, - nil, - BlockNode(737...743)( - [], - nil, - StatementsNode(739...741)([BackReferenceReadNode(739...741)()]), - (737...738), - (742...743) - ), - 0, - "map" - ), - CallNode(745...757)( - ConstantPathNode(745...749)( - ConstantReadNode(745...746)(:A), - ConstantReadNode(748...749)(:B), - (746...748) - ), - (749...751), - (751...752), - nil, - ArgumentsNode(753...757)( - [SymbolNode(753...757)((753...754), (754...757), nil, "foo")] - ), - nil, - nil, - 0, - "C" - ), - CallNode(759...772)( - ConstantPathNode(759...763)( - ConstantReadNode(759...760)(:A), - ConstantReadNode(762...763)(:B), - (760...762) - ), - (763...765), - (765...766), - (766...767), - ArgumentsNode(767...771)( - [SymbolNode(767...771)((767...768), (768...771), nil, "foo")] - ), - (771...772), - nil, - 0, - "C" - ), - CallNode(774...791)( - ConstantPathNode(774...778)( - ConstantReadNode(774...775)(:A), - ConstantReadNode(777...778)(:B), - (775...777) - ), - (778...780), - (780...781), - (781...782), - ArgumentsNode(782...786)( - [SymbolNode(782...786)((782...783), (783...786), nil, "foo")] - ), - (786...787), - BlockNode(788...791)([], nil, nil, (788...789), (790...791)), - 0, - "C" - ), - CallNode(793...805)( - nil, - nil, - (793...796), - (796...797), - ArgumentsNode(797...804)( - [KeywordHashNode(797...804)( - [AssocNode(797...804)( - SymbolNode(797...801)( - (797...798), - (798...799), - (799...801), - "a" - ), - IntegerNode(802...804)(), - nil - )] - )] - ), - (804...805), - nil, - 0, - "foo" - ), - CallNode(807...835)( - nil, - nil, - (807...810), - nil, - ArgumentsNode(811...835)( - [KeywordHashNode(811...835)( - [AssocNode(811...835)( - SymbolNode(811...815)(nil, (811...814), (814...815), "bar"), - HashNode(816...835)( - (816...817), - [AssocNode(818...833)( - SymbolNode(818...822)( - nil, - (818...821), - (821...822), - "baz" - ), - CallNode(823...833)( - nil, - nil, - (823...826), - nil, - nil, - nil, - BlockNode(827...833)( - [], - nil, - nil, - (827...829), - (830...833) - ), - 0, - "qux" - ), - nil - )], - (834...835) - ), - nil - )] - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(837...861)( - nil, - nil, - (837...840), - nil, - ArgumentsNode(841...861)( - [KeywordHashNode(841...861)( - [AssocNode(841...861)( - SymbolNode(841...845)(nil, (841...844), (844...845), "bar"), - HashNode(846...861)( - (846...847), - [AssocSplatNode(848...859)( - CallNode(850...859)( - nil, - nil, - (850...852), - nil, - nil, - nil, - BlockNode(853...859)( - [], - nil, - nil, - (853...855), - (856...859) - ), - 0, - "kw" - ), - (848...850) - )], - (860...861) - ), - nil - )] - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(863...899)( - nil, - nil, - (863...866), - nil, - ArgumentsNode(867...892)( - [InterpolatedStringNode(867...892)( - (867...868), - [EmbeddedStatementsNode(868...891)( - (868...870), - StatementsNode(870...890)( - [CallNode(870...890)( - CallNode(870...873)( - nil, - nil, - (870...873), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (873...874), - (874...877), - nil, - nil, - nil, - BlockNode(878...890)( - [], - nil, - StatementsNode(881...886)( - [StringNode(881...886)( - (881...882), - (882...885), - (885...886), - "baz" - )] - ), - (878...880), - (887...890) - ), - 0, - "map" - )] - ), - (890...891) - )], - (891...892) - )] - ), - nil, - BlockNode(893...899)([], nil, nil, (893...895), (896...899)), - 0, - "foo" - ), - CallNode(901...929)( - nil, - nil, - (901...904), - nil, - ArgumentsNode(905...929)( - [ClassNode(905...929)( - [], - (905...910), - ConstantReadNode(911...914)(:Bar), - nil, - nil, - StatementsNode(915...925)( - [CallNode(915...925)( - nil, - nil, - (915...918), - nil, - nil, - nil, - BlockNode(919...925)([], nil, nil, (919...921), (922...925)), - 0, - "baz" - )] - ), - (926...929), - :Bar - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(931...960)( - nil, - nil, - (931...934), - nil, - ArgumentsNode(935...960)( - [ModuleNode(935...960)( - [], - (935...941), - ConstantReadNode(942...945)(:Bar), - StatementsNode(946...956)( - [CallNode(946...956)( - nil, - nil, - (946...949), - nil, - nil, - nil, - BlockNode(950...956)([], nil, nil, (950...952), (953...956)), - 0, - "baz" - )] - ), - (957...960), - :Bar - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(962...978)( - nil, - nil, - (962...965), - nil, - ArgumentsNode(966...978)( - [ArrayNode(966...978)( - [CallNode(967...977)( - nil, - nil, - (967...970), - nil, - nil, - nil, - BlockNode(971...977)([], nil, nil, (971...973), (974...977)), - 0, - "baz" - )], - (966...967), - (977...978) - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(980...1008)( - nil, - nil, - (980...981), - nil, - ArgumentsNode(982...1008)( - [BeginNode(982...1008)( - (982...987), - StatementsNode(988...1004)( - [CallNode(988...1004)( - IntegerNode(988...989)(), - (989...990), - (990...995), - nil, - nil, - nil, - BlockNode(996...1004)( - [], - nil, - StatementsNode(999...1000)([IntegerNode(999...1000)()]), - (996...998), - (1001...1004) - ), - 0, - "times" - )] - ), - nil, - nil, - nil, - (1005...1008) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(1010...1061)( - nil, - nil, - (1010...1013), - nil, - ArgumentsNode(1014...1061)( - [SymbolNode(1014...1016)((1014...1015), (1015...1016), nil, "a"), - IfNode(1020...1061)( - (1020...1022), - CallNode(1023...1024)( - nil, - nil, - (1023...1024), - nil, - nil, - nil, - nil, - 2, - "x" - ), - StatementsNode(1029...1055)( - [CallNode(1029...1055)( - nil, - nil, - (1029...1032), - nil, - nil, - nil, - BlockNode(1033...1055)( - [:a], - BlockParametersNode(1036...1039)( - ParametersNode(1037...1038)( - [RequiredParameterNode(1037...1038)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (1036...1037), - (1038...1039) - ), - StatementsNode(1046...1047)( - [LocalVariableReadNode(1046...1047)(:a, 0)] - ), - (1033...1035), - (1052...1055) - ), - 0, - "bar" - )] - ), - nil, - (1058...1061) - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(1063...1153)( - nil, - nil, - (1063...1066), - nil, - ArgumentsNode(1067...1153)( - [SymbolNode(1067...1069)((1067...1068), (1068...1069), nil, "a"), - WhileNode(1073...1117)( - (1073...1078), - (1114...1117), - CallNode(1079...1080)( - nil, - nil, - (1079...1080), - nil, - nil, - nil, - nil, - 2, - "x" - ), - StatementsNode(1085...1111)( - [CallNode(1085...1111)( - nil, - nil, - (1085...1088), - nil, - nil, - nil, - BlockNode(1089...1111)( - [:a], - BlockParametersNode(1092...1095)( - ParametersNode(1093...1094)( - [RequiredParameterNode(1093...1094)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (1092...1093), - (1094...1095) - ), - StatementsNode(1102...1103)( - [LocalVariableReadNode(1102...1103)(:a, 0)] - ), - (1089...1091), - (1108...1111) - ), - 0, - "bar" - )] - ), - 0 - ), - UntilNode(1121...1153)( - (1121...1126), - (1150...1153), - CallNode(1127...1128)( - nil, - nil, - (1127...1128), - nil, - nil, - nil, - nil, - 2, - "x" - ), - StatementsNode(1133...1147)( - [CallNode(1133...1147)( - nil, - nil, - (1133...1136), - nil, - nil, - nil, - BlockNode(1137...1147)( - [], - nil, - nil, - (1137...1139), - (1144...1147) - ), - 0, - "baz" - )] - ), - 0 - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(1155...1164)( - HashNode(1155...1157)((1155...1156), [], (1156...1157)), - nil, - (1158...1159), - nil, - ArgumentsNode(1160...1164)( - [CallNode(1160...1164)( - nil, - nil, - (1160...1161), - nil, - nil, - nil, - BlockNode(1162...1164)([], nil, nil, (1162...1163), (1163...1164)), - 0, - "A" - )] - ), - nil, - nil, - 0, - "+" - ), - CallNode(1166...1182)( - HashNode(1166...1168)((1166...1167), [], (1167...1168)), - nil, - (1169...1170), - nil, - ArgumentsNode(1171...1182)( - [CallNode(1171...1182)( - nil, - nil, - (1171...1172), - nil, - nil, - nil, - BlockNode(1173...1182)( - [:a], - BlockParametersNode(1175...1178)( - ParametersNode(1176...1177)( - [RequiredParameterNode(1176...1177)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (1175...1176), - (1177...1178) - ), - StatementsNode(1179...1180)( - [LocalVariableReadNode(1179...1180)(:a, 0)] - ), - (1173...1174), - (1181...1182) - ), - 0, - "A" - )] - ), - nil, - nil, - 0, - "+" - ), - CallNode(1184...1195)( - CallNode(1184...1188)( - nil, - nil, - (1184...1185), - nil, - nil, - nil, - BlockNode(1186...1188)([], nil, nil, (1186...1187), (1187...1188)), - 0, - "A" - ), - nil, - (1189...1190), - nil, - ArgumentsNode(1191...1195)( - [CallNode(1191...1195)( - nil, - nil, - (1191...1192), - nil, - nil, - nil, - BlockNode(1193...1195)([], nil, nil, (1193...1194), (1194...1195)), - 0, - "A" - )] - ), - nil, - nil, - 0, - "+" - ), - CallNode(1197...1208)( - CallNode(1197...1200)( - nil, - nil, - (1197...1200), - nil, - nil, - nil, - nil, - 2, - "lst" - ), - nil, - (1201...1203), - nil, - ArgumentsNode(1204...1208)( - [CallNode(1204...1208)( - nil, - nil, - (1204...1205), - nil, - nil, - nil, - BlockNode(1206...1208)([], nil, nil, (1206...1207), (1207...1208)), - 0, - "A" - )] - ), - nil, - nil, - 0, - "<<" - ), - InterpolatedStringNode(1210...1227)( - (1210...1211), - [EmbeddedStatementsNode(1211...1226)( - (1211...1213), - StatementsNode(1214...1224)( - [CallNode(1214...1224)( - nil, - nil, - (1214...1218), - nil, - ArgumentsNode(1219...1224)( - [ParenthesesNode(1219...1224)( - StatementsNode(1220...1223)( - [StringNode(1220...1223)( - (1220...1221), - (1221...1222), - (1222...1223), - " " - )] - ), - (1219...1220), - (1223...1224) - )] - ), - nil, - nil, - 0, - "join" - )] - ), - (1225...1226) - )], - (1226...1227) - ), - InterpolatedStringNode(1229...1237)( - (1229...1230), - [EmbeddedStatementsNode(1230...1236)( - (1230...1232), - StatementsNode(1232...1235)( - [ParenthesesNode(1232...1235)( - StatementsNode(1233...1234)( - [CallNode(1233...1234)( - nil, - nil, - (1233...1234), - nil, - nil, - nil, - nil, - 2, - "v" - )] - ), - (1232...1233), - (1234...1235) - )] - ), - (1235...1236) - )], - (1236...1237) - )] - ) -) diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt deleted file mode 100644 index 3b0b5ca29997b4..00000000000000 --- a/test/yarp/snapshots/methods.txt +++ /dev/null @@ -1,1469 +0,0 @@ -ProgramNode(0...1194)( - [:a, :c], - StatementsNode(0...1194)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - ParametersNode(8...18)( - [RequiredDestructuredParameterNode(8...18)( - [RequiredParameterNode(9...12)(:bar), - RequiredParameterNode(14...17)(:baz)], - (8...9), - (17...18) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:bar, :baz], - (0...3), - nil, - (7...8), - (18...19), - nil, - (20...23) - ), - DefNode(25...74)( - :foo, - (29...32), - nil, - ParametersNode(33...69)( - [RequiredDestructuredParameterNode(33...43)( - [RequiredParameterNode(34...37)(:bar), - RequiredParameterNode(39...42)(:baz)], - (33...34), - (42...43) - )], - [OptionalParameterNode(45...57)( - :optional, - (45...53), - (54...55), - IntegerNode(56...57)() - )], - [RequiredDestructuredParameterNode(59...69)( - [RequiredParameterNode(60...63)(:bin), - RequiredParameterNode(65...68)(:bag)], - (59...60), - (68...69) - )], - nil, - [], - nil, - nil - ), - nil, - [:bar, :baz, :optional, :bin, :bag], - (25...28), - nil, - (32...33), - (69...70), - nil, - (71...74) - ), - DefNode(77...95)( - :a, - (81...82), - nil, - nil, - BeginNode(84...95)( - nil, - nil, - nil, - nil, - EnsureNode(84...95)((84...90), nil, (92...95)), - (92...95) - ), - [], - (77...80), - nil, - nil, - nil, - nil, - (92...95) - ), - DefNode(97...110)( - :a, - (105...106), - ParenthesesNode(101...104)( - CallNode(102...103)( - nil, - nil, - (102...103), - nil, - nil, - nil, - nil, - 2, - "b" - ), - (101...102), - (103...104) - ), - nil, - nil, - [], - (97...100), - (104...105), - nil, - nil, - nil, - (107...110) - ), - DefNode(112...126)( - :b, - (121...122), - ParenthesesNode(116...119)( - CallNode(117...118)( - nil, - nil, - (117...118), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (116...117), - (118...119) - ), - nil, - nil, - [], - (112...115), - (119...121), - nil, - nil, - nil, - (123...126) - ), - DefNode(128...143)( - :a, - (138...139), - FalseNode(132...137)(), - nil, - nil, - [], - (128...131), - (137...138), - nil, - nil, - nil, - (140...143) - ), - DefNode(145...159)( - :a, - (149...150), - nil, - ParametersNode(151...154)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(151...154)(), - nil - ), - nil, - [:"..."], - (145...148), - nil, - (150...151), - (154...155), - nil, - (156...159) - ), - DefNode(161...175)( - :a, - (170...171), - GlobalVariableReadNode(165...169)(:$var), - nil, - nil, - [], - (161...164), - (169...170), - nil, - nil, - nil, - (172...175) - ), - DefNode(177...188)( - :b, - (183...184), - CallNode(181...182)(nil, nil, (181...182), nil, nil, nil, nil, 2, "a"), - nil, - nil, - [], - (177...180), - (182...183), - nil, - nil, - nil, - (185...188) - ), - DefNode(190...204)( - :a, - (199...200), - InstanceVariableReadNode(194...198)(:@var), - nil, - nil, - [], - (190...193), - (198...199), - nil, - nil, - nil, - (201...204) - ), - DefNode(206...219)( - :a, - (210...211), - nil, - ParametersNode(212...214)( - [], - [], - [], - nil, - [KeywordParameterNode(212...214)(:b, (212...214), nil)], - nil, - nil - ), - nil, - [:b], - (206...209), - nil, - nil, - nil, - nil, - (216...219) - ), - StringNode(221...227)((221...223), (223...226), (226...227), "abc"), - DefNode(229...242)( - :a, - (233...234), - nil, - ParametersNode(235...237)( - [], - [], - [], - nil, - [KeywordParameterNode(235...237)(:b, (235...237), nil)], - nil, - nil - ), - nil, - [:b], - (229...232), - nil, - (234...235), - (237...238), - nil, - (239...242) - ), - DefNode(244...258)( - :a, - (248...249), - nil, - ParametersNode(250...253)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(250...253)(:b, (252...253), (250...252)), - nil - ), - nil, - [:b], - (244...247), - nil, - (249...250), - (253...254), - nil, - (255...258) - ), - DefNode(260...273)( - :a, - (264...265), - nil, - ParametersNode(266...268)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(266...268)(nil, nil, (266...268)), - nil - ), - nil, - [:**], - (260...263), - nil, - (265...266), - (268...269), - nil, - (270...273) - ), - LocalVariableWriteNode(275...280)( - :a, - 0, - (275...276), - IntegerNode(279...280)(), - (277...278) - ), - DefNode(282...291)( - :a, - (286...287), - nil, - nil, - nil, - [], - (282...285), - nil, - nil, - nil, - nil, - (288...291) - ), - DefNode(293...310)( - :a, - (297...298), - nil, - ParametersNode(299...306)( - [RequiredParameterNode(299...300)(:b), - RequiredParameterNode(302...303)(:c), - RequiredParameterNode(305...306)(:d)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:b, :c, :d], - (293...296), - nil, - nil, - nil, - nil, - (307...310) - ), - DefNode(312...325)( - :a, - (320...321), - NilNode(316...319)(), - nil, - nil, - [], - (312...315), - (319...320), - nil, - nil, - nil, - (322...325) - ), - DefNode(327...345)( - :a, - (331...332), - nil, - ParametersNode(333...341)( - [], - [], - [], - nil, - [KeywordParameterNode(333...335)(:b, (333...335), nil), - KeywordParameterNode(337...341)( - :c, - (337...339), - IntegerNode(340...341)() - )], - nil, - nil - ), - nil, - [:b, :c], - (327...330), - nil, - nil, - nil, - nil, - (342...345) - ), - DefNode(347...366)( - :a, - (351...352), - nil, - ParametersNode(353...361)( - [], - [], - [], - nil, - [KeywordParameterNode(353...355)(:b, (353...355), nil), - KeywordParameterNode(357...361)( - :c, - (357...359), - IntegerNode(360...361)() - )], - nil, - nil - ), - nil, - [:b, :c], - (347...350), - nil, - (352...353), - (361...362), - nil, - (363...366) - ), - DefNode(368...389)( - :a, - (372...373), - nil, - ParametersNode(374...384)( - [], - [], - [], - nil, - [KeywordParameterNode(374...380)( - :b, - (374...376), - IntegerNode(379...380)() - ), - KeywordParameterNode(382...384)(:c, (382...384), nil)], - nil, - nil - ), - nil, - [:b, :c], - (368...371), - nil, - (373...374), - (384...385), - nil, - (386...389) - ), - StringNode(391...397)((391...393), (393...396), (396...397), "abc"), - DefNode(399...421)( - :a, - (403...404), - nil, - ParametersNode(405...417)( - [], - [OptionalParameterNode(405...410)( - :b, - (405...406), - (407...408), - IntegerNode(409...410)() - ), - OptionalParameterNode(412...417)( - :c, - (412...413), - (414...415), - IntegerNode(416...417)() - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:b, :c], - (399...402), - nil, - nil, - nil, - nil, - (418...421) - ), - DefNode(423...434)( - :a, - (427...428), - nil, - nil, - nil, - [], - (423...426), - nil, - (428...429), - (429...430), - nil, - (431...434) - ), - DefNode(436...454)( - :a, - (440...441), - nil, - ParametersNode(442...450)( - [RequiredParameterNode(442...443)(:b)], - [OptionalParameterNode(445...450)( - :c, - (445...446), - (447...448), - IntegerNode(449...450)() - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:b, :c], - (436...439), - nil, - nil, - nil, - nil, - (451...454) - ), - DefNode(456...467)( - :a, - (460...461), - nil, - ParametersNode(462...463)( - [RequiredParameterNode(462...463)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:b], - (456...459), - nil, - nil, - nil, - nil, - (464...467) - ), - DefNode(469...501)( - :a, - (473...474), - nil, - nil, - BeginNode(476...501)( - nil, - nil, - RescueNode(476...482)((476...482), [], nil, nil, nil, nil), - ElseNode(484...496)((484...488), nil, (490...496)), - EnsureNode(490...501)((490...496), nil, (498...501)), - (498...501) - ), - [], - (469...472), - nil, - nil, - nil, - nil, - (498...501) - ), - DefNode(503...515)( - :a, - (507...508), - nil, - ParametersNode(509...511)( - [], - [], - [], - RestParameterNode(509...511)(:b, (510...511), (509...510)), - [], - nil, - nil - ), - nil, - [:b], - (503...506), - nil, - nil, - nil, - nil, - (512...515) - ), - DefNode(517...529)( - :a, - (521...522), - nil, - ParametersNode(523...524)( - [], - [], - [], - RestParameterNode(523...524)(nil, nil, (523...524)), - [], - nil, - nil - ), - nil, - [:*], - (517...520), - nil, - (522...523), - (524...525), - nil, - (526...529) - ), - DefNode(531...546)( - :a, - (535...536), - nil, - nil, - StatementsNode(537...542)( - [LocalVariableWriteNode(537...542)( - :b, - 0, - (537...538), - IntegerNode(541...542)(), - (539...540) - )] - ), - [:b], - (531...534), - nil, - nil, - nil, - nil, - (543...546) - ), - DefNode(548...562)( - :a, - (557...558), - SelfNode(552...556)(), - nil, - nil, - [], - (548...551), - (556...557), - nil, - nil, - nil, - (559...562) - ), - DefNode(564...578)( - :a, - (573...574), - TrueNode(568...572)(), - nil, - nil, - [], - (564...567), - (572...573), - nil, - nil, - nil, - (575...578) - ), - DefNode(580...589)( - :a, - (584...585), - nil, - nil, - nil, - [], - (580...583), - nil, - nil, - nil, - nil, - (586...589) - ), - DefNode(591...625)( - :hi, - (595...597), - nil, - nil, - StatementsNode(598...621)( - [IfNode(598...616)( - (609...611), - TrueNode(612...616)(), - StatementsNode(598...608)( - [ReturnNode(598...608)( - (598...604), - ArgumentsNode(605...608)( - [SymbolNode(605...608)((605...606), (606...608), nil, "hi")] - ) - )] - ), - nil, - nil - ), - SymbolNode(617...621)((617...618), (618...621), nil, "bye")] - ), - [], - (591...594), - nil, - nil, - nil, - nil, - (622...625) - ), - DefNode(627...638)( - :foo, - (631...634), - nil, - nil, - StatementsNode(637...638)([IntegerNode(637...638)()]), - [], - (627...630), - nil, - nil, - nil, - (635...636), - nil - ), - DefNode(639...650)( - :bar, - (643...646), - nil, - nil, - StatementsNode(649...650)([IntegerNode(649...650)()]), - [], - (639...642), - nil, - nil, - nil, - (647...648), - nil - ), - DefNode(652...670)( - :foo, - (656...659), - nil, - ParametersNode(660...663)( - [RequiredParameterNode(660...663)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(667...670)([IntegerNode(667...670)()]), - [:bar], - (652...655), - nil, - (659...660), - (663...664), - (665...666), - nil - ), - DefNode(672...685)( - :foo, - (676...679), - nil, - nil, - StatementsNode(682...685)([IntegerNode(682...685)()]), - [], - (672...675), - nil, - nil, - nil, - (680...681), - nil - ), - DefNode(687...706)( - :a, - (691...692), - nil, - ParametersNode(693...694)( - [], - [], - [], - RestParameterNode(693...694)(nil, nil, (693...694)), - [], - nil, - nil - ), - StatementsNode(697...701)( - [CallNode(697...701)( - nil, - nil, - (697...698), - (698...699), - ArgumentsNode(699...700)([SplatNode(699...700)((699...700), nil)]), - (700...701), - nil, - 0, - "b" - )] - ), - [:*], - (687...690), - nil, - (692...693), - (694...695), - nil, - (703...706) - ), - DefNode(708...731)( - :a, - (712...713), - nil, - ParametersNode(714...717)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(714...717)(), - nil - ), - StatementsNode(720...726)( - [CallNode(720...726)( - nil, - nil, - (720...721), - (721...722), - ArgumentsNode(722...725)([ForwardingArgumentsNode(722...725)()]), - (725...726), - nil, - 0, - "b" - )] - ), - [:"..."], - (708...711), - nil, - (713...714), - (717...718), - nil, - (728...731) - ), - DefNode(733...762)( - :a, - (737...738), - nil, - ParametersNode(739...742)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(739...742)(), - nil - ), - StatementsNode(745...757)( - [CallNode(745...757)( - nil, - nil, - (745...746), - (746...747), - ArgumentsNode(747...756)( - [IntegerNode(747...748)(), - IntegerNode(750...751)(), - ForwardingArgumentsNode(753...756)()] - ), - (756...757), - nil, - 0, - "b" - )] - ), - [:"..."], - (733...736), - nil, - (738...739), - (742...743), - nil, - (759...762) - ), - DefNode(764...781)( - :a, - (776...777), - ParenthesesNode(768...775)( - LocalVariableWriteNode(769...774)( - :c, - 0, - (769...770), - CallNode(773...774)( - nil, - nil, - (773...774), - nil, - nil, - nil, - nil, - 2, - "b" - ), - (771...772) - ), - (768...769), - (774...775) - ), - nil, - nil, - [], - (764...767), - (775...776), - nil, - nil, - nil, - (778...781) - ), - DefNode(783...795)( - :a, - (787...788), - nil, - ParametersNode(789...791)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(789...791)(:b, (790...791), (789...790)) - ), - nil, - [:b], - (783...786), - nil, - nil, - nil, - nil, - (792...795) - ), - DefNode(797...809)( - :a, - (801...802), - nil, - ParametersNode(803...804)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(803...804)(nil, nil, (803...804)) - ), - nil, - [:&], - (797...800), - nil, - (802...803), - (804...805), - nil, - (806...809) - ), - DefNode(811...826)( - :a, - (821...822), - ClassVariableReadNode(815...820)(:@@var), - nil, - nil, - [], - (811...814), - (820...821), - nil, - nil, - nil, - (823...826) - ), - DefNode(828...845)( - :C, - (840...841), - ParenthesesNode(832...839)( - LocalVariableWriteNode(833...838)( - :a, - 0, - (833...834), - CallNode(837...838)( - nil, - nil, - (837...838), - nil, - nil, - nil, - nil, - 2, - "b" - ), - (835...836) - ), - (832...833), - (838...839) - ), - nil, - nil, - [], - (828...831), - (839...840), - nil, - nil, - nil, - (842...845) - ), - DefNode(847...875)( - :Array_function, - (856...870), - SelfNode(851...855)(), - nil, - nil, - [], - (847...850), - (855...856), - nil, - nil, - nil, - (872...875) - ), - ConstantWriteNode(877...886)( - :Const, - (877...882), - IntegerNode(885...886)(), - (883...884) - ), - DefNode(888...903)( - :a, - (898...899), - ConstantReadNode(892...897)(:Const), - nil, - nil, - [], - (888...891), - (897...898), - nil, - nil, - nil, - (900...903) - ), - DefNode(905...936)( - :a, - (909...910), - nil, - ParametersNode(911...914)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(911...914)(), - nil - ), - StatementsNode(917...931)( - [InterpolatedStringNode(917...931)( - (917...918), - [StringNode(918...921)(nil, (918...921), nil, "foo"), - EmbeddedStatementsNode(921...930)( - (921...923), - StatementsNode(923...929)( - [CallNode(923...929)( - nil, - nil, - (923...924), - (924...925), - ArgumentsNode(925...928)( - [ForwardingArgumentsNode(925...928)()] - ), - (928...929), - nil, - 0, - "b" - )] - ), - (929...930) - )], - (930...931) - )] - ), - [:"..."], - (905...908), - nil, - (910...911), - (914...915), - nil, - (933...936) - ), - DefNode(938...980)( - :foo, - (942...945), - nil, - nil, - StatementsNode(948...976)( - [CallNode(948...976)( - HashNode(948...950)((948...949), [], (949...950)), - (950...951), - (951...956), - nil, - ArgumentsNode(957...976)( - [KeywordHashNode(957...976)( - [AssocSplatNode(957...962)( - CallNode(959...962)( - nil, - nil, - (959...962), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (957...959) - ), - AssocSplatNode(964...969)( - CallNode(966...969)( - nil, - nil, - (966...969), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (964...966) - ), - AssocSplatNode(971...976)( - CallNode(973...976)( - nil, - nil, - (973...976), - nil, - nil, - nil, - nil, - 2, - "qux" - ), - (971...973) - )] - )] - ), - nil, - nil, - 0, - "merge" - )] - ), - [], - (938...941), - nil, - nil, - nil, - nil, - (977...980) - ), - DefNode(982...1006)( - :bar, - (986...989), - nil, - ParametersNode(990...1001)( - [], - [], - [], - nil, - [KeywordParameterNode(990...1001)( - :a, - (990...992), - ParenthesesNode(993...1001)( - StatementsNode(994...1000)( - [RangeNode(994...1000)( - IntegerNode(994...995)(), - IntegerNode(998...1000)(), - (995...998), - 1 - )] - ), - (993...994), - (1000...1001) - ) - )], - nil, - nil - ), - nil, - [:a], - (982...985), - nil, - (989...990), - (1001...1002), - nil, - (1003...1006) - ), - DefNode(1008...1031)( - :bar, - (1012...1015), - nil, - ParametersNode(1016...1026)( - [], - [], - [], - nil, - [KeywordParameterNode(1016...1026)( - :a, - (1016...1018), - ParenthesesNode(1019...1026)( - StatementsNode(1020...1025)( - [RangeNode(1020...1025)( - nil, - IntegerNode(1023...1025)(), - (1020...1023), - 1 - )] - ), - (1019...1020), - (1025...1026) - ) - )], - nil, - nil - ), - nil, - [:a], - (1008...1011), - nil, - (1015...1016), - (1026...1027), - nil, - (1028...1031) - ), - DefNode(1033...1055)( - :bar, - (1037...1040), - nil, - ParametersNode(1041...1050)( - [], - [], - [], - nil, - [KeywordParameterNode(1041...1050)( - :a, - (1041...1043), - ParenthesesNode(1044...1050)( - StatementsNode(1045...1049)( - [RangeNode(1045...1049)( - IntegerNode(1045...1046)(), - nil, - (1046...1049), - 1 - )] - ), - (1044...1045), - (1049...1050) - ) - )], - nil, - nil - ), - nil, - [:a], - (1033...1036), - nil, - (1040...1041), - (1050...1051), - nil, - (1052...1055) - ), - DefNode(1057...1082)( - :bar, - (1061...1064), - nil, - ParametersNode(1065...1077)( - [], - [OptionalParameterNode(1065...1077)( - :a, - (1065...1066), - (1067...1068), - ParenthesesNode(1069...1077)( - StatementsNode(1070...1076)( - [RangeNode(1070...1076)( - IntegerNode(1070...1071)(), - IntegerNode(1074...1076)(), - (1071...1074), - 1 - )] - ), - (1069...1070), - (1076...1077) - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (1057...1060), - nil, - (1064...1065), - (1077...1078), - nil, - (1079...1082) - ), - DefNode(1084...1108)( - :bar, - (1088...1091), - nil, - ParametersNode(1092...1103)( - [], - [OptionalParameterNode(1092...1103)( - :a, - (1092...1093), - (1094...1095), - ParenthesesNode(1096...1103)( - StatementsNode(1097...1102)( - [RangeNode(1097...1102)( - nil, - IntegerNode(1100...1102)(), - (1097...1100), - 1 - )] - ), - (1096...1097), - (1102...1103) - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (1084...1087), - nil, - (1091...1092), - (1103...1104), - nil, - (1105...1108) - ), - DefNode(1110...1133)( - :bar, - (1114...1117), - nil, - ParametersNode(1118...1128)( - [], - [OptionalParameterNode(1118...1128)( - :a, - (1118...1119), - (1120...1121), - ParenthesesNode(1122...1128)( - StatementsNode(1123...1127)( - [RangeNode(1123...1127)( - IntegerNode(1123...1124)(), - nil, - (1124...1127), - 1 - )] - ), - (1122...1123), - (1127...1128) - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (1110...1113), - nil, - (1117...1118), - (1128...1129), - nil, - (1130...1133) - ), - DefNode(1135...1167)( - :method, - (1139...1145), - nil, - ParametersNode(1146...1147)( - [RequiredParameterNode(1146...1147)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(1151...1163)( - [CallNode(1151...1163)( - CallNode(1151...1155)( - nil, - nil, - (1151...1155), - nil, - nil, - nil, - nil, - 2, - "item" - ), - nil, - (1156...1158), - nil, - ArgumentsNode(1159...1163)( - [CallNode(1159...1163)( - nil, - nil, - (1159...1160), - nil, - nil, - nil, - BlockNode(1161...1163)( - [], - nil, - nil, - (1161...1162), - (1162...1163) - ), - 0, - "a" - )] - ), - nil, - nil, - 0, - ">>" - )] - ), - [:a], - (1135...1138), - nil, - (1145...1146), - (1147...1148), - nil, - (1164...1167) - ), - DefNode(1169...1194)( - :foo, - (1173...1176), - nil, - ParametersNode(1177...1189)( - [RequiredParameterNode(1177...1179)(:_a), - RequiredParameterNode(1181...1183)(:_a), - RequiredParameterNode(1185...1186)(:b), - RequiredParameterNode(1188...1189)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:_a, :b, :c], - (1169...1172), - nil, - (1176...1177), - (1189...1190), - nil, - (1191...1194) - )] - ) -) diff --git a/test/yarp/snapshots/modules.txt b/test/yarp/snapshots/modules.txt deleted file mode 100644 index 741c3c842092cb..00000000000000 --- a/test/yarp/snapshots/modules.txt +++ /dev/null @@ -1,135 +0,0 @@ -ProgramNode(0...140)( - [], - StatementsNode(0...140)( - [ModuleNode(0...18)( - [:a], - (0...6), - ConstantReadNode(7...8)(:A), - StatementsNode(9...14)( - [LocalVariableWriteNode(9...14)( - :a, - 0, - (9...10), - IntegerNode(13...14)(), - (11...12) - )] - ), - (15...18), - :A - ), - InterpolatedStringNode(20...38)( - (20...23), - [StringNode(23...27)(nil, (23...27), nil, "aaa "), - EmbeddedStatementsNode(27...33)( - (27...29), - StatementsNode(29...32)( - [CallNode(29...32)( - nil, - nil, - (29...32), - nil, - nil, - nil, - nil, - 2, - "bbb" - )] - ), - (32...33) - ), - StringNode(33...37)(nil, (33...37), nil, " ccc")], - (37...38) - ), - ModuleNode(40...55)( - [], - (40...46), - ConstantPathNode(47...51)( - CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 2, "m"), - ConstantReadNode(50...51)(:M), - (48...50) - ), - nil, - (52...55), - :M - ), - ModuleNode(57...85)( - [:x], - (57...63), - ConstantReadNode(64...65)(:A), - BeginNode(67...85)( - nil, - StatementsNode(67...72)( - [LocalVariableWriteNode(67...72)( - :x, - 0, - (67...68), - IntegerNode(71...72)(), - (69...70) - )] - ), - RescueNode(74...80)((74...80), [], nil, nil, nil, nil), - nil, - nil, - (82...85) - ), - (82...85), - :A - ), - ModuleNode(87...101)( - [], - (87...93), - ConstantPathNode(94...97)( - nil, - ConstantReadNode(96...97)(:A), - (94...96) - ), - nil, - (98...101), - :A - ), - ModuleNode(103...120)( - [], - (103...109), - ConstantPathNode(110...116)( - CallNode(110...113)( - ConstantReadNode(110...111)(:A), - nil, - (111...113), - (111...112), - nil, - (112...113), - nil, - 0, - "[]" - ), - ConstantReadNode(115...116)(:B), - (113...115) - ), - nil, - (117...120), - :B - ), - ModuleNode(122...140)( - [], - (122...128), - ConstantPathNode(129...136)( - CallNode(129...133)( - ConstantReadNode(129...130)(:A), - nil, - (130...133), - (130...131), - ArgumentsNode(131...132)([IntegerNode(131...132)()]), - (132...133), - nil, - 0, - "[]" - ), - ConstantReadNode(135...136)(:B), - (133...135) - ), - nil, - (137...140), - :B - )] - ) -) diff --git a/test/yarp/snapshots/newline_terminated.txt b/test/yarp/snapshots/newline_terminated.txt deleted file mode 100644 index 06ad6a989eead8..00000000000000 --- a/test/yarp/snapshots/newline_terminated.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(76...212)( - [], - StatementsNode(76...212)( - [StringNode(76...82)((76...78), (78...81), (81...82), "abc"), - StringNode(84...90)((84...86), (86...89), (89...90), "abc"), - StringNode(92...98)((92...94), (94...97), (97...98), "abc"), - StringNode(100...106)((100...102), (102...105), (105...106), "abc"), - StringNode(108...114)((108...110), (110...113), (113...114), "abc"), - StringNode(116...122)((116...118), (118...121), (121...122), "abc"), - StringNode(124...130)((124...126), (126...129), (129...130), "abc"), - StringNode(132...139)((132...134), (134...138), (138...139), "\rabc"), - StringNode(142...149)((142...144), (144...148), (148...149), "\rabc"), - StringNode(151...157)((151...153), (153...156), (156...157), "abc"), - StringNode(159...165)((159...161), (161...164), (164...165), "abc"), - StringNode(167...173)((167...169), (169...172), (172...173), "abc"), - StringNode(175...181)((175...177), (177...180), (180...181), "abc"), - StringNode(182...188)((182...184), (184...187), (187...188), "foo"), - StringNode(189...196)((189...192), (192...195), (195...196), "foo"), - StringNode(197...204)((197...200), (200...203), (203...204), "foo"), - RegularExpressionNode(205...212)( - (205...208), - (208...211), - (211...212), - "foo", - 0 - )] - ) -) diff --git a/test/yarp/snapshots/next.txt b/test/yarp/snapshots/next.txt deleted file mode 100644 index 533cf33bb8f7da..00000000000000 --- a/test/yarp/snapshots/next.txt +++ /dev/null @@ -1,88 +0,0 @@ -ProgramNode(0...118)( - [], - StatementsNode(0...118)( - [NextNode(0...4)(nil, (0...4)), - NextNode(6...24)( - ArgumentsNode(11...24)( - [ParenthesesNode(11...14)( - StatementsNode(12...13)([IntegerNode(12...13)()]), - (11...12), - (13...14) - ), - ParenthesesNode(16...19)( - StatementsNode(17...18)([IntegerNode(17...18)()]), - (16...17), - (18...19) - ), - ParenthesesNode(21...24)( - StatementsNode(22...23)([IntegerNode(22...23)()]), - (21...22), - (23...24) - )] - ), - (6...10) - ), - NextNode(26...32)( - ArgumentsNode(31...32)([IntegerNode(31...32)()]), - (26...30) - ), - NextNode(34...46)( - ArgumentsNode(39...46)( - [IntegerNode(39...40)(), - IntegerNode(42...43)(), - IntegerNode(45...46)()] - ), - (34...38) - ), - NextNode(48...60)( - ArgumentsNode(53...60)( - [IntegerNode(53...54)(), - IntegerNode(56...57)(), - IntegerNode(59...60)()] - ), - (48...52) - ), - NextNode(62...76)( - ArgumentsNode(67...76)( - [ArrayNode(67...76)( - [IntegerNode(68...69)(), - IntegerNode(71...72)(), - IntegerNode(74...75)()], - (67...68), - (75...76) - )] - ), - (62...66) - ), - NextNode(78...93)( - ArgumentsNode(82...93)( - [ParenthesesNode(82...93)( - StatementsNode(86...91)( - [IntegerNode(86...87)(), IntegerNode(90...91)()] - ), - (82...83), - (92...93) - )] - ), - (78...82) - ), - NextNode(95...99)(nil, (95...99)), - IntegerNode(100...101)(), - NextNode(103...109)( - ArgumentsNode(107...109)( - [ParenthesesNode(107...109)(nil, (107...108), (108...109))] - ), - (103...107) - ), - NextNode(111...118)( - ArgumentsNode(115...118)( - [ParenthesesNode(115...118)( - StatementsNode(116...117)([IntegerNode(116...117)()]), - (115...116), - (117...118) - )] - ), - (111...115) - )] - ) -) diff --git a/test/yarp/snapshots/nils.txt b/test/yarp/snapshots/nils.txt deleted file mode 100644 index daf9168e7ea35c..00000000000000 --- a/test/yarp/snapshots/nils.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [NilNode(0...3)(), - ParenthesesNode(5...7)(nil, (5...6), (6...7)), - ParenthesesNode(9...16)(nil, (9...10), (15...16)), - PostExecutionNode(18...27)( - StatementsNode(24...25)([IntegerNode(24...25)()]), - (18...21), - (22...23), - (26...27) - ), - PreExecutionNode(29...40)( - StatementsNode(37...38)([IntegerNode(37...38)()]), - (29...34), - (35...36), - (39...40) - )] - ) -) diff --git a/test/yarp/snapshots/non_alphanumeric_methods.txt b/test/yarp/snapshots/non_alphanumeric_methods.txt deleted file mode 100644 index a4cc39b6d3984e..00000000000000 --- a/test/yarp/snapshots/non_alphanumeric_methods.txt +++ /dev/null @@ -1,512 +0,0 @@ -ProgramNode(0...434)( - [], - StatementsNode(0...434)( - [DefNode(0...9)( - :!, - (4...5), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (6...9) - ), - DefNode(11...21)( - :!=, - (15...17), - nil, - nil, - nil, - [], - (11...14), - nil, - nil, - nil, - nil, - (18...21) - ), - DefNode(23...33)( - :!~, - (27...29), - nil, - nil, - nil, - [], - (23...26), - nil, - nil, - nil, - nil, - (30...33) - ), - DefNode(35...44)( - :%, - (39...40), - nil, - nil, - nil, - [], - (35...38), - nil, - nil, - nil, - nil, - (41...44) - ), - DefNode(46...60)( - :+, - (55...56), - SelfNode(50...54)(), - nil, - nil, - [], - (46...49), - (54...55), - nil, - nil, - nil, - (57...60) - ), - DefNode(62...71)( - :&, - (66...67), - nil, - nil, - nil, - [], - (62...65), - nil, - nil, - nil, - nil, - (68...71) - ), - DefNode(73...82)( - :*, - (77...78), - nil, - nil, - nil, - [], - (73...76), - nil, - nil, - nil, - nil, - (79...82) - ), - DefNode(84...94)( - :**, - (88...90), - nil, - nil, - nil, - [], - (84...87), - nil, - nil, - nil, - nil, - (91...94) - ), - StringNode(96...102)((96...98), (98...101), (101...102), "abc"), - DefNode(104...117)( - :+, - (108...109), - nil, - ParametersNode(110...113)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(110...113)(:b, (112...113), (110...112)), - nil - ), - nil, - [:b], - (104...107), - nil, - nil, - nil, - nil, - (114...117) - ), - DefNode(119...130)( - :+, - (123...124), - nil, - nil, - nil, - [], - (119...122), - nil, - (124...125), - (125...126), - nil, - (127...130) - ), - DefNode(132...143)( - :+, - (136...137), - nil, - ParametersNode(138...139)( - [RequiredParameterNode(138...139)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:b], - (132...135), - nil, - nil, - nil, - nil, - (140...143) - ), - DefNode(145...159)( - :+, - (154...155), - SelfNode(149...153)(), - nil, - nil, - [], - (145...148), - (153...154), - nil, - nil, - nil, - (156...159) - ), - DefNode(161...170)( - :+, - (165...166), - nil, - nil, - nil, - [], - (161...164), - nil, - nil, - nil, - nil, - (167...170) - ), - DefNode(172...182)( - :+@, - (176...178), - nil, - nil, - nil, - [], - (172...175), - nil, - nil, - nil, - nil, - (179...182) - ), - DefNode(184...193)( - :-, - (188...189), - nil, - nil, - nil, - [], - (184...187), - nil, - nil, - nil, - nil, - (190...193) - ), - DefNode(195...206)( - :-, - (201...202), - CallNode(199...200)(nil, nil, (199...200), nil, nil, nil, nil, 2, "a"), - nil, - nil, - [], - (195...198), - (200...201), - nil, - nil, - nil, - (203...206) - ), - DefNode(208...218)( - :-@, - (212...214), - nil, - nil, - nil, - [], - (208...211), - nil, - nil, - nil, - nil, - (215...218) - ), - DefNode(220...229)( - :/, - (224...225), - nil, - nil, - nil, - [], - (220...223), - nil, - nil, - nil, - nil, - (226...229) - ), - DefNode(231...240)( - :<, - (235...236), - nil, - nil, - nil, - [], - (231...234), - nil, - nil, - nil, - nil, - (237...240) - ), - DefNode(242...252)( - :<<, - (246...248), - nil, - nil, - nil, - [], - (242...245), - nil, - nil, - nil, - nil, - (249...252) - ), - DefNode(254...264)( - :<=, - (258...260), - nil, - nil, - nil, - [], - (254...257), - nil, - nil, - nil, - nil, - (261...264) - ), - DefNode(266...277)( - :<=>, - (270...273), - nil, - nil, - nil, - [], - (266...269), - nil, - nil, - nil, - nil, - (274...277) - ), - DefNode(279...289)( - :==, - (283...285), - nil, - nil, - nil, - [], - (279...282), - nil, - nil, - nil, - nil, - (286...289) - ), - DefNode(291...302)( - :===, - (295...298), - nil, - nil, - nil, - [], - (291...294), - nil, - nil, - nil, - nil, - (299...302) - ), - DefNode(304...314)( - :=~, - (308...310), - nil, - nil, - nil, - [], - (304...307), - nil, - nil, - nil, - nil, - (311...314) - ), - DefNode(316...325)( - :>, - (320...321), - nil, - nil, - nil, - [], - (316...319), - nil, - nil, - nil, - nil, - (322...325) - ), - DefNode(327...337)( - :>=, - (331...333), - nil, - nil, - nil, - [], - (327...330), - nil, - nil, - nil, - nil, - (334...337) - ), - DefNode(339...349)( - :>>, - (343...345), - nil, - nil, - nil, - [], - (339...342), - nil, - nil, - nil, - nil, - (346...349) - ), - DefNode(351...361)( - :[], - (355...357), - nil, - nil, - nil, - [], - (351...354), - nil, - nil, - nil, - nil, - (358...361) - ), - DefNode(363...374)( - :[]=, - (367...370), - nil, - nil, - nil, - [], - (363...366), - nil, - nil, - nil, - nil, - (371...374) - ), - DefNode(376...385)( - :^, - (380...381), - nil, - nil, - nil, - [], - (376...379), - nil, - nil, - nil, - nil, - (382...385) - ), - DefNode(387...396)( - :`, - (391...392), - nil, - nil, - nil, - [], - (387...390), - nil, - nil, - nil, - nil, - (393...396) - ), - DefNode(398...412)( - :`, - (407...408), - SelfNode(402...406)(), - nil, - nil, - [], - (398...401), - (406...407), - nil, - nil, - nil, - (409...412) - ), - DefNode(414...423)( - :|, - (418...419), - nil, - nil, - nil, - [], - (414...417), - nil, - nil, - nil, - nil, - (420...423) - ), - DefNode(425...434)( - :~, - (429...430), - nil, - nil, - nil, - [], - (425...428), - nil, - nil, - nil, - nil, - (431...434) - )] - ) -) diff --git a/test/yarp/snapshots/not.txt b/test/yarp/snapshots/not.txt deleted file mode 100644 index 5a9889bf6aa5cd..00000000000000 --- a/test/yarp/snapshots/not.txt +++ /dev/null @@ -1,271 +0,0 @@ -ProgramNode(0...190)( - [], - StatementsNode(0...190)( - [AndNode(0...19)( - CallNode(0...7)( - CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "foo"), - nil, - (0...3), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(12...19)( - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "bar"), - nil, - (12...15), - nil, - nil, - nil, - nil, - 0, - "!" - ), - (8...11) - ), - CallNode(21...37)( - AndNode(25...36)( - CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 2, "foo"), - CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 2, "bar"), - (29...32) - ), - nil, - (21...24), - (24...25), - nil, - (36...37), - nil, - 0, - "!" - ), - CallNode(39...46)( - CallNode(43...46)(nil, nil, (43...46), nil, nil, nil, nil, 2, "foo"), - nil, - (39...42), - nil, - nil, - nil, - nil, - 0, - "!" - ), - AndNode(48...69)( - CallNode(48...55)( - CallNode(52...55)(nil, nil, (52...55), nil, nil, nil, nil, 2, "foo"), - nil, - (48...51), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(60...69)( - CallNode(66...69)(nil, nil, (66...69), nil, nil, nil, nil, 2, "bar"), - nil, - (60...63), - nil, - nil, - nil, - nil, - 0, - "!" - ), - (56...59) - ), - AndNode(72...97)( - CallNode(72...79)( - CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 2, "foo"), - nil, - (72...75), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(88...97)( - CallNode(94...97)(nil, nil, (94...97), nil, nil, nil, nil, 2, "bar"), - nil, - (88...91), - nil, - nil, - nil, - nil, - 0, - "!" - ), - (80...83) - ), - AndNode(100...125)( - CallNode(100...107)( - CallNode(104...107)( - nil, - nil, - (104...107), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (100...103), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(114...125)( - CallNode(122...125)( - nil, - nil, - (122...125), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (114...117), - nil, - nil, - nil, - nil, - 0, - "!" - ), - (108...111) - ), - CallNode(127...138)( - CallNode(131...134)( - nil, - nil, - (131...134), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (127...130), - (130...131), - nil, - (137...138), - nil, - 0, - "!" - ), - CallNode(140...156)( - CallNode(147...150)( - nil, - nil, - (147...150), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (140...143), - (143...144), - nil, - (155...156), - nil, - 0, - "!" - ), - CallNode(158...172)( - FlipFlopNode(162...172)( - CallNode(162...165)( - nil, - nil, - (162...165), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(169...172)( - nil, - nil, - (169...172), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (166...168), - 0 - ), - nil, - (158...161), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(174...190)( - ParenthesesNode(178...190)( - StatementsNode(179...189)( - [FlipFlopNode(179...189)( - CallNode(179...182)( - nil, - nil, - (179...182), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(186...189)( - nil, - nil, - (186...189), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (183...185), - 0 - )] - ), - (178...179), - (189...190) - ), - nil, - (174...177), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/numbers.txt b/test/yarp/snapshots/numbers.txt deleted file mode 100644 index 72fb895125d250..00000000000000 --- a/test/yarp/snapshots/numbers.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...161)( - [], - StatementsNode(0...161)( - [IntegerNode(0...1)(), - IntegerNode(3...4)(), - FloatNode(6...9)(), - IntegerNode(11...12)(), - IntegerNode(14...17)(), - IntegerNode(19...22)(), - IntegerNode(24...28)(), - IntegerNode(30...33)(), - IntegerNode(35...38)(), - IntegerNode(40...43)(), - IntegerNode(45...47)(), - IntegerNode(49...51)(), - IntegerNode(53...55)(), - IntegerNode(57...60)(), - IntegerNode(62...65)(), - IntegerNode(67...70)(), - IntegerNode(72...75)(), - IntegerNode(77...80)(), - IntegerNode(82...85)(), - ImaginaryNode(87...89)(IntegerNode(87...88)()), - RationalNode(91...93)(IntegerNode(91...92)()), - IntegerNode(95...97)(), - ImaginaryNode(99...102)(RationalNode(99...101)(IntegerNode(99...100)())), - ImaginaryNode(104...109)(RationalNode(104...108)(FloatNode(104...107)())), - ImaginaryNode(111...115)( - RationalNode(111...114)(IntegerNode(111...113)()) - ), - ImaginaryNode(117...123)(RationalNode(117...122)(FloatNode(117...121)())), - RationalNode(125...129)(IntegerNode(125...128)()), - ImaginaryNode(131...135)(IntegerNode(131...134)()), - ImaginaryNode(137...142)( - RationalNode(137...141)(IntegerNode(137...140)()) - ), - RationalNode(144...148)(IntegerNode(144...147)()), - ImaginaryNode(150...154)(IntegerNode(150...153)()), - ImaginaryNode(156...161)( - RationalNode(156...160)(IntegerNode(156...159)()) - )] - ) -) diff --git a/test/yarp/snapshots/patterns.txt b/test/yarp/snapshots/patterns.txt deleted file mode 100644 index b2f03f6b6836df..00000000000000 --- a/test/yarp/snapshots/patterns.txt +++ /dev/null @@ -1,3850 +0,0 @@ -ProgramNode(0...3743)( - [:bar, :baz, :qux, :b, :a], - StatementsNode(0...3743)( - [MatchRequiredNode(0...10)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - LocalVariableTargetNode(7...10)(:bar, 0), - (4...6) - ), - MatchRequiredNode(11...19)( - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - IntegerNode(18...19)(), - (15...17) - ), - MatchRequiredNode(20...30)( - CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "foo"), - FloatNode(27...30)(), - (24...26) - ), - MatchRequiredNode(31...40)( - CallNode(31...34)(nil, nil, (31...34), nil, nil, nil, nil, 2, "foo"), - ImaginaryNode(38...40)(IntegerNode(38...39)()), - (35...37) - ), - MatchRequiredNode(41...50)( - CallNode(41...44)(nil, nil, (41...44), nil, nil, nil, nil, 2, "foo"), - RationalNode(48...50)(IntegerNode(48...49)()), - (45...47) - ), - MatchRequiredNode(51...62)( - CallNode(51...54)(nil, nil, (51...54), nil, nil, nil, nil, 2, "foo"), - SymbolNode(58...62)((58...59), (59...62), nil, "foo"), - (55...57) - ), - MatchRequiredNode(63...77)( - CallNode(63...66)(nil, nil, (63...66), nil, nil, nil, nil, 2, "foo"), - SymbolNode(70...77)((70...73), (73...76), (76...77), "foo"), - (67...69) - ), - MatchRequiredNode(78...91)( - CallNode(78...81)(nil, nil, (78...81), nil, nil, nil, nil, 2, "foo"), - SymbolNode(85...91)((85...87), (87...90), (90...91), "foo"), - (82...84) - ), - MatchRequiredNode(92...104)( - CallNode(92...95)(nil, nil, (92...95), nil, nil, nil, nil, 2, "foo"), - RegularExpressionNode(99...104)( - (99...100), - (100...103), - (103...104), - "foo", - 0 - ), - (96...98) - ), - MatchRequiredNode(105...117)( - CallNode(105...108)( - nil, - nil, - (105...108), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - XStringNode(112...117)((112...113), (113...116), (116...117), "foo"), - (109...111) - ), - MatchRequiredNode(118...132)( - CallNode(118...121)( - nil, - nil, - (118...121), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - XStringNode(125...132)((125...128), (128...131), (131...132), "foo"), - (122...124) - ), - MatchRequiredNode(133...147)( - CallNode(133...136)( - nil, - nil, - (133...136), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(140...147)( - [SymbolNode(143...146)(nil, (143...146), nil, "foo")], - (140...143), - (146...147) - ), - (137...139) - ), - MatchRequiredNode(148...162)( - CallNode(148...151)( - nil, - nil, - (148...151), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(155...162)( - [SymbolNode(158...161)(nil, (158...161), nil, "foo")], - (155...158), - (161...162) - ), - (152...154) - ), - MatchRequiredNode(163...177)( - CallNode(163...166)( - nil, - nil, - (163...166), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(170...177)( - [StringNode(173...176)(nil, (173...176), nil, "foo")], - (170...173), - (176...177) - ), - (167...169) - ), - MatchRequiredNode(178...192)( - CallNode(178...181)( - nil, - nil, - (178...181), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(185...192)( - [StringNode(188...191)(nil, (188...191), nil, "foo")], - (185...188), - (191...192) - ), - (182...184) - ), - MatchRequiredNode(193...207)( - CallNode(193...196)( - nil, - nil, - (193...196), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(200...207)((200...203), (203...206), (206...207), "foo"), - (197...199) - ), - MatchRequiredNode(208...222)( - CallNode(208...211)( - nil, - nil, - (208...211), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(215...222)((215...218), (218...221), (221...222), "foo"), - (212...214) - ), - MatchRequiredNode(223...235)( - CallNode(223...226)( - nil, - nil, - (223...226), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(230...235)((230...231), (231...234), (234...235), "foo"), - (227...229) - ), - MatchRequiredNode(236...246)( - CallNode(236...239)( - nil, - nil, - (236...239), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - NilNode(243...246)(), - (240...242) - ), - MatchRequiredNode(247...258)( - CallNode(247...250)( - nil, - nil, - (247...250), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SelfNode(254...258)(), - (251...253) - ), - MatchRequiredNode(259...270)( - CallNode(259...262)( - nil, - nil, - (259...262), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - TrueNode(266...270)(), - (263...265) - ), - MatchRequiredNode(271...283)( - CallNode(271...274)( - nil, - nil, - (271...274), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FalseNode(278...283)(), - (275...277) - ), - MatchRequiredNode(284...299)( - CallNode(284...287)( - nil, - nil, - (284...287), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceFileNode(291...299)("patterns.txt"), - (288...290) - ), - MatchRequiredNode(300...315)( - CallNode(300...303)( - nil, - nil, - (300...303), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceLineNode(307...315)(), - (304...306) - ), - MatchRequiredNode(316...335)( - CallNode(316...319)( - nil, - nil, - (316...319), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceEncodingNode(323...335)(), - (320...322) - ), - MatchRequiredNode(336...353)( - CallNode(336...339)( - nil, - nil, - (336...339), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - LambdaNode(343...353)( - [], - (343...345), - (346...347), - (352...353), - nil, - StatementsNode(348...351)([LocalVariableReadNode(348...351)(:bar, 1)]) - ), - (340...342) - ), - MatchRequiredNode(355...368)( - CallNode(355...358)( - nil, - nil, - (355...358), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(362...368)( - IntegerNode(362...363)(), - IntegerNode(367...368)(), - (364...366), - 0 - ), - (359...361) - ), - MatchRequiredNode(369...386)( - CallNode(369...372)( - nil, - nil, - (369...372), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(376...386)( - FloatNode(376...379)(), - FloatNode(383...386)(), - (380...382), - 0 - ), - (373...375) - ), - MatchRequiredNode(387...402)( - CallNode(387...390)( - nil, - nil, - (387...390), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(394...402)( - ImaginaryNode(394...396)(IntegerNode(394...395)()), - ImaginaryNode(400...402)(IntegerNode(400...401)()), - (397...399), - 0 - ), - (391...393) - ), - MatchRequiredNode(403...418)( - CallNode(403...406)( - nil, - nil, - (403...406), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(410...418)( - RationalNode(410...412)(IntegerNode(410...411)()), - RationalNode(416...418)(IntegerNode(416...417)()), - (413...415), - 0 - ), - (407...409) - ), - MatchRequiredNode(419...438)( - CallNode(419...422)( - nil, - nil, - (419...422), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(426...438)( - SymbolNode(426...430)((426...427), (427...430), nil, "foo"), - SymbolNode(434...438)((434...435), (435...438), nil, "foo"), - (431...433), - 0 - ), - (423...425) - ), - MatchRequiredNode(439...464)( - CallNode(439...442)( - nil, - nil, - (439...442), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(446...464)( - SymbolNode(446...453)((446...449), (449...452), (452...453), "foo"), - SymbolNode(457...464)((457...460), (460...463), (463...464), "foo"), - (454...456), - 0 - ), - (443...445) - ), - MatchRequiredNode(465...488)( - CallNode(465...468)( - nil, - nil, - (465...468), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(472...488)( - SymbolNode(472...478)((472...474), (474...477), (477...478), "foo"), - SymbolNode(482...488)((482...484), (484...487), (487...488), "foo"), - (479...481), - 0 - ), - (469...471) - ), - MatchRequiredNode(489...510)( - CallNode(489...492)( - nil, - nil, - (489...492), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(496...510)( - RegularExpressionNode(496...501)( - (496...497), - (497...500), - (500...501), - "foo", - 0 - ), - RegularExpressionNode(505...510)( - (505...506), - (506...509), - (509...510), - "foo", - 0 - ), - (502...504), - 0 - ), - (493...495) - ), - MatchRequiredNode(511...532)( - CallNode(511...514)( - nil, - nil, - (511...514), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(518...532)( - XStringNode(518...523)((518...519), (519...522), (522...523), "foo"), - XStringNode(527...532)((527...528), (528...531), (531...532), "foo"), - (524...526), - 0 - ), - (515...517) - ), - MatchRequiredNode(533...558)( - CallNode(533...536)( - nil, - nil, - (533...536), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(540...558)( - XStringNode(540...547)((540...543), (543...546), (546...547), "foo"), - XStringNode(551...558)((551...554), (554...557), (557...558), "foo"), - (548...550), - 0 - ), - (537...539) - ), - MatchRequiredNode(559...584)( - CallNode(559...562)( - nil, - nil, - (559...562), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(566...584)( - ArrayNode(566...573)( - [SymbolNode(569...572)(nil, (569...572), nil, "foo")], - (566...569), - (572...573) - ), - ArrayNode(577...584)( - [SymbolNode(580...583)(nil, (580...583), nil, "foo")], - (577...580), - (583...584) - ), - (574...576), - 0 - ), - (563...565) - ), - MatchRequiredNode(585...610)( - CallNode(585...588)( - nil, - nil, - (585...588), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(592...610)( - ArrayNode(592...599)( - [SymbolNode(595...598)(nil, (595...598), nil, "foo")], - (592...595), - (598...599) - ), - ArrayNode(603...610)( - [SymbolNode(606...609)(nil, (606...609), nil, "foo")], - (603...606), - (609...610) - ), - (600...602), - 0 - ), - (589...591) - ), - MatchRequiredNode(611...636)( - CallNode(611...614)( - nil, - nil, - (611...614), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(618...636)( - ArrayNode(618...625)( - [StringNode(621...624)(nil, (621...624), nil, "foo")], - (618...621), - (624...625) - ), - ArrayNode(629...636)( - [StringNode(632...635)(nil, (632...635), nil, "foo")], - (629...632), - (635...636) - ), - (626...628), - 0 - ), - (615...617) - ), - MatchRequiredNode(637...662)( - CallNode(637...640)( - nil, - nil, - (637...640), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(644...662)( - ArrayNode(644...651)( - [StringNode(647...650)(nil, (647...650), nil, "foo")], - (644...647), - (650...651) - ), - ArrayNode(655...662)( - [StringNode(658...661)(nil, (658...661), nil, "foo")], - (655...658), - (661...662) - ), - (652...654), - 0 - ), - (641...643) - ), - MatchRequiredNode(663...688)( - CallNode(663...666)( - nil, - nil, - (663...666), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(670...688)( - StringNode(670...677)((670...673), (673...676), (676...677), "foo"), - StringNode(681...688)((681...684), (684...687), (687...688), "foo"), - (678...680), - 0 - ), - (667...669) - ), - MatchRequiredNode(689...714)( - CallNode(689...692)( - nil, - nil, - (689...692), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(696...714)( - StringNode(696...703)((696...699), (699...702), (702...703), "foo"), - StringNode(707...714)((707...710), (710...713), (713...714), "foo"), - (704...706), - 0 - ), - (693...695) - ), - MatchRequiredNode(715...736)( - CallNode(715...718)( - nil, - nil, - (715...718), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(722...736)( - StringNode(722...727)((722...723), (723...726), (726...727), "foo"), - StringNode(731...736)((731...732), (732...735), (735...736), "foo"), - (728...730), - 0 - ), - (719...721) - ), - MatchRequiredNode(737...754)( - CallNode(737...740)( - nil, - nil, - (737...740), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(744...754)( - NilNode(744...747)(), - NilNode(751...754)(), - (748...750), - 0 - ), - (741...743) - ), - MatchRequiredNode(755...774)( - CallNode(755...758)( - nil, - nil, - (755...758), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(762...774)( - SelfNode(762...766)(), - SelfNode(770...774)(), - (767...769), - 0 - ), - (759...761) - ), - MatchRequiredNode(775...794)( - CallNode(775...778)( - nil, - nil, - (775...778), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(782...794)( - TrueNode(782...786)(), - TrueNode(790...794)(), - (787...789), - 0 - ), - (779...781) - ), - MatchRequiredNode(795...816)( - CallNode(795...798)( - nil, - nil, - (795...798), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(802...816)( - FalseNode(802...807)(), - FalseNode(811...816)(), - (808...810), - 0 - ), - (799...801) - ), - MatchRequiredNode(817...844)( - CallNode(817...820)( - nil, - nil, - (817...820), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(824...844)( - SourceFileNode(824...832)("patterns.txt"), - SourceFileNode(836...844)("patterns.txt"), - (833...835), - 0 - ), - (821...823) - ), - MatchRequiredNode(845...872)( - CallNode(845...848)( - nil, - nil, - (845...848), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(852...872)( - SourceLineNode(852...860)(), - SourceLineNode(864...872)(), - (861...863), - 0 - ), - (849...851) - ), - MatchRequiredNode(873...908)( - CallNode(873...876)( - nil, - nil, - (873...876), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(880...908)( - SourceEncodingNode(880...892)(), - SourceEncodingNode(896...908)(), - (893...895), - 0 - ), - (877...879) - ), - MatchRequiredNode(909...940)( - CallNode(909...912)( - nil, - nil, - (909...912), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RangeNode(916...940)( - LambdaNode(916...926)( - [], - (916...918), - (919...920), - (925...926), - nil, - StatementsNode(921...924)( - [LocalVariableReadNode(921...924)(:bar, 1)] - ) - ), - LambdaNode(930...940)( - [], - (930...932), - (933...934), - (939...940), - nil, - StatementsNode(935...938)( - [LocalVariableReadNode(935...938)(:bar, 1)] - ) - ), - (927...929), - 0 - ), - (913...915) - ), - MatchRequiredNode(942...953)( - CallNode(942...945)( - nil, - nil, - (942...945), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedVariableNode(949...953)( - LocalVariableReadNode(950...953)(:bar, 0), - (949...950) - ), - (946...948) - ), - MatchRequiredNode(954...966)( - CallNode(954...957)( - nil, - nil, - (954...957), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedVariableNode(961...966)( - InstanceVariableReadNode(962...966)(:@bar), - (961...962) - ), - (958...960) - ), - MatchRequiredNode(967...980)( - CallNode(967...970)( - nil, - nil, - (967...970), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedVariableNode(974...980)( - ClassVariableReadNode(975...980)(:@@bar), - (974...975) - ), - (971...973) - ), - MatchRequiredNode(981...993)( - CallNode(981...984)( - nil, - nil, - (981...984), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedVariableNode(988...993)( - GlobalVariableReadNode(989...993)(:$bar), - (988...989) - ), - (985...987) - ), - MatchRequiredNode(995...1006)( - CallNode(995...998)( - nil, - nil, - (995...998), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedExpressionNode(1002...1006)( - IntegerNode(1004...1005)(), - (1002...1003), - (1003...1004), - (1005...1006) - ), - (999...1001) - ), - MatchRequiredNode(1007...1020)( - CallNode(1007...1010)( - nil, - nil, - (1007...1010), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedExpressionNode(1014...1020)( - NilNode(1016...1019)(), - (1014...1015), - (1015...1016), - (1019...1020) - ), - (1011...1013) - ), - MatchRequiredNode(1021...1044)( - CallNode(1021...1024)( - nil, - nil, - (1021...1024), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - PinnedExpressionNode(1028...1044)( - CallNode(1030...1043)( - StringNode(1030...1035)( - (1030...1031), - (1031...1034), - (1034...1035), - "bar" - ), - nil, - (1036...1037), - nil, - ArgumentsNode(1038...1043)( - [StringNode(1038...1043)( - (1038...1039), - (1039...1042), - (1042...1043), - "baz" - )] - ), - nil, - nil, - 0, - "+" - ), - (1028...1029), - (1029...1030), - (1043...1044) - ), - (1025...1027) - ), - MatchRequiredNode(1046...1056)( - CallNode(1046...1049)( - nil, - nil, - (1046...1049), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ConstantReadNode(1053...1056)(:Foo), - (1050...1052) - ), - MatchRequiredNode(1057...1077)( - CallNode(1057...1060)( - nil, - nil, - (1057...1060), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ConstantPathNode(1064...1077)( - ConstantPathNode(1064...1072)( - ConstantReadNode(1064...1067)(:Foo), - ConstantReadNode(1069...1072)(:Bar), - (1067...1069) - ), - ConstantReadNode(1074...1077)(:Baz), - (1072...1074) - ), - (1061...1063) - ), - MatchRequiredNode(1078...1090)( - CallNode(1078...1081)( - nil, - nil, - (1078...1081), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ConstantPathNode(1085...1090)( - nil, - ConstantReadNode(1087...1090)(:Foo), - (1085...1087) - ), - (1082...1084) - ), - MatchRequiredNode(1091...1113)( - CallNode(1091...1094)( - nil, - nil, - (1091...1094), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ConstantPathNode(1098...1113)( - ConstantPathNode(1098...1108)( - ConstantPathNode(1098...1103)( - nil, - ConstantReadNode(1100...1103)(:Foo), - (1098...1100) - ), - ConstantReadNode(1105...1108)(:Bar), - (1103...1105) - ), - ConstantReadNode(1110...1113)(:Baz), - (1108...1110) - ), - (1095...1097) - ), - MatchRequiredNode(1115...1127)( - CallNode(1115...1118)( - nil, - nil, - (1115...1118), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1122...1127)( - ConstantReadNode(1122...1125)(:Foo), - [], - nil, - [], - (1125...1126), - (1126...1127) - ), - (1119...1121) - ), - MatchRequiredNode(1128...1141)( - CallNode(1128...1131)( - nil, - nil, - (1128...1131), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1135...1141)( - ConstantReadNode(1135...1138)(:Foo), - [IntegerNode(1139...1140)()], - nil, - [], - (1138...1139), - (1140...1141) - ), - (1132...1134) - ), - MatchRequiredNode(1142...1161)( - CallNode(1142...1145)( - nil, - nil, - (1142...1145), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1149...1161)( - ConstantReadNode(1149...1152)(:Foo), - [IntegerNode(1153...1154)(), - IntegerNode(1156...1157)(), - IntegerNode(1159...1160)()], - nil, - [], - (1152...1153), - (1160...1161) - ), - (1146...1148) - ), - MatchRequiredNode(1162...1177)( - CallNode(1162...1165)( - nil, - nil, - (1162...1165), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1169...1177)( - ConstantReadNode(1169...1172)(:Foo), - [LocalVariableTargetNode(1173...1176)(:bar, 0)], - nil, - [], - (1172...1173), - (1176...1177) - ), - (1166...1168) - ), - MatchRequiredNode(1178...1199)( - CallNode(1178...1181)( - nil, - nil, - (1178...1181), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1185...1199)( - ConstantReadNode(1185...1188)(:Foo), - [], - SplatNode(1189...1193)( - (1189...1190), - LocalVariableTargetNode(1190...1193)(:bar, 0) - ), - [LocalVariableTargetNode(1195...1198)(:baz, 0)], - (1188...1189), - (1198...1199) - ), - (1182...1184) - ), - MatchRequiredNode(1200...1221)( - CallNode(1200...1203)( - nil, - nil, - (1200...1203), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1207...1221)( - ConstantReadNode(1207...1210)(:Foo), - [LocalVariableTargetNode(1211...1214)(:bar, 0)], - SplatNode(1216...1220)( - (1216...1217), - LocalVariableTargetNode(1217...1220)(:baz, 0) - ), - [], - (1210...1211), - (1220...1221) - ), - (1204...1206) - ), - MatchRequiredNode(1222...1249)( - CallNode(1222...1225)( - nil, - nil, - (1222...1225), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FindPatternNode(1229...1249)( - ConstantReadNode(1229...1232)(:Foo), - SplatNode(1233...1237)( - (1233...1234), - LocalVariableTargetNode(1234...1237)(:bar, 0) - ), - [LocalVariableTargetNode(1239...1242)(:baz, 0)], - SplatNode(1244...1248)( - (1244...1245), - LocalVariableTargetNode(1245...1248)(:qux, 0) - ), - (1232...1233), - (1248...1249) - ), - (1226...1228) - ), - MatchRequiredNode(1251...1263)( - CallNode(1251...1254)( - nil, - nil, - (1251...1254), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1258...1263)( - ConstantReadNode(1258...1261)(:Foo), - [], - nil, - [], - (1261...1262), - (1262...1263) - ), - (1255...1257) - ), - MatchRequiredNode(1264...1277)( - CallNode(1264...1267)( - nil, - nil, - (1264...1267), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1271...1277)( - ConstantReadNode(1271...1274)(:Foo), - [IntegerNode(1275...1276)()], - nil, - [], - (1274...1275), - (1276...1277) - ), - (1268...1270) - ), - MatchRequiredNode(1278...1297)( - CallNode(1278...1281)( - nil, - nil, - (1278...1281), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1285...1297)( - ConstantReadNode(1285...1288)(:Foo), - [IntegerNode(1289...1290)(), - IntegerNode(1292...1293)(), - IntegerNode(1295...1296)()], - nil, - [], - (1288...1289), - (1296...1297) - ), - (1282...1284) - ), - MatchRequiredNode(1298...1315)( - CallNode(1298...1301)( - nil, - nil, - (1298...1301), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1305...1315)( - ConstantReadNode(1305...1308)(:Foo), - [ArrayPatternNode(1309...1314)( - ConstantReadNode(1309...1312)(:Foo), - [], - nil, - [], - (1312...1313), - (1313...1314) - )], - nil, - [], - (1308...1309), - (1314...1315) - ), - (1302...1304) - ), - MatchRequiredNode(1316...1331)( - CallNode(1316...1319)( - nil, - nil, - (1316...1319), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1323...1331)( - ConstantReadNode(1323...1326)(:Foo), - [LocalVariableTargetNode(1327...1330)(:bar, 0)], - nil, - [], - (1326...1327), - (1330...1331) - ), - (1320...1322) - ), - MatchRequiredNode(1332...1353)( - CallNode(1332...1335)( - nil, - nil, - (1332...1335), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1339...1353)( - ConstantReadNode(1339...1342)(:Foo), - [], - SplatNode(1343...1347)( - (1343...1344), - LocalVariableTargetNode(1344...1347)(:bar, 0) - ), - [LocalVariableTargetNode(1349...1352)(:baz, 0)], - (1342...1343), - (1352...1353) - ), - (1336...1338) - ), - MatchRequiredNode(1354...1375)( - CallNode(1354...1357)( - nil, - nil, - (1354...1357), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1361...1375)( - ConstantReadNode(1361...1364)(:Foo), - [LocalVariableTargetNode(1365...1368)(:bar, 0)], - SplatNode(1370...1374)( - (1370...1371), - LocalVariableTargetNode(1371...1374)(:baz, 0) - ), - [], - (1364...1365), - (1374...1375) - ), - (1358...1360) - ), - MatchRequiredNode(1376...1403)( - CallNode(1376...1379)( - nil, - nil, - (1376...1379), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FindPatternNode(1383...1403)( - ConstantReadNode(1383...1386)(:Foo), - SplatNode(1387...1391)( - (1387...1388), - LocalVariableTargetNode(1388...1391)(:bar, 0) - ), - [LocalVariableTargetNode(1393...1396)(:baz, 0)], - SplatNode(1398...1402)( - (1398...1399), - LocalVariableTargetNode(1399...1402)(:qux, 0) - ), - (1386...1387), - (1402...1403) - ), - (1380...1382) - ), - MatchRequiredNode(1405...1416)( - CallNode(1405...1408)( - nil, - nil, - (1405...1408), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1412...1416)( - nil, - [], - SplatNode(1412...1416)( - (1412...1413), - LocalVariableTargetNode(1413...1416)(:bar, 0) - ), - [], - nil, - nil - ), - (1409...1411) - ), - MatchRequiredNode(1417...1438)( - CallNode(1417...1420)( - nil, - nil, - (1417...1420), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1424...1438)( - nil, - [], - SplatNode(1424...1428)( - (1424...1425), - LocalVariableTargetNode(1425...1428)(:bar, 0) - ), - [LocalVariableTargetNode(1430...1433)(:baz, 0), - LocalVariableTargetNode(1435...1438)(:qux, 0)], - nil, - nil - ), - (1421...1423) - ), - MatchRequiredNode(1439...1460)( - CallNode(1439...1442)( - nil, - nil, - (1439...1442), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1446...1460)( - nil, - [LocalVariableTargetNode(1446...1449)(:bar, 0)], - SplatNode(1451...1455)( - (1451...1452), - LocalVariableTargetNode(1452...1455)(:baz, 0) - ), - [LocalVariableTargetNode(1457...1460)(:qux, 0)], - nil, - nil - ), - (1443...1445) - ), - MatchRequiredNode(1461...1482)( - CallNode(1461...1464)( - nil, - nil, - (1461...1464), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1468...1482)( - nil, - [LocalVariableTargetNode(1468...1471)(:bar, 0), - LocalVariableTargetNode(1473...1476)(:baz, 0)], - SplatNode(1478...1482)( - (1478...1479), - LocalVariableTargetNode(1479...1482)(:qux, 0) - ), - [], - nil, - nil - ), - (1465...1467) - ), - MatchRequiredNode(1483...1505)( - CallNode(1483...1486)( - nil, - nil, - (1483...1486), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FindPatternNode(1490...1505)( - nil, - SplatNode(1490...1494)( - (1490...1491), - LocalVariableTargetNode(1491...1494)(:bar, 0) - ), - [LocalVariableTargetNode(1496...1499)(:baz, 0)], - SplatNode(1501...1505)( - (1501...1502), - LocalVariableTargetNode(1502...1505)(:qux, 0) - ), - nil, - nil - ), - (1487...1489) - ), - MatchRequiredNode(1507...1516)( - CallNode(1507...1510)( - nil, - nil, - (1507...1510), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1514...1516)( - nil, - [], - nil, - [], - (1514...1515), - (1515...1516) - ), - (1511...1513) - ), - MatchRequiredNode(1517...1534)( - CallNode(1517...1520)( - nil, - nil, - (1517...1520), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1524...1534)( - nil, - [ArrayPatternNode(1525...1533)( - nil, - [ArrayPatternNode(1526...1532)( - nil, - [ArrayPatternNode(1527...1531)( - nil, - [ArrayPatternNode(1528...1530)( - nil, - [], - nil, - [], - (1528...1529), - (1529...1530) - )], - nil, - [], - (1527...1528), - (1530...1531) - )], - nil, - [], - (1526...1527), - (1531...1532) - )], - nil, - [], - (1525...1526), - (1532...1533) - )], - nil, - [], - (1524...1525), - (1533...1534) - ), - (1521...1523) - ), - MatchRequiredNode(1536...1549)( - CallNode(1536...1539)( - nil, - nil, - (1536...1539), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1543...1549)( - nil, - [], - SplatNode(1544...1548)( - (1544...1545), - LocalVariableTargetNode(1545...1548)(:bar, 0) - ), - [], - (1543...1544), - (1548...1549) - ), - (1540...1542) - ), - MatchRequiredNode(1550...1573)( - CallNode(1550...1553)( - nil, - nil, - (1550...1553), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1557...1573)( - nil, - [], - SplatNode(1558...1562)( - (1558...1559), - LocalVariableTargetNode(1559...1562)(:bar, 0) - ), - [LocalVariableTargetNode(1564...1567)(:baz, 0), - LocalVariableTargetNode(1569...1572)(:qux, 0)], - (1557...1558), - (1572...1573) - ), - (1554...1556) - ), - MatchRequiredNode(1574...1597)( - CallNode(1574...1577)( - nil, - nil, - (1574...1577), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1581...1597)( - nil, - [LocalVariableTargetNode(1582...1585)(:bar, 0)], - SplatNode(1587...1591)( - (1587...1588), - LocalVariableTargetNode(1588...1591)(:baz, 0) - ), - [LocalVariableTargetNode(1593...1596)(:qux, 0)], - (1581...1582), - (1596...1597) - ), - (1578...1580) - ), - MatchRequiredNode(1598...1621)( - CallNode(1598...1601)( - nil, - nil, - (1598...1601), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayPatternNode(1605...1621)( - nil, - [LocalVariableTargetNode(1606...1609)(:bar, 0), - LocalVariableTargetNode(1611...1614)(:baz, 0)], - SplatNode(1616...1620)( - (1616...1617), - LocalVariableTargetNode(1617...1620)(:qux, 0) - ), - [], - (1605...1606), - (1620...1621) - ), - (1602...1604) - ), - MatchRequiredNode(1622...1646)( - CallNode(1622...1625)( - nil, - nil, - (1622...1625), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FindPatternNode(1629...1646)( - nil, - SplatNode(1630...1634)( - (1630...1631), - LocalVariableTargetNode(1631...1634)(:bar, 0) - ), - [LocalVariableTargetNode(1636...1639)(:baz, 0)], - SplatNode(1641...1645)( - (1641...1642), - LocalVariableTargetNode(1642...1645)(:qux, 0) - ), - (1629...1630), - (1645...1646) - ), - (1626...1628) - ), - MatchPredicateNode(1648...1658)( - CallNode(1648...1651)( - nil, - nil, - (1648...1651), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - LocalVariableTargetNode(1655...1658)(:bar, 0), - (1652...1654) - ), - MatchPredicateNode(1659...1667)( - CallNode(1659...1662)( - nil, - nil, - (1659...1662), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - IntegerNode(1666...1667)(), - (1663...1665) - ), - MatchPredicateNode(1668...1678)( - CallNode(1668...1671)( - nil, - nil, - (1668...1671), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FloatNode(1675...1678)(), - (1672...1674) - ), - MatchPredicateNode(1679...1688)( - CallNode(1679...1682)( - nil, - nil, - (1679...1682), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ImaginaryNode(1686...1688)(IntegerNode(1686...1687)()), - (1683...1685) - ), - MatchPredicateNode(1689...1698)( - CallNode(1689...1692)( - nil, - nil, - (1689...1692), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RationalNode(1696...1698)(IntegerNode(1696...1697)()), - (1693...1695) - ), - MatchPredicateNode(1699...1710)( - CallNode(1699...1702)( - nil, - nil, - (1699...1702), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SymbolNode(1706...1710)((1706...1707), (1707...1710), nil, "foo"), - (1703...1705) - ), - MatchPredicateNode(1711...1725)( - CallNode(1711...1714)( - nil, - nil, - (1711...1714), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SymbolNode(1718...1725)( - (1718...1721), - (1721...1724), - (1724...1725), - "foo" - ), - (1715...1717) - ), - MatchPredicateNode(1726...1739)( - CallNode(1726...1729)( - nil, - nil, - (1726...1729), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SymbolNode(1733...1739)( - (1733...1735), - (1735...1738), - (1738...1739), - "foo" - ), - (1730...1732) - ), - MatchPredicateNode(1740...1752)( - CallNode(1740...1743)( - nil, - nil, - (1740...1743), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - RegularExpressionNode(1747...1752)( - (1747...1748), - (1748...1751), - (1751...1752), - "foo", - 0 - ), - (1744...1746) - ), - MatchPredicateNode(1753...1765)( - CallNode(1753...1756)( - nil, - nil, - (1753...1756), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - XStringNode(1760...1765)( - (1760...1761), - (1761...1764), - (1764...1765), - "foo" - ), - (1757...1759) - ), - MatchPredicateNode(1766...1780)( - CallNode(1766...1769)( - nil, - nil, - (1766...1769), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - XStringNode(1773...1780)( - (1773...1776), - (1776...1779), - (1779...1780), - "foo" - ), - (1770...1772) - ), - MatchPredicateNode(1781...1795)( - CallNode(1781...1784)( - nil, - nil, - (1781...1784), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(1788...1795)( - [SymbolNode(1791...1794)(nil, (1791...1794), nil, "foo")], - (1788...1791), - (1794...1795) - ), - (1785...1787) - ), - MatchPredicateNode(1796...1810)( - CallNode(1796...1799)( - nil, - nil, - (1796...1799), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(1803...1810)( - [SymbolNode(1806...1809)(nil, (1806...1809), nil, "foo")], - (1803...1806), - (1809...1810) - ), - (1800...1802) - ), - MatchPredicateNode(1811...1825)( - CallNode(1811...1814)( - nil, - nil, - (1811...1814), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(1818...1825)( - [StringNode(1821...1824)(nil, (1821...1824), nil, "foo")], - (1818...1821), - (1824...1825) - ), - (1815...1817) - ), - MatchPredicateNode(1826...1840)( - CallNode(1826...1829)( - nil, - nil, - (1826...1829), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - ArrayNode(1833...1840)( - [StringNode(1836...1839)(nil, (1836...1839), nil, "foo")], - (1833...1836), - (1839...1840) - ), - (1830...1832) - ), - MatchPredicateNode(1841...1855)( - CallNode(1841...1844)( - nil, - nil, - (1841...1844), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(1848...1855)( - (1848...1851), - (1851...1854), - (1854...1855), - "foo" - ), - (1845...1847) - ), - MatchPredicateNode(1856...1870)( - CallNode(1856...1859)( - nil, - nil, - (1856...1859), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(1863...1870)( - (1863...1866), - (1866...1869), - (1869...1870), - "foo" - ), - (1860...1862) - ), - MatchPredicateNode(1871...1883)( - CallNode(1871...1874)( - nil, - nil, - (1871...1874), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StringNode(1878...1883)( - (1878...1879), - (1879...1882), - (1882...1883), - "foo" - ), - (1875...1877) - ), - MatchPredicateNode(1884...1894)( - CallNode(1884...1887)( - nil, - nil, - (1884...1887), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - NilNode(1891...1894)(), - (1888...1890) - ), - MatchPredicateNode(1895...1906)( - CallNode(1895...1898)( - nil, - nil, - (1895...1898), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SelfNode(1902...1906)(), - (1899...1901) - ), - MatchPredicateNode(1907...1918)( - CallNode(1907...1910)( - nil, - nil, - (1907...1910), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - TrueNode(1914...1918)(), - (1911...1913) - ), - MatchPredicateNode(1919...1931)( - CallNode(1919...1922)( - nil, - nil, - (1919...1922), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - FalseNode(1926...1931)(), - (1923...1925) - ), - MatchPredicateNode(1932...1947)( - CallNode(1932...1935)( - nil, - nil, - (1932...1935), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceFileNode(1939...1947)("patterns.txt"), - (1936...1938) - ), - MatchPredicateNode(1948...1963)( - CallNode(1948...1951)( - nil, - nil, - (1948...1951), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceLineNode(1955...1963)(), - (1952...1954) - ), - MatchPredicateNode(1964...1983)( - CallNode(1964...1967)( - nil, - nil, - (1964...1967), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SourceEncodingNode(1971...1983)(), - (1968...1970) - ), - MatchPredicateNode(1984...2001)( - CallNode(1984...1987)( - nil, - nil, - (1984...1987), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - LambdaNode(1991...2001)( - [], - (1991...1993), - (1994...1995), - (2000...2001), - nil, - StatementsNode(1996...1999)( - [LocalVariableReadNode(1996...1999)(:bar, 1)] - ) - ), - (1988...1990) - ), - CaseNode(2003...2028)( - CallNode(2008...2011)( - nil, - nil, - (2008...2011), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2013...2024)( - LocalVariableTargetNode(2016...2019)(:bar, 0), - nil, - (2013...2015), - (2020...2024) - )], - nil, - (2003...2007), - (2025...2028) - ), - CaseNode(2029...2052)( - CallNode(2034...2037)( - nil, - nil, - (2034...2037), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2039...2048)( - IntegerNode(2042...2043)(), - nil, - (2039...2041), - (2044...2048) - )], - nil, - (2029...2033), - (2049...2052) - ), - CaseNode(2053...2078)( - CallNode(2058...2061)( - nil, - nil, - (2058...2061), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2063...2074)( - FloatNode(2066...2069)(), - nil, - (2063...2065), - (2070...2074) - )], - nil, - (2053...2057), - (2075...2078) - ), - CaseNode(2079...2103)( - CallNode(2084...2087)( - nil, - nil, - (2084...2087), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2089...2099)( - ImaginaryNode(2092...2094)(IntegerNode(2092...2093)()), - nil, - (2089...2091), - (2095...2099) - )], - nil, - (2079...2083), - (2100...2103) - ), - CaseNode(2104...2128)( - CallNode(2109...2112)( - nil, - nil, - (2109...2112), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2114...2124)( - RationalNode(2117...2119)(IntegerNode(2117...2118)()), - nil, - (2114...2116), - (2120...2124) - )], - nil, - (2104...2108), - (2125...2128) - ), - CaseNode(2129...2155)( - CallNode(2134...2137)( - nil, - nil, - (2134...2137), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2139...2151)( - SymbolNode(2142...2146)((2142...2143), (2143...2146), nil, "foo"), - nil, - (2139...2141), - (2147...2151) - )], - nil, - (2129...2133), - (2152...2155) - ), - CaseNode(2156...2185)( - CallNode(2161...2164)( - nil, - nil, - (2161...2164), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2166...2181)( - SymbolNode(2169...2176)( - (2169...2172), - (2172...2175), - (2175...2176), - "foo" - ), - nil, - (2166...2168), - (2177...2181) - )], - nil, - (2156...2160), - (2182...2185) - ), - CaseNode(2186...2214)( - CallNode(2191...2194)( - nil, - nil, - (2191...2194), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2196...2210)( - SymbolNode(2199...2205)( - (2199...2201), - (2201...2204), - (2204...2205), - "foo" - ), - nil, - (2196...2198), - (2206...2210) - )], - nil, - (2186...2190), - (2211...2214) - ), - CaseNode(2215...2242)( - CallNode(2220...2223)( - nil, - nil, - (2220...2223), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2225...2238)( - RegularExpressionNode(2228...2233)( - (2228...2229), - (2229...2232), - (2232...2233), - "foo", - 0 - ), - nil, - (2225...2227), - (2234...2238) - )], - nil, - (2215...2219), - (2239...2242) - ), - CaseNode(2243...2270)( - CallNode(2248...2251)( - nil, - nil, - (2248...2251), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2253...2266)( - XStringNode(2256...2261)( - (2256...2257), - (2257...2260), - (2260...2261), - "foo" - ), - nil, - (2253...2255), - (2262...2266) - )], - nil, - (2243...2247), - (2267...2270) - ), - CaseNode(2271...2300)( - CallNode(2276...2279)( - nil, - nil, - (2276...2279), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2281...2296)( - XStringNode(2284...2291)( - (2284...2287), - (2287...2290), - (2290...2291), - "foo" - ), - nil, - (2281...2283), - (2292...2296) - )], - nil, - (2271...2275), - (2297...2300) - ), - CaseNode(2301...2330)( - CallNode(2306...2309)( - nil, - nil, - (2306...2309), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2311...2326)( - ArrayNode(2314...2321)( - [SymbolNode(2317...2320)(nil, (2317...2320), nil, "foo")], - (2314...2317), - (2320...2321) - ), - nil, - (2311...2313), - (2322...2326) - )], - nil, - (2301...2305), - (2327...2330) - ), - CaseNode(2331...2360)( - CallNode(2336...2339)( - nil, - nil, - (2336...2339), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2341...2356)( - ArrayNode(2344...2351)( - [SymbolNode(2347...2350)(nil, (2347...2350), nil, "foo")], - (2344...2347), - (2350...2351) - ), - nil, - (2341...2343), - (2352...2356) - )], - nil, - (2331...2335), - (2357...2360) - ), - CaseNode(2361...2390)( - CallNode(2366...2369)( - nil, - nil, - (2366...2369), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2371...2386)( - ArrayNode(2374...2381)( - [StringNode(2377...2380)(nil, (2377...2380), nil, "foo")], - (2374...2377), - (2380...2381) - ), - nil, - (2371...2373), - (2382...2386) - )], - nil, - (2361...2365), - (2387...2390) - ), - CaseNode(2391...2420)( - CallNode(2396...2399)( - nil, - nil, - (2396...2399), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2401...2416)( - ArrayNode(2404...2411)( - [StringNode(2407...2410)(nil, (2407...2410), nil, "foo")], - (2404...2407), - (2410...2411) - ), - nil, - (2401...2403), - (2412...2416) - )], - nil, - (2391...2395), - (2417...2420) - ), - CaseNode(2421...2450)( - CallNode(2426...2429)( - nil, - nil, - (2426...2429), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2431...2446)( - StringNode(2434...2441)( - (2434...2437), - (2437...2440), - (2440...2441), - "foo" - ), - nil, - (2431...2433), - (2442...2446) - )], - nil, - (2421...2425), - (2447...2450) - ), - CaseNode(2451...2480)( - CallNode(2456...2459)( - nil, - nil, - (2456...2459), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2461...2476)( - StringNode(2464...2471)( - (2464...2467), - (2467...2470), - (2470...2471), - "foo" - ), - nil, - (2461...2463), - (2472...2476) - )], - nil, - (2451...2455), - (2477...2480) - ), - CaseNode(2481...2508)( - CallNode(2486...2489)( - nil, - nil, - (2486...2489), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2491...2504)( - StringNode(2494...2499)( - (2494...2495), - (2495...2498), - (2498...2499), - "foo" - ), - nil, - (2491...2493), - (2500...2504) - )], - nil, - (2481...2485), - (2505...2508) - ), - CaseNode(2509...2534)( - CallNode(2514...2517)( - nil, - nil, - (2514...2517), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2519...2530)( - NilNode(2522...2525)(), - nil, - (2519...2521), - (2526...2530) - )], - nil, - (2509...2513), - (2531...2534) - ), - CaseNode(2535...2561)( - CallNode(2540...2543)( - nil, - nil, - (2540...2543), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2545...2557)( - SelfNode(2548...2552)(), - nil, - (2545...2547), - (2553...2557) - )], - nil, - (2535...2539), - (2558...2561) - ), - CaseNode(2562...2588)( - CallNode(2567...2570)( - nil, - nil, - (2567...2570), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2572...2584)( - TrueNode(2575...2579)(), - nil, - (2572...2574), - (2580...2584) - )], - nil, - (2562...2566), - (2585...2588) - ), - CaseNode(2589...2616)( - CallNode(2594...2597)( - nil, - nil, - (2594...2597), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2599...2612)( - FalseNode(2602...2607)(), - nil, - (2599...2601), - (2608...2612) - )], - nil, - (2589...2593), - (2613...2616) - ), - CaseNode(2617...2647)( - CallNode(2622...2625)( - nil, - nil, - (2622...2625), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2627...2643)( - SourceFileNode(2630...2638)("patterns.txt"), - nil, - (2627...2629), - (2639...2643) - )], - nil, - (2617...2621), - (2644...2647) - ), - CaseNode(2648...2678)( - CallNode(2653...2656)( - nil, - nil, - (2653...2656), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2658...2674)( - SourceLineNode(2661...2669)(), - nil, - (2658...2660), - (2670...2674) - )], - nil, - (2648...2652), - (2675...2678) - ), - CaseNode(2679...2713)( - CallNode(2684...2687)( - nil, - nil, - (2684...2687), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2689...2709)( - SourceEncodingNode(2692...2704)(), - nil, - (2689...2691), - (2705...2709) - )], - nil, - (2679...2683), - (2710...2713) - ), - CaseNode(2714...2746)( - CallNode(2719...2722)( - nil, - nil, - (2719...2722), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2724...2742)( - LambdaNode(2727...2737)( - [], - (2727...2729), - (2730...2731), - (2736...2737), - nil, - StatementsNode(2732...2735)( - [LocalVariableReadNode(2732...2735)(:bar, 1)] - ) - ), - nil, - (2724...2726), - (2738...2742) - )], - nil, - (2714...2718), - (2743...2746) - ), - CaseNode(2748...2780)( - CallNode(2753...2756)( - nil, - nil, - (2753...2756), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2758...2776)( - IfNode(2761...2771)( - (2765...2767), - LocalVariableReadNode(2768...2771)(:baz, 0), - StatementsNode(2761...2764)( - [LocalVariableTargetNode(2761...2764)(:bar, 0)] - ), - nil, - nil - ), - nil, - (2758...2760), - (2772...2776) - )], - nil, - (2748...2752), - (2777...2780) - ), - CaseNode(2781...2811)( - CallNode(2786...2789)( - nil, - nil, - (2786...2789), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2791...2807)( - IfNode(2794...2802)( - (2796...2798), - LocalVariableReadNode(2799...2802)(:baz, 0), - StatementsNode(2794...2795)([IntegerNode(2794...2795)()]), - nil, - nil - ), - nil, - (2791...2793), - (2803...2807) - )], - nil, - (2781...2785), - (2808...2811) - ), - CaseNode(2812...2844)( - CallNode(2817...2820)( - nil, - nil, - (2817...2820), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2822...2840)( - IfNode(2825...2835)( - (2829...2831), - LocalVariableReadNode(2832...2835)(:baz, 0), - StatementsNode(2825...2828)([FloatNode(2825...2828)()]), - nil, - nil - ), - nil, - (2822...2824), - (2836...2840) - )], - nil, - (2812...2816), - (2841...2844) - ), - CaseNode(2845...2876)( - CallNode(2850...2853)( - nil, - nil, - (2850...2853), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2855...2872)( - IfNode(2858...2867)( - (2861...2863), - LocalVariableReadNode(2864...2867)(:baz, 0), - StatementsNode(2858...2860)( - [ImaginaryNode(2858...2860)(IntegerNode(2858...2859)())] - ), - nil, - nil - ), - nil, - (2855...2857), - (2868...2872) - )], - nil, - (2845...2849), - (2873...2876) - ), - CaseNode(2877...2908)( - CallNode(2882...2885)( - nil, - nil, - (2882...2885), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2887...2904)( - IfNode(2890...2899)( - (2893...2895), - LocalVariableReadNode(2896...2899)(:baz, 0), - StatementsNode(2890...2892)( - [RationalNode(2890...2892)(IntegerNode(2890...2891)())] - ), - nil, - nil - ), - nil, - (2887...2889), - (2900...2904) - )], - nil, - (2877...2881), - (2905...2908) - ), - CaseNode(2909...2942)( - CallNode(2914...2917)( - nil, - nil, - (2914...2917), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2919...2938)( - IfNode(2922...2933)( - (2927...2929), - LocalVariableReadNode(2930...2933)(:baz, 0), - StatementsNode(2922...2926)( - [SymbolNode(2922...2926)( - (2922...2923), - (2923...2926), - nil, - "foo" - )] - ), - nil, - nil - ), - nil, - (2919...2921), - (2934...2938) - )], - nil, - (2909...2913), - (2939...2942) - ), - CaseNode(2943...2979)( - CallNode(2948...2951)( - nil, - nil, - (2948...2951), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2953...2975)( - IfNode(2956...2970)( - (2964...2966), - LocalVariableReadNode(2967...2970)(:baz, 0), - StatementsNode(2956...2963)( - [SymbolNode(2956...2963)( - (2956...2959), - (2959...2962), - (2962...2963), - "foo" - )] - ), - nil, - nil - ), - nil, - (2953...2955), - (2971...2975) - )], - nil, - (2943...2947), - (2976...2979) - ), - CaseNode(2980...3015)( - CallNode(2985...2988)( - nil, - nil, - (2985...2988), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(2990...3011)( - IfNode(2993...3006)( - (3000...3002), - LocalVariableReadNode(3003...3006)(:baz, 0), - StatementsNode(2993...2999)( - [SymbolNode(2993...2999)( - (2993...2995), - (2995...2998), - (2998...2999), - "foo" - )] - ), - nil, - nil - ), - nil, - (2990...2992), - (3007...3011) - )], - nil, - (2980...2984), - (3012...3015) - ), - CaseNode(3016...3050)( - CallNode(3021...3024)( - nil, - nil, - (3021...3024), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3026...3046)( - IfNode(3029...3041)( - (3035...3037), - LocalVariableReadNode(3038...3041)(:baz, 0), - StatementsNode(3029...3034)( - [RegularExpressionNode(3029...3034)( - (3029...3030), - (3030...3033), - (3033...3034), - "foo", - 0 - )] - ), - nil, - nil - ), - nil, - (3026...3028), - (3042...3046) - )], - nil, - (3016...3020), - (3047...3050) - ), - CaseNode(3051...3085)( - CallNode(3056...3059)( - nil, - nil, - (3056...3059), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3061...3081)( - IfNode(3064...3076)( - (3070...3072), - LocalVariableReadNode(3073...3076)(:baz, 0), - StatementsNode(3064...3069)( - [XStringNode(3064...3069)( - (3064...3065), - (3065...3068), - (3068...3069), - "foo" - )] - ), - nil, - nil - ), - nil, - (3061...3063), - (3077...3081) - )], - nil, - (3051...3055), - (3082...3085) - ), - CaseNode(3086...3122)( - CallNode(3091...3094)( - nil, - nil, - (3091...3094), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3096...3118)( - IfNode(3099...3113)( - (3107...3109), - LocalVariableReadNode(3110...3113)(:baz, 0), - StatementsNode(3099...3106)( - [XStringNode(3099...3106)( - (3099...3102), - (3102...3105), - (3105...3106), - "foo" - )] - ), - nil, - nil - ), - nil, - (3096...3098), - (3114...3118) - )], - nil, - (3086...3090), - (3119...3122) - ), - CaseNode(3123...3159)( - CallNode(3128...3131)( - nil, - nil, - (3128...3131), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3133...3155)( - IfNode(3136...3150)( - (3144...3146), - LocalVariableReadNode(3147...3150)(:baz, 0), - StatementsNode(3136...3143)( - [ArrayNode(3136...3143)( - [SymbolNode(3139...3142)(nil, (3139...3142), nil, "foo")], - (3136...3139), - (3142...3143) - )] - ), - nil, - nil - ), - nil, - (3133...3135), - (3151...3155) - )], - nil, - (3123...3127), - (3156...3159) - ), - CaseNode(3160...3196)( - CallNode(3165...3168)( - nil, - nil, - (3165...3168), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3170...3192)( - IfNode(3173...3187)( - (3181...3183), - LocalVariableReadNode(3184...3187)(:baz, 0), - StatementsNode(3173...3180)( - [ArrayNode(3173...3180)( - [SymbolNode(3176...3179)(nil, (3176...3179), nil, "foo")], - (3173...3176), - (3179...3180) - )] - ), - nil, - nil - ), - nil, - (3170...3172), - (3188...3192) - )], - nil, - (3160...3164), - (3193...3196) - ), - CaseNode(3197...3233)( - CallNode(3202...3205)( - nil, - nil, - (3202...3205), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3207...3229)( - IfNode(3210...3224)( - (3218...3220), - LocalVariableReadNode(3221...3224)(:baz, 0), - StatementsNode(3210...3217)( - [ArrayNode(3210...3217)( - [StringNode(3213...3216)(nil, (3213...3216), nil, "foo")], - (3210...3213), - (3216...3217) - )] - ), - nil, - nil - ), - nil, - (3207...3209), - (3225...3229) - )], - nil, - (3197...3201), - (3230...3233) - ), - CaseNode(3234...3270)( - CallNode(3239...3242)( - nil, - nil, - (3239...3242), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3244...3266)( - IfNode(3247...3261)( - (3255...3257), - LocalVariableReadNode(3258...3261)(:baz, 0), - StatementsNode(3247...3254)( - [ArrayNode(3247...3254)( - [StringNode(3250...3253)(nil, (3250...3253), nil, "foo")], - (3247...3250), - (3253...3254) - )] - ), - nil, - nil - ), - nil, - (3244...3246), - (3262...3266) - )], - nil, - (3234...3238), - (3267...3270) - ), - CaseNode(3271...3307)( - CallNode(3276...3279)( - nil, - nil, - (3276...3279), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3281...3303)( - IfNode(3284...3298)( - (3292...3294), - LocalVariableReadNode(3295...3298)(:baz, 0), - StatementsNode(3284...3291)( - [StringNode(3284...3291)( - (3284...3287), - (3287...3290), - (3290...3291), - "foo" - )] - ), - nil, - nil - ), - nil, - (3281...3283), - (3299...3303) - )], - nil, - (3271...3275), - (3304...3307) - ), - CaseNode(3308...3344)( - CallNode(3313...3316)( - nil, - nil, - (3313...3316), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3318...3340)( - IfNode(3321...3335)( - (3329...3331), - LocalVariableReadNode(3332...3335)(:baz, 0), - StatementsNode(3321...3328)( - [StringNode(3321...3328)( - (3321...3324), - (3324...3327), - (3327...3328), - "foo" - )] - ), - nil, - nil - ), - nil, - (3318...3320), - (3336...3340) - )], - nil, - (3308...3312), - (3341...3344) - ), - CaseNode(3345...3379)( - CallNode(3350...3353)( - nil, - nil, - (3350...3353), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3355...3375)( - IfNode(3358...3370)( - (3364...3366), - LocalVariableReadNode(3367...3370)(:baz, 0), - StatementsNode(3358...3363)( - [StringNode(3358...3363)( - (3358...3359), - (3359...3362), - (3362...3363), - "foo" - )] - ), - nil, - nil - ), - nil, - (3355...3357), - (3371...3375) - )], - nil, - (3345...3349), - (3376...3379) - ), - CaseNode(3380...3412)( - CallNode(3385...3388)( - nil, - nil, - (3385...3388), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3390...3408)( - IfNode(3393...3403)( - (3397...3399), - LocalVariableReadNode(3400...3403)(:baz, 0), - StatementsNode(3393...3396)([NilNode(3393...3396)()]), - nil, - nil - ), - nil, - (3390...3392), - (3404...3408) - )], - nil, - (3380...3384), - (3409...3412) - ), - CaseNode(3413...3446)( - CallNode(3418...3421)( - nil, - nil, - (3418...3421), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3423...3442)( - IfNode(3426...3437)( - (3431...3433), - LocalVariableReadNode(3434...3437)(:baz, 0), - StatementsNode(3426...3430)([SelfNode(3426...3430)()]), - nil, - nil - ), - nil, - (3423...3425), - (3438...3442) - )], - nil, - (3413...3417), - (3443...3446) - ), - CaseNode(3447...3480)( - CallNode(3452...3455)( - nil, - nil, - (3452...3455), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3457...3476)( - IfNode(3460...3471)( - (3465...3467), - LocalVariableReadNode(3468...3471)(:baz, 0), - StatementsNode(3460...3464)([TrueNode(3460...3464)()]), - nil, - nil - ), - nil, - (3457...3459), - (3472...3476) - )], - nil, - (3447...3451), - (3477...3480) - ), - CaseNode(3481...3515)( - CallNode(3486...3489)( - nil, - nil, - (3486...3489), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3491...3511)( - IfNode(3494...3506)( - (3500...3502), - LocalVariableReadNode(3503...3506)(:baz, 0), - StatementsNode(3494...3499)([FalseNode(3494...3499)()]), - nil, - nil - ), - nil, - (3491...3493), - (3507...3511) - )], - nil, - (3481...3485), - (3512...3515) - ), - CaseNode(3516...3553)( - CallNode(3521...3524)( - nil, - nil, - (3521...3524), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3526...3549)( - IfNode(3529...3544)( - (3538...3540), - LocalVariableReadNode(3541...3544)(:baz, 0), - StatementsNode(3529...3537)( - [SourceFileNode(3529...3537)("patterns.txt")] - ), - nil, - nil - ), - nil, - (3526...3528), - (3545...3549) - )], - nil, - (3516...3520), - (3550...3553) - ), - CaseNode(3554...3591)( - CallNode(3559...3562)( - nil, - nil, - (3559...3562), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3564...3587)( - IfNode(3567...3582)( - (3576...3578), - LocalVariableReadNode(3579...3582)(:baz, 0), - StatementsNode(3567...3575)([SourceLineNode(3567...3575)()]), - nil, - nil - ), - nil, - (3564...3566), - (3583...3587) - )], - nil, - (3554...3558), - (3588...3591) - ), - CaseNode(3592...3633)( - CallNode(3597...3600)( - nil, - nil, - (3597...3600), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3602...3629)( - IfNode(3605...3624)( - (3618...3620), - LocalVariableReadNode(3621...3624)(:baz, 0), - StatementsNode(3605...3617)([SourceEncodingNode(3605...3617)()]), - nil, - nil - ), - nil, - (3602...3604), - (3625...3629) - )], - nil, - (3592...3596), - (3630...3633) - ), - CaseNode(3634...3673)( - CallNode(3639...3642)( - nil, - nil, - (3639...3642), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(3644...3669)( - IfNode(3647...3664)( - (3658...3660), - LocalVariableReadNode(3661...3664)(:baz, 0), - StatementsNode(3647...3657)( - [LambdaNode(3647...3657)( - [], - (3647...3649), - (3650...3651), - (3656...3657), - nil, - StatementsNode(3652...3655)( - [LocalVariableReadNode(3652...3655)(:bar, 1)] - ) - )] - ), - nil, - nil - ), - nil, - (3644...3646), - (3665...3669) - )], - nil, - (3634...3638), - (3670...3673) - ), - IfNode(3675...3689)( - (3675...3677), - MatchPredicateNode(3678...3685)( - CallNode(3678...3679)( - nil, - nil, - (3678...3679), - nil, - nil, - nil, - nil, - 2, - "a" - ), - ArrayPatternNode(3683...3685)( - nil, - [], - nil, - [], - (3683...3684), - (3684...3685) - ), - (3680...3682) - ), - nil, - nil, - (3686...3689) - ), - MatchRequiredNode(3691...3703)( - CallNode(3691...3692)( - nil, - nil, - (3691...3692), - nil, - nil, - nil, - nil, - 2, - "a" - ), - ArrayPatternNode(3696...3703)( - nil, - [LocalVariableTargetNode(3700...3701)(:b, 0)], - nil, - [], - (3696...3697), - (3702...3703) - ), - (3693...3695) - ), - MatchPredicateNode(3705...3743)( - CallNode(3705...3708)( - nil, - nil, - (3705...3708), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - HashPatternNode(3712...3743)( - ConstantReadNode(3712...3713)(:A), - [AssocNode(3717...3741)( - SymbolNode(3717...3721)(nil, (3717...3720), (3720...3721), "bar"), - HashPatternNode(3722...3741)( - ConstantReadNode(3722...3723)(:B), - [AssocNode(3729...3737)( - SymbolNode(3729...3735)( - nil, - (3729...3734), - (3734...3735), - "value" - ), - LocalVariableTargetNode(3736...3737)(:a, 0), - nil - )], - nil, - (3723...3724), - (3740...3741) - ), - nil - )], - nil, - (3713...3714), - (3742...3743) - ), - (3709...3711) - )] - ) -) diff --git a/test/yarp/snapshots/procs.txt b/test/yarp/snapshots/procs.txt deleted file mode 100644 index fca9ccb7103a9a..00000000000000 --- a/test/yarp/snapshots/procs.txt +++ /dev/null @@ -1,242 +0,0 @@ -ProgramNode(0...266)( - [], - StatementsNode(0...266)( - [LambdaNode(0...21)( - [:a, :b, :c, :d], - (0...2), - (16...17), - (20...21), - BlockParametersNode(3...15)( - ParametersNode(4...5)( - [RequiredParameterNode(4...5)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(7...8)(:b), - BlockLocalVariableNode(10...11)(:c), - BlockLocalVariableNode(13...14)(:d)], - (3...4), - (14...15) - ), - StatementsNode(18...19)([LocalVariableReadNode(18...19)(:b, 0)]) - ), - LambdaNode(23...39)( - [], - (23...25), - (26...28), - (36...39), - nil, - BeginNode(29...39)( - nil, - nil, - nil, - nil, - EnsureNode(29...39)((29...35), nil, (36...39)), - (36...39) - ) - ), - LambdaNode(41...69)( - [], - (41...43), - (44...46), - (66...69), - nil, - BeginNode(47...69)( - nil, - nil, - RescueNode(47...53)((47...53), [], nil, nil, nil, nil), - ElseNode(54...65)((54...58), nil, (59...65)), - EnsureNode(59...69)((59...65), nil, (66...69)), - (66...69) - ) - ), - LambdaNode(71...81)( - [], - (71...73), - (74...75), - (80...81), - nil, - StatementsNode(76...79)( - [CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 2, "foo")] - ) - ), - LambdaNode(83...98)( - [], - (83...85), - (86...88), - (95...98), - nil, - StatementsNode(90...93)( - [CallNode(90...93)(nil, nil, (90...93), nil, nil, nil, nil, 2, "foo")] - ) - ), - LambdaNode(100...129)( - [:a, :b, :c, :d, :e], - (100...102), - (124...125), - (128...129), - BlockParametersNode(103...123)( - ParametersNode(103...123)( - [RequiredParameterNode(103...104)(:a)], - [OptionalParameterNode(106...111)( - :b, - (106...107), - (108...109), - IntegerNode(110...111)() - )], - [], - nil, - [KeywordParameterNode(113...115)(:c, (113...115), nil), - KeywordParameterNode(117...119)(:d, (117...119), nil)], - nil, - BlockParameterNode(121...123)(:e, (122...123), (121...122)) - ), - [], - nil, - nil - ), - StatementsNode(126...127)([LocalVariableReadNode(126...127)(:a, 0)]) - ), - LambdaNode(131...171)( - [:a, :b, :c, :d, :e, :f, :g], - (131...133), - (166...167), - (170...171), - BlockParametersNode(134...165)( - ParametersNode(135...164)( - [RequiredParameterNode(135...136)(:a)], - [OptionalParameterNode(138...143)( - :b, - (138...139), - (140...141), - IntegerNode(142...143)() - )], - [], - RestParameterNode(145...147)(:c, (146...147), (145...146)), - [KeywordParameterNode(149...151)(:d, (149...151), nil), - KeywordParameterNode(153...155)(:e, (153...155), nil)], - KeywordRestParameterNode(157...160)(:f, (159...160), (157...159)), - BlockParameterNode(162...164)(:g, (163...164), (162...163)) - ), - [], - (134...135), - (164...165) - ), - StatementsNode(168...169)([LocalVariableReadNode(168...169)(:a, 0)]) - ), - LambdaNode(173...218)( - [:a, :b, :c, :d, :e, :f, :g], - (173...175), - (208...210), - (215...218), - BlockParametersNode(176...207)( - ParametersNode(177...206)( - [RequiredParameterNode(177...178)(:a)], - [OptionalParameterNode(180...185)( - :b, - (180...181), - (182...183), - IntegerNode(184...185)() - )], - [], - RestParameterNode(187...189)(:c, (188...189), (187...188)), - [KeywordParameterNode(191...193)(:d, (191...193), nil), - KeywordParameterNode(195...197)(:e, (195...197), nil)], - KeywordRestParameterNode(199...202)(:f, (201...202), (199...201)), - BlockParameterNode(204...206)(:g, (205...206), (204...205)) - ), - [], - (176...177), - (206...207) - ), - StatementsNode(213...214)([LocalVariableReadNode(213...214)(:a, 0)]) - ), - LambdaNode(220...245)( - [:a], - (220...222), - (227...228), - (244...245), - BlockParametersNode(223...226)( - ParametersNode(224...225)( - [RequiredParameterNode(224...225)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (223...224), - (225...226) - ), - StatementsNode(229...243)( - [LambdaNode(229...243)( - [:b], - (229...231), - (234...235), - (242...243), - BlockParametersNode(232...233)( - ParametersNode(232...233)( - [RequiredParameterNode(232...233)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - nil, - nil - ), - StatementsNode(236...241)( - [CallNode(236...241)( - LocalVariableReadNode(236...237)(:a, 1), - nil, - (238...239), - nil, - ArgumentsNode(240...241)( - [LocalVariableReadNode(240...241)(:b, 0)] - ), - nil, - nil, - 0, - "*" - )] - ) - )] - ) - ), - LambdaNode(247...266)( - [:a, :b, :c], - (247...249), - (263...264), - (265...266), - BlockParametersNode(250...262)( - ParametersNode(251...261)( - [RequiredDestructuredParameterNode(251...257)( - [RequiredParameterNode(252...253)(:a), - RequiredParameterNode(255...256)(:b)], - (251...252), - (256...257) - )], - [], - [], - RestParameterNode(259...261)(:c, (260...261), (259...260)), - [], - nil, - nil - ), - [], - (250...251), - (261...262) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/range_begin_open_exclusive.txt b/test/yarp/snapshots/range_begin_open_exclusive.txt deleted file mode 100644 index 50a6593c4662de..00000000000000 --- a/test/yarp/snapshots/range_begin_open_exclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [RangeNode(0...4)(nil, IntegerNode(3...4)(), (0...3), 1)] - ) -) diff --git a/test/yarp/snapshots/range_begin_open_inclusive.txt b/test/yarp/snapshots/range_begin_open_inclusive.txt deleted file mode 100644 index 7d09381f30c31e..00000000000000 --- a/test/yarp/snapshots/range_begin_open_inclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)( - [RangeNode(0...3)(nil, IntegerNode(2...3)(), (0...2), 0)] - ) -) diff --git a/test/yarp/snapshots/range_end_open_exclusive.txt b/test/yarp/snapshots/range_end_open_exclusive.txt deleted file mode 100644 index 3da37b123ce306..00000000000000 --- a/test/yarp/snapshots/range_end_open_exclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [RangeNode(0...4)(IntegerNode(0...1)(), nil, (1...4), 1)] - ) -) diff --git a/test/yarp/snapshots/range_end_open_inclusive.txt b/test/yarp/snapshots/range_end_open_inclusive.txt deleted file mode 100644 index e1b90bdffcfad1..00000000000000 --- a/test/yarp/snapshots/range_end_open_inclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)( - [RangeNode(0...3)(IntegerNode(0...1)(), nil, (1...3), 0)] - ) -) diff --git a/test/yarp/snapshots/ranges.txt b/test/yarp/snapshots/ranges.txt deleted file mode 100644 index 8873f61b0a9d68..00000000000000 --- a/test/yarp/snapshots/ranges.txt +++ /dev/null @@ -1,106 +0,0 @@ -ProgramNode(0...85)( - [], - StatementsNode(0...85)( - [ParenthesesNode(0...6)( - StatementsNode(1...5)( - [RangeNode(1...5)(nil, IntegerNode(4...5)(), (1...4), 1)] - ), - (0...1), - (5...6) - ), - ParenthesesNode(8...13)( - StatementsNode(9...12)( - [RangeNode(9...12)(nil, IntegerNode(11...12)(), (9...11), 0)] - ), - (8...9), - (12...13) - ), - RangeNode(15...20)( - IntegerNode(15...16)(), - IntegerNode(19...20)(), - (16...19), - 1 - ), - CallNode(22...31)( - CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "foo"), - nil, - (25...31), - (25...26), - ArgumentsNode(26...30)( - [RangeNode(26...30)(nil, IntegerNode(29...30)(), (26...29), 1)] - ), - (30...31), - nil, - 0, - "[]" - ), - HashNode(33...48)( - (33...34), - [AssocNode(35...46)( - SymbolNode(35...39)(nil, (35...38), (38...39), "foo"), - RangeNode(40...46)( - nil, - CallNode(43...46)( - nil, - nil, - (43...46), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (40...43), - 1 - ), - nil - )], - (47...48) - ), - ParenthesesNode(50...56)( - StatementsNode(51...55)( - [RangeNode(51...55)(IntegerNode(51...52)(), nil, (52...55), 1)] - ), - (50...51), - (55...56) - ), - RangeNode(58...62)( - IntegerNode(58...59)(), - IntegerNode(61...62)(), - (59...61), - 0 - ), - HashNode(64...78)( - (64...65), - [AssocNode(66...76)( - SymbolNode(66...70)(nil, (66...69), (69...70), "foo"), - RangeNode(71...76)( - nil, - CallNode(73...76)( - nil, - nil, - (73...76), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (71...73), - 0 - ), - nil - )], - (77...78) - ), - ParenthesesNode(80...85)( - StatementsNode(81...84)( - [RangeNode(81...84)(IntegerNode(81...82)(), nil, (82...84), 0)] - ), - (80...81), - (84...85) - )] - ) -) diff --git a/test/yarp/snapshots/regex.txt b/test/yarp/snapshots/regex.txt deleted file mode 100644 index 37e32c4dd86f78..00000000000000 --- a/test/yarp/snapshots/regex.txt +++ /dev/null @@ -1,166 +0,0 @@ -ProgramNode(0...293)( - [:foo], - StatementsNode(0...293)( - [CallNode(0...9)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...9)( - [RegularExpressionNode(4...9)((4...5), (5...8), (8...9), "bar", 0)] - ), - nil, - nil, - 0, - "foo" - ), - RegularExpressionNode(11...19)((11...14), (14...17), (17...19), "abc", 1), - RegularExpressionNode(21...26)((21...22), (22...25), (25...26), "a\b", 0), - InterpolatedRegularExpressionNode(28...39)( - (28...29), - [StringNode(29...33)(nil, (29...33), nil, "aaa "), - EmbeddedVariableNode(33...38)( - (33...34), - GlobalVariableReadNode(34...38)(:$bbb) - )], - (38...39), - 0 - ), - InterpolatedRegularExpressionNode(41...57)( - (41...42), - [StringNode(42...46)(nil, (42...46), nil, "aaa "), - EmbeddedStatementsNode(46...52)( - (46...48), - StatementsNode(48...51)( - [CallNode(48...51)( - nil, - nil, - (48...51), - nil, - nil, - nil, - nil, - 2, - "bbb" - )] - ), - (51...52) - ), - StringNode(52...56)(nil, (52...56), nil, " ccc")], - (56...57), - 0 - ), - ArrayNode(59...86)( - [CallNode(60...80)( - RegularExpressionNode(60...73)( - (60...61), - (61...72), - (72...73), - "(?bar)", - 0 - ), - nil, - (74...76), - nil, - ArgumentsNode(77...80)( - [CallNode(77...80)( - nil, - nil, - (77...80), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil, - nil, - 0, - "=~" - ), - LocalVariableReadNode(82...85)(:foo, 0)], - (59...60), - (85...86) - ), - RegularExpressionNode(88...94)((88...89), (89...92), (92...94), "abc", 1), - RegularExpressionNode(96...122)( - (96...99), - (99...120), - (120...122), - "[a-z$._?][w$.?\#@~]*:", - 1 - ), - RegularExpressionNode(124...161)( - (124...127), - (127...159), - (159...161), - "([a-z$._?][w$.?\#@~]*)( +)(equ)", - 1 - ), - RegularExpressionNode(163...188)( - (163...166), - (166...186), - (186...188), - "[a-z$._?][w$.?\#@~]*", - 1 - ), - RegularExpressionNode(190...249)( - (190...193), - (193...248), - (248...249), - "\n" + "(?:[w\#$%_']|()|(,)|[]|[0-9])*\n" + " (?:[w\#$%_']+)\n", - 0 - ), - CallNode(251...267)( - RegularExpressionNode(251...259)( - (251...252), - (252...258), - (258...259), - "(?#))", - 0 - ), - nil, - (260...262), - nil, - ArgumentsNode(263...267)( - [StringNode(263...267)((263...264), (264...266), (266...267), "hi")] - ), - nil, - nil, - 0, - "=~" - ), - RegularExpressionNode(269...278)( - (269...272), - (272...277), - (277...278), - "pound", - 0 - ), - InterpolatedRegularExpressionNode(280...293)( - (280...281), - [StringNode(281...285)(nil, (281...285), nil, "aaa "), - EmbeddedStatementsNode(285...291)( - (285...287), - StatementsNode(287...290)( - [CallNode(287...290)( - nil, - nil, - (287...290), - nil, - nil, - nil, - nil, - 2, - "bbb" - )] - ), - (290...291) - )], - (291...293), - 128 - )] - ) -) diff --git a/test/yarp/snapshots/rescue.txt b/test/yarp/snapshots/rescue.txt deleted file mode 100644 index 9decb56292bf2c..00000000000000 --- a/test/yarp/snapshots/rescue.txt +++ /dev/null @@ -1,308 +0,0 @@ -ProgramNode(0...316)( - [:a], - StatementsNode(0...316)( - [RescueModifierNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (4...10), - NilNode(11...14)() - ), - RescueModifierNode(16...30)( - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "foo"), - (20...26), - NilNode(27...30)() - ), - RescueModifierNode(32...48)( - BreakNode(32...37)(nil, (32...37)), - (38...44), - NilNode(45...48)() - ), - RescueModifierNode(50...65)( - NextNode(50...54)(nil, (50...54)), - (55...61), - NilNode(62...65)() - ), - RescueModifierNode(67...84)( - ReturnNode(67...73)((67...73), nil), - (74...80), - NilNode(81...84)() - ), - RescueModifierNode(86...105)( - CallNode(86...89)(nil, nil, (86...89), nil, nil, nil, nil, 2, "foo"), - (90...96), - OrNode(97...105)( - NilNode(97...100)(), - IntegerNode(104...105)(), - (101...103) - ) - ), - RescueModifierNode(107...129)( - CallNode(107...110)( - nil, - nil, - (107...110), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (111...117), - IfNode(118...129)( - nil, - NilNode(118...121)(), - StatementsNode(124...125)([IntegerNode(124...125)()]), - ElseNode(126...129)( - (126...127), - StatementsNode(128...129)([IntegerNode(128...129)()]), - nil - ), - nil - ) - ), - BeginNode(131...155)( - (131...136), - StatementsNode(138...139)( - [CallNode(138...139)( - nil, - nil, - (138...139), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(141...150)( - (141...147), - [SplatNode(148...150)( - (148...149), - CallNode(149...150)( - nil, - nil, - (149...150), - nil, - nil, - nil, - nil, - 2, - "b" - ) - )], - nil, - nil, - nil, - nil - ), - nil, - nil, - (152...155) - ), - CallNode(157...212)( - nil, - nil, - (157...160), - nil, - nil, - nil, - BlockNode(161...212)( - [:x], - BlockParametersNode(164...167)( - ParametersNode(165...166)( - [RequiredParameterNode(165...166)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (164...165), - (166...167) - ), - StatementsNode(170...208)( - [RescueModifierNode(170...208)( - CallNode(170...176)( - nil, - nil, - (170...173), - (173...174), - ArgumentsNode(174...175)( - [CallNode(174...175)( - nil, - nil, - (174...175), - nil, - nil, - nil, - nil, - 2, - "y" - )] - ), - (175...176), - nil, - 0, - "bar" - ), - (177...183), - CallNode(184...208)( - nil, - nil, - (184...197), - nil, - ArgumentsNode(198...208)( - [CallNode(198...208)( - nil, - nil, - (198...202), - nil, - ArgumentsNode(203...208)( - [StringNode(203...208)( - (203...204), - (204...207), - (207...208), - "baz" - )] - ), - nil, - nil, - 0, - "fail" - )] - ), - nil, - nil, - 0, - "ArgumentError" - ) - )] - ), - (161...163), - (209...212) - ), - 0, - "foo" - ), - IfNode(214...245)( - (214...216), - LocalVariableWriteNode(217...235)( - :a, - 0, - (217...218), - RescueModifierNode(221...235)( - CallNode(221...224)( - nil, - nil, - (221...224), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (225...231), - NilNode(232...235)() - ), - (219...220) - ), - StatementsNode(238...241)( - [CallNode(238...241)( - nil, - nil, - (238...241), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - (242...245) - ), - DefNode(247...291)( - :some_method, - (251...262), - nil, - nil, - StatementsNode(265...291)( - [CallNode(265...291)( - nil, - nil, - (265...277), - nil, - ArgumentsNode(278...291)( - [RescueModifierNode(278...291)( - IntegerNode(278...280)(), - (281...287), - NilNode(288...291)() - )] - ), - nil, - nil, - 0, - "other_method" - )] - ), - [], - (247...250), - nil, - nil, - nil, - (263...264), - nil - ), - DefNode(293...316)( - :a, - (297...298), - nil, - nil, - BeginNode(301...316)( - nil, - StatementsNode(301...305)( - [CallNode(301...305)( - nil, - nil, - (301...302), - nil, - ArgumentsNode(303...305)( - [KeywordHashNode(303...305)( - [AssocNode(303...305)( - SymbolNode(303...305)( - nil, - (303...304), - (304...305), - "b" - ), - nil, - nil - )] - )] - ), - nil, - nil, - 0, - "a" - )] - ), - RescueNode(306...312)((306...312), [], nil, nil, nil, nil), - nil, - nil, - (313...316) - ), - [], - (293...296), - nil, - nil, - nil, - nil, - (313...316) - )] - ) -) diff --git a/test/yarp/snapshots/return.txt b/test/yarp/snapshots/return.txt deleted file mode 100644 index bbb4b63af22185..00000000000000 --- a/test/yarp/snapshots/return.txt +++ /dev/null @@ -1,92 +0,0 @@ -ProgramNode(0...139)( - [], - StatementsNode(0...139)( - [ReturnNode(0...6)((0...6), nil), - ReturnNode(8...28)( - (8...14), - ArgumentsNode(15...28)( - [ParenthesesNode(15...18)( - StatementsNode(16...17)([IntegerNode(16...17)()]), - (15...16), - (17...18) - ), - ParenthesesNode(20...23)( - StatementsNode(21...22)([IntegerNode(21...22)()]), - (20...21), - (22...23) - ), - ParenthesesNode(25...28)( - StatementsNode(26...27)([IntegerNode(26...27)()]), - (25...26), - (27...28) - )] - ) - ), - ReturnNode(30...39)( - (30...36), - ArgumentsNode(37...39)( - [SplatNode(37...39)((37...38), IntegerNode(38...39)())] - ) - ), - ReturnNode(41...49)( - (41...47), - ArgumentsNode(48...49)([IntegerNode(48...49)()]) - ), - ReturnNode(51...65)( - (51...57), - ArgumentsNode(58...65)( - [IntegerNode(58...59)(), - IntegerNode(61...62)(), - IntegerNode(64...65)()] - ) - ), - ReturnNode(67...81)( - (67...73), - ArgumentsNode(74...81)( - [IntegerNode(74...75)(), - IntegerNode(77...78)(), - IntegerNode(80...81)()] - ) - ), - ReturnNode(83...99)( - (83...89), - ArgumentsNode(90...99)( - [ArrayNode(90...99)( - [IntegerNode(91...92)(), - IntegerNode(94...95)(), - IntegerNode(97...98)()], - (90...91), - (98...99) - )] - ) - ), - ReturnNode(101...118)( - (101...107), - ArgumentsNode(107...118)( - [ParenthesesNode(107...118)( - StatementsNode(111...116)( - [IntegerNode(111...112)(), IntegerNode(115...116)()] - ), - (107...108), - (117...118) - )] - ) - ), - ReturnNode(120...128)( - (120...126), - ArgumentsNode(126...128)( - [ParenthesesNode(126...128)(nil, (126...127), (127...128))] - ) - ), - ReturnNode(130...139)( - (130...136), - ArgumentsNode(136...139)( - [ParenthesesNode(136...139)( - StatementsNode(137...138)([IntegerNode(137...138)()]), - (136...137), - (138...139) - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/BEGIN.txt b/test/yarp/snapshots/seattlerb/BEGIN.txt deleted file mode 100644 index f3366c5610f4af..00000000000000 --- a/test/yarp/snapshots/seattlerb/BEGIN.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [PreExecutionNode(0...12)( - StatementsNode(8...10)([IntegerNode(8...10)()]), - (0...5), - (6...7), - (11...12) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt b/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt deleted file mode 100644 index 8c4c0ecc509c01..00000000000000 --- a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt +++ /dev/null @@ -1,228 +0,0 @@ -ProgramNode(0...689)( - [], - StatementsNode(0...689)( - [ArrayNode(0...7)([], (0...3), (6...7)), - ArrayNode(9...26)( - [SymbolNode(13...18)(nil, (13...18), nil, "line2"), - SymbolNode(19...24)(nil, (19...24), nil, "line3")], - (9...12), - (25...26) - ), - ArrayNode(28...35)([], (28...31), (34...35)), - ArrayNode(37...54)( - [StringNode(41...46)(nil, (41...46), nil, "line2"), - StringNode(47...52)(nil, (47...52), nil, "line3")], - (37...40), - (53...54) - ), - ArrayNode(56...63)([], (56...59), (62...63)), - ArrayNode(65...82)( - [SymbolNode(69...74)(nil, (69...74), nil, "line2"), - SymbolNode(75...80)(nil, (75...80), nil, "line3")], - (65...68), - (81...82) - ), - RegularExpressionNode(84...91)( - (84...87), - (87...90), - (90...91), - "\n" + "\n" + "\n", - 0 - ), - ArrayNode(93...100)([], (93...96), (99...100)), - ArrayNode(102...119)( - [StringNode(106...111)(nil, (106...111), nil, "line2"), - StringNode(112...117)(nil, (112...117), nil, "line3")], - (102...105), - (118...119) - ), - ArrayNode(121...139)( - [SymbolNode(123...129)((123...124), (124...129), nil, "line2"), - SymbolNode(131...137)((131...132), (132...137), nil, "line3")], - (121...122), - (138...139) - ), - ClassNode(141...269)( - [], - (141...146), - ConstantReadNode(147...148)(:X), - nil, - nil, - StatementsNode(168...246)( - [DefNode(168...246)( - :y, - (177...178), - SelfNode(172...176)(), - ParametersNode(179...200)( - [RequiredParameterNode(179...180)(:a), - RequiredParameterNode(199...200)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(220...225)( - [CallNode(220...225)( - LocalVariableReadNode(220...221)(:a, 0), - nil, - (222...223), - nil, - ArgumentsNode(224...225)( - [LocalVariableReadNode(224...225)(:b, 0)] - ), - nil, - nil, - 0, - "+" - )] - ), - [:a, :b], - (168...171), - (176...177), - (178...179), - (200...201), - nil, - (243...246) - )] - ), - (266...269), - :X - ), - ClassNode(293...376)( - [], - (293...298), - ConstantReadNode(299...300)(:X), - nil, - nil, - StatementsNode(315...358)( - [ClassNode(315...358)( - [], - (315...320), - ConstantReadNode(321...322)(:Y), - nil, - nil, - StatementsNode(337...343)( - [ConstantWriteNode(337...343)( - :Z, - (337...338), - IntegerNode(341...343)(), - (339...340) - )] - ), - (355...358), - :Y - )] - ), - (373...376), - :X - ), - ClassNode(395...498)( - [], - (395...400), - ConstantReadNode(401...402)(:X), - nil, - nil, - StatementsNode(417...480)( - [DefNode(417...480)( - :y, - (421...422), - nil, - ParametersNode(423...444)( - [RequiredParameterNode(423...424)(:a), - RequiredParameterNode(443...444)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(459...464)( - [CallNode(459...464)( - LocalVariableReadNode(459...460)(:a, 0), - nil, - (461...462), - nil, - ArgumentsNode(463...464)( - [LocalVariableReadNode(463...464)(:b, 0)] - ), - nil, - nil, - 0, - "+" - )] - ), - [:a, :b], - (417...420), - nil, - (422...423), - (444...445), - nil, - (477...480) - )] - ), - (495...498), - :X - ), - ModuleNode(517...565)( - [], - (517...523), - ConstantReadNode(524...525)(:X), - StatementsNode(528...561)( - [ConstantWriteNode(528...561)( - :X, - (528...529), - ArrayNode(532...561)( - [SymbolNode(538...544)((538...539), (539...544), nil, "line3"), - SymbolNode(550...556)((550...551), (551...556), nil, "line4")], - (532...533), - (560...561) - ), - (530...531) - )] - ), - (562...565), - :X - ), - ModuleNode(568...651)( - [], - (568...574), - ConstantReadNode(575...576)(:X), - StatementsNode(590...633)( - [ModuleNode(590...633)( - [], - (590...596), - ConstantReadNode(597...598)(:Y), - StatementsNode(612...618)( - [ConstantWriteNode(612...618)( - :Z, - (612...613), - IntegerNode(616...618)(), - (614...615) - )] - ), - (630...633), - :Y - )] - ), - (648...651), - :X - ), - CallNode(670...689)( - nil, - nil, - (670...671), - (671...672), - ArgumentsNode(673...687)( - [SymbolNode(673...679)((673...674), (674...679), nil, "line2"), - SymbolNode(681...687)((681...682), (682...687), nil, "line3")] - ), - (688...689), - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/__ENCODING__.txt b/test/yarp/snapshots/seattlerb/__ENCODING__.txt deleted file mode 100644 index 2f5aaa5dfce1b2..00000000000000 --- a/test/yarp/snapshots/seattlerb/__ENCODING__.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...12)([], StatementsNode(0...12)([SourceEncodingNode(0...12)()])) diff --git a/test/yarp/snapshots/seattlerb/alias_gvar_backref.txt b/test/yarp/snapshots/seattlerb/alias_gvar_backref.txt deleted file mode 100644 index d4890ed587a599..00000000000000 --- a/test/yarp/snapshots/seattlerb/alias_gvar_backref.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [AliasNode(0...15)( - GlobalVariableReadNode(6...12)(:$MATCH), - BackReferenceReadNode(13...15)(), - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/alias_resword.txt b/test/yarp/snapshots/seattlerb/alias_resword.txt deleted file mode 100644 index 8452f548260b64..00000000000000 --- a/test/yarp/snapshots/seattlerb/alias_resword.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [AliasNode(0...12)( - SymbolNode(6...8)(nil, (6...8), nil, "in"), - SymbolNode(9...12)(nil, (9...12), nil, "out"), - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/and_multi.txt b/test/yarp/snapshots/seattlerb/and_multi.txt deleted file mode 100644 index 2db7d7ceddf45b..00000000000000 --- a/test/yarp/snapshots/seattlerb/and_multi.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [AndNode(0...27)( - AndNode(0...18)( - TrueNode(0...4)(), - CallNode(9...18)( - FalseNode(13...18)(), - nil, - (9...12), - nil, - nil, - nil, - nil, - 0, - "!" - ), - (5...8) - ), - TrueNode(23...27)(), - (19...22) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/aref_args_assocs.txt b/test/yarp/snapshots/seattlerb/aref_args_assocs.txt deleted file mode 100644 index aac10a67634d38..00000000000000 --- a/test/yarp/snapshots/seattlerb/aref_args_assocs.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [ArrayNode(0...8)( - [KeywordHashNode(1...7)( - [AssocNode(1...7)( - IntegerNode(1...2)(), - IntegerNode(6...7)(), - (3...5) - )] - )], - (0...1), - (7...8) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/aref_args_lit_assocs.txt b/test/yarp/snapshots/seattlerb/aref_args_lit_assocs.txt deleted file mode 100644 index 24857076d01fdb..00000000000000 --- a/test/yarp/snapshots/seattlerb/aref_args_lit_assocs.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...11)( - [IntegerNode(1...2)(), - KeywordHashNode(4...10)( - [AssocNode(4...10)( - IntegerNode(4...5)(), - IntegerNode(9...10)(), - (6...8) - )] - )], - (0...1), - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/args_kw_block.txt b/test/yarp/snapshots/seattlerb/args_kw_block.txt deleted file mode 100644 index 6aef28d170489f..00000000000000 --- a/test/yarp/snapshots/seattlerb/args_kw_block.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [DefNode(0...20)( - :f, - (4...5), - nil, - ParametersNode(6...14)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:a, (6...8), IntegerNode(9...10)())], - nil, - BlockParameterNode(12...14)(:b, (13...14), (12...13)) - ), - nil, - [:a, :b], - (0...3), - nil, - (5...6), - (14...15), - nil, - (17...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/array_line_breaks.txt b/test/yarp/snapshots/seattlerb/array_line_breaks.txt deleted file mode 100644 index 4d5224564b6371..00000000000000 --- a/test/yarp/snapshots/seattlerb/array_line_breaks.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [ArrayNode(0...11)( - [StringNode(2...5)((2...3), (3...4), (4...5), "a"), - StringNode(7...10)((7...8), (8...9), (9...10), "b")], - (0...1), - (10...11) - ), - IntegerNode(12...13)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/array_lits_trailing_calls.txt b/test/yarp/snapshots/seattlerb/array_lits_trailing_calls.txt deleted file mode 100644 index 8e9c1318467a9d..00000000000000 --- a/test/yarp/snapshots/seattlerb/array_lits_trailing_calls.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...6)( - ArrayNode(0...4)([], (0...3), (3...4)), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "b" - ), - CallNode(8...12)( - ArrayNode(8...10)([], (8...9), (9...10)), - (10...11), - (11...12), - nil, - nil, - nil, - nil, - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/assoc__bare.txt b/test/yarp/snapshots/seattlerb/assoc__bare.txt deleted file mode 100644 index ddefbd1f62eb9c..00000000000000 --- a/test/yarp/snapshots/seattlerb/assoc__bare.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [HashNode(0...6)( - (0...1), - [AssocNode(2...4)( - SymbolNode(2...4)(nil, (2...3), (3...4), "y"), - nil, - nil - )], - (5...6) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/assoc_label.txt b/test/yarp/snapshots/seattlerb/assoc_label.txt deleted file mode 100644 index 4fa881d1914a79..00000000000000 --- a/test/yarp/snapshots/seattlerb/assoc_label.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...5)( - [KeywordHashNode(2...5)( - [AssocNode(2...5)( - SymbolNode(2...4)(nil, (2...3), (3...4), "b"), - IntegerNode(4...5)(), - nil - )] - )] - ), - (5...6), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/attr_asgn_colon_id.txt b/test/yarp/snapshots/seattlerb/attr_asgn_colon_id.txt deleted file mode 100644 index b9f459e5f1e192..00000000000000 --- a/test/yarp/snapshots/seattlerb/attr_asgn_colon_id.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - ConstantReadNode(0...1)(:A), - (1...3), - (3...4), - nil, - ArgumentsNode(7...8)([IntegerNode(7...8)()]), - nil, - nil, - 0, - "b=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/attrasgn_array_arg.txt b/test/yarp/snapshots/seattlerb/attrasgn_array_arg.txt deleted file mode 100644 index b9a116975a9bbb..00000000000000 --- a/test/yarp/snapshots/seattlerb/attrasgn_array_arg.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...9), - (1...2), - ArgumentsNode(2...13)( - [ArrayNode(2...8)( - [IntegerNode(3...4)(), IntegerNode(6...7)()], - (2...3), - (7...8) - ), - IntegerNode(12...13)()] - ), - (8...9), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/attrasgn_array_lhs.txt b/test/yarp/snapshots/seattlerb/attrasgn_array_lhs.txt deleted file mode 100644 index 666f9e34765e2b..00000000000000 --- a/test/yarp/snapshots/seattlerb/attrasgn_array_lhs.txt +++ /dev/null @@ -1,57 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [CallNode(0...42)( - ArrayNode(0...12)( - [IntegerNode(1...2)(), - IntegerNode(4...5)(), - IntegerNode(7...8)(), - IntegerNode(10...11)()], - (0...1), - (11...12) - ), - nil, - (12...24), - (12...13), - ArgumentsNode(13...42)( - [RangeNode(13...23)( - CallNode(13...17)( - nil, - nil, - (13...17), - nil, - nil, - nil, - nil, - 2, - "from" - ), - CallNode(21...23)( - nil, - nil, - (21...23), - nil, - nil, - nil, - nil, - 2, - "to" - ), - (18...20), - 0 - ), - ArrayNode(27...42)( - [StringNode(28...31)((28...29), (29...30), (30...31), "a"), - StringNode(33...36)((33...34), (34...35), (35...36), "b"), - StringNode(38...41)((38...39), (39...40), (40...41), "c")], - (27...28), - (41...42) - )] - ), - (23...24), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/attrasgn_primary_dot_constant.txt b/test/yarp/snapshots/seattlerb/attrasgn_primary_dot_constant.txt deleted file mode 100644 index f9d549a27bee7a..00000000000000 --- a/test/yarp/snapshots/seattlerb/attrasgn_primary_dot_constant.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(6...7)([IntegerNode(6...7)()]), - nil, - nil, - 0, - "B=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/backticks_interpolation_line.txt b/test/yarp/snapshots/seattlerb/backticks_interpolation_line.txt deleted file mode 100644 index 86c78947fa9591..00000000000000 --- a/test/yarp/snapshots/seattlerb/backticks_interpolation_line.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...8)( - [InterpolatedXStringNode(2...8)( - (2...3), - [EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)( - [CallNode(5...6)( - nil, - nil, - (5...6), - nil, - nil, - nil, - nil, - 2, - "y" - )] - ), - (6...7) - )], - (7...8) - )] - ), - nil, - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bang_eq.txt b/test/yarp/snapshots/seattlerb/bang_eq.txt deleted file mode 100644 index 3a04d4603a9f2b..00000000000000 --- a/test/yarp/snapshots/seattlerb/bang_eq.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 0, - "!=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bdot2.txt b/test/yarp/snapshots/seattlerb/bdot2.txt deleted file mode 100644 index ff960bce8eb784..00000000000000 --- a/test/yarp/snapshots/seattlerb/bdot2.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [RangeNode(0...4)(nil, IntegerNode(2...4)(), (0...2), 0), - RangeNode(7...10)( - nil, - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "a"), - (7...9), - 0 - ), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bdot3.txt b/test/yarp/snapshots/seattlerb/bdot3.txt deleted file mode 100644 index abc8a679f1c0fe..00000000000000 --- a/test/yarp/snapshots/seattlerb/bdot3.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [RangeNode(0...5)(nil, IntegerNode(3...5)(), (0...3), 1), - RangeNode(8...12)( - nil, - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"), - (8...11), - 1 - ), - CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/begin_ensure_no_bodies.txt b/test/yarp/snapshots/seattlerb/begin_ensure_no_bodies.txt deleted file mode 100644 index 39ac8bfea17660..00000000000000 --- a/test/yarp/snapshots/seattlerb/begin_ensure_no_bodies.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [BeginNode(0...16)( - (0...5), - nil, - nil, - nil, - EnsureNode(6...16)((6...12), nil, (13...16)), - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt b/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt deleted file mode 100644 index 4ad22bbc28e69d..00000000000000 --- a/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_bodies.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...44)( - [], - StatementsNode(0...44)( - [BeginNode(0...44)( - (0...5), - StatementsNode(8...9)([IntegerNode(8...9)()]), - RescueNode(10...20)( - (10...16), - [], - nil, - nil, - StatementsNode(19...20)([IntegerNode(19...20)()]), - nil - ), - ElseNode(21...36)( - (21...25), - StatementsNode(28...29)([IntegerNode(28...29)()]), - (30...36) - ), - EnsureNode(30...44)( - (30...36), - StatementsNode(39...40)([IntegerNode(39...40)()]), - (41...44) - ), - (41...44) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt b/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt deleted file mode 100644 index f8cc5345e309bb..00000000000000 --- a/test/yarp/snapshots/seattlerb/begin_rescue_else_ensure_no_bodies.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [BeginNode(0...32)( - (0...5), - nil, - RescueNode(7...13)((7...13), [], nil, nil, nil, nil), - ElseNode(15...27)((15...19), nil, (21...27)), - EnsureNode(21...32)((21...27), nil, (29...32)), - (29...32) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt b/test/yarp/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt deleted file mode 100644 index 1152a0cddfbabc..00000000000000 --- a/test/yarp/snapshots/seattlerb/begin_rescue_ensure_no_bodies.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [BeginNode(0...23)( - (0...5), - nil, - RescueNode(6...12)((6...12), [], nil, nil, nil, nil), - nil, - EnsureNode(13...23)((13...19), nil, (20...23)), - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg__bare.txt b/test/yarp/snapshots/seattlerb/block_arg__bare.txt deleted file mode 100644 index 2634a94099c612..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg__bare.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [DefNode(0...13)( - :x, - (4...5), - nil, - ParametersNode(6...7)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(6...7)(nil, nil, (6...7)) - ), - nil, - [:&], - (0...3), - nil, - (5...6), - (7...8), - nil, - (10...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt b/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt deleted file mode 100644 index 196b4d250f2fd2..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...11)( - [:b], - BlockParametersNode(4...9)( - ParametersNode(5...8)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(5...8)(:b, (7...8), (5...7)), - nil - ), - [], - (4...5), - (8...9) - ), - nil, - (2...3), - (10...11) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_opt_arg_block.txt b/test/yarp/snapshots/seattlerb/block_arg_opt_arg_block.txt deleted file mode 100644 index dd24630442aa5a..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_opt_arg_block.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...21)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...21)( - [:b, :c, :d, :e], - BlockParametersNode(4...19)( - ParametersNode(5...18)( - [RequiredParameterNode(5...6)(:b)], - [OptionalParameterNode(8...11)( - :c, - (8...9), - (9...10), - IntegerNode(10...11)() - )], - [RequiredParameterNode(13...14)(:d)], - nil, - [], - nil, - BlockParameterNode(16...18)(:e, (17...18), (16...17)) - ), - [], - (4...5), - (18...19) - ), - nil, - (2...3), - (20...21) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt b/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt deleted file mode 100644 index 28e355ebe55787..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...20)( - [:b, :c, :d], - BlockParametersNode(4...18)( - ParametersNode(5...17)( - [RequiredParameterNode(5...6)(:b)], - [OptionalParameterNode(8...13)( - :c, - (8...9), - (10...11), - IntegerNode(12...13)() - )], - [], - RestParameterNode(15...17)(:d, (16...17), (15...16)), - [], - nil, - nil - ), - [], - (4...5), - (17...18) - ), - nil, - (2...3), - (19...20) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt deleted file mode 100644 index 2bfb380f06be22..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...25)( - [:b, :c, :d, :e, :f], - BlockParametersNode(4...23)( - ParametersNode(5...22)( - [RequiredParameterNode(5...6)(:b)], - [OptionalParameterNode(8...11)( - :c, - (8...9), - (9...10), - IntegerNode(10...11)() - )], - [RequiredParameterNode(17...18)(:e)], - RestParameterNode(13...15)(:d, (14...15), (13...14)), - [], - nil, - BlockParameterNode(20...22)(:f, (21...22), (20...21)) - ), - [], - (4...5), - (22...23) - ), - nil, - (2...3), - (24...25) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_optional.txt b/test/yarp/snapshots/seattlerb/block_arg_optional.txt deleted file mode 100644 index cb71821778a06e..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_optional.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...13)( - [:b], - BlockParametersNode(4...11)( - ParametersNode(5...10)( - [], - [OptionalParameterNode(5...10)( - :b, - (5...6), - (7...8), - IntegerNode(9...10)() - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (10...11) - ), - nil, - (2...3), - (12...13) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_scope.txt b/test/yarp/snapshots/seattlerb/block_arg_scope.txt deleted file mode 100644 index be99e78eecc891..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_scope.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...12)( - [:b, :c], - BlockParametersNode(4...10)( - ParametersNode(5...6)( - [RequiredParameterNode(5...6)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(8...9)(:c)], - (4...5), - (9...10) - ), - nil, - (2...3), - (11...12) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_scope2.txt b/test/yarp/snapshots/seattlerb/block_arg_scope2.txt deleted file mode 100644 index fcee4898aa00a2..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_scope2.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:b, :c, :d], - BlockParametersNode(3...12)( - ParametersNode(4...5)( - [RequiredParameterNode(4...5)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(7...8)(:c), - BlockLocalVariableNode(10...11)(:d)], - (3...4), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt deleted file mode 100644 index bc2cb81b640946..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...16)( - [:b, :c, :d], - BlockParametersNode(4...14)( - ParametersNode(5...13)( - [RequiredParameterNode(5...6)(:b)], - [], - [RequiredParameterNode(12...13)(:d)], - RestParameterNode(8...10)(:c, (9...10), (8...9)), - [], - nil, - nil - ), - [], - (4...5), - (13...14) - ), - nil, - (2...3), - (15...16) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_kwargs.txt b/test/yarp/snapshots/seattlerb/block_args_kwargs.txt deleted file mode 100644 index 8db4d3f0ea2727..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_kwargs.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [CallNode(0...23)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...23)( - [:kwargs], - BlockParametersNode(4...14)( - ParametersNode(5...13)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(5...13)(:kwargs, (7...13), (5...7)), - nil - ), - [], - (4...5), - (13...14) - ), - StatementsNode(15...21)([LocalVariableReadNode(15...21)(:kwargs, 0)]), - (2...3), - (22...23) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_no_kwargs.txt b/test/yarp/snapshots/seattlerb/block_args_no_kwargs.txt deleted file mode 100644 index 7e4fa1e9f8bba3..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_no_kwargs.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...13)( - [], - BlockParametersNode(4...11)( - ParametersNode(5...10)( - [], - [], - [], - nil, - [], - NoKeywordsParameterNode(5...10)((5...7), (7...10)), - nil - ), - [], - (4...5), - (10...11) - ), - nil, - (2...3), - (12...13) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_opt1.txt b/test/yarp/snapshots/seattlerb/block_args_opt1.txt deleted file mode 100644 index 271638e3d8eff7..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_opt1.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [CallNode(0...24)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...24)( - [:a, :b], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - StatementsNode(16...22)( - [ArrayNode(16...22)( - [LocalVariableReadNode(17...18)(:a, 0), - LocalVariableReadNode(20...21)(:b, 0)], - (16...17), - (21...22) - )] - ), - (2...3), - (23...24) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_opt2.txt b/test/yarp/snapshots/seattlerb/block_args_opt2.txt deleted file mode 100644 index 6b98d4f75cdde6..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_opt2.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:b, :c], - BlockParametersNode(4...16)( - ParametersNode(6...14)( - [], - [OptionalParameterNode(6...9)( - :b, - (6...7), - (7...8), - IntegerNode(8...9)() - ), - OptionalParameterNode(11...14)( - :c, - (11...12), - (12...13), - IntegerNode(13...14)() - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_opt2_2.txt b/test/yarp/snapshots/seattlerb/block_args_opt2_2.txt deleted file mode 100644 index cdda0997df38bf..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_opt2_2.txt +++ /dev/null @@ -1,54 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [CallNode(0...35)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...35)( - [:a, :b, :c], - BlockParametersNode(4...23)( - ParametersNode(5...22)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - ), - OptionalParameterNode(16...22)( - :c, - (16...17), - (18...19), - IntegerNode(20...22)() - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (22...23) - ), - StatementsNode(24...33)( - [ArrayNode(24...33)( - [LocalVariableReadNode(25...26)(:a, 0), - LocalVariableReadNode(28...29)(:b, 0), - LocalVariableReadNode(31...32)(:c, 0)], - (24...25), - (32...33) - )] - ), - (2...3), - (34...35) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_args_opt3.txt b/test/yarp/snapshots/seattlerb/block_args_opt3.txt deleted file mode 100644 index 6d4e26c8eda195..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_args_opt3.txt +++ /dev/null @@ -1,55 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [CallNode(0...42)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...42)( - [:a, :b, :c, :d], - BlockParametersNode(4...27)( - ParametersNode(5...26)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - ), - OptionalParameterNode(16...22)( - :c, - (16...17), - (18...19), - IntegerNode(20...22)() - )], - [], - nil, - [], - nil, - BlockParameterNode(24...26)(:d, (25...26), (24...25)) - ), - [], - (4...5), - (26...27) - ), - StatementsNode(28...40)( - [ArrayNode(28...40)( - [LocalVariableReadNode(29...30)(:a, 0), - LocalVariableReadNode(32...33)(:b, 0), - LocalVariableReadNode(35...36)(:c, 0), - LocalVariableReadNode(38...39)(:d, 0)], - (28...29), - (39...40) - )] - ), - (2...3), - (41...42) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_break.txt b/test/yarp/snapshots/seattlerb/block_break.txt deleted file mode 100644 index 9ebe2b1488f2b7..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_break.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [BreakNode(0...26)( - ArgumentsNode(6...26)( - [CallNode(6...26)( - nil, - nil, - (6...9), - nil, - ArgumentsNode(10...13)( - [CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "arg" - )] - ), - nil, - BlockNode(14...26)( - [:bar], - BlockParametersNode(17...22)( - ParametersNode(18...21)( - [RequiredParameterNode(18...21)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (17...18), - (21...22) - ), - nil, - (14...16), - (23...26) - ), - 0, - "foo" - )] - ), - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt b/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt deleted file mode 100644 index 79c6b347e5a622..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt +++ /dev/null @@ -1,62 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...18)( - [DefNode(2...18)( - :b, - (6...7), - nil, - ParametersNode(8...9)( - [RequiredParameterNode(8...9)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(12...13)( - [CallNode(12...13)( - nil, - nil, - (12...13), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - [:c], - (2...5), - nil, - (7...8), - (9...10), - nil, - (15...18) - )] - ), - nil, - nil, - 0, - "a" - ), - CallNode(20...30)( - CallNode(20...21)(nil, nil, (20...21), nil, nil, nil, nil, 2, "e"), - (21...22), - (22...23), - nil, - nil, - nil, - BlockNode(24...30)([], nil, nil, (24...26), (27...30)), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_dot_op2_brace_block.txt b/test/yarp/snapshots/seattlerb/block_call_dot_op2_brace_block.txt deleted file mode 100644 index 60c529a4253913..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_dot_op2_brace_block.txt +++ /dev/null @@ -1,77 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CallNode(0...31)( - CallNode(0...16)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...7)( - [CallNode(4...7)( - nil, - nil, - (4...5), - (5...6), - nil, - (6...7), - nil, - 0, - "c" - )] - ), - nil, - BlockNode(8...16)( - [], - nil, - StatementsNode(11...12)( - [CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (8...10), - (13...16) - ), - 0, - "b" - ), - (16...17), - (17...18), - nil, - nil, - nil, - BlockNode(19...31)( - [:f], - BlockParametersNode(22...25)( - ParametersNode(23...24)( - [RequiredParameterNode(23...24)(:f)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (22...23), - (24...25) - ), - StatementsNode(26...27)( - [CallNode(26...27)(nil, nil, (26...27), nil, nil, nil, nil, 2, "g")] - ), - (19...21), - (28...31) - ), - 0, - "e" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt b/test/yarp/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt deleted file mode 100644 index c41a55f13fe948..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_dot_op2_cmd_args_do_block.txt +++ /dev/null @@ -1,79 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [CallNode(0...33)( - CallNode(0...16)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...7)( - [CallNode(4...7)( - nil, - nil, - (4...5), - (5...6), - nil, - (6...7), - nil, - 0, - "c" - )] - ), - nil, - BlockNode(8...16)( - [], - nil, - StatementsNode(11...12)( - [CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (8...10), - (13...16) - ), - 0, - "b" - ), - (16...17), - (17...18), - nil, - ArgumentsNode(19...20)( - [CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "f")] - ), - nil, - BlockNode(21...33)( - [:g], - BlockParametersNode(24...27)( - ParametersNode(25...26)( - [RequiredParameterNode(25...26)(:g)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (24...25), - (26...27) - ), - StatementsNode(28...29)( - [CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 2, "h")] - ), - (21...23), - (30...33) - ), - 0, - "e" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_operation_colon.txt b/test/yarp/snapshots/seattlerb/block_call_operation_colon.txt deleted file mode 100644 index 348e82f706c1a8..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_operation_colon.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - CallNode(0...12)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...5)( - [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c")] - ), - nil, - BlockNode(6...12)([], nil, nil, (6...8), (9...12)), - 0, - "b" - ), - (12...14), - (14...15), - nil, - nil, - nil, - nil, - 0, - "d" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_operation_dot.txt b/test/yarp/snapshots/seattlerb/block_call_operation_dot.txt deleted file mode 100644 index 05edca98a44f6a..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_operation_dot.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - CallNode(0...12)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...5)( - [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c")] - ), - nil, - BlockNode(6...12)([], nil, nil, (6...8), (9...12)), - 0, - "b" - ), - (12...13), - (13...14), - nil, - nil, - nil, - nil, - 0, - "d" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_call_paren_call_block_call.txt b/test/yarp/snapshots/seattlerb/block_call_paren_call_block_call.txt deleted file mode 100644 index 4b7916f0e6b8d1..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_call_paren_call_block_call.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...5)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...5)( - [ParenthesesNode(2...5)( - StatementsNode(3...4)( - [CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b")] - ), - (2...3), - (4...5) - )] - ), - nil, - nil, - 0, - "a" - ), - CallNode(6...16)( - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "c"), - (7...8), - (8...9), - nil, - nil, - nil, - BlockNode(10...16)([], nil, nil, (10...12), (13...16)), - 0, - "d" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_command_operation_colon.txt b/test/yarp/snapshots/seattlerb/block_command_operation_colon.txt deleted file mode 100644 index afac178321bfd0..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_command_operation_colon.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - CallNode(0...11)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([SymbolNode(2...4)((2...3), (3...4), nil, "b")]), - nil, - BlockNode(5...11)([], nil, nil, (5...7), (8...11)), - 0, - "a" - ), - (11...13), - (13...14), - nil, - ArgumentsNode(15...17)( - [SymbolNode(15...17)((15...16), (16...17), nil, "d")] - ), - nil, - nil, - 0, - "c" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_command_operation_dot.txt b/test/yarp/snapshots/seattlerb/block_command_operation_dot.txt deleted file mode 100644 index 8225ce403f25b6..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_command_operation_dot.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - CallNode(0...11)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([SymbolNode(2...4)((2...3), (3...4), nil, "b")]), - nil, - BlockNode(5...11)([], nil, nil, (5...7), (8...11)), - 0, - "a" - ), - (11...12), - (12...13), - nil, - ArgumentsNode(14...16)( - [SymbolNode(14...16)((14...15), (15...16), nil, "d")] - ), - nil, - nil, - 0, - "c" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_decomp_anon_splat_arg.txt b/test/yarp/snapshots/seattlerb/block_decomp_anon_splat_arg.txt deleted file mode 100644 index f5bee5b9260d3d..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_decomp_anon_splat_arg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:a], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [RequiredDestructuredParameterNode(5...11)( - [SplatNode(6...7)((6...7), nil), - RequiredParameterNode(9...10)(:a)], - (5...6), - (10...11) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_decomp_arg_splat.txt b/test/yarp/snapshots/seattlerb/block_decomp_arg_splat.txt deleted file mode 100644 index b1c8e2e9b8f239..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_decomp_arg_splat.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:b], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [RequiredDestructuredParameterNode(5...11)( - [RequiredParameterNode(6...7)(:b), - SplatNode(9...10)((9...10), nil)], - (5...6), - (10...11) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_decomp_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/block_decomp_arg_splat_arg.txt deleted file mode 100644 index f66bef6ccb9926..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_decomp_arg_splat_arg.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:a, :b, :c], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [RequiredDestructuredParameterNode(5...15)( - [RequiredParameterNode(6...7)(:a), - SplatNode(9...11)( - (9...10), - RequiredParameterNode(10...11)(:b) - ), - RequiredParameterNode(13...14)(:c)], - (5...6), - (14...15) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_decomp_splat.txt b/test/yarp/snapshots/seattlerb/block_decomp_splat.txt deleted file mode 100644 index c78fd82317ee6d..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_decomp_splat.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...12)( - [:a], - BlockParametersNode(4...10)( - ParametersNode(5...9)( - [RequiredDestructuredParameterNode(5...9)( - [SplatNode(6...8)((6...7), RequiredParameterNode(7...8)(:a))], - (5...6), - (8...9) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (9...10) - ), - nil, - (2...3), - (11...12) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_kw.txt b/test/yarp/snapshots/seattlerb/block_kw.txt deleted file mode 100644 index 32a518dc394b1c..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_kw.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - nil, - nil, - (0...4), - nil, - nil, - nil, - BlockNode(5...15)( - [:k], - BlockParametersNode(7...13)( - ParametersNode(8...12)( - [], - [], - [], - nil, - [KeywordParameterNode(8...12)( - :k, - (8...10), - IntegerNode(10...12)() - )], - nil, - nil - ), - [], - (7...8), - (12...13) - ), - nil, - (5...6), - (14...15) - ), - 0, - "blah" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_kw__required.txt b/test/yarp/snapshots/seattlerb/block_kw__required.txt deleted file mode 100644 index be6125fa1d826f..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_kw__required.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...4), - nil, - nil, - nil, - BlockNode(5...16)( - [:k], - BlockParametersNode(8...12)( - ParametersNode(9...11)( - [], - [], - [], - nil, - [KeywordParameterNode(9...11)(:k, (9...11), nil)], - nil, - nil - ), - [], - (8...9), - (11...12) - ), - nil, - (5...7), - (13...16) - ), - 0, - "blah" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt b/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt deleted file mode 100644 index eb215151086ec8..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - nil, - nil, - (0...2), - nil, - nil, - nil, - BlockNode(3...20)( - [:kw], - BlockParametersNode(5...15)( - ParametersNode(6...14)( - [], - [], - [], - nil, - [KeywordParameterNode(6...14)( - :kw, - (6...9), - SymbolNode(10...14)((10...11), (11...14), nil, "val") - )], - nil, - nil - ), - [], - (5...6), - (14...15) - ), - StatementsNode(16...18)([LocalVariableReadNode(16...18)(:kw, 0)]), - (3...4), - (19...20) - ), - 0, - "bl" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt b/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt deleted file mode 100644 index 240ece6f7066e4..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [CallNode(0...33)( - nil, - nil, - (0...2), - nil, - nil, - nil, - BlockNode(3...33)( - [:kw, :kw2], - BlockParametersNode(5...28)( - ParametersNode(6...26)( - [], - [], - [], - nil, - [KeywordParameterNode(6...14)( - :kw, - (6...9), - SymbolNode(10...14)((10...11), (11...14), nil, "val") - ), - KeywordParameterNode(16...26)( - :kw2, - (16...20), - SymbolNode(21...26)((21...22), (22...26), nil, "val2") - )], - nil, - nil - ), - [], - (5...6), - (27...28) - ), - StatementsNode(29...31)([LocalVariableReadNode(29...31)(:kw, 0)]), - (3...4), - (32...33) - ), - 0, - "bl" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_next.txt b/test/yarp/snapshots/seattlerb/block_next.txt deleted file mode 100644 index 021f2ed15c55bd..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_next.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [NextNode(0...25)( - ArgumentsNode(5...25)( - [CallNode(5...25)( - nil, - nil, - (5...8), - nil, - ArgumentsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "arg" - )] - ), - nil, - BlockNode(13...25)( - [:bar], - BlockParametersNode(16...21)( - ParametersNode(17...20)( - [RequiredParameterNode(17...20)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (16...17), - (20...21) - ), - nil, - (13...15), - (22...25) - ), - 0, - "foo" - )] - ), - (0...4) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_opt_arg.txt b/test/yarp/snapshots/seattlerb/block_opt_arg.txt deleted file mode 100644 index 09279538183fbd..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_opt_arg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:b, :c], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [], - [OptionalParameterNode(5...8)( - :b, - (5...6), - (6...7), - IntegerNode(7...8)() - )], - [RequiredParameterNode(10...11)(:c)], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_opt_splat.txt b/test/yarp/snapshots/seattlerb/block_opt_splat.txt deleted file mode 100644 index 7e5aebff1bc689..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_opt_splat.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [], - [OptionalParameterNode(5...10)( - :b, - (5...6), - (7...8), - IntegerNode(9...10)() - )], - [], - RestParameterNode(12...14)(:c, (13...14), (12...13)), - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt deleted file mode 100644 index 89ee3553bff602..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...22)( - [:b, :c, :d, :e], - BlockParametersNode(4...20)( - ParametersNode(5...19)( - [], - [OptionalParameterNode(5...8)( - :b, - (5...6), - (6...7), - IntegerNode(7...8)() - )], - [RequiredParameterNode(14...15)(:d)], - RestParameterNode(10...12)(:c, (11...12), (10...11)), - [], - nil, - BlockParameterNode(17...19)(:e, (18...19), (17...18)) - ), - [], - (4...5), - (19...20) - ), - nil, - (2...3), - (21...22) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_optarg.txt b/test/yarp/snapshots/seattlerb/block_optarg.txt deleted file mode 100644 index faaaf22e0ed189..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_optarg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:b], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [], - [OptionalParameterNode(5...11)( - :b, - (5...6), - (7...8), - SymbolNode(9...11)((9...10), (10...11), nil, "c") - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_paren_splat.txt b/test/yarp/snapshots/seattlerb/block_paren_splat.txt deleted file mode 100644 index 74a59ed1de5041..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_paren_splat.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...15)( - [:b, :c], - BlockParametersNode(4...13)( - ParametersNode(5...12)( - [RequiredDestructuredParameterNode(5...12)( - [RequiredParameterNode(6...7)(:b), - SplatNode(9...11)( - (9...10), - RequiredParameterNode(10...11)(:c) - )], - (5...6), - (11...12) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (12...13) - ), - nil, - (2...3), - (14...15) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_reg_optarg.txt b/test/yarp/snapshots/seattlerb/block_reg_optarg.txt deleted file mode 100644 index c6cbc623e07f89..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_reg_optarg.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredParameterNode(5...6)(:b)], - [OptionalParameterNode(8...14)( - :c, - (8...9), - (10...11), - SymbolNode(12...14)((12...13), (13...14), nil, "d") - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_return.txt b/test/yarp/snapshots/seattlerb/block_return.txt deleted file mode 100644 index 97fab8c51438ef..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_return.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [ReturnNode(0...27)( - (0...6), - ArgumentsNode(7...27)( - [CallNode(7...27)( - nil, - nil, - (7...10), - nil, - ArgumentsNode(11...14)( - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "arg" - )] - ), - nil, - BlockNode(15...27)( - [:bar], - BlockParametersNode(18...23)( - ParametersNode(19...22)( - [RequiredParameterNode(19...22)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (18...19), - (22...23) - ), - nil, - (15...17), - (24...27) - ), - 0, - "foo" - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_scope.txt b/test/yarp/snapshots/seattlerb/block_scope.txt deleted file mode 100644 index bcdb26caa70706..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_scope.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...10)( - [:b], - BlockParametersNode(4...8)( - nil, - [BlockLocalVariableNode(6...7)(:b)], - (4...5), - (7...8) - ), - nil, - (2...3), - (9...10) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/block_splat_reg.txt b/test/yarp/snapshots/seattlerb/block_splat_reg.txt deleted file mode 100644 index b8d574b454080c..00000000000000 --- a/test/yarp/snapshots/seattlerb/block_splat_reg.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...13)( - [:b, :c], - BlockParametersNode(4...11)( - ParametersNode(5...10)( - [], - [], - [RequiredParameterNode(9...10)(:c)], - RestParameterNode(5...7)(:b, (6...7), (5...6)), - [], - nil, - nil - ), - [], - (4...5), - (10...11) - ), - nil, - (2...3), - (12...13) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug169.txt b/test/yarp/snapshots/seattlerb/bug169.txt deleted file mode 100644 index d6b75f5369712d..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug169.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([ParenthesesNode(2...4)(nil, (2...3), (3...4))]), - nil, - BlockNode(5...7)([], nil, nil, (5...6), (6...7)), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug179.txt b/test/yarp/snapshots/seattlerb/bug179.txt deleted file mode 100644 index 9dc2331c9397b3..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug179.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...9)( - [RangeNode(2...9)( - ParenthesesNode(2...4)(nil, (2...3), (3...4)), - NilNode(6...9)(), - (4...6), - 0 - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug190.txt b/test/yarp/snapshots/seattlerb/bug190.txt deleted file mode 100644 index 1ad483ada994be..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug190.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [RegularExpressionNode(0...6)((0...3), (3...5), (5...6), "'", 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug191.txt b/test/yarp/snapshots/seattlerb/bug191.txt deleted file mode 100644 index 46d5ed6d7408f9..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug191.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [IfNode(0...9)( - nil, - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - StatementsNode(4...6)( - [StringNode(4...6)((4...5), (5...5), (5...6), "")] - ), - ElseNode(6...9)( - (6...7), - StatementsNode(8...9)( - [CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - nil - ), - IfNode(11...20)( - nil, - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"), - StatementsNode(15...17)( - [StringNode(15...17)((15...16), (16...16), (16...17), "")] - ), - ElseNode(17...20)( - (17...18), - StatementsNode(19...20)( - [CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug202.txt b/test/yarp/snapshots/seattlerb/bug202.txt deleted file mode 100644 index 08bcfd6b7d3395..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug202.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...22)( - [:测试], - StatementsNode(0...22)( - [GlobalVariableWriteNode(0...11)( - :$测试, - (0...7), - IntegerNode(10...11)(), - (8...9) - ), - LocalVariableWriteNode(12...22)( - :测试, - 0, - (12...18), - IntegerNode(21...22)(), - (19...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug236.txt b/test/yarp/snapshots/seattlerb/bug236.txt deleted file mode 100644 index c83125b65ff7fa..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug236.txt +++ /dev/null @@ -1,65 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...7)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(1...7)( - [:a], - BlockParametersNode(2...6)( - ParametersNode(3...5)( - [RequiredParameterNode(3...4)(:a)], - [], - [], - RestParameterNode(4...5)(nil, nil, (4...5)), - [], - nil, - nil - ), - [], - (2...3), - (5...6) - ), - nil, - (1...2), - (6...7) - ), - 0, - "x" - ), - CallNode(9...15)( - nil, - nil, - (9...10), - nil, - nil, - nil, - BlockNode(10...15)( - [:a], - BlockParametersNode(11...14)( - ParametersNode(12...13)( - [RequiredParameterNode(12...13)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (11...12), - (13...14) - ), - nil, - (10...11), - (14...15) - ), - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug290.txt b/test/yarp/snapshots/seattlerb/bug290.txt deleted file mode 100644 index 30d5780f5059f2..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug290.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [BeginNode(0...15)( - (0...5), - StatementsNode(8...11)( - [CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 2, "foo")] - ), - nil, - nil, - nil, - (12...15) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_187.txt b/test/yarp/snapshots/seattlerb/bug_187.txt deleted file mode 100644 index a62a9f30be1110..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_187.txt +++ /dev/null @@ -1,53 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...28)( - nil, - nil, - (0...7), - nil, - ArgumentsNode(8...28)( - [DefNode(8...28)( - :f, - (12...13), - nil, - nil, - StatementsNode(14...24)( - [CallNode(14...24)( - CallNode(14...15)( - nil, - nil, - (14...15), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (15...16), - (16...17), - nil, - nil, - nil, - BlockNode(18...24)([], nil, nil, (18...20), (21...24)), - 0, - "b" - )] - ), - [], - (8...11), - nil, - nil, - nil, - nil, - (25...28) - )] - ), - nil, - nil, - 0, - "private" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_215.txt b/test/yarp/snapshots/seattlerb/bug_215.txt deleted file mode 100644 index 16a2ca3be19070..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_215.txt +++ /dev/null @@ -1,9 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [UndefNode(0...13)( - [SymbolNode(6...13)((6...9), (9...12), (12...13), "foo")], - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_249.txt b/test/yarp/snapshots/seattlerb/bug_249.txt deleted file mode 100644 index 776132c6d2cb39..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_249.txt +++ /dev/null @@ -1,77 +0,0 @@ -ProgramNode(0...67)( - [], - StatementsNode(0...67)( - [CallNode(0...67)( - nil, - nil, - (0...5), - nil, - ArgumentsNode(6...67)( - [CallNode(6...48)( - ParenthesesNode(6...44)( - StatementsNode(7...43)( - [CallNode(7...43)( - ConstantReadNode(7...12)(:Class), - (12...13), - (13...16), - nil, - nil, - nil, - BlockNode(17...43)( - [], - nil, - StatementsNode(20...38)( - [DefNode(20...38)( - :initialize, - (24...34), - nil, - nil, - nil, - [], - (20...23), - nil, - nil, - nil, - nil, - (35...38) - )] - ), - (17...19), - (40...43) - ), - 0, - "new" - )] - ), - (6...7), - (43...44) - ), - (44...45), - (45...48), - nil, - nil, - nil, - nil, - 0, - "new" - ), - KeywordHashNode(50...67)( - [AssocNode(50...67)( - SymbolNode(50...53)((50...51), (51...53), nil, "at"), - StringNode(57...67)( - (57...58), - (58...66), - (66...67), - "endpoint" - ), - (54...56) - )] - )] - ), - nil, - nil, - 0, - "mount" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_and.txt b/test/yarp/snapshots/seattlerb/bug_and.txt deleted file mode 100644 index b81ddb4d87200d..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_and.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [AndNode(0...13)(TrueNode(0...4)(), TrueNode(9...13)(), (5...8)), - AndNode(15...26)( - TrueNode(15...19)(), - ArrayNode(24...26)([], (24...25), (25...26)), - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_args__19.txt b/test/yarp/snapshots/seattlerb/bug_args__19.txt deleted file mode 100644 index eba3f72951a957..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_args__19.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...16)( - [:a, :b], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [RequiredDestructuredParameterNode(5...11)( - [RequiredParameterNode(6...7)(:a), - RequiredParameterNode(9...10)(:b)], - (5...6), - (10...11) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - StatementsNode(13...14)( - [CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "d")] - ), - (2...3), - (15...16) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_args_masgn.txt b/test/yarp/snapshots/seattlerb/bug_args_masgn.txt deleted file mode 100644 index 5a79af6c92745a..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_args_masgn.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredDestructuredParameterNode(5...11)( - [RequiredParameterNode(6...7)(:a), - RequiredParameterNode(9...10)(:b)], - (5...6), - (10...11) - ), - RequiredParameterNode(13...14)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_args_masgn2.txt b/test/yarp/snapshots/seattlerb/bug_args_masgn2.txt deleted file mode 100644 index 410d5f7ebd771e..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_args_masgn2.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...22)( - [:a, :b, :c, :d], - BlockParametersNode(4...20)( - ParametersNode(5...19)( - [RequiredDestructuredParameterNode(5...16)( - [RequiredDestructuredParameterNode(6...12)( - [RequiredParameterNode(7...8)(:a), - RequiredParameterNode(10...11)(:b)], - (6...7), - (11...12) - ), - RequiredParameterNode(14...15)(:c)], - (5...6), - (15...16) - ), - RequiredParameterNode(18...19)(:d)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (19...20) - ), - nil, - (2...3), - (21...22) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt b/test/yarp/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt deleted file mode 100644 index c0b97dce6b1fb9..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_args_masgn_outer_parens__19.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [CallNode(0...19)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...19)( - [:k, :v, :i], - BlockParametersNode(4...17)( - ParametersNode(5...16)( - [RequiredDestructuredParameterNode(5...16)( - [RequiredDestructuredParameterNode(6...12)( - [RequiredParameterNode(7...8)(:k), - RequiredParameterNode(10...11)(:v)], - (6...7), - (11...12) - ), - RequiredParameterNode(14...15)(:i)], - (5...6), - (15...16) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (16...17) - ), - nil, - (2...3), - (18...19) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt b/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt deleted file mode 100644 index 67934a28dc1cdb..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt +++ /dev/null @@ -1,89 +0,0 @@ -ProgramNode(6...94)( - [], - StatementsNode(6...94)( - [DefNode(6...39)( - :f, - (10...11), - nil, - nil, - StatementsNode(20...29)( - [CallNode(20...29)( - nil, - nil, - (20...21), - nil, - ArgumentsNode(22...29)( - [ParenthesesNode(22...26)( - StatementsNode(24...25)([IntegerNode(24...25)()]), - (22...23), - (25...26) - ), - IntegerNode(28...29)()] - ), - nil, - nil, - 0, - "g" - )] - ), - [], - (6...9), - nil, - nil, - nil, - nil, - (36...39) - ), - DefNode(48...82)( - :f, - (52...53), - nil, - nil, - StatementsNode(64...72)( - [CallNode(64...72)( - nil, - nil, - (64...65), - nil, - ArgumentsNode(66...72)( - [ParenthesesNode(66...69)( - StatementsNode(67...68)([IntegerNode(67...68)()]), - (66...67), - (68...69) - ), - IntegerNode(71...72)()] - ), - nil, - nil, - 0, - "g" - )] - ), - [], - (48...51), - nil, - (53...54), - (54...55), - nil, - (79...82) - ), - CallNode(85...94)( - nil, - nil, - (85...86), - nil, - ArgumentsNode(87...94)( - [ParenthesesNode(87...91)( - StatementsNode(89...90)([IntegerNode(89...90)()]), - (87...88), - (90...91) - ), - IntegerNode(93...94)()] - ), - nil, - nil, - 0, - "g" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_case_when_regexp.txt b/test/yarp/snapshots/seattlerb/bug_case_when_regexp.txt deleted file mode 100644 index 0b898fd52362d9..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_case_when_regexp.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CaseNode(0...26)( - SymbolNode(5...7)((5...6), (6...7), nil, "x"), - [WhenNode(9...17)( - (9...13), - [RegularExpressionNode(14...17)( - (14...15), - (15...16), - (16...17), - "x", - 0 - )], - nil - )], - nil, - (0...4), - (23...26) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_comma.txt b/test/yarp/snapshots/seattlerb/bug_comma.txt deleted file mode 100644 index a6dd7516aebf8e..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_comma.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [IfNode(0...24)( - (0...2), - CallNode(3...15)( - nil, - nil, - (3...7), - nil, - ArgumentsNode(8...15)( - [StringNode(8...10)((8...9), (9...10), nil, "d"), - CallNode(12...15)( - nil, - nil, - (12...15), - nil, - nil, - nil, - nil, - 2, - "dir" - )] - ), - nil, - nil, - 0, - "test" - ), - nil, - nil, - (21...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_cond_pct.txt b/test/yarp/snapshots/seattlerb/bug_cond_pct.txt deleted file mode 100644 index 6a73ca7493ae04..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_cond_pct.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CaseNode(0...28)( - nil, - [WhenNode(6...23)( - (6...10), - [RegularExpressionNode(11...23)( - (11...14), - (14...22), - (22...23), - "blahblah", - 0 - )], - nil - )], - nil, - (0...4), - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_hash_args.txt b/test/yarp/snapshots/seattlerb/bug_hash_args.txt deleted file mode 100644 index 1eec48e9302d14..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_hash_args.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [CallNode(0...19)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...18)( - [SymbolNode(4...8)((4...5), (5...8), nil, "bar"), - KeywordHashNode(10...18)( - [AssocNode(10...18)( - SymbolNode(10...14)(nil, (10...13), (13...14), "baz"), - NilNode(15...18)(), - nil - )] - )] - ), - (18...19), - nil, - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_hash_args_trailing_comma.txt b/test/yarp/snapshots/seattlerb/bug_hash_args_trailing_comma.txt deleted file mode 100644 index 3801df91bfeb77..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_hash_args_trailing_comma.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...18)( - [SymbolNode(4...8)((4...5), (5...8), nil, "bar"), - KeywordHashNode(10...18)( - [AssocNode(10...18)( - SymbolNode(10...14)(nil, (10...13), (13...14), "baz"), - NilNode(15...18)(), - nil - )] - )] - ), - (19...20), - nil, - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_hash_interp_array.txt b/test/yarp/snapshots/seattlerb/bug_hash_interp_array.txt deleted file mode 100644 index fff5c3bfb64f44..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_hash_interp_array.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [HashNode(0...13)( - (0...1), - [AssocNode(2...11)( - InterpolatedSymbolNode(2...8)( - (2...3), - [EmbeddedStatementsNode(3...6)((3...5), nil, (5...6))], - (6...8) - ), - ArrayNode(9...11)([], (9...10), (10...11)), - nil - )], - (12...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_masgn_right.txt b/test/yarp/snapshots/seattlerb/bug_masgn_right.txt deleted file mode 100644 index beee1f79905413..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_masgn_right.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...14)( - [RequiredParameterNode(9...10)(:b), - RequiredParameterNode(12...13)(:c)], - (8...9), - (13...14) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_not_parens.txt b/test/yarp/snapshots/seattlerb/bug_not_parens.txt deleted file mode 100644 index e4a01de3f48a92..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_not_parens.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"), - nil, - (0...3), - (3...4), - nil, - (5...6), - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/bug_op_asgn_rescue.txt b/test/yarp/snapshots/seattlerb/bug_op_asgn_rescue.txt deleted file mode 100644 index 2bd4f430e3549f..00000000000000 --- a/test/yarp/snapshots/seattlerb/bug_op_asgn_rescue.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...18)( - [:a], - StatementsNode(0...18)( - [LocalVariableOrWriteNode(0...18)( - (0...1), - (2...5), - RescueModifierNode(6...18)( - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"), - (8...14), - NilNode(15...18)() - ), - :a, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_and.txt b/test/yarp/snapshots/seattlerb/call_and.txt deleted file mode 100644 index d6b4d8d6ce1f33..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_and.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "&" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_arg_assoc.txt b/test/yarp/snapshots/seattlerb/call_arg_assoc.txt deleted file mode 100644 index e6c88afdf05318..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_arg_assoc.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...9)( - [IntegerNode(2...3)(), - KeywordHashNode(5...9)( - [AssocNode(5...9)( - IntegerNode(5...6)(), - IntegerNode(8...9)(), - (6...8) - )] - )] - ), - (9...10), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_arg_assoc_kwsplat.txt b/test/yarp/snapshots/seattlerb/call_arg_assoc_kwsplat.txt deleted file mode 100644 index 076fe7a8b222bc..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_arg_assoc_kwsplat.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...15)( - [IntegerNode(2...3)(), - KeywordHashNode(5...15)( - [AssocNode(5...10)( - SymbolNode(5...8)(nil, (5...7), (7...8), "kw"), - IntegerNode(9...10)(), - nil - ), - AssocSplatNode(12...15)(IntegerNode(14...15)(), (12...14))] - )] - ), - (15...16), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_arg_kwsplat.txt b/test/yarp/snapshots/seattlerb/call_arg_kwsplat.txt deleted file mode 100644 index 6a98d992d3c9fc..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_arg_kwsplat.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...8)( - [CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"), - KeywordHashNode(5...8)( - [AssocSplatNode(5...8)(IntegerNode(7...8)(), (5...7))] - )] - ), - (8...9), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_args_assoc_quoted.txt b/test/yarp/snapshots/seattlerb/call_args_assoc_quoted.txt deleted file mode 100644 index b632adc6ba5016..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_args_assoc_quoted.txt +++ /dev/null @@ -1,82 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CallNode(0...11)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...11)( - [KeywordHashNode(2...11)( - [AssocNode(2...11)( - InterpolatedSymbolNode(2...9)( - (2...3), - [EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)( - [CallNode(5...6)( - nil, - nil, - (5...6), - nil, - nil, - nil, - nil, - 2, - "k" - )] - ), - (6...7) - )], - (7...9) - ), - IntegerNode(9...11)(), - nil - )] - )] - ), - nil, - nil, - 0, - "x" - ), - CallNode(13...21)( - nil, - nil, - (13...14), - nil, - ArgumentsNode(15...21)( - [KeywordHashNode(15...21)( - [AssocNode(15...21)( - SymbolNode(15...19)((15...16), (16...17), (17...19), "k"), - IntegerNode(19...21)(), - nil - )] - )] - ), - nil, - nil, - 0, - "x" - ), - CallNode(23...31)( - nil, - nil, - (23...24), - nil, - ArgumentsNode(25...31)( - [KeywordHashNode(25...31)( - [AssocNode(25...31)( - SymbolNode(25...29)((25...26), (26...27), (27...29), "k"), - IntegerNode(29...31)(), - nil - )] - )] - ), - nil, - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_args_assoc_trailing_comma.txt b/test/yarp/snapshots/seattlerb/call_args_assoc_trailing_comma.txt deleted file mode 100644 index 432a7c0a44be29..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_args_assoc_trailing_comma.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...9)( - [IntegerNode(2...3)(), - KeywordHashNode(5...9)( - [AssocNode(5...9)( - IntegerNode(5...6)(), - IntegerNode(8...9)(), - (6...8) - )] - )] - ), - (10...11), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_args_command.txt b/test/yarp/snapshots/seattlerb/call_args_command.txt deleted file mode 100644 index fa5c35b8680781..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_args_command.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...9)( - [CallNode(4...9)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c"), - (5...6), - (6...7), - nil, - ArgumentsNode(8...9)([IntegerNode(8...9)()]), - nil, - nil, - 0, - "d" - )] - ), - nil, - nil, - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_array_arg.txt b/test/yarp/snapshots/seattlerb/call_array_arg.txt deleted file mode 100644 index ade225a9e63e8c..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_array_arg.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...13)( - [ArrayNode(5...13)( - [SymbolNode(6...8)((6...7), (7...8), nil, "b"), - SymbolNode(10...12)((10...11), (11...12), nil, "c")], - (5...6), - (12...13) - )] - ), - nil, - nil, - 0, - "==" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_array_block_call.txt b/test/yarp/snapshots/seattlerb/call_array_block_call.txt deleted file mode 100644 index 460621a13148b7..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_array_block_call.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [CallNode(0...19)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...19)( - [ArrayNode(2...19)( - [NilNode(4...7)(), - CallNode(9...17)( - nil, - nil, - (9...10), - nil, - nil, - nil, - BlockNode(11...17)([], nil, nil, (11...13), (14...17)), - 0, - "b" - )], - (2...3), - (18...19) - )] - ), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_array_lambda_block_call.txt b/test/yarp/snapshots/seattlerb/call_array_lambda_block_call.txt deleted file mode 100644 index c83adb235f72be..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_array_lambda_block_call.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...11)( - [ArrayNode(2...11)( - [LambdaNode(3...10)( - [], - (3...5), - (8...9), - (9...10), - BlockParametersNode(5...7)(nil, [], (5...6), (6...7)), - nil - )], - (2...3), - (10...11) - )] - ), - nil, - BlockNode(12...18)([], nil, nil, (12...14), (15...18)), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_array_lit_inline_hash.txt b/test/yarp/snapshots/seattlerb/call_array_lit_inline_hash.txt deleted file mode 100644 index ef336c5a153d13..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_array_lit_inline_hash.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...15)( - [ArrayNode(2...15)( - [SymbolNode(3...5)((3...4), (4...5), nil, "b"), - KeywordHashNode(7...14)( - [AssocNode(7...14)( - SymbolNode(7...9)((7...8), (8...9), nil, "c"), - IntegerNode(13...14)(), - (10...12) - )] - )], - (2...3), - (14...15) - )] - ), - (15...16), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_assoc.txt b/test/yarp/snapshots/seattlerb/call_assoc.txt deleted file mode 100644 index bd6a6e286c2a15..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_assoc.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...6)( - [KeywordHashNode(2...6)( - [AssocNode(2...6)( - IntegerNode(2...3)(), - IntegerNode(5...6)(), - (3...5) - )] - )] - ), - (6...7), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_assoc_new.txt b/test/yarp/snapshots/seattlerb/call_assoc_new.txt deleted file mode 100644 index 525b3b1472b66b..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_assoc_new.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...5)( - [KeywordHashNode(2...5)( - [AssocNode(2...5)( - SymbolNode(2...4)(nil, (2...3), (3...4), "a"), - IntegerNode(4...5)(), - nil - )] - )] - ), - (5...6), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_assoc_new_if_multiline.txt b/test/yarp/snapshots/seattlerb/call_assoc_new_if_multiline.txt deleted file mode 100644 index 5bfb5a08877745..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_assoc_new_if_multiline.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [CallNode(0...24)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...23)( - [KeywordHashNode(2...23)( - [AssocNode(2...23)( - SymbolNode(2...4)(nil, (2...3), (3...4), "b"), - IfNode(5...23)( - (5...7), - SymbolNode(8...10)((8...9), (9...10), nil, "c"), - StatementsNode(11...12)([IntegerNode(11...12)()]), - ElseNode(13...23)( - (13...17), - StatementsNode(18...19)([IntegerNode(18...19)()]), - (20...23) - ), - (20...23) - ), - nil - )] - )] - ), - (23...24), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_assoc_trailing_comma.txt b/test/yarp/snapshots/seattlerb/call_assoc_trailing_comma.txt deleted file mode 100644 index 0f68852c190e55..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_assoc_trailing_comma.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...6)( - [KeywordHashNode(2...6)( - [AssocNode(2...6)( - IntegerNode(2...3)(), - IntegerNode(5...6)(), - (3...5) - )] - )] - ), - (7...8), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_bang_command_call.txt b/test/yarp/snapshots/seattlerb/call_bang_command_call.txt deleted file mode 100644 index 104d90d1c2a1a1..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_bang_command_call.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(2...7)( - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a"), - (3...4), - (4...5), - nil, - ArgumentsNode(6...7)([IntegerNode(6...7)()]), - nil, - nil, - 0, - "b" - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_bang_squiggle.txt b/test/yarp/snapshots/seattlerb/call_bang_squiggle.txt deleted file mode 100644 index 56146957714899..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_bang_squiggle.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 0, - "!~" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_begin_call_block_call.txt b/test/yarp/snapshots/seattlerb/call_begin_call_block_call.txt deleted file mode 100644 index 9b60d515f0c75e..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_begin_call_block_call.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...22)( - [BeginNode(2...22)( - (2...7), - StatementsNode(8...18)( - [CallNode(8...18)( - CallNode(8...9)( - nil, - nil, - (8...9), - nil, - nil, - nil, - nil, - 2, - "b" - ), - (9...10), - (10...11), - nil, - nil, - nil, - BlockNode(12...18)([], nil, nil, (12...14), (15...18)), - 0, - "c" - )] - ), - nil, - nil, - nil, - (19...22) - )] - ), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_block_arg_named.txt b/test/yarp/snapshots/seattlerb/call_block_arg_named.txt deleted file mode 100644 index f24da1bcd504c1..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_block_arg_named.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...6)( - [BlockArgumentNode(2...6)( - CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "blk"), - (2...3) - )] - ), - (6...7), - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_carat.txt b/test/yarp/snapshots/seattlerb/call_carat.txt deleted file mode 100644 index bea1ff7c6808f7..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_carat.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "^" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_colon2.txt b/test/yarp/snapshots/seattlerb/call_colon2.txt deleted file mode 100644 index 66b8a4a0177982..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_colon2.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - ConstantReadNode(0...1)(:A), - (1...3), - (3...4), - nil, - nil, - nil, - nil, - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_colon_parens.txt b/test/yarp/snapshots/seattlerb/call_colon_parens.txt deleted file mode 100644 index 14c7247bcd47cb..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_colon_parens.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - (1...3), - nil, - (3...4), - nil, - (4...5), - nil, - 0, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_div.txt b/test/yarp/snapshots/seattlerb/call_div.txt deleted file mode 100644 index f7caf104146425..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_div.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "/" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_dot_parens.txt b/test/yarp/snapshots/seattlerb/call_dot_parens.txt deleted file mode 100644 index 073336ed48525b..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_dot_parens.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - IntegerNode(0...1)(), - (1...2), - nil, - (2...3), - nil, - (3...4), - nil, - 0, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_env.txt b/test/yarp/snapshots/seattlerb/call_env.txt deleted file mode 100644 index 8af975cdce7ef6..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_env.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...7), - nil, - nil, - nil, - nil, - 0, - "happy" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_eq3.txt b/test/yarp/snapshots/seattlerb/call_eq3.txt deleted file mode 100644 index 192a3c97c5dfd1..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_eq3.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - IntegerNode(0...1)(), - nil, - (2...5), - nil, - ArgumentsNode(6...7)([IntegerNode(6...7)()]), - nil, - nil, - 0, - "===" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_gt.txt b/test/yarp/snapshots/seattlerb/call_gt.txt deleted file mode 100644 index 9eadb5ee2f0f5f..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_gt.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - ">" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_kwsplat.txt b/test/yarp/snapshots/seattlerb/call_kwsplat.txt deleted file mode 100644 index c5b45b9cb2796a..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_kwsplat.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...5)( - [KeywordHashNode(2...5)( - [AssocSplatNode(2...5)(IntegerNode(4...5)(), (2...4))] - )] - ), - (5...6), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_leading_dots.txt b/test/yarp/snapshots/seattlerb/call_leading_dots.txt deleted file mode 100644 index bc418635a105f8..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_leading_dots.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (2...3), - (3...4), - nil, - nil, - nil, - nil, - 0, - "b" - ), - (5...6), - (6...7), - nil, - nil, - nil, - nil, - 0, - "c" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_leading_dots_comment.txt b/test/yarp/snapshots/seattlerb/call_leading_dots_comment.txt deleted file mode 100644 index e9a88d05d4b850..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_leading_dots_comment.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (2...3), - (3...4), - nil, - nil, - nil, - nil, - 0, - "b" - ), - (9...10), - (10...11), - nil, - nil, - nil, - nil, - 0, - "d" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_lt.txt b/test/yarp/snapshots/seattlerb/call_lt.txt deleted file mode 100644 index 11fcd8c44ff9af..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_lt.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "<" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_lte.txt b/test/yarp/snapshots/seattlerb/call_lte.txt deleted file mode 100644 index 5ad45cbf0e4e64..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_lte.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 0, - "<=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_not.txt b/test/yarp/snapshots/seattlerb/call_not.txt deleted file mode 100644 index d42b852ead670e..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_not.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(4...6)(), - nil, - (0...3), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_pipe.txt b/test/yarp/snapshots/seattlerb/call_pipe.txt deleted file mode 100644 index e372fce6e52089..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_pipe.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "|" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_rshift.txt b/test/yarp/snapshots/seattlerb/call_rshift.txt deleted file mode 100644 index 9a523669eb4aa0..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_rshift.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 0, - ">>" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_self_brackets.txt b/test/yarp/snapshots/seattlerb/call_self_brackets.txt deleted file mode 100644 index 7dfe5a50be0f25..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_self_brackets.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - SelfNode(0...4)(), - nil, - (4...7), - (4...5), - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - (6...7), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_spaceship.txt b/test/yarp/snapshots/seattlerb/call_spaceship.txt deleted file mode 100644 index a7ee86597819ea..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_spaceship.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - IntegerNode(0...1)(), - nil, - (2...5), - nil, - ArgumentsNode(6...7)([IntegerNode(6...7)()]), - nil, - nil, - 0, - "<=>" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_stabby_do_end_with_block.txt b/test/yarp/snapshots/seattlerb/call_stabby_do_end_with_block.txt deleted file mode 100644 index f541c529851ce2..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_stabby_do_end_with_block.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...13)( - [LambdaNode(2...13)( - [], - (2...4), - (5...7), - (10...13), - nil, - StatementsNode(8...9)([IntegerNode(8...9)()]) - )] - ), - nil, - BlockNode(14...22)( - [], - nil, - StatementsNode(17...18)([IntegerNode(17...18)()]), - (14...16), - (19...22) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_stabby_with_braces_block.txt b/test/yarp/snapshots/seattlerb/call_stabby_with_braces_block.txt deleted file mode 100644 index 83c62571fd7c44..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_stabby_with_braces_block.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [CallNode(0...19)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...10)( - [LambdaNode(2...10)( - [], - (2...4), - (5...6), - (9...10), - nil, - StatementsNode(7...8)([IntegerNode(7...8)()]) - )] - ), - nil, - BlockNode(11...19)( - [], - nil, - StatementsNode(14...15)([IntegerNode(14...15)()]), - (11...13), - (16...19) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_star.txt b/test/yarp/snapshots/seattlerb/call_star.txt deleted file mode 100644 index 1e4683a882bf47..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_star.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (2...3), - nil, - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - nil, - nil, - 0, - "*" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_star2.txt b/test/yarp/snapshots/seattlerb/call_star2.txt deleted file mode 100644 index d051c4a3136266..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_star2.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - IntegerNode(0...1)(), - nil, - (2...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 0, - "**" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_trailing_comma.txt b/test/yarp/snapshots/seattlerb/call_trailing_comma.txt deleted file mode 100644 index da971880af3e5e..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_trailing_comma.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...3)([IntegerNode(2...3)()]), - (4...5), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_trailing_dots.txt b/test/yarp/snapshots/seattlerb/call_trailing_dots.txt deleted file mode 100644 index a2ccf8addde234..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_trailing_dots.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (3...4), - nil, - nil, - nil, - nil, - 0, - "b" - ), - (4...5), - (6...7), - nil, - nil, - nil, - nil, - 0, - "c" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/call_unary_bang.txt b/test/yarp/snapshots/seattlerb/call_unary_bang.txt deleted file mode 100644 index e0de2a924f5799..00000000000000 --- a/test/yarp/snapshots/seattlerb/call_unary_bang.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)( - [CallNode(0...2)( - IntegerNode(1...2)(), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in.txt b/test/yarp/snapshots/seattlerb/case_in.txt deleted file mode 100644 index a1e26410133a8f..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in.txt +++ /dev/null @@ -1,597 +0,0 @@ -ProgramNode(0...747)( - [:b, :_, :lhs, :x, :rhs, :c, :e], - StatementsNode(0...747)( - [CaseNode(0...21)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...16)( - HashPatternNode(12...16)( - nil, - [AssocNode(12...16)( - SymbolNode(12...16)((12...13), (13...14), (14...16), "b"), - nil, - nil - )], - nil, - nil, - nil - ), - nil, - (8...10), - nil - )], - nil, - (0...4), - (18...21) - ), - CaseNode(23...45)( - SymbolNode(28...30)((28...29), (29...30), nil, "a"), - [InNode(31...41)( - ArrayNode(34...41)( - [SymbolNode(37...38)(nil, (37...38), nil, "a"), - SymbolNode(39...40)(nil, (39...40), nil, "b")], - (34...37), - (40...41) - ), - nil, - (31...33), - nil - )], - nil, - (23...27), - (42...45) - ), - CaseNode(47...69)( - SymbolNode(52...54)((52...53), (53...54), nil, "a"), - [InNode(55...65)( - ArrayNode(58...65)( - [StringNode(61...62)(nil, (61...62), nil, "a"), - StringNode(63...64)(nil, (63...64), nil, "b")], - (58...61), - (64...65) - ), - nil, - (55...57), - nil - )], - nil, - (47...51), - (66...69) - ), - CaseNode(71...93)( - SymbolNode(76...78)((76...77), (77...78), nil, "a"), - [InNode(79...89)( - ArrayNode(82...89)( - [SymbolNode(85...86)(nil, (85...86), nil, "a"), - SymbolNode(87...88)(nil, (87...88), nil, "b")], - (82...85), - (88...89) - ), - nil, - (79...81), - nil - )], - nil, - (71...75), - (90...93) - ), - CaseNode(95...117)( - SymbolNode(100...102)((100...101), (101...102), nil, "a"), - [InNode(103...113)( - ArrayNode(106...113)( - [StringNode(109...110)(nil, (109...110), nil, "a"), - StringNode(111...112)(nil, (111...112), nil, "b")], - (106...109), - (112...113) - ), - nil, - (103...105), - nil - )], - nil, - (95...99), - (114...117) - ), - CaseNode(119...141)( - SymbolNode(124...126)((124...125), (125...126), nil, "a"), - [InNode(127...136)( - RangeNode(131...136)(nil, IntegerNode(134...136)(), (131...134), 1), - nil, - (127...129), - nil - )], - nil, - (119...123), - (138...141) - ), - CaseNode(143...164)( - SymbolNode(148...150)((148...149), (149...150), nil, "a"), - [InNode(151...159)( - RangeNode(155...159)(nil, IntegerNode(157...159)(), (155...157), 0), - nil, - (151...153), - nil - )], - nil, - (143...147), - (161...164) - ), - CaseNode(166...187)( - SymbolNode(171...173)((171...172), (172...173), nil, "a"), - [InNode(174...182)( - RangeNode(178...182)(IntegerNode(178...179)(), nil, (179...182), 1), - nil, - (174...176), - nil - )], - nil, - (166...170), - (184...187) - ), - CaseNode(189...211)( - SymbolNode(194...196)((194...195), (195...196), nil, "a"), - [InNode(197...206)( - RangeNode(201...206)( - IntegerNode(201...202)(), - IntegerNode(205...206)(), - (202...205), - 1 - ), - nil, - (197...199), - nil - )], - nil, - (189...193), - (208...211) - ), - CaseNode(213...232)( - SymbolNode(218...220)((218...219), (219...220), nil, "a"), - [InNode(221...227)(IntegerNode(225...227)(), nil, (221...223), nil)], - nil, - (213...217), - (229...232) - ), - CaseNode(234...254)( - SymbolNode(239...241)((239...240), (240...241), nil, "a"), - [InNode(242...250)( - HashPatternNode(245...250)( - nil, - [NoKeywordsParameterNode(245...250)((245...247), (247...250))], - nil, - nil, - nil - ), - nil, - (242...244), - nil - )], - nil, - (234...238), - (251...254) - ), - CaseNode(256...279)( - SymbolNode(261...263)((261...262), (262...263), nil, "a"), - [InNode(264...275)( - RegularExpressionNode(267...275)( - (267...268), - (268...274), - (274...275), - "regexp", - 0 - ), - nil, - (264...266), - nil - )], - nil, - (256...260), - (276...279) - ), - CaseNode(281...306)( - SymbolNode(286...288)((286...287), (287...288), nil, "a"), - [InNode(289...302)( - ArrayPatternNode(292...302)( - nil, - [SymbolNode(292...294)((292...293), (293...294), nil, "b")], - SplatNode(296...298)( - (296...297), - LocalVariableTargetNode(297...298)(:_, 0) - ), - [SymbolNode(300...302)((300...301), (301...302), nil, "c")], - nil, - nil - ), - nil, - (289...291), - nil - )], - nil, - (281...285), - (303...306) - ), - CaseNode(308...331)( - SymbolNode(313...315)((313...314), (314...315), nil, "a"), - [InNode(316...327)( - ArrayPatternNode(319...327)( - nil, - [SymbolNode(319...321)((319...320), (320...321), nil, "b"), - ArrayPatternNode(323...327)( - nil, - [SymbolNode(324...326)((324...325), (325...326), nil, "c")], - nil, - [], - (323...324), - (326...327) - )], - nil, - [], - nil, - nil - ), - nil, - (316...318), - nil - )], - nil, - (308...312), - (328...331) - ), - CaseNode(333...356)( - SymbolNode(338...340)((338...339), (339...340), nil, "a"), - [InNode(341...352)( - ArrayPatternNode(344...352)( - ConstantReadNode(344...350)(:Symbol), - [], - nil, - [], - (350...351), - (351...352) - ), - nil, - (341...343), - nil - )], - nil, - (333...337), - (353...356) - ), - CaseNode(358...394)( - SymbolNode(363...365)((363...364), (364...365), nil, "a"), - [InNode(366...390)( - FindPatternNode(369...390)( - ConstantReadNode(369...375)(:Symbol), - SplatNode(376...380)( - (376...377), - LocalVariableTargetNode(377...380)(:lhs, 0) - ), - [LocalVariableTargetNode(382...383)(:x, 0)], - SplatNode(385...389)( - (385...386), - LocalVariableTargetNode(386...389)(:rhs, 0) - ), - (375...376), - (389...390) - ), - nil, - (366...368), - nil - )], - nil, - (358...362), - (391...394) - ), - CaseNode(396...432)( - SymbolNode(401...403)((401...402), (402...403), nil, "a"), - [InNode(404...428)( - FindPatternNode(407...428)( - ConstantReadNode(407...413)(:Symbol), - SplatNode(414...418)( - (414...415), - LocalVariableTargetNode(415...418)(:lhs, 0) - ), - [LocalVariableTargetNode(420...421)(:x, 0)], - SplatNode(423...427)( - (423...424), - LocalVariableTargetNode(424...427)(:rhs, 0) - ), - (413...414), - (427...428) - ), - nil, - (404...406), - nil - )], - nil, - (396...400), - (429...432) - ), - CaseNode(434...468)( - SymbolNode(439...441)((439...440), (440...441), nil, "a"), - [InNode(442...464)( - ArrayPatternNode(445...464)( - nil, - [LambdaNode(446...460)( - [:b], - (446...448), - (452...453), - (459...460), - BlockParametersNode(448...451)( - ParametersNode(449...450)( - [RequiredParameterNode(449...450)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (448...449), - (450...451) - ), - StatementsNode(454...458)([TrueNode(454...458)()]) - ), - LocalVariableTargetNode(462...463)(:c, 0)], - nil, - [], - (445...446), - (463...464) - ), - nil, - (442...444), - nil - )], - nil, - (434...438), - (465...468) - ), - CaseNode(470...510)( - SymbolNode(475...477)((475...476), (476...477), nil, "a"), - [InNode(478...506)( - ArrayPatternNode(481...506)( - nil, - [SymbolNode(482...484)((482...483), (483...484), nil, "a"), - LocalVariableTargetNode(486...487)(:b, 0), - LocalVariableTargetNode(489...490)(:c, 0), - ArrayPatternNode(492...505)( - nil, - [SymbolNode(493...495)((493...494), (494...495), nil, "d")], - SplatNode(497...499)( - (497...498), - LocalVariableTargetNode(498...499)(:e, 0) - ), - [NilNode(501...504)()], - (492...493), - (504...505) - )], - nil, - [], - (481...482), - (505...506) - ), - nil, - (478...480), - nil - )], - nil, - (470...474), - (507...510) - ), - CaseNode(512...536)( - SymbolNode(517...519)((517...518), (518...519), nil, "a"), - [InNode(520...532)( - ArrayPatternNode(523...532)( - nil, - [ConstantReadNode(524...525)(:A)], - SplatNode(527...528)((527...528), nil), - [ConstantReadNode(530...531)(:B)], - (523...524), - (531...532) - ), - nil, - (520...522), - nil - )], - nil, - (512...516), - (533...536) - ), - CaseNode(538...572)( - SymbolNode(543...545)((543...544), (544...545), nil, "a"), - [InNode(546...568)( - ArrayPatternNode(549...568)( - nil, - [ArrayPatternNode(550...557)( - nil, - [SymbolNode(551...553)((551...552), (552...553), nil, "b"), - LocalVariableTargetNode(555...556)(:c, 0)], - nil, - [], - (550...551), - (556...557) - ), - ArrayPatternNode(559...567)( - nil, - [SymbolNode(560...562)((560...561), (561...562), nil, "d"), - PinnedVariableNode(564...566)( - LocalVariableReadNode(565...566)(:e, 0), - (564...565) - )], - nil, - [], - (559...560), - (566...567) - )], - nil, - [], - (549...550), - (567...568) - ), - nil, - (546...548), - nil - )], - nil, - (538...542), - (569...572) - ), - CaseNode(574...591)( - SymbolNode(579...581)((579...580), (580...581), nil, "a"), - [InNode(582...587)( - ArrayPatternNode(585...587)( - nil, - [], - nil, - [], - (585...586), - (586...587) - ), - nil, - (582...584), - nil - )], - nil, - (574...578), - (588...591) - ), - CaseNode(593...614)( - SymbolNode(598...600)((598...599), (599...600), nil, "a"), - [InNode(601...610)( - ArrayPatternNode(604...610)( - nil, - [PinnedExpressionNode(605...609)( - CallNode(607...608)( - nil, - nil, - (607...608), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (605...606), - (606...607), - (608...609) - )], - nil, - [], - (604...605), - (609...610) - ), - nil, - (601...603), - nil - )], - nil, - (593...597), - (611...614) - ), - CaseNode(616...647)( - SymbolNode(621...623)((621...622), (622...623), nil, "a"), - [InNode(624...643)( - ArrayPatternNode(627...643)( - nil, - [PinnedVariableNode(628...631)( - InstanceVariableReadNode(629...631)(:@a), - (628...629) - ), - PinnedVariableNode(633...636)( - GlobalVariableReadNode(634...636)(:$b), - (633...634) - ), - PinnedVariableNode(638...642)( - ClassVariableReadNode(639...642)(:@@c), - (638...639) - )], - nil, - [], - (627...628), - (642...643) - ), - nil, - (624...626), - nil - )], - nil, - (616...620), - (644...647) - ), - CaseNode(649...673)( - SymbolNode(654...656)((654...655), (655...656), nil, "a"), - [InNode(657...669)( - XStringNode(660...669)( - (660...661), - (661...668), - (668...669), - "echo hi" - ), - nil, - (657...659), - nil - )], - nil, - (649...653), - (670...673) - ), - CaseNode(675...703)( - SymbolNode(680...682)((680...681), (681...682), nil, "a"), - [InNode(683...699)( - ArrayPatternNode(686...699)( - nil, - [NilNode(686...689)(), NilNode(691...694)(), NilNode(696...699)()], - nil, - [], - nil, - nil - ), - nil, - (683...685), - nil - )], - nil, - (675...679), - (700...703) - ), - CaseNode(705...728)( - SymbolNode(710...712)((710...711), (711...712), nil, "a"), - [InNode(713...724)( - HashPatternNode(716...724)( - nil, - [AssocNode(718...722)( - SymbolNode(718...722)( - (718...719), - (719...720), - (720...722), - "b" - ), - nil, - nil - )], - nil, - (716...717), - (723...724) - ), - nil, - (713...715), - nil - )], - nil, - (705...709), - (725...728) - ), - CaseNode(730...747)( - SymbolNode(735...737)((735...736), (736...737), nil, "a"), - [InNode(738...743)( - HashPatternNode(741...743)(nil, [], nil, (741...742), (742...743)), - nil, - (738...740), - nil - )], - nil, - (730...734), - (744...747) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_31.txt b/test/yarp/snapshots/seattlerb/case_in_31.txt deleted file mode 100644 index c34b271b848e76..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_31.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...28)( - [:c], - StatementsNode(0...28)( - [CaseNode(0...28)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...24)( - ArrayPatternNode(11...19)( - nil, - [SymbolNode(12...14)((12...13), (13...14), nil, "b")], - SplatNode(16...18)( - (16...17), - LocalVariableTargetNode(17...18)(:c, 0) - ), - [], - (11...12), - (18...19) - ), - StatementsNode(22...24)( - [SymbolNode(22...24)((22...23), (23...24), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_37.txt b/test/yarp/snapshots/seattlerb/case_in_37.txt deleted file mode 100644 index 47137d795d177e..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_37.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...36)( - [], - StatementsNode(0...36)( - [CaseNode(0...36)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...32)( - HashPatternNode(11...27)( - nil, - [AssocNode(13...25)( - SymbolNode(13...15)(nil, (13...14), (14...15), "b"), - ArrayPatternNode(16...25)( - nil, - [ConstantReadNode(17...21)(:Hash)], - SplatNode(23...24)((23...24), nil), - [], - (16...17), - (24...25) - ), - nil - )], - nil, - (11...12), - (26...27) - ), - StatementsNode(30...32)( - [SymbolNode(30...32)((30...31), (31...32), nil, "c")] - ), - (8...10), - nil - )], - nil, - (0...4), - (33...36) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_42.txt b/test/yarp/snapshots/seattlerb/case_in_42.txt deleted file mode 100644 index b98fd9f4b78f60..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_42.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...30)( - [:_], - StatementsNode(0...30)( - [CaseNode(0...30)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...26)( - ArrayPatternNode(11...17)( - nil, - [SymbolNode(11...13)((11...12), (12...13), nil, "b")], - SplatNode(15...17)( - (15...16), - LocalVariableTargetNode(16...17)(:_, 0) - ), - [], - nil, - nil - ), - StatementsNode(23...26)([NilNode(23...26)()]), - (8...10), - (18...22) - )], - nil, - (0...4), - (27...30) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_42_2.txt b/test/yarp/snapshots/seattlerb/case_in_42_2.txt deleted file mode 100644 index 5d7fc68646462a..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_42_2.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...32)( - [:list], - StatementsNode(0...32)( - [CaseNode(0...32)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...28)( - ArrayPatternNode(11...19)( - ConstantReadNode(11...12)(:A), - [], - SplatNode(13...18)( - (13...14), - LocalVariableTargetNode(14...18)(:list, 0) - ), - [], - (12...13), - (18...19) - ), - StatementsNode(25...28)([NilNode(25...28)()]), - (8...10), - (20...24) - )], - nil, - (0...4), - (29...32) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_47.txt b/test/yarp/snapshots/seattlerb/case_in_47.txt deleted file mode 100644 index 727efebddee0ab..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_47.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CaseNode(0...31)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...27)( - ArrayPatternNode(11...22)( - nil, - [], - SplatNode(12...13)((12...13), nil), - [SymbolNode(15...17)((15...16), (16...17), nil, "b"), - SymbolNode(19...21)((19...20), (20...21), nil, "c")], - (11...12), - (21...22) - ), - StatementsNode(25...27)( - [SymbolNode(25...27)((25...26), (26...27), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (28...31) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_67.txt b/test/yarp/snapshots/seattlerb/case_in_67.txt deleted file mode 100644 index 094d6711aa37b6..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_67.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [CaseNode(0...27)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...23)( - RangeNode(11...14)(IntegerNode(11...12)(), nil, (12...14), 0), - StatementsNode(20...23)([NilNode(20...23)()]), - (8...10), - (15...19) - )], - nil, - (0...4), - (24...27) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_86.txt b/test/yarp/snapshots/seattlerb/case_in_86.txt deleted file mode 100644 index c6287b9c3efb60..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_86.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CaseNode(0...43)( - ArrayNode(5...13)( - [SymbolNode(6...8)((6...7), (7...8), nil, "a"), - SymbolNode(10...12)((10...11), (11...12), nil, "b")], - (5...6), - (12...13) - ), - [InNode(14...39)( - ArrayPatternNode(17...30)( - nil, - [ConstantPathNode(17...27)( - nil, - ConstantReadNode(19...27)(:NilClass), - (17...19) - )], - SplatNode(29...30)((29...30), nil), - [], - nil, - nil - ), - StatementsNode(36...39)([NilNode(36...39)()]), - (14...16), - (31...35) - )], - nil, - (0...4), - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_86_2.txt b/test/yarp/snapshots/seattlerb/case_in_86_2.txt deleted file mode 100644 index 16fdad3d3c8c31..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_86_2.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CaseNode(0...43)( - ArrayNode(5...13)( - [SymbolNode(6...8)((6...7), (7...8), nil, "a"), - SymbolNode(10...12)((10...11), (11...12), nil, "b")], - (5...6), - (12...13) - ), - [InNode(14...39)( - ArrayPatternNode(17...30)( - nil, - [], - SplatNode(17...18)((17...18), nil), - [ConstantPathNode(20...30)( - nil, - ConstantReadNode(22...30)(:NilClass), - (20...22) - )], - nil, - nil - ), - StatementsNode(36...39)([NilNode(36...39)()]), - (14...16), - (31...35) - )], - nil, - (0...4), - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_array_pat_const.txt b/test/yarp/snapshots/seattlerb/case_in_array_pat_const.txt deleted file mode 100644 index bf332c3d5d3ae6..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_array_pat_const.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...24)( - [:c], - StatementsNode(0...24)( - [CaseNode(0...24)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...20)( - ArrayPatternNode(11...15)( - ConstantReadNode(11...12)(:B), - [LocalVariableTargetNode(13...14)(:c, 0)], - nil, - [], - (12...13), - (14...15) - ), - StatementsNode(18...20)( - [SymbolNode(18...20)((18...19), (19...20), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (21...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_array_pat_const2.txt b/test/yarp/snapshots/seattlerb/case_in_array_pat_const2.txt deleted file mode 100644 index 382db335d54664..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_array_pat_const2.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...27)( - [:d], - StatementsNode(0...27)( - [CaseNode(0...27)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...23)( - ArrayPatternNode(11...18)( - ConstantPathNode(11...15)( - ConstantReadNode(11...12)(:B), - ConstantReadNode(14...15)(:C), - (12...14) - ), - [LocalVariableTargetNode(16...17)(:d, 0)], - nil, - [], - (15...16), - (17...18) - ), - StatementsNode(21...23)( - [SymbolNode(21...23)((21...22), (22...23), nil, "e")] - ), - (8...10), - nil - )], - nil, - (0...4), - (24...27) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_array_pat_paren_assign.txt b/test/yarp/snapshots/seattlerb/case_in_array_pat_paren_assign.txt deleted file mode 100644 index c2a74beaabb08c..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_array_pat_paren_assign.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...29)( - [:d], - StatementsNode(0...29)( - [CaseNode(0...29)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...25)( - ArrayPatternNode(11...20)( - ConstantReadNode(11...12)(:B), - [CapturePatternNode(13...19)( - ConstantReadNode(13...14)(:C), - LocalVariableTargetNode(18...19)(:d, 0), - (15...17) - )], - nil, - [], - (12...13), - (19...20) - ), - StatementsNode(23...25)( - [SymbolNode(23...25)((23...24), (24...25), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_const.txt b/test/yarp/snapshots/seattlerb/case_in_const.txt deleted file mode 100644 index b2312a5d7ad67f..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_const.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CaseNode(0...28)( - ConstantReadNode(5...10)(:Array), - [InNode(11...24)( - ConstantReadNode(14...19)(:Class), - StatementsNode(22...24)( - [SymbolNode(22...24)((22...23), (23...24), nil, "b")] - ), - (11...13), - nil - )], - nil, - (0...4), - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_else.txt b/test/yarp/snapshots/seattlerb/case_in_else.txt deleted file mode 100644 index edbcff9af85694..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_else.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [CaseNode(0...38)( - ConstantReadNode(5...10)(:Array), - [InNode(11...24)( - ConstantReadNode(14...19)(:Class), - StatementsNode(22...24)( - [SymbolNode(22...24)((22...23), (23...24), nil, "b")] - ), - (11...13), - nil - )], - ElseNode(25...38)( - (25...29), - StatementsNode(32...34)( - [SymbolNode(32...34)((32...33), (33...34), nil, "c")] - ), - (35...38) - ), - (0...4), - (35...38) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_find.txt b/test/yarp/snapshots/seattlerb/case_in_find.txt deleted file mode 100644 index 3c8e6442448236..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_find.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...27)( - [:a, :b], - StatementsNode(0...27)( - [CaseNode(0...27)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(10...23)( - FindPatternNode(13...23)( - nil, - SplatNode(13...15)( - (13...14), - LocalVariableTargetNode(14...15)(:a, 0) - ), - [SymbolNode(17...19)((17...18), (18...19), nil, "+")], - SplatNode(21...23)( - (21...22), - LocalVariableTargetNode(22...23)(:b, 0) - ), - nil, - nil - ), - nil, - (10...12), - nil - )], - nil, - (0...4), - (24...27) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_find_array.txt b/test/yarp/snapshots/seattlerb/case_in_find_array.txt deleted file mode 100644 index 616c8f864bc634..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_find_array.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...28)( - [:c], - StatementsNode(0...28)( - [CaseNode(0...28)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...24)( - FindPatternNode(11...24)( - nil, - SplatNode(12...13)((12...13), nil), - [SymbolNode(15...17)((15...16), (16...17), nil, "b"), - LocalVariableTargetNode(19...20)(:c, 0)], - SplatNode(22...23)((22...23), nil), - (11...12), - (23...24) - ), - nil, - (8...10), - nil - )], - nil, - (0...4), - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat.txt deleted file mode 100644 index b7c8e7eb823bf0..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CaseNode(0...43)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...39)( - HashPatternNode(11...29)( - nil, - [AssocNode(13...19)( - SymbolNode(13...15)(nil, (13...14), (14...15), "b"), - StringNode(16...19)((16...17), (17...18), (18...19), "c"), - nil - ), - AssocNode(21...27)( - SymbolNode(21...23)(nil, (21...22), (22...23), "d"), - StringNode(24...27)((24...25), (25...26), (26...27), "e"), - nil - )], - nil, - (11...12), - (28...29) - ), - StatementsNode(37...39)( - [SymbolNode(37...39)((37...38), (38...39), nil, "f")] - ), - (8...10), - (30...34) - )], - nil, - (0...4), - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat_assign.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat_assign.txt deleted file mode 100644 index bac4076d27c9db..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat_assign.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...56)( - [:x, :f], - StatementsNode(0...56)( - [CaseNode(0...56)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...52)( - HashPatternNode(11...42)( - nil, - [AssocNode(13...28)( - SymbolNode(13...15)(nil, (13...14), (14...15), "b"), - CapturePatternNode(16...28)( - ConstantReadNode(16...23)(:Integer), - LocalVariableTargetNode(27...28)(:x, 0), - (24...26) - ), - nil - ), - AssocNode(30...36)( - SymbolNode(30...32)(nil, (30...31), (31...32), "d"), - StringNode(33...36)((33...34), (34...35), (35...36), "e"), - nil - ), - AssocNode(38...40)( - SymbolNode(38...40)(nil, (38...39), (39...40), "f"), - nil, - nil - )], - nil, - (11...12), - (41...42) - ), - StatementsNode(50...52)( - [SymbolNode(50...52)((50...51), (51...52), nil, "g")] - ), - (8...10), - (43...47) - )], - nil, - (0...4), - (53...56) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt deleted file mode 100644 index 352da8ab8bb602..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_assign.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CaseNode(0...28)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...24)( - HashPatternNode(11...19)( - ConstantReadNode(11...12)(:B), - [AssocNode(13...18)( - SymbolNode(13...15)(nil, (13...14), (14...15), "a"), - IntegerNode(16...18)(), - nil - )], - nil, - (12...13), - (18...19) - ), - StatementsNode(22...24)( - [SymbolNode(22...24)((22...23), (23...24), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_true.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_true.txt deleted file mode 100644 index c1bc104eff00e7..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat_paren_true.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [CaseNode(0...32)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...28)( - HashPatternNode(11...18)( - nil, - [AssocNode(11...18)( - SymbolNode(11...13)(nil, (11...12), (12...13), "b"), - TrueNode(14...18)(), - nil - )], - nil, - nil, - nil - ), - StatementsNode(26...28)( - [SymbolNode(26...28)((26...27), (27...28), nil, "c")] - ), - (8...10), - (19...23) - )], - nil, - (0...4), - (29...32) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest.txt deleted file mode 100644 index 9998de3cfe6b15..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...35)( - [:c, :rest], - StatementsNode(0...35)( - [CaseNode(0...35)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...31)( - HashPatternNode(11...23)( - nil, - [AssocNode(11...15)( - SymbolNode(11...13)(nil, (11...12), (12...13), "b"), - LocalVariableTargetNode(14...15)(:c, 0), - nil - ), - AssocSplatNode(17...23)( - LocalVariableTargetNode(19...23)(:rest, 0), - (17...19) - )], - nil, - nil, - nil - ), - StatementsNode(29...31)( - [SymbolNode(29...31)((29...30), (30...31), nil, "d")] - ), - (8...10), - (24...28) - )], - nil, - (0...4), - (32...35) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt b/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt deleted file mode 100644 index 7d6634c7f8d3d6..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_hash_pat_rest_solo.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...29)( - [:rest], - StatementsNode(0...29)( - [CaseNode(0...29)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...25)( - HashPatternNode(11...17)( - nil, - [AssocSplatNode(11...17)( - LocalVariableTargetNode(13...17)(:rest, 0), - (11...13) - )], - nil, - nil, - nil - ), - StatementsNode(23...25)( - [SymbolNode(23...25)((23...24), (24...25), nil, "d")] - ), - (8...10), - (18...22) - )], - nil, - (0...4), - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_if_unless_post_mod.txt b/test/yarp/snapshots/seattlerb/case_in_if_unless_post_mod.txt deleted file mode 100644 index d4869db8ede315..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_if_unless_post_mod.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...52)( - [], - StatementsNode(0...52)( - [CaseNode(0...52)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...25)( - IfNode(11...20)( - (13...15), - TrueNode(16...20)(), - StatementsNode(11...12)([ConstantReadNode(11...12)(:A)]), - nil, - nil - ), - StatementsNode(23...25)( - [SymbolNode(23...25)((23...24), (24...25), nil, "C")] - ), - (8...10), - nil - ), - InNode(26...48)( - UnlessNode(29...43)( - (31...37), - FalseNode(38...43)(), - StatementsNode(29...30)([ConstantReadNode(29...30)(:D)]), - nil, - nil - ), - StatementsNode(46...48)( - [SymbolNode(46...48)((46...47), (47...48), nil, "E")] - ), - (26...28), - nil - )], - nil, - (0...4), - (49...52) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_multiple.txt b/test/yarp/snapshots/seattlerb/case_in_multiple.txt deleted file mode 100644 index 2210570cb9eb37..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_multiple.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [CaseNode(0...37)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...20)( - ConstantPathNode(11...15)( - ConstantReadNode(11...12)(:A), - ConstantReadNode(14...15)(:B), - (12...14) - ), - StatementsNode(18...20)( - [SymbolNode(18...20)((18...19), (19...20), nil, "C")] - ), - (8...10), - nil - ), - InNode(21...33)( - ConstantPathNode(24...28)( - ConstantReadNode(24...25)(:D), - ConstantReadNode(27...28)(:E), - (25...27) - ), - StatementsNode(31...33)( - [SymbolNode(31...33)((31...32), (32...33), nil, "F")] - ), - (21...23), - nil - )], - nil, - (0...4), - (34...37) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/case_in_or.txt b/test/yarp/snapshots/seattlerb/case_in_or.txt deleted file mode 100644 index 2a5ec39441819f..00000000000000 --- a/test/yarp/snapshots/seattlerb/case_in_or.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CaseNode(0...25)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...21)( - AlternationPatternNode(11...16)( - ConstantReadNode(11...12)(:B), - ConstantReadNode(15...16)(:C), - (13...14) - ), - StatementsNode(19...21)( - [SymbolNode(19...21)((19...20), (20...21), nil, "d")] - ), - (8...10), - nil - )], - nil, - (0...4), - (22...25) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/class_comments.txt b/test/yarp/snapshots/seattlerb/class_comments.txt deleted file mode 100644 index 5314c70cc4bafe..00000000000000 --- a/test/yarp/snapshots/seattlerb/class_comments.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(19...71)( - [], - StatementsNode(19...71)( - [ClassNode(19...71)( - [], - (19...24), - ConstantReadNode(25...26)(:X), - nil, - nil, - StatementsNode(40...67)( - [DefNode(40...67)( - :blah, - (44...48), - nil, - nil, - nil, - [], - (40...43), - nil, - nil, - nil, - nil, - (64...67) - )] - ), - (68...71), - :X - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/cond_unary_minus.txt b/test/yarp/snapshots/seattlerb/cond_unary_minus.txt deleted file mode 100644 index d4453066740ebd..00000000000000 --- a/test/yarp/snapshots/seattlerb/cond_unary_minus.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [IfNode(0...10)((0...2), IntegerNode(3...5)(), nil, nil, (7...10))] - ) -) diff --git a/test/yarp/snapshots/seattlerb/const_2_op_asgn_or2.txt b/test/yarp/snapshots/seattlerb/const_2_op_asgn_or2.txt deleted file mode 100644 index ea0d0bc196524b..00000000000000 --- a/test/yarp/snapshots/seattlerb/const_2_op_asgn_or2.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [ConstantPathOrWriteNode(0...12)( - ConstantPathNode(0...6)( - ConstantPathNode(0...3)(nil, ConstantReadNode(2...3)(:X), (0...2)), - ConstantReadNode(5...6)(:Y), - (3...5) - ), - (7...10), - IntegerNode(11...12)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/const_3_op_asgn_or.txt b/test/yarp/snapshots/seattlerb/const_3_op_asgn_or.txt deleted file mode 100644 index 99bbb930cf882d..00000000000000 --- a/test/yarp/snapshots/seattlerb/const_3_op_asgn_or.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [ConstantPathOrWriteNode(0...9)( - ConstantPathNode(0...3)(nil, ConstantReadNode(2...3)(:X), (0...2)), - (4...7), - IntegerNode(8...9)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/const_op_asgn_and1.txt b/test/yarp/snapshots/seattlerb/const_op_asgn_and1.txt deleted file mode 100644 index 53fed283e1d288..00000000000000 --- a/test/yarp/snapshots/seattlerb/const_op_asgn_and1.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [ConstantPathOperatorWriteNode(0...8)( - ConstantPathNode(0...3)(nil, ConstantReadNode(2...3)(:X), (0...2)), - (4...6), - IntegerNode(7...8)(), - :& - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/const_op_asgn_and2.txt b/test/yarp/snapshots/seattlerb/const_op_asgn_and2.txt deleted file mode 100644 index cd13c1f5a73e13..00000000000000 --- a/test/yarp/snapshots/seattlerb/const_op_asgn_and2.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [ConstantPathAndWriteNode(0...9)( - ConstantPathNode(0...3)(nil, ConstantReadNode(2...3)(:X), (0...2)), - (4...7), - IntegerNode(8...9)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/const_op_asgn_or.txt b/test/yarp/snapshots/seattlerb/const_op_asgn_or.txt deleted file mode 100644 index 1b8fdf986e5710..00000000000000 --- a/test/yarp/snapshots/seattlerb/const_op_asgn_or.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [ConstantPathOrWriteNode(0...10)( - ConstantPathNode(0...4)( - ConstantReadNode(0...1)(:X), - ConstantReadNode(3...4)(:Y), - (1...3) - ), - (5...8), - IntegerNode(9...10)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dasgn_icky2.txt b/test/yarp/snapshots/seattlerb/dasgn_icky2.txt deleted file mode 100644 index d37ac900b2630f..00000000000000 --- a/test/yarp/snapshots/seattlerb/dasgn_icky2.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...76)( - [], - StatementsNode(0...76)( - [CallNode(0...76)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...76)( - [:v], - nil, - StatementsNode(7...72)( - [LocalVariableWriteNode(7...14)( - :v, - 0, - (7...8), - NilNode(11...14)(), - (9...10) - ), - BeginNode(17...72)( - (17...22), - StatementsNode(27...32)( - [YieldNode(27...32)((27...32), nil, nil, nil)] - ), - RescueNode(35...66)( - (35...41), - [ConstantReadNode(42...51)(:Exception)], - (52...54), - LocalVariableTargetNode(55...56)(:v, 0), - StatementsNode(61...66)([BreakNode(61...66)(nil, (61...66))]), - nil - ), - nil, - nil, - (69...72) - )] - ), - (2...4), - (73...76) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defined_eh_parens.txt b/test/yarp/snapshots/seattlerb/defined_eh_parens.txt deleted file mode 100644 index 5aedca1fbb5c68..00000000000000 --- a/test/yarp/snapshots/seattlerb/defined_eh_parens.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [DefinedNode(0...12)((8...9), IntegerNode(9...11)(), (11...12), (0...8))] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt deleted file mode 100644 index 207e45aab9eed4..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [DefNode(0...29)( - :call, - (4...8), - nil, - ParametersNode(9...24)( - [RequiredParameterNode(9...15)(:interp)], - [], - [RequiredParameterNode(20...24)(:args)], - RestParameterNode(17...18)(nil, nil, (17...18)), - [], - nil, - nil - ), - nil, - [:interp, :*, :args], - (0...3), - nil, - (8...9), - (24...25), - nil, - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt deleted file mode 100644 index 908be093371206..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [DefNode(0...29)( - :a, - (4...5), - nil, - ParametersNode(6...12)( - [RequiredParameterNode(6...7)(:x)], - [], - [], - nil, - [], - ForwardingParameterNode(9...12)(), - nil - ), - StatementsNode(15...24)( - [CallNode(15...24)( - nil, - nil, - (15...16), - (16...17), - ArgumentsNode(17...23)( - [LocalVariableReadNode(17...18)(:x, 0), - ForwardingArgumentsNode(20...23)()] - ), - (23...24), - nil, - 0, - "b" - )] - ), - [:x, :"..."], - (0...3), - nil, - (5...6), - (12...13), - nil, - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt deleted file mode 100644 index bdb721f2d21d27..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [DefNode(0...41)( - :a, - (4...5), - nil, - ParametersNode(6...18)( - [RequiredParameterNode(6...7)(:x), - RequiredParameterNode(9...10)(:y), - RequiredParameterNode(12...13)(:z)], - [], - [], - nil, - [], - ForwardingParameterNode(15...18)(), - nil - ), - StatementsNode(21...36)( - [CallNode(21...36)( - nil, - nil, - (21...22), - (22...23), - ArgumentsNode(23...35)( - [SymbolNode(23...27)((23...24), (24...27), nil, "get"), - LocalVariableReadNode(29...30)(:z, 0), - ForwardingArgumentsNode(32...35)()] - ), - (35...36), - nil, - 0, - "b" - )] - ), - [:x, :y, :z, :"..."], - (0...3), - nil, - (5...6), - (18...19), - nil, - (38...41) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_comments.txt b/test/yarp/snapshots/seattlerb/defn_comments.txt deleted file mode 100644 index a9b5501204745a..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_comments.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(19...31)( - [], - StatementsNode(19...31)( - [DefNode(19...31)( - :blah, - (23...27), - nil, - nil, - nil, - [], - (19...22), - nil, - nil, - nil, - nil, - (28...31) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_endless_command.txt b/test/yarp/snapshots/seattlerb/defn_endless_command.txt deleted file mode 100644 index 4e8833808043a2..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_endless_command.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [DefNode(0...33)( - :some_method, - (4...15), - nil, - nil, - StatementsNode(18...33)( - [CallNode(18...33)( - nil, - nil, - (18...30), - nil, - ArgumentsNode(31...33)([IntegerNode(31...33)()]), - nil, - nil, - 0, - "other_method" - )] - ), - [], - (0...3), - nil, - nil, - nil, - (16...17), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt b/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt deleted file mode 100644 index 30e99d44fef538..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [DefNode(0...43)( - :some_method, - (4...15), - nil, - nil, - StatementsNode(18...43)( - [CallNode(18...43)( - nil, - nil, - (18...30), - nil, - ArgumentsNode(31...43)( - [RescueModifierNode(31...43)( - IntegerNode(31...33)(), - (34...40), - IntegerNode(41...43)() - )] - ), - nil, - nil, - 0, - "other_method" - )] - ), - [], - (0...3), - nil, - nil, - nil, - (16...17), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_forward_args.txt deleted file mode 100644 index 6b06726352def1..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_forward_args.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :a, - (4...5), - nil, - ParametersNode(6...9)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(6...9)(), - nil - ), - StatementsNode(12...18)( - [CallNode(12...18)( - nil, - nil, - (12...13), - (13...14), - ArgumentsNode(14...17)([ForwardingArgumentsNode(14...17)()]), - (17...18), - nil, - 0, - "b" - )] - ), - [:"..."], - (0...3), - nil, - (5...6), - (9...10), - nil, - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt b/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt deleted file mode 100644 index b0a199c7bd7300..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [DefNode(0...22)( - :f, - (4...5), - nil, - ParametersNode(6...9)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(6...9)(), - nil - ), - StatementsNode(12...18)( - [CallNode(12...18)( - nil, - nil, - (12...13), - (13...14), - ArgumentsNode(14...17)([ForwardingArgumentsNode(14...17)()]), - (17...18), - nil, - 0, - "m" - )] - ), - [:"..."], - (0...3), - nil, - nil, - nil, - nil, - (19...22) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt deleted file mode 100644 index ec45e1790ba45a..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...45)( - [], - StatementsNode(0...45)( - [DefNode(0...45)( - :test, - (4...8), - nil, - ParametersNode(9...18)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(9...18)(:testing, (11...18), (9...11)), - nil - ), - StatementsNode(20...41)( - [CallNode(20...41)( - nil, - nil, - (20...30), - (30...31), - ArgumentsNode(31...40)( - [KeywordHashNode(31...40)( - [AssocSplatNode(31...40)( - LocalVariableReadNode(33...40)(:testing, 0), - (31...33) - )] - )] - ), - (40...41), - nil, - 0, - "test_splat" - )] - ), - [:testing], - (0...3), - nil, - (8...9), - (18...19), - nil, - (42...45) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt deleted file mode 100644 index aa90849328282c..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [DefNode(0...24)( - :f, - (4...5), - nil, - ParametersNode(6...19)( - [RequiredParameterNode(6...7)(:a)], - [], - [], - nil, - [KeywordParameterNode(9...13)(:b, (9...11), IntegerNode(12...13)()), - KeywordParameterNode(15...19)( - :c, - (15...17), - IntegerNode(18...19)() - )], - nil, - nil - ), - nil, - [:a, :b, :c], - (0...3), - nil, - (5...6), - (19...20), - nil, - (21...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt deleted file mode 100644 index 83e1bc2f23e8bd..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [DefNode(0...20)( - :a, - (4...5), - nil, - ParametersNode(6...15)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...15)(:c, (14...15), (12...14)), - nil - ), - nil, - [:b, :c], - (0...3), - nil, - (5...6), - (15...16), - nil, - (17...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt deleted file mode 100644 index 58930bb8477fad..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [DefNode(0...19)( - :a, - (4...5), - nil, - ParametersNode(6...14)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...14)(nil, nil, (12...14)), - nil - ), - nil, - [:b, :**], - (0...3), - nil, - (5...6), - (14...15), - nil, - (16...19) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt deleted file mode 100644 index 2e1afdea71ad33..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [DefNode(0...26)( - :fun, - (4...7), - nil, - ParametersNode(8...16)( - [], - [], - [], - nil, - [KeywordParameterNode(8...16)( - :kw, - (8...11), - SymbolNode(12...16)((12...13), (13...16), nil, "val") - )], - nil, - nil - ), - StatementsNode(19...21)([LocalVariableReadNode(19...21)(:kw, 0)]), - [:kw], - (0...3), - nil, - (7...8), - (16...17), - nil, - (23...26) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt deleted file mode 100644 index c98e8317b66abd..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [DefNode(0...14)( - :f, - (4...5), - nil, - ParametersNode(6...10)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:a, (6...8), IntegerNode(9...10)())], - nil, - nil - ), - nil, - [:a], - (0...3), - nil, - nil, - nil, - nil, - (11...14) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt deleted file mode 100644 index 8a0be77d223bfb..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :f, - (4...5), - nil, - ParametersNode(6...12)( - [RequiredParameterNode(6...7)(:a)], - [], - [], - nil, - [KeywordParameterNode(9...12)(:b, (9...11), IntegerNode(11...12)())], - nil, - nil - ), - nil, - [:a, :b], - (0...3), - nil, - (5...6), - (12...13), - nil, - (14...17) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt b/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt deleted file mode 100644 index a810609fbc31a6..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :x, - (4...5), - nil, - ParametersNode(6...11)( - [], - [], - [], - nil, - [], - NoKeywordsParameterNode(6...11)((6...8), (8...11)), - nil - ), - nil, - [], - (0...3), - nil, - (5...6), - (11...12), - nil, - (14...17) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner.txt b/test/yarp/snapshots/seattlerb/defn_oneliner.txt deleted file mode 100644 index 1b1600dfedab9a..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_oneliner.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [DefNode(0...27)( - :exec, - (4...8), - nil, - ParametersNode(9...12)( - [RequiredParameterNode(9...12)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(16...27)( - [CallNode(16...27)( - nil, - nil, - (16...22), - (22...23), - ArgumentsNode(23...26)([LocalVariableReadNode(23...26)(:cmd, 0)]), - (26...27), - nil, - 0, - "system" - )] - ), - [:cmd], - (0...3), - nil, - (8...9), - (12...13), - (14...15), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt deleted file mode 100644 index db923d773e7f31..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [ClassNode(0...28)( - [], - (0...5), - ConstantReadNode(6...7)(:X), - nil, - nil, - StatementsNode(10...24)( - [DefNode(10...24)( - :==, - (14...16), - nil, - ParametersNode(17...18)( - [RequiredParameterNode(17...18)(:o)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(22...24)([IntegerNode(22...24)()]), - [:o], - (10...13), - nil, - (16...17), - (18...19), - (20...21), - nil - )] - ), - (25...28), - :X - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt deleted file mode 100644 index 2da92bf5598b9e..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :exec, - (4...8), - nil, - nil, - StatementsNode(11...17)( - [CallNode(11...17)( - nil, - nil, - (11...17), - nil, - nil, - nil, - nil, - 2, - "system" - )] - ), - [], - (0...3), - nil, - nil, - nil, - (9...10), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt deleted file mode 100644 index b416121718ccde..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [DefNode(0...19)( - :exec, - (4...8), - nil, - nil, - StatementsNode(13...19)( - [CallNode(13...19)( - nil, - nil, - (13...19), - nil, - nil, - nil, - nil, - 2, - "system" - )] - ), - [], - (0...3), - nil, - (8...9), - (9...10), - (11...12), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt deleted file mode 100644 index 0a1f6cbd931e88..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt +++ /dev/null @@ -1,135 +0,0 @@ -ProgramNode(0...130)( - [], - StatementsNode(0...130)( - [DefNode(0...44)( - :exec, - (4...8), - nil, - ParametersNode(9...12)( - [RequiredParameterNode(9...12)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - BeginNode(16...44)( - nil, - StatementsNode(16...27)( - [CallNode(16...27)( - nil, - nil, - (16...22), - (22...23), - ArgumentsNode(23...26)( - [LocalVariableReadNode(23...26)(:cmd, 0)] - ), - (26...27), - nil, - 0, - "system" - )] - ), - RescueNode(28...40)( - (28...34), - [], - nil, - nil, - StatementsNode(37...40)([NilNode(37...40)()]), - nil - ), - nil, - nil, - (41...44) - ), - [:cmd], - (0...3), - nil, - (8...9), - (12...13), - nil, - (41...44) - ), - DefNode(47...89)( - :exec, - (51...55), - nil, - ParametersNode(56...59)( - [RequiredParameterNode(56...59)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(63...85)( - [RescueModifierNode(63...85)( - CallNode(63...74)( - nil, - nil, - (63...69), - (69...70), - ArgumentsNode(70...73)( - [LocalVariableReadNode(70...73)(:cmd, 0)] - ), - (73...74), - nil, - 0, - "system" - ), - (75...81), - NilNode(82...85)() - )] - ), - [:cmd], - (47...50), - nil, - (55...56), - (59...60), - nil, - (86...89) - ), - DefNode(92...130)( - :exec, - (96...100), - nil, - ParametersNode(101...104)( - [RequiredParameterNode(101...104)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(108...130)( - [RescueModifierNode(108...130)( - CallNode(108...119)( - nil, - nil, - (108...114), - (114...115), - ArgumentsNode(115...118)( - [LocalVariableReadNode(115...118)(:cmd, 0)] - ), - (118...119), - nil, - 0, - "system" - ), - (120...126), - NilNode(127...130)() - )] - ), - [:cmd], - (92...95), - nil, - (100...101), - (104...105), - (106...107), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt b/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt deleted file mode 100644 index b9fe1dcf52a679..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [DefNode(0...21)( - :m, - (4...5), - nil, - ParametersNode(6...17)( - [], - [OptionalParameterNode(6...17)( - :arg, - (6...9), - (10...11), - FalseNode(12...17)() - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:arg], - (0...3), - nil, - nil, - nil, - nil, - (18...21) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_opt_reg.txt b/test/yarp/snapshots/seattlerb/defn_opt_reg.txt deleted file mode 100644 index 0ae5037d598a19..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_opt_reg.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [DefNode(0...19)( - :f, - (4...5), - nil, - ParametersNode(6...14)( - [], - [OptionalParameterNode(6...11)( - :a, - (6...7), - (7...8), - NilNode(8...11)() - )], - [RequiredParameterNode(13...14)(:b)], - nil, - [], - nil, - nil - ), - nil, - [:a, :b], - (0...3), - nil, - (5...6), - (14...15), - nil, - (16...19) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt deleted file mode 100644 index 2148a93df5071d..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [DefNode(0...24)( - :f, - (4...5), - nil, - ParametersNode(7...19)( - [], - [OptionalParameterNode(7...12)( - :a, - (7...8), - (9...10), - IntegerNode(11...12)() - )], - [RequiredParameterNode(18...19)(:c)], - RestParameterNode(14...16)(:b, (15...16), (14...15)), - [], - nil, - nil - ), - nil, - [:a, :b, :c], - (0...3), - nil, - (6...7), - (19...20), - nil, - (21...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_powarg.txt b/test/yarp/snapshots/seattlerb/defn_powarg.txt deleted file mode 100644 index b57aa3c9c707c1..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_powarg.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :f, - (4...5), - nil, - ParametersNode(6...12)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(6...12)(:opts, (8...12), (6...8)), - nil - ), - nil, - [:opts], - (0...3), - nil, - (5...6), - (12...13), - nil, - (14...17) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt b/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt deleted file mode 100644 index ee789ca0ae3e3d..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :f, - (4...5), - nil, - ParametersNode(6...18)( - [RequiredParameterNode(6...7)(:a)], - [OptionalParameterNode(9...15)( - :b, - (9...10), - (11...12), - SymbolNode(13...15)((13...14), (14...15), nil, "c") - )], - [RequiredParameterNode(17...18)(:d)], - nil, - [], - nil, - nil - ), - nil, - [:a, :b, :d], - (0...3), - nil, - (5...6), - (18...19), - nil, - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt deleted file mode 100644 index 95a16a11b56e25..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [DefNode(0...15)( - :f, - (4...5), - nil, - ParametersNode(6...10)( - [], - [], - [RequiredParameterNode(9...10)(:a)], - RestParameterNode(6...7)(nil, nil, (6...7)), - [], - nil, - nil - ), - nil, - [:*, :a], - (0...3), - nil, - (5...6), - (10...11), - nil, - (12...15) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defn_unary_not.txt b/test/yarp/snapshots/seattlerb/defn_unary_not.txt deleted file mode 100644 index e167c2aee9b9f2..00000000000000 --- a/test/yarp/snapshots/seattlerb/defn_unary_not.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :"!@", - (4...6), - nil, - nil, - StatementsNode(8...12)([TrueNode(8...12)()]), - [], - (0...3), - nil, - nil, - nil, - nil, - (14...17) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defns_reserved.txt b/test/yarp/snapshots/seattlerb/defns_reserved.txt deleted file mode 100644 index 7d12edeb9b3d5c..00000000000000 --- a/test/yarp/snapshots/seattlerb/defns_reserved.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [DefNode(0...20)( - :return, - (9...15), - SelfNode(4...8)(), - nil, - nil, - [], - (0...3), - (8...9), - nil, - nil, - nil, - (17...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt deleted file mode 100644 index 5474d1e825d4d8..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt +++ /dev/null @@ -1,53 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [CallNode(0...30)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...30)( - [DefNode(2...30)( - :b, - (11...12), - SelfNode(6...10)(), - nil, - StatementsNode(14...25)( - [CallNode(14...25)( - CallNode(14...15)( - nil, - nil, - (14...15), - nil, - nil, - nil, - nil, - 2, - "x" - ), - (15...16), - (16...17), - nil, - nil, - nil, - BlockNode(18...25)([], nil, nil, (18...20), (22...25)), - 0, - "y" - )] - ), - [], - (2...5), - (10...11), - nil, - nil, - nil, - (27...30) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_comments.txt b/test/yarp/snapshots/seattlerb/defs_comments.txt deleted file mode 100644 index 640576684b0ef2..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_comments.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(19...36)( - [], - StatementsNode(19...36)( - [DefNode(19...36)( - :blah, - (28...32), - SelfNode(23...27)(), - nil, - nil, - [], - (19...22), - (27...28), - nil, - nil, - nil, - (33...36) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_endless_command.txt b/test/yarp/snapshots/seattlerb/defs_endless_command.txt deleted file mode 100644 index 068e7de9b3ab96..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_endless_command.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [DefNode(0...35)( - :some_method, - (6...17), - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"), - nil, - StatementsNode(20...35)( - [CallNode(20...35)( - nil, - nil, - (20...32), - nil, - ArgumentsNode(33...35)([IntegerNode(33...35)()]), - nil, - nil, - 0, - "other_method" - )] - ), - [], - (0...3), - (5...6), - nil, - nil, - (18...19), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt b/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt deleted file mode 100644 index 00b4472689b978..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...45)( - [], - StatementsNode(0...45)( - [DefNode(0...45)( - :some_method, - (6...17), - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"), - nil, - StatementsNode(20...45)( - [CallNode(20...45)( - nil, - nil, - (20...32), - nil, - ArgumentsNode(33...45)( - [RescueModifierNode(33...45)( - IntegerNode(33...35)(), - (36...42), - IntegerNode(43...45)() - )] - ), - nil, - nil, - 0, - "other_method" - )] - ), - [], - (0...3), - (5...6), - nil, - nil, - (18...19), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_kwarg.txt b/test/yarp/snapshots/seattlerb/defs_kwarg.txt deleted file mode 100644 index 6b1e60d602cada..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_kwarg.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [DefNode(0...19)( - :a, - (9...10), - SelfNode(4...8)(), - ParametersNode(11...15)( - [], - [], - [], - nil, - [KeywordParameterNode(11...15)( - :b, - (11...13), - IntegerNode(14...15)() - )], - nil, - nil - ), - nil, - [:b], - (0...3), - (8...9), - nil, - nil, - nil, - (16...19) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner.txt b/test/yarp/snapshots/seattlerb/defs_oneliner.txt deleted file mode 100644 index f8214ef3f6f503..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_oneliner.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [DefNode(0...32)( - :exec, - (9...13), - SelfNode(4...8)(), - ParametersNode(14...17)( - [RequiredParameterNode(14...17)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(21...32)( - [CallNode(21...32)( - nil, - nil, - (21...27), - (27...28), - ArgumentsNode(28...31)([LocalVariableReadNode(28...31)(:cmd, 0)]), - (31...32), - nil, - 0, - "system" - )] - ), - [:cmd], - (0...3), - (8...9), - (13...14), - (17...18), - (19...20), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt deleted file mode 100644 index ee69fa0752562e..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [ClassNode(0...33)( - [], - (0...5), - ConstantReadNode(6...7)(:X), - nil, - nil, - StatementsNode(10...29)( - [DefNode(10...29)( - :==, - (19...21), - SelfNode(14...18)(), - ParametersNode(22...23)( - [RequiredParameterNode(22...23)(:o)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(27...29)([IntegerNode(27...29)()]), - [:o], - (10...13), - (18...19), - (21...22), - (23...24), - (25...26), - nil - )] - ), - (30...33), - :X - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt b/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt deleted file mode 100644 index 9f510cdb72ba4f..00000000000000 --- a/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt +++ /dev/null @@ -1,135 +0,0 @@ -ProgramNode(0...145)( - [], - StatementsNode(0...145)( - [DefNode(0...49)( - :exec, - (9...13), - SelfNode(4...8)(), - ParametersNode(14...17)( - [RequiredParameterNode(14...17)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - BeginNode(21...49)( - nil, - StatementsNode(21...32)( - [CallNode(21...32)( - nil, - nil, - (21...27), - (27...28), - ArgumentsNode(28...31)( - [LocalVariableReadNode(28...31)(:cmd, 0)] - ), - (31...32), - nil, - 0, - "system" - )] - ), - RescueNode(33...45)( - (33...39), - [], - nil, - nil, - StatementsNode(42...45)([NilNode(42...45)()]), - nil - ), - nil, - nil, - (46...49) - ), - [:cmd], - (0...3), - (8...9), - (13...14), - (17...18), - nil, - (46...49) - ), - DefNode(52...99)( - :exec, - (61...65), - SelfNode(56...60)(), - ParametersNode(66...69)( - [RequiredParameterNode(66...69)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(73...95)( - [RescueModifierNode(73...95)( - CallNode(73...84)( - nil, - nil, - (73...79), - (79...80), - ArgumentsNode(80...83)( - [LocalVariableReadNode(80...83)(:cmd, 0)] - ), - (83...84), - nil, - 0, - "system" - ), - (85...91), - NilNode(92...95)() - )] - ), - [:cmd], - (52...55), - (60...61), - (65...66), - (69...70), - nil, - (96...99) - ), - DefNode(102...145)( - :exec, - (111...115), - SelfNode(106...110)(), - ParametersNode(116...119)( - [RequiredParameterNode(116...119)(:cmd)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(123...145)( - [RescueModifierNode(123...145)( - CallNode(123...134)( - nil, - nil, - (123...129), - (129...130), - ArgumentsNode(130...133)( - [LocalVariableReadNode(130...133)(:cmd, 0)] - ), - (133...134), - nil, - 0, - "system" - ), - (135...141), - NilNode(142...145)() - )] - ), - [:cmd], - (102...105), - (110...111), - (115...116), - (119...120), - (121...122), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult0_.txt b/test/yarp/snapshots/seattlerb/difficult0_.txt deleted file mode 100644 index c68a126eb09b46..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult0_.txt +++ /dev/null @@ -1,51 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [CallNode(0...30)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...30)( - [CallNode(2...30)( - CallNode(2...26)( - InterpolatedStringNode(2...8)( - (2...8), - [StringNode(12...16)(nil, (12...16), nil, " a\n")], - (16...22) - ), - nil, - (8...9), - nil, - ArgumentsNode(9...26)( - [InterpolatedStringNode(9...26)( - (9...10), - [StringNode(10...12)(nil, (10...12), nil, "b\n"), - StringNode(22...25)(nil, (22...25), nil, " c")], - (25...26) - )] - ), - nil, - nil, - 0, - "+" - ), - nil, - (26...27), - nil, - ArgumentsNode(27...30)( - [StringNode(27...30)((27...28), (28...29), (29...30), "d")] - ), - nil, - nil, - 0, - "+" - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult1_line_numbers.txt b/test/yarp/snapshots/seattlerb/difficult1_line_numbers.txt deleted file mode 100644 index 69736976411983..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult1_line_numbers.txt +++ /dev/null @@ -1,131 +0,0 @@ -ProgramNode(0...104)( - [], - StatementsNode(0...104)( - [IfNode(0...104)( - (0...2), - TrueNode(3...7)(), - StatementsNode(10...100)( - [CallNode(10...13)( - nil, - nil, - (10...11), - nil, - ArgumentsNode(12...13)([IntegerNode(12...13)()]), - nil, - nil, - 0, - "p" - ), - CallNode(16...21)( - CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "a"), - (17...18), - (18...19), - nil, - ArgumentsNode(20...21)([IntegerNode(20...21)()]), - nil, - nil, - 0, - "b" - ), - CallNode(24...32)( - CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "c"), - (25...26), - (26...27), - nil, - ArgumentsNode(28...32)( - [IntegerNode(28...29)(), IntegerNode(31...32)()] - ), - nil, - nil, - 0, - "d" - ), - CallNode(35...40)( - CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 2, "e"), - (36...37), - (37...38), - nil, - ArgumentsNode(39...40)([IntegerNode(39...40)()]), - nil, - nil, - 0, - "f" - ), - CallNode(43...51)( - CallNode(43...44)(nil, nil, (43...44), nil, nil, nil, nil, 2, "g"), - (44...45), - (45...46), - nil, - ArgumentsNode(47...51)( - [IntegerNode(47...48)(), IntegerNode(50...51)()] - ), - nil, - nil, - 0, - "h" - ), - CallNode(54...58)( - nil, - nil, - (54...55), - (55...56), - ArgumentsNode(56...57)([IntegerNode(56...57)()]), - (57...58), - nil, - 0, - "p" - ), - CallNode(61...67)( - CallNode(61...62)(nil, nil, (61...62), nil, nil, nil, nil, 2, "a"), - (62...63), - (63...64), - (64...65), - ArgumentsNode(65...66)([IntegerNode(65...66)()]), - (66...67), - nil, - 0, - "b" - ), - CallNode(70...79)( - CallNode(70...71)(nil, nil, (70...71), nil, nil, nil, nil, 2, "c"), - (71...72), - (72...73), - (73...74), - ArgumentsNode(74...78)( - [IntegerNode(74...75)(), IntegerNode(77...78)()] - ), - (78...79), - nil, - 0, - "d" - ), - CallNode(82...88)( - CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "e"), - (83...84), - (84...85), - (85...86), - ArgumentsNode(86...87)([IntegerNode(86...87)()]), - (87...88), - nil, - 0, - "f" - ), - CallNode(91...100)( - CallNode(91...92)(nil, nil, (91...92), nil, nil, nil, nil, 2, "g"), - (92...93), - (93...94), - (94...95), - ArgumentsNode(95...99)( - [IntegerNode(95...96)(), IntegerNode(98...99)()] - ), - (99...100), - nil, - 0, - "h" - )] - ), - nil, - (101...104) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt b/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt deleted file mode 100644 index d19d6d817b6e7d..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult1_line_numbers2.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...48)( - [:b, :c], - StatementsNode(0...48)( - [IfNode(0...46)( - (0...2), - TrueNode(3...7)(), - StatementsNode(15...42)( - [CallNode(15...21)( - nil, - nil, - (15...16), - (16...17), - ArgumentsNode(17...20)( - [StringNode(17...20)((17...18), (18...19), (19...20), "a")] - ), - (20...21), - nil, - 0, - "p" - ), - LocalVariableWriteNode(24...29)( - :b, - 0, - (24...25), - IntegerNode(28...29)(), - (26...27) - ), - CallNode(32...35)( - nil, - nil, - (32...33), - nil, - ArgumentsNode(34...35)([LocalVariableReadNode(34...35)(:b, 0)]), - nil, - nil, - 0, - "p" - ), - LocalVariableWriteNode(38...42)( - :c, - 0, - (38...39), - IntegerNode(41...42)(), - (40...41) - )] - ), - nil, - (43...46) - ), - CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 2, "a")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult2_.txt b/test/yarp/snapshots/seattlerb/difficult2_.txt deleted file mode 100644 index 78772ca20d1b18..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult2_.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [IfNode(0...13)( - nil, - IntegerNode(0...1)(), - StatementsNode(4...9)( - [CallNode(4...9)( - nil, - nil, - (4...5), - (5...6), - ArgumentsNode(6...8)( - [StringNode(6...8)((6...7), (7...7), (7...8), "")] - ), - (8...9), - nil, - 0, - "b" - )] - ), - ElseNode(10...13)( - (10...11), - StatementsNode(12...13)([IntegerNode(12...13)()]), - nil - ), - nil - ), - CallNode(14...20)( - nil, - nil, - (14...15), - nil, - ArgumentsNode(16...20)( - [KeywordHashNode(16...20)( - [AssocNode(16...20)( - SymbolNode(16...18)(nil, (16...17), (17...18), "d"), - IntegerNode(19...20)(), - nil - )] - )] - ), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3_.txt b/test/yarp/snapshots/seattlerb/difficult3_.txt deleted file mode 100644 index ba5d6c3aeda680..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3_.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:a, :b, :c], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...15)( - [RequiredParameterNode(9...10)(:b), - SplatNode(12...14)( - (12...13), - RequiredParameterNode(13...14)(:c) - )], - (8...9), - (14...15) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3_2.txt b/test/yarp/snapshots/seattlerb/difficult3_2.txt deleted file mode 100644 index fffcbac8be6349..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3_2.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...13)( - [:a, :b], - BlockParametersNode(4...11)( - ParametersNode(5...10)( - [], - [], - [RequiredParameterNode(9...10)(:b)], - RestParameterNode(5...7)(:a, (6...7), (5...6)), - [], - nil, - nil - ), - [], - (4...5), - (10...11) - ), - nil, - (2...3), - (12...13) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3_3.txt b/test/yarp/snapshots/seattlerb/difficult3_3.txt deleted file mode 100644 index 700f53cb673a7c..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3_3.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [], - [], - [RequiredParameterNode(9...10)(:b)], - RestParameterNode(5...7)(:a, (6...7), (5...6)), - [], - nil, - BlockParameterNode(12...14)(:c, (13...14), (12...13)) - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3_4.txt b/test/yarp/snapshots/seattlerb/difficult3_4.txt deleted file mode 100644 index 40ebfca6612174..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3_4.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...17)( - [:a], - StatementsNode(0...17)( - [LocalVariableWriteNode(0...17)( - :a, - 0, - (0...1), - IfNode(2...17)( - nil, - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"), - StatementsNode(6...10)([TrueNode(6...10)()]), - ElseNode(10...17)( - (10...11), - StatementsNode(12...17)([FalseNode(12...17)()]), - nil - ), - nil - ), - (1...2) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3_5.txt b/test/yarp/snapshots/seattlerb/difficult3_5.txt deleted file mode 100644 index 746786b8a5fb10..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3_5.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [CallNode(0...19)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...19)( - [LambdaNode(2...19)( - [], - (2...4), - (7...8), - (18...19), - BlockParametersNode(4...6)(nil, [], (4...5), (5...6)), - StatementsNode(9...17)( - [CallNode(9...17)( - nil, - nil, - (9...10), - nil, - nil, - nil, - BlockNode(11...17)([], nil, nil, (11...13), (14...17)), - 0, - "g" - )] - ) - )] - ), - nil, - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__10.txt b/test/yarp/snapshots/seattlerb/difficult3__10.txt deleted file mode 100644 index 7b7dc6f41b3cba..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__10.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:a, :b, :c], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...15)( - [SplatNode(9...11)( - (9...10), - RequiredParameterNode(10...11)(:b) - ), - RequiredParameterNode(13...14)(:c)], - (8...9), - (14...15) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__11.txt b/test/yarp/snapshots/seattlerb/difficult3__11.txt deleted file mode 100644 index c5b8b81b18bef1..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__11.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:a], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...11)( - [SplatNode(9...10)((9...10), nil)], - (8...9), - (10...11) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__12.txt b/test/yarp/snapshots/seattlerb/difficult3__12.txt deleted file mode 100644 index 87dd280a9e0c59..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__12.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...14)( - [SplatNode(9...10)((9...10), nil), - RequiredParameterNode(12...13)(:b)], - (8...9), - (13...14) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__6.txt b/test/yarp/snapshots/seattlerb/difficult3__6.txt deleted file mode 100644 index 578a22e843e2e2..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__6.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...21)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...21)( - [:a, :b, :c, :d], - BlockParametersNode(4...19)( - ParametersNode(5...18)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...18)( - [RequiredParameterNode(9...10)(:b), - SplatNode(12...14)( - (12...13), - RequiredParameterNode(13...14)(:c) - ), - RequiredParameterNode(16...17)(:d)], - (8...9), - (17...18) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (18...19) - ), - nil, - (2...3), - (20...21) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__7.txt b/test/yarp/snapshots/seattlerb/difficult3__7.txt deleted file mode 100644 index a306b1f895aa00..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__7.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...14)( - [RequiredParameterNode(9...10)(:b), - SplatNode(12...13)((12...13), nil)], - (8...9), - (13...14) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__8.txt b/test/yarp/snapshots/seattlerb/difficult3__8.txt deleted file mode 100644 index 9d0eb813574130..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__8.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...20)( - [:a, :b, :c], - BlockParametersNode(4...18)( - ParametersNode(5...17)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...17)( - [RequiredParameterNode(9...10)(:b), - SplatNode(12...13)((12...13), nil), - RequiredParameterNode(15...16)(:c)], - (8...9), - (16...17) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (17...18) - ), - nil, - (2...3), - (19...20) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult3__9.txt b/test/yarp/snapshots/seattlerb/difficult3__9.txt deleted file mode 100644 index a3a5ccd89d7081..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult3__9.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...15)( - [:a, :b], - BlockParametersNode(4...13)( - ParametersNode(5...12)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...12)( - [SplatNode(9...11)( - (9...10), - RequiredParameterNode(10...11)(:b) - )], - (8...9), - (11...12) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (12...13) - ), - nil, - (2...3), - (14...15) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult4__leading_dots.txt b/test/yarp/snapshots/seattlerb/difficult4__leading_dots.txt deleted file mode 100644 index 881cc6d5a873fe..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult4__leading_dots.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (2...3), - (3...4), - nil, - nil, - nil, - nil, - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult4__leading_dots2.txt b/test/yarp/snapshots/seattlerb/difficult4__leading_dots2.txt deleted file mode 100644 index 8a246f58271b15..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult4__leading_dots2.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [IntegerNode(0...1)(), - RangeNode(2...5)(nil, IntegerNode(4...5)(), (2...4), 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult6_.txt b/test/yarp/snapshots/seattlerb/difficult6_.txt deleted file mode 100644 index 2d1677e108f7e9..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult6_.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [LambdaNode(0...25)( - [:a, :b], - (0...2), - (13...14), - (24...25), - BlockParametersNode(2...12)( - ParametersNode(3...11)( - [RequiredParameterNode(3...4)(:a)], - [OptionalParameterNode(6...11)( - :b, - (6...7), - (7...8), - NilNode(8...11)() - )], - [], - nil, - [], - nil, - nil - ), - [], - (2...3), - (11...12) - ), - StatementsNode(15...23)( - [CallNode(15...23)( - nil, - nil, - (15...16), - nil, - ArgumentsNode(17...23)( - [ArrayNode(17...23)( - [LocalVariableReadNode(18...19)(:a, 0), - LocalVariableReadNode(21...22)(:b, 0)], - (17...18), - (22...23) - )] - ), - nil, - nil, - 0, - "p" - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult6__7.txt b/test/yarp/snapshots/seattlerb/difficult6__7.txt deleted file mode 100644 index 60b902f4d232ea..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult6__7.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - ArgumentsNode(4...7)( - [ParenthesesNode(4...7)( - StatementsNode(5...6)([IntegerNode(5...6)()]), - (4...5), - (6...7) - )] - ), - nil, - BlockNode(8...11)( - [], - nil, - StatementsNode(9...10)( - [CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "c")] - ), - (8...9), - (10...11) - ), - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult6__8.txt b/test/yarp/snapshots/seattlerb/difficult6__8.txt deleted file mode 100644 index ed7a53a89a85b2..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult6__8.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - ArgumentsNode(5...8)( - [ParenthesesNode(5...8)( - StatementsNode(6...7)([IntegerNode(6...7)()]), - (5...6), - (7...8) - )] - ), - nil, - BlockNode(9...12)( - [], - nil, - StatementsNode(10...11)( - [CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c")] - ), - (9...10), - (11...12) - ), - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/difficult7_.txt b/test/yarp/snapshots/seattlerb/difficult7_.txt deleted file mode 100644 index 44a67b33775e27..00000000000000 --- a/test/yarp/snapshots/seattlerb/difficult7_.txt +++ /dev/null @@ -1,81 +0,0 @@ -ProgramNode(6...66)( - [], - StatementsNode(6...66)( - [HashNode(6...66)( - (6...7), - [AssocNode(16...41)( - SymbolNode(16...18)(nil, (16...17), (17...18), "a"), - CallNode(19...41)( - nil, - nil, - (19...25), - nil, - nil, - nil, - BlockNode(26...41)( - [], - nil, - StatementsNode(28...39)( - [IfNode(28...39)( - nil, - CallNode(28...29)( - nil, - nil, - (28...29), - nil, - nil, - nil, - nil, - 2, - "b" - ), - StatementsNode(32...35)( - [CallNode(32...35)( - nil, - nil, - (32...33), - (33...34), - nil, - (34...35), - nil, - 0, - "c" - )] - ), - ElseNode(36...39)( - (36...37), - StatementsNode(38...39)( - [CallNode(38...39)( - nil, - nil, - (38...39), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil - ), - nil - )] - ), - (26...27), - (40...41) - ), - 0, - "lambda" - ), - nil - ), - AssocNode(51...57)( - SymbolNode(51...53)(nil, (51...52), (52...53), "e"), - NilNode(54...57)(), - nil - )], - (65...66) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/do_bug.txt b/test/yarp/snapshots/seattlerb/do_bug.txt deleted file mode 100644 index 269d349519a6ce..00000000000000 --- a/test/yarp/snapshots/seattlerb/do_bug.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [CallNode(0...3)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...3)([IntegerNode(2...3)()]), - nil, - nil, - 0, - "a" - ), - CallNode(4...33)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"), - (5...6), - (6...7), - nil, - nil, - nil, - BlockNode(8...33)( - [:c], - BlockParametersNode(11...14)( - ParametersNode(12...13)( - [RequiredParameterNode(12...13)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (11...12), - (13...14) - ), - nil, - (8...10), - (30...33) - ), - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/do_lambda.txt b/test/yarp/snapshots/seattlerb/do_lambda.txt deleted file mode 100644 index a7eb211623e8fe..00000000000000 --- a/test/yarp/snapshots/seattlerb/do_lambda.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [LambdaNode(0...11)( - [], - (0...2), - (5...7), - (8...11), - BlockParametersNode(2...4)(nil, [], (2...3), (3...4)), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dot2_nil__26.txt b/test/yarp/snapshots/seattlerb/dot2_nil__26.txt deleted file mode 100644 index 38e8dfd9c0f009..00000000000000 --- a/test/yarp/snapshots/seattlerb/dot2_nil__26.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)( - [RangeNode(0...3)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...3), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dot3_nil__26.txt b/test/yarp/snapshots/seattlerb/dot3_nil__26.txt deleted file mode 100644 index 91cf903a9a2d54..00000000000000 --- a/test/yarp/snapshots/seattlerb/dot3_nil__26.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [RangeNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...4), - 1 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dstr_evstr.txt b/test/yarp/snapshots/seattlerb/dstr_evstr.txt deleted file mode 100644 index 75377e9c7faaf9..00000000000000 --- a/test/yarp/snapshots/seattlerb/dstr_evstr.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [InterpolatedStringNode(0...12)( - (0...1), - [EmbeddedStatementsNode(1...7)( - (1...3), - StatementsNode(3...6)( - [StringNode(3...6)((3...4), (4...5), (5...6), "a")] - ), - (6...7) - ), - EmbeddedStatementsNode(7...11)( - (7...9), - StatementsNode(9...10)( - [CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "b")] - ), - (10...11) - )], - (11...12) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dstr_evstr_empty_end.txt b/test/yarp/snapshots/seattlerb/dstr_evstr_empty_end.txt deleted file mode 100644 index e4a9c81b8854c1..00000000000000 --- a/test/yarp/snapshots/seattlerb/dstr_evstr_empty_end.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [InterpolatedSymbolNode(0...11)( - (0...2), - [EmbeddedStatementsNode(2...10)( - (2...4), - StatementsNode(4...9)( - [CallNode(4...9)( - nil, - nil, - (4...9), - nil, - nil, - nil, - nil, - 2, - "field" - )] - ), - (9...10) - )], - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dstr_lex_state.txt b/test/yarp/snapshots/seattlerb/dstr_lex_state.txt deleted file mode 100644 index 50e327ab9c00a9..00000000000000 --- a/test/yarp/snapshots/seattlerb/dstr_lex_state.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...1), - [EmbeddedStatementsNode(1...7)( - (1...3), - StatementsNode(3...6)( - [CallNode(3...6)( - nil, - nil, - (3...4), - nil, - ArgumentsNode(4...6)( - [SymbolNode(4...6)((4...5), (5...6), nil, "a")] - ), - nil, - nil, - 0, - "p" - )] - ), - (6...7) - )], - (7...8) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dstr_str.txt b/test/yarp/snapshots/seattlerb/dstr_str.txt deleted file mode 100644 index e17b035d2f02f9..00000000000000 --- a/test/yarp/snapshots/seattlerb/dstr_str.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [InterpolatedStringNode(0...10)( - (0...1), - [EmbeddedStatementsNode(1...7)( - (1...3), - StatementsNode(3...6)( - [StringNode(3...6)((3...4), (4...5), (5...6), "a")] - ), - (6...7) - ), - StringNode(7...9)(nil, (7...9), nil, " b")], - (9...10) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dsym_esc_to_sym.txt b/test/yarp/snapshots/seattlerb/dsym_esc_to_sym.txt deleted file mode 100644 index 4f6697237b1a70..00000000000000 --- a/test/yarp/snapshots/seattlerb/dsym_esc_to_sym.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [SymbolNode(0...17)((0...2), (2...16), (16...17), "Varietà")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/dsym_to_sym.txt b/test/yarp/snapshots/seattlerb/dsym_to_sym.txt deleted file mode 100644 index d383b67184c1dc..00000000000000 --- a/test/yarp/snapshots/seattlerb/dsym_to_sym.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [AliasNode(0...17)( - SymbolNode(6...11)((6...8), (8...10), (10...11), "<<"), - SymbolNode(12...17)((12...14), (14...16), (16...17), ">>"), - (0...5) - ), - AliasNode(19...32)( - SymbolNode(25...28)((25...26), (26...28), nil, "<<"), - SymbolNode(29...32)((29...30), (30...32), nil, ">>"), - (19...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/eq_begin_line_numbers.txt b/test/yarp/snapshots/seattlerb/eq_begin_line_numbers.txt deleted file mode 100644 index 46a167a8def379..00000000000000 --- a/test/yarp/snapshots/seattlerb/eq_begin_line_numbers.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)([IntegerNode(0...1)(), IntegerNode(30...31)()]) -) diff --git a/test/yarp/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt b/test/yarp/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt deleted file mode 100644 index e277d15a349438..00000000000000 --- a/test/yarp/snapshots/seattlerb/eq_begin_why_wont_people_use_their_spacebar.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [CallNode(0...29)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "h"), - nil, - (1...4), - (1...2), - ArgumentsNode(2...29)( - [CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "k"), - BeginNode(5...29)( - (5...10), - StatementsNode(18...20)([IntegerNode(18...20)()]), - nil, - nil, - nil, - (26...29) - )] - ), - (3...4), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/evstr_evstr.txt b/test/yarp/snapshots/seattlerb/evstr_evstr.txt deleted file mode 100644 index f194b1b94a968e..00000000000000 --- a/test/yarp/snapshots/seattlerb/evstr_evstr.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [InterpolatedStringNode(0...10)( - (0...1), - [EmbeddedStatementsNode(1...5)( - (1...3), - StatementsNode(3...4)( - [CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a")] - ), - (4...5) - ), - EmbeddedStatementsNode(5...9)( - (5...7), - StatementsNode(7...8)( - [CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b")] - ), - (8...9) - )], - (9...10) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/evstr_str.txt b/test/yarp/snapshots/seattlerb/evstr_str.txt deleted file mode 100644 index 2ebd4e46398021..00000000000000 --- a/test/yarp/snapshots/seattlerb/evstr_str.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...1), - [EmbeddedStatementsNode(1...5)( - (1...3), - StatementsNode(3...4)( - [CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a")] - ), - (4...5) - ), - StringNode(5...7)(nil, (5...7), nil, " b")], - (7...8) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/expr_not_bang.txt b/test/yarp/snapshots/seattlerb/expr_not_bang.txt deleted file mode 100644 index 43e47cb03b4987..00000000000000 --- a/test/yarp/snapshots/seattlerb/expr_not_bang.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - CallNode(2...5)( - nil, - nil, - (2...3), - nil, - ArgumentsNode(4...5)( - [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b")] - ), - nil, - nil, - 0, - "a" - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/f_kw.txt b/test/yarp/snapshots/seattlerb/f_kw.txt deleted file mode 100644 index 053e093303e625..00000000000000 --- a/test/yarp/snapshots/seattlerb/f_kw.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [DefNode(0...15)( - :x, - (4...5), - nil, - ParametersNode(6...10)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:k, (6...8), IntegerNode(8...10)())], - nil, - nil - ), - nil, - [:k], - (0...3), - nil, - nil, - nil, - nil, - (12...15) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/f_kw__required.txt b/test/yarp/snapshots/seattlerb/f_kw__required.txt deleted file mode 100644 index 8f29a7a9c9877a..00000000000000 --- a/test/yarp/snapshots/seattlerb/f_kw__required.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [DefNode(0...13)( - :x, - (4...5), - nil, - ParametersNode(6...8)( - [], - [], - [], - nil, - [KeywordParameterNode(6...8)(:k, (6...8), nil)], - nil, - nil - ), - nil, - [:k], - (0...3), - nil, - nil, - nil, - nil, - (10...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt b/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt deleted file mode 100644 index bca1426fc13fe5..00000000000000 --- a/test/yarp/snapshots/seattlerb/flip2_env_lvar.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [IfNode(0...16)( - (0...2), - FlipFlopNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a"), - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"), - (4...6), - 0 - ), - nil, - nil, - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/float_with_if_modifier.txt b/test/yarp/snapshots/seattlerb/float_with_if_modifier.txt deleted file mode 100644 index c27a5bfe3b2cfc..00000000000000 --- a/test/yarp/snapshots/seattlerb/float_with_if_modifier.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [IfNode(0...10)( - (3...5), - TrueNode(6...10)(), - StatementsNode(0...3)([FloatNode(0...3)()]), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt b/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt deleted file mode 100644 index befdff81ee76ce..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc__backslash_dos_format.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...12)( - [:str], - StatementsNode(0...12)( - [LocalVariableWriteNode(0...12)( - :str, - 0, - (0...3), - InterpolatedStringNode(6...12)( - (6...12), - [StringNode(14...30)(nil, (14...30), nil, "beforeafter\r\n")], - (30...35) - ), - (4...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_backslash_nl.txt b/test/yarp/snapshots/seattlerb/heredoc_backslash_nl.txt deleted file mode 100644 index 532b1fe9e7e84d..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_backslash_nl.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...49)( - [], - StatementsNode(0...49)( - [StringNode(0...40)( - (0...1), - (1...39), - (39...40), - " why would someone do this? blah\n" - ), - InterpolatedStringNode(42...49)( - (42...49), - [StringNode(50...88)( - nil, - (50...88), - nil, - " why would someone do this? blah\n" - )], - (88...93) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt b/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt deleted file mode 100644 index 842da16d1d52f6..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_bad_hex_escape.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...9)( - [:s], - StatementsNode(0...9)( - [LocalVariableWriteNode(0...9)( - :s, - 0, - (0...1), - InterpolatedStringNode(4...9)( - (4...9), - [StringNode(10...17)(nil, (10...17), nil, "a\xE9b\n")], - (17...21) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt b/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt deleted file mode 100644 index 14c02bdfb33c37..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_bad_oct_escape.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...10)( - [:s], - StatementsNode(0...10)( - [LocalVariableWriteNode(0...10)( - :s, - 0, - (0...1), - InterpolatedStringNode(4...10)( - (4...10), - [StringNode(11...23)(nil, (11...23), nil, "a\xA7b\n" + "cöd\n")], - (23...27) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_comma_arg.txt b/test/yarp/snapshots/seattlerb/heredoc_comma_arg.txt deleted file mode 100644 index bbded2484ec43f..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_comma_arg.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...47)( - [], - StatementsNode(0...47)( - [ArrayNode(0...17)( - [StringNode(1...15)((1...2), (2...14), (14...15), " some text\n")], - (0...1), - (16...17) - ), - ArrayNode(19...47)( - [InterpolatedStringNode(20...27)( - (20...27), - [StringNode(29...41)(nil, (29...41), nil, " some text\n")], - (41...46) - )], - (19...20), - (46...47) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_lineno.txt b/test/yarp/snapshots/seattlerb/heredoc_lineno.txt deleted file mode 100644 index 9bbc817c20f30d..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_lineno.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...41)( - [:c, :d], - StatementsNode(0...41)( - [LocalVariableWriteNode(0...11)( - :c, - 0, - (0...1), - InterpolatedStringNode(4...11)( - (4...11), - [StringNode(12...30)( - nil, - (12...30), - nil, - "line2\n" + "line3\n" + "line4\n" - )], - (30...34) - ), - (2...3) - ), - LocalVariableWriteNode(35...41)( - :d, - 0, - (35...36), - IntegerNode(39...41)(), - (37...38) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_nested.txt b/test/yarp/snapshots/seattlerb/heredoc_nested.txt deleted file mode 100644 index 3c3d30d958aa6d..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_nested.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [ArrayNode(0...23)( - [InterpolatedStringNode(1...4)( - (1...4), - [EmbeddedStatementsNode(6...12)( - (6...8), - StatementsNode(8...11)( - [InterpolatedStringNode(8...11)( - (8...11), - [StringNode(13...15)(nil, (13...15), nil, "b\n")], - (15...17) - )] - ), - (11...12) - ), - StringNode(12...13)(nil, (12...13), nil, "\n"), - StringNode(17...19)(nil, (17...19), nil, "a\n")], - (19...21) - ), - IntegerNode(21...22)()], - (0...1), - (22...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt deleted file mode 100644 index 6491c86c04c5aa..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...12)( - [:a], - StatementsNode(0...12)( - [LocalVariableWriteNode(0...12)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...12)( - (4...12), - [StringNode(13...25)(nil, (13...25), nil, "x\n" + "y\n" + "z\n")], - (25...31) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt deleted file mode 100644 index f2c3c1b1a902b9..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_line_plus_interpolation.txt +++ /dev/null @@ -1,56 +0,0 @@ -ProgramNode(0...20)( - [:a], - StatementsNode(0...20)( - [LocalVariableWriteNode(0...20)( - :a, - 0, - (0...1), - CallNode(4...20)( - nil, - nil, - (4...7), - (7...8), - ArgumentsNode(8...19)( - [CallNode(8...19)( - InterpolatedStringNode(8...14)( - (8...14), - [StringNode(21...26)(nil, (21...26), nil, "\n"), - EmbeddedStatementsNode(26...32)( - (26...28), - StatementsNode(28...31)( - [CallNode(28...31)( - nil, - nil, - (28...31), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (31...32) - ), - StringNode(32...36)(nil, (32...36), nil, "baz\n")], - (36...42) - ), - (14...15), - (15...19), - nil, - nil, - nil, - nil, - 0, - "chop" - )] - ), - (19...20), - nil, - 0, - "foo" - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt deleted file mode 100644 index 4b59c352461881..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_blank_lines.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [LocalVariableWriteNode(0...10)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...10)( - (4...10), - [StringNode(11...20)(nil, (11...20), nil, "x\n" + "\n" + "z\n")], - (20...24) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_empty.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_empty.txt deleted file mode 100644 index 7303a5ee71cb35..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([InterpolatedStringNode(0...4)((0...4), [], (5...7))]) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt deleted file mode 100644 index e03304a7d147b0..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_interp.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [LocalVariableWriteNode(0...10)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...10)( - (4...10), - [StringNode(11...22)(nil, (11...22), nil, " w\n" + "x"), - EmbeddedStatementsNode(22...27)( - (22...24), - StatementsNode(24...26)([IntegerNode(24...26)()]), - (26...27) - ), - StringNode(27...36)(nil, (27...36), nil, " y\n" + " z\n")], - (36...42) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_no_indent.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_no_indent.txt deleted file mode 100644 index 47a116dab26f12..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_no_indent.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [InterpolatedStringNode(0...4)( - (0...4), - [StringNode(5...7)(nil, (5...7), nil, "a\n")], - (7...9) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt deleted file mode 100644 index 1592d1310476e9..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...12)( - [:a], - StatementsNode(0...12)( - [LocalVariableWriteNode(0...12)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...12)( - (4...12), - [StringNode(13...43)( - nil, - (13...43), - nil, - "blah blah\n" + " blah blah\n" - )], - (43...49) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt deleted file mode 100644 index 63ff5887c9e25e..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_tabs_extra.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...12)( - [:a], - StatementsNode(0...12)( - [LocalVariableWriteNode(0...12)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...12)( - (4...12), - [StringNode(13...37)( - nil, - (13...37), - nil, - "blah blah\n" + "\tblah blah\n" - )], - (37...43) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt b/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt deleted file mode 100644 index 866c5fac084cd5..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_squiggly_visually_blank_lines.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [LocalVariableWriteNode(0...10)( - :a, - 0, - (0...1), - InterpolatedStringNode(4...10)( - (4...10), - [StringNode(11...21)(nil, (11...21), nil, "x\n" + "\n" + "z\n")], - (21...25) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt b/test/yarp/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt deleted file mode 100644 index b672fceefca2dd..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_trailing_slash_continued_call.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - InterpolatedStringNode(0...5)( - (0...5), - [StringNode(7...12)(nil, (7...12), nil, "blah\n")], - (12...16) - ), - (16...17), - (17...22), - nil, - nil, - nil, - nil, - 0, - "strip" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_unicode.txt b/test/yarp/snapshots/seattlerb/heredoc_unicode.txt deleted file mode 100644 index 42e475b08a0528..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_unicode.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [InterpolatedStringNode(0...9)( - (0...9), - [StringNode(10...12)(nil, (10...12), nil, ".\n")], - (12...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt b/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt deleted file mode 100644 index f3a7cdd423acf8..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(6...21)(nil, (6...21), nil, "foo\rbar\n" + "baz\r\n")], - (21...25) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt b/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt deleted file mode 100644 index e206ee78a9c8dd..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_carriage_return_escapes_windows.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(7...24)(nil, (7...24), nil, "foo\rbar\r\n" + "baz\r\r\n")], - (24...29) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt b/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt deleted file mode 100644 index 2c5d16dcabc667..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_horrible_mix.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [InterpolatedStringNode(0...7)( - (0...7), - [StringNode(9...15)(nil, (9...15), nil, "body\r\n")], - (15...19) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt b/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt deleted file mode 100644 index 35583e32899ba5..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(6...19)(nil, (6...19), nil, "foo\rbar\r\n" + "baz\n")], - (19...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt b/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt deleted file mode 100644 index c36008cfcebcc8..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_extra_carriage_returns_windows.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(7...22)(nil, (7...22), nil, "foo\rbar\r\r\n" + "baz\r\n")], - (22...27) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt b/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt deleted file mode 100644 index 452e5b605b8ef5..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(6...11)(nil, (6...11), nil, "foo\r"), - EmbeddedVariableNode(11...16)( - (11...12), - InstanceVariableReadNode(12...16)(:@bar) - ), - StringNode(16...17)(nil, (16...17), nil, "\n")], - (17...21) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt b/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt deleted file mode 100644 index 99b42f6122a97e..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_interpolation_and_carriage_return_escapes_windows.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(7...12)(nil, (7...12), nil, "foo\r"), - EmbeddedVariableNode(12...17)( - (12...13), - InstanceVariableReadNode(13...17)(:@bar) - ), - StringNode(17...19)(nil, (17...19), nil, "\r\n")], - (19...24) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt b/test/yarp/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt deleted file mode 100644 index be3f48e171bbdb..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_not_global_interpolation.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [InterpolatedStringNode(0...10)( - (0...10), - [StringNode(11...15)(nil, (11...15), nil, "\#${\n")], - (15...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt b/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt deleted file mode 100644 index f4a65965f68fc1..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(6...14)(nil, (6...14), nil, "\r\n" + "\r\r\n" + "\r\n")], - (14...18) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt b/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt deleted file mode 100644 index e3fbb71b7f4b2a..00000000000000 --- a/test/yarp/snapshots/seattlerb/heredoc_with_only_carriage_returns_windows.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [InterpolatedStringNode(0...5)( - (0...5), - [StringNode(7...18)( - nil, - (7...18), - nil, - "\r\r\n" + "\r\r\r\n" + "\r\r\n" - )], - (18...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/if_elsif.txt b/test/yarp/snapshots/seattlerb/if_elsif.txt deleted file mode 100644 index 51c89a9a32b540..00000000000000 --- a/test/yarp/snapshots/seattlerb/if_elsif.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [IfNode(0...18)( - (0...2), - IntegerNode(3...4)(), - nil, - IfNode(6...18)((6...11), IntegerNode(12...13)(), nil, nil, (15...18)), - (15...18) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/if_symbol.txt b/test/yarp/snapshots/seattlerb/if_symbol.txt deleted file mode 100644 index 4e4fdcefcef611..00000000000000 --- a/test/yarp/snapshots/seattlerb/if_symbol.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [IfNode(0...12)( - (0...2), - CallNode(3...7)( - nil, - nil, - (3...4), - nil, - ArgumentsNode(5...7)([SymbolNode(5...7)((5...6), (6...7), nil, "x")]), - nil, - nil, - 0, - "f" - ), - nil, - nil, - (9...12) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/in_expr_no_case.txt b/test/yarp/snapshots/seattlerb/in_expr_no_case.txt deleted file mode 100644 index a4249f6414c37a..00000000000000 --- a/test/yarp/snapshots/seattlerb/in_expr_no_case.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [MatchPredicateNode(0...16)( - StringNode(0...6)((0...1), (1...5), (5...6), "woot"), - ConstantReadNode(10...16)(:String), - (7...9) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/index_0.txt b/test/yarp/snapshots/seattlerb/index_0.txt deleted file mode 100644 index 42a7239752988d..00000000000000 --- a/test/yarp/snapshots/seattlerb/index_0.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...3), - (1...2), - ArgumentsNode(6...7)( - [CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b")] - ), - (2...3), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/index_0_opasgn.txt b/test/yarp/snapshots/seattlerb/index_0_opasgn.txt deleted file mode 100644 index 60c76d0d005ecb..00000000000000 --- a/test/yarp/snapshots/seattlerb/index_0_opasgn.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallOperatorWriteNode(0...8)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...3), - (1...2), - nil, - (2...3), - 0, - "[]", - "[]=", - :+, - (4...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/integer_with_if_modifier.txt b/test/yarp/snapshots/seattlerb/integer_with_if_modifier.txt deleted file mode 100644 index f57ed6c4229648..00000000000000 --- a/test/yarp/snapshots/seattlerb/integer_with_if_modifier.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [IfNode(0...12)( - (5...7), - TrueNode(8...12)(), - StatementsNode(0...5)([IntegerNode(0...5)()]), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt b/test/yarp/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt deleted file mode 100644 index 0a779610a699c8..00000000000000 --- a/test/yarp/snapshots/seattlerb/interpolated_symbol_array_line_breaks.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...9)( - [SymbolNode(4...5)(nil, (4...5), nil, "a"), - SymbolNode(6...7)(nil, (6...7), nil, "b")], - (0...3), - (8...9) - ), - IntegerNode(10...11)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/interpolated_word_array_line_breaks.txt b/test/yarp/snapshots/seattlerb/interpolated_word_array_line_breaks.txt deleted file mode 100644 index 901575f9a8dde8..00000000000000 --- a/test/yarp/snapshots/seattlerb/interpolated_word_array_line_breaks.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...9)( - [StringNode(4...5)(nil, (4...5), nil, "a"), - StringNode(6...7)(nil, (6...7), nil, "b")], - (0...3), - (8...9) - ), - IntegerNode(10...11)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_1.txt b/test/yarp/snapshots/seattlerb/iter_args_1.txt deleted file mode 100644 index 9fdbf688181966..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_1.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...11)( - [:a, :b], - BlockParametersNode(4...9)( - ParametersNode(5...8)( - [RequiredParameterNode(5...6)(:a), - RequiredParameterNode(7...8)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (8...9) - ), - nil, - (2...3), - (10...11) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_10_1.txt b/test/yarp/snapshots/seattlerb/iter_args_10_1.txt deleted file mode 100644 index 3086873b0d2b40..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_10_1.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...21)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...21)( - [:a, :b, :c], - BlockParametersNode(4...19)( - ParametersNode(5...18)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - )], - [], - RestParameterNode(16...18)(:c, (17...18), (16...17)), - [], - nil, - nil - ), - [], - (4...5), - (18...19) - ), - nil, - (2...3), - (20...21) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_10_2.txt b/test/yarp/snapshots/seattlerb/iter_args_10_2.txt deleted file mode 100644 index 1b6efea49f6478..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_10_2.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...25)( - [:a, :b, :c, :d], - BlockParametersNode(4...23)( - ParametersNode(5...22)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - )], - [], - RestParameterNode(16...18)(:c, (17...18), (16...17)), - [], - nil, - BlockParameterNode(20...22)(:d, (21...22), (20...21)) - ), - [], - (4...5), - (22...23) - ), - nil, - (2...3), - (24...25) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_11_1.txt b/test/yarp/snapshots/seattlerb/iter_args_11_1.txt deleted file mode 100644 index 4b2e76f11675d9..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_11_1.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [CallNode(0...24)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...24)( - [:a, :b, :c, :d], - BlockParametersNode(4...22)( - ParametersNode(5...21)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - )], - [RequiredParameterNode(20...21)(:d)], - RestParameterNode(16...18)(:c, (17...18), (16...17)), - [], - nil, - nil - ), - [], - (4...5), - (21...22) - ), - nil, - (2...3), - (23...24) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_11_2.txt b/test/yarp/snapshots/seattlerb/iter_args_11_2.txt deleted file mode 100644 index e9fa853130be83..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_11_2.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...28)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...28)( - [:a, :b, :c, :d, :e], - BlockParametersNode(4...26)( - ParametersNode(5...25)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...14)( - :b, - (8...9), - (10...11), - IntegerNode(12...14)() - )], - [RequiredParameterNode(20...21)(:d)], - RestParameterNode(16...18)(:c, (17...18), (16...17)), - [], - nil, - BlockParameterNode(23...25)(:e, (24...25), (23...24)) - ), - [], - (4...5), - (25...26) - ), - nil, - (2...3), - (27...28) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_2__19.txt b/test/yarp/snapshots/seattlerb/iter_args_2__19.txt deleted file mode 100644 index e9e94d3d6e172b..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_2__19.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...14)( - [:a, :b], - BlockParametersNode(4...12)( - ParametersNode(5...11)( - [RequiredDestructuredParameterNode(5...11)( - [RequiredParameterNode(6...7)(:a), - RequiredParameterNode(9...10)(:b)], - (5...6), - (10...11) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (11...12) - ), - nil, - (2...3), - (13...14) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_3.txt b/test/yarp/snapshots/seattlerb/iter_args_3.txt deleted file mode 100644 index 8d191cc2e5bd36..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_3.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...20)( - [:a, :b, :c, :d], - BlockParametersNode(4...18)( - ParametersNode(5...17)( - [RequiredParameterNode(5...6)(:a), - RequiredDestructuredParameterNode(8...14)( - [RequiredParameterNode(9...10)(:b), - RequiredParameterNode(12...13)(:c)], - (8...9), - (13...14) - ), - RequiredParameterNode(16...17)(:d)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (17...18) - ), - nil, - (2...3), - (19...20) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_4.txt b/test/yarp/snapshots/seattlerb/iter_args_4.txt deleted file mode 100644 index 18671a18327b21..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_4.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...16)( - [:a, :b, :c], - BlockParametersNode(4...14)( - ParametersNode(5...13)( - [RequiredParameterNode(5...6)(:a)], - [], - [RequiredParameterNode(12...13)(:c)], - RestParameterNode(8...10)(:b, (9...10), (8...9)), - [], - nil, - nil - ), - [], - (4...5), - (13...14) - ), - nil, - (2...3), - (15...16) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_5.txt b/test/yarp/snapshots/seattlerb/iter_args_5.txt deleted file mode 100644 index 224bdc0bf9b14d..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_5.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...13)( - [:a, :b], - BlockParametersNode(4...11)( - ParametersNode(5...10)( - [RequiredParameterNode(5...6)(:a)], - [], - [], - nil, - [], - nil, - BlockParameterNode(8...10)(:b, (9...10), (8...9)) - ), - [], - (4...5), - (10...11) - ), - nil, - (2...3), - (12...13) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_6.txt b/test/yarp/snapshots/seattlerb/iter_args_6.txt deleted file mode 100644 index 8a69456b62e231..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_6.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:a, :b, :c], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [RequiredParameterNode(5...6)(:a)], - [OptionalParameterNode(8...12)( - :b, - (8...9), - (9...10), - IntegerNode(10...12)() - )], - [RequiredParameterNode(14...15)(:c)], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_7_1.txt b/test/yarp/snapshots/seattlerb/iter_args_7_1.txt deleted file mode 100644 index 8bfb90fc33a3ce..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_7_1.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:a, :b], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [], - RestParameterNode(13...15)(:b, (14...15), (13...14)), - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_7_2.txt b/test/yarp/snapshots/seattlerb/iter_args_7_2.txt deleted file mode 100644 index 21d217da226218..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_7_2.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...22)( - [:a, :b, :c], - BlockParametersNode(4...20)( - ParametersNode(5...19)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [], - RestParameterNode(13...15)(:b, (14...15), (13...14)), - [], - nil, - BlockParameterNode(17...19)(:c, (18...19), (17...18)) - ), - [], - (4...5), - (19...20) - ), - nil, - (2...3), - (21...22) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_8_1.txt b/test/yarp/snapshots/seattlerb/iter_args_8_1.txt deleted file mode 100644 index 6b94b67e0e4ac4..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_8_1.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...21)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...21)( - [:a, :b, :c], - BlockParametersNode(4...19)( - ParametersNode(5...18)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [RequiredParameterNode(17...18)(:c)], - RestParameterNode(13...15)(:b, (14...15), (13...14)), - [], - nil, - nil - ), - [], - (4...5), - (18...19) - ), - nil, - (2...3), - (20...21) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_8_2.txt b/test/yarp/snapshots/seattlerb/iter_args_8_2.txt deleted file mode 100644 index f16d2fca9a5af9..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_8_2.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...25)( - [:a, :b, :c, :d], - BlockParametersNode(4...23)( - ParametersNode(5...22)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [RequiredParameterNode(17...18)(:c)], - RestParameterNode(13...15)(:b, (14...15), (13...14)), - [], - nil, - BlockParameterNode(20...22)(:d, (21...22), (20...21)) - ), - [], - (4...5), - (22...23) - ), - nil, - (2...3), - (24...25) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_9_1.txt b/test/yarp/snapshots/seattlerb/iter_args_9_1.txt deleted file mode 100644 index 68d1fe93388cf3..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_9_1.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:a, :b], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [RequiredParameterNode(13...14)(:b)], - nil, - [], - nil, - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_args_9_2.txt b/test/yarp/snapshots/seattlerb/iter_args_9_2.txt deleted file mode 100644 index 904d13e7e160a7..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_args_9_2.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...21)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...21)( - [:a, :b, :c], - BlockParametersNode(4...19)( - ParametersNode(5...18)( - [], - [OptionalParameterNode(5...11)( - :a, - (5...6), - (7...8), - IntegerNode(9...11)() - )], - [RequiredParameterNode(13...14)(:b)], - nil, - [], - nil, - BlockParameterNode(16...18)(:c, (17...18), (16...17)) - ), - [], - (4...5), - (18...19) - ), - nil, - (2...3), - (20...21) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_kwarg.txt b/test/yarp/snapshots/seattlerb/iter_kwarg.txt deleted file mode 100644 index 4dfc24209a4140..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_kwarg.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...12)( - [:b], - BlockParametersNode(4...10)( - ParametersNode(5...9)( - [], - [], - [], - nil, - [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], - nil, - nil - ), - [], - (4...5), - (9...10) - ), - nil, - (2...3), - (11...12) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt deleted file mode 100644 index 5ade32c4838c74..00000000000000 --- a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...17)( - [:b, :c], - BlockParametersNode(4...15)( - ParametersNode(5...14)( - [], - [], - [], - nil, - [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], - KeywordRestParameterNode(11...14)(:c, (13...14), (11...13)), - nil - ), - [], - (4...5), - (14...15) - ), - nil, - (2...3), - (16...17) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/label_vs_string.txt b/test/yarp/snapshots/seattlerb/label_vs_string.txt deleted file mode 100644 index f647e6da0e4859..00000000000000 --- a/test/yarp/snapshots/seattlerb/label_vs_string.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - CallNode(0...4)(nil, nil, (0...4), nil, nil, nil, nil, 2, "_buf"), - nil, - (5...7), - nil, - ArgumentsNode(8...12)( - [StringNode(8...12)((8...9), (9...11), (11...12), ":\n")] - ), - nil, - nil, - 0, - "<<" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lambda_do_vs_brace.txt b/test/yarp/snapshots/seattlerb/lambda_do_vs_brace.txt deleted file mode 100644 index c7f83a9b512023..00000000000000 --- a/test/yarp/snapshots/seattlerb/lambda_do_vs_brace.txt +++ /dev/null @@ -1,71 +0,0 @@ -ProgramNode(0...46)( - [], - StatementsNode(0...46)( - [CallNode(0...11)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...11)( - [LambdaNode(2...11)([], (2...4), (5...7), (8...11), nil, nil)] - ), - nil, - nil, - 0, - "f" - ), - CallNode(13...20)( - nil, - nil, - (13...14), - nil, - ArgumentsNode(15...20)( - [LambdaNode(15...20)([], (15...17), (18...19), (19...20), nil, nil)] - ), - nil, - nil, - 0, - "f" - ), - CallNode(22...35)( - nil, - nil, - (22...23), - nil, - ArgumentsNode(24...35)( - [LambdaNode(24...35)( - [], - (24...26), - (29...31), - (32...35), - BlockParametersNode(26...28)(nil, [], (26...27), (27...28)), - nil - )] - ), - nil, - nil, - 0, - "f" - ), - CallNode(37...46)( - nil, - nil, - (37...38), - nil, - ArgumentsNode(39...46)( - [LambdaNode(39...46)( - [], - (39...41), - (44...45), - (45...46), - BlockParametersNode(41...43)(nil, [], (41...42), (42...43)), - nil - )] - ), - nil, - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt deleted file mode 100644 index ad36a5edb4eab8..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_arg_rescue_arg.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...14)( - [:a], - StatementsNode(0...14)( - [LocalVariableWriteNode(0...14)( - :a, - 0, - (0...1), - RescueModifierNode(4...14)( - IntegerNode(4...5)(), - (6...12), - IntegerNode(13...14)() - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt deleted file mode 100644 index 86469f1c9129e5..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_call_bracket_rescue_arg.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...17)( - [:a], - StatementsNode(0...17)( - [LocalVariableWriteNode(0...17)( - :a, - 0, - (0...1), - RescueModifierNode(4...17)( - CallNode(4...8)( - nil, - nil, - (4...5), - (5...6), - ArgumentsNode(6...7)([IntegerNode(6...7)()]), - (7...8), - nil, - 0, - "b" - ), - (9...15), - IntegerNode(16...17)() - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt b/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt deleted file mode 100644 index 72e54e010160ce..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_call_nobracket_rescue_arg.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...16)( - [:a], - StatementsNode(0...16)( - [LocalVariableWriteNode(0...16)( - :a, - 0, - (0...1), - CallNode(4...16)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...16)( - [RescueModifierNode(6...16)( - IntegerNode(6...7)(), - (8...14), - IntegerNode(15...16)() - )] - ), - nil, - nil, - 0, - "b" - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_command.txt b/test/yarp/snapshots/seattlerb/lasgn_command.txt deleted file mode 100644 index b1912a7c6d22cf..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_command.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...9)( - [:a], - StatementsNode(0...9)( - [LocalVariableWriteNode(0...9)( - :a, - 0, - (0...1), - CallNode(4...9)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"), - (5...6), - (6...7), - nil, - ArgumentsNode(8...9)([IntegerNode(8...9)()]), - nil, - nil, - 0, - "c" - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_env.txt b/test/yarp/snapshots/seattlerb/lasgn_env.txt deleted file mode 100644 index cfd276b1b28557..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_env.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...6)( - [:a], - StatementsNode(0...6)( - [LocalVariableWriteNode(0...6)( - :a, - 0, - (0...1), - IntegerNode(4...6)(), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_ivar_env.txt b/test/yarp/snapshots/seattlerb/lasgn_ivar_env.txt deleted file mode 100644 index cf47f6dc7e5ded..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_ivar_env.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [InstanceVariableWriteNode(0...7)( - :@a, - (0...2), - IntegerNode(5...7)(), - (3...4) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt b/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt deleted file mode 100644 index 49f22eeb4311b1..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_lasgn_command_call.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...11)( - [:a, :b], - StatementsNode(0...11)( - [LocalVariableWriteNode(0...11)( - :a, - 0, - (0...1), - LocalVariableWriteNode(4...11)( - :b, - 0, - (4...5), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "c" - ), - (6...7) - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt b/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt deleted file mode 100644 index acb6c844673f99..00000000000000 --- a/test/yarp/snapshots/seattlerb/lasgn_middle_splat.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...12)( - [:a], - StatementsNode(0...12)( - [LocalVariableWriteNode(0...12)( - :a, - 0, - (0...1), - ArrayNode(4...12)( - [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"), - SplatNode(7...9)( - (7...8), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") - ), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d")], - nil, - nil - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt deleted file mode 100644 index 010fe793941105..00000000000000 --- a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(18...90)( - [], - StatementsNode(18...90)( - [ClassNode(18...90)( - [], - (18...23), - ConstantReadNode(24...52)(:ExampleUTF8ClassNameVarietà), - nil, - nil, - StatementsNode(54...86)( - [DefNode(54...86)( - :è, - (63...65), - SelfNode(58...62)(), - nil, - StatementsNode(67...81)( - [LocalVariableWriteNode(67...81)( - :così, - 0, - (67...72), - SymbolNode(75...81)((75...76), (76...81), nil, "però"), - (73...74) - )] - ), - [:così], - (54...57), - (62...63), - nil, - nil, - nil, - (83...86) - )] - ), - (87...90), - :ExampleUTF8ClassNameVarietà - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt deleted file mode 100644 index 2fb68f7b6db4ea..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...8)( - [:a], - StatementsNode(0...8)( - [MultiWriteNode(0...8)( - [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), - LocalVariableTargetNode(3...4)(:a, 0)], - nil, - nil, - (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt deleted file mode 100644 index fd2eeb213aa871..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...11)( - [:a], - StatementsNode(0...11)( - [MultiWriteNode(0...11)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...6), - (6...7), - nil, - nil, - nil, - nil, - 0, - "c=" - )], - nil, - nil, - (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt deleted file mode 100644 index a8b17ce70710c1..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [MultiWriteNode(0...10)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...6)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "C=" - )], - nil, - nil, - (7...8), - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt deleted file mode 100644 index e922b3b5e8737e..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...12)( - [:a, :b, :c], - StatementsNode(0...12)( - [MultiWriteNode(0...12)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), - LocalVariableTargetNode(7...8)(:c, 0)], - nil, - nil, - (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_colon2.txt b/test/yarp/snapshots/seattlerb/masgn_colon2.txt deleted file mode 100644 index d9a2744466fb45..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_colon2.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...14)( - [:a], - StatementsNode(0...14)( - [MultiWriteNode(0...14)( - [LocalVariableTargetNode(0...1)(:a, 0), - ConstantPathTargetNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - ConstantReadNode(6...7)(:C), - (4...6) - )], - nil, - nil, - (8...9), - ArrayNode(10...14)( - [IntegerNode(10...11)(), IntegerNode(13...14)()], - nil, - nil - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_colon3.txt b/test/yarp/snapshots/seattlerb/masgn_colon3.txt deleted file mode 100644 index 355f40f1cfb8fd..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_colon3.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [MultiWriteNode(0...15)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - ConstantPathTargetNode(5...8)( - nil, - ConstantReadNode(7...8)(:B), - (5...7) - )], - nil, - nil, - (9...10), - ArrayNode(11...15)( - [IntegerNode(11...12)(), IntegerNode(14...15)()], - nil, - nil - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_command_call.txt b/test/yarp/snapshots/seattlerb/masgn_command_call.txt deleted file mode 100644 index 4563136c2f2bc8..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_command_call.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [MultiWriteNode(0...10)( - [LocalVariableTargetNode(0...1)(:a, 0), SplatNode(1...2)((1...2), nil)], - nil, - nil, - (3...4), - CallNode(5...10)( - CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b"), - (6...7), - (7...8), - nil, - ArgumentsNode(9...10)([IntegerNode(9...10)()]), - nil, - nil, - 0, - "c" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt deleted file mode 100644 index 107be851e3a907..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(1...9)( - [:a, :b], - StatementsNode(1...9)( - [MultiWriteNode(1...9)( - [MultiTargetNode(1...6)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], - (1...2), - (5...6) - )], - nil, - nil, - (7...8), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt deleted file mode 100644 index 4730ed961825b7..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...12)( - [:a], - StatementsNode(0...12)( - [MultiWriteNode(0...12)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil, - (3...4), - ArrayNode(5...12)( - [IntegerNode(5...6)(), IntegerNode(8...9)(), IntegerNode(11...12)()], - nil, - nil - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_paren.txt b/test/yarp/snapshots/seattlerb/masgn_paren.txt deleted file mode 100644 index 32b4fc2989b576..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_paren.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...12)( - [:a, :b], - StatementsNode(0...12)( - [MultiWriteNode(0...12)( - [LocalVariableTargetNode(1...2)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], - (0...1), - (5...6), - (7...8), - CallNode(9...12)( - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "c"), - (10...11), - (11...12), - nil, - nil, - nil, - nil, - 0, - "d" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt deleted file mode 100644 index e2729a861dc8f1..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...9)( - [:a, :b], - StatementsNode(0...9)( - [MultiWriteNode(0...9)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0)], - nil, - nil, - (6...7), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt deleted file mode 100644 index bd6a51261480a3..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...12)( - [:a, :b, :c], - StatementsNode(0...12)( - [MultiWriteNode(0...12)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0), - LocalVariableTargetNode(7...8)(:c, 0)], - nil, - nil, - (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_star.txt b/test/yarp/snapshots/seattlerb/masgn_star.txt deleted file mode 100644 index 015e5edcc9cbcd..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_star.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [MultiWriteNode(0...5)( - [SplatNode(0...1)((0...1), nil)], - nil, - nil, - (2...3), - IntegerNode(4...5)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt deleted file mode 100644 index f6d0136d99ffee..00000000000000 --- a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...11)( - [:a, :b], - StatementsNode(0...11)( - [MultiWriteNode(0...11)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...4)((3...4), nil), - LocalVariableTargetNode(6...7)(:b, 0)], - nil, - nil, - (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/messy_op_asgn_lineno.txt b/test/yarp/snapshots/seattlerb/messy_op_asgn_lineno.txt deleted file mode 100644 index 74da38dee6310c..00000000000000 --- a/test/yarp/snapshots/seattlerb/messy_op_asgn_lineno.txt +++ /dev/null @@ -1,55 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...15)( - [ParenthesesNode(2...15)( - StatementsNode(3...14)( - [ConstantPathOperatorWriteNode(3...14)( - ConstantPathNode(3...7)( - ConstantReadNode(3...4)(:B), - ConstantReadNode(6...7)(:C), - (4...6) - ), - (8...10), - CallNode(11...14)( - nil, - nil, - (11...12), - nil, - ArgumentsNode(13...14)( - [CallNode(13...14)( - nil, - nil, - (13...14), - nil, - nil, - nil, - nil, - 2, - "e" - )] - ), - nil, - nil, - 0, - "d" - ), - :* - )] - ), - (2...3), - (14...15) - )] - ), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/method_call_assoc_trailing_comma.txt b/test/yarp/snapshots/seattlerb/method_call_assoc_trailing_comma.txt deleted file mode 100644 index 1c0c544e85d5da..00000000000000 --- a/test/yarp/snapshots/seattlerb/method_call_assoc_trailing_comma.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - (3...4), - ArgumentsNode(4...8)( - [KeywordHashNode(4...8)( - [AssocNode(4...8)( - IntegerNode(4...5)(), - IntegerNode(7...8)(), - (5...7) - )] - )] - ), - (9...10), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/method_call_trailing_comma.txt b/test/yarp/snapshots/seattlerb/method_call_trailing_comma.txt deleted file mode 100644 index 18089701db8f01..00000000000000 --- a/test/yarp/snapshots/seattlerb/method_call_trailing_comma.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - (3...4), - ArgumentsNode(4...5)([IntegerNode(4...5)()]), - (6...7), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt deleted file mode 100644 index 59e954706b19ea..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...14)( - [:a, :b, :c], - StatementsNode(0...14)( - [MultiWriteNode(0...14)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil)], - nil, - nil, - (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt deleted file mode 100644 index 8014663bd34ffa..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...15)( - [:a, :b, :c, :s], - StatementsNode(0...15)( - [MultiWriteNode(0...15)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0))], - nil, - nil, - (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt deleted file mode 100644 index 74a63d328bfe58..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...14)( - [:x, :y, :z], - StatementsNode(0...14)( - [MultiWriteNode(0...14)( - [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), - LocalVariableTargetNode(3...4)(:x, 0), - LocalVariableTargetNode(6...7)(:y, 0), - LocalVariableTargetNode(9...10)(:z, 0)], - nil, - nil, - (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt deleted file mode 100644 index f3110882cc1133..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...15)( - [:s, :x, :y, :z], - StatementsNode(0...15)( - [MultiWriteNode(0...15)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:s, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:x, 0), - LocalVariableTargetNode(7...8)(:y, 0), - LocalVariableTargetNode(10...11)(:z, 0)], - nil, - nil, - (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_keyword.txt b/test/yarp/snapshots/seattlerb/mlhs_keyword.txt deleted file mode 100644 index 8910c8b5d1a990..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_keyword.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...4), - (4...5), - ArgumentsNode(5...15)([TrueNode(5...9)(), TrueNode(11...15)()]), - (15...16), - nil, - 0, - "!=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt deleted file mode 100644 index c0e3acc145169f..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...23)( - [:a, :b, :c, :x, :y, :z], - StatementsNode(0...23)( - [MultiWriteNode(0...23)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil), - LocalVariableTargetNode(12...13)(:x, 0), - LocalVariableTargetNode(15...16)(:y, 0), - LocalVariableTargetNode(18...19)(:z, 0)], - nil, - nil, - (20...21), - CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt deleted file mode 100644 index 46d81adf646bb7..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...24)( - [:a, :b, :c, :s, :x, :y, :z], - StatementsNode(0...24)( - [MultiWriteNode(0...24)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0)), - LocalVariableTargetNode(13...14)(:x, 0), - LocalVariableTargetNode(16...17)(:y, 0), - LocalVariableTargetNode(19...20)(:z, 0)], - nil, - nil, - (21...22), - CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "f") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt deleted file mode 100644 index 427c56dfea2b4a..00000000000000 --- a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...18)( - [:a, :b], - StatementsNode(0...18)( - [MultiWriteNode(0...18)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], - nil, - nil, - (5...6), - RescueModifierNode(7...18)( - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "f"), - (9...15), - IntegerNode(16...18)() - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/module_comments.txt b/test/yarp/snapshots/seattlerb/module_comments.txt deleted file mode 100644 index a049665ce0529c..00000000000000 --- a/test/yarp/snapshots/seattlerb/module_comments.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(24...77)( - [], - StatementsNode(24...77)( - [ModuleNode(24...77)( - [], - (24...30), - ConstantReadNode(31...32)(:X), - StatementsNode(46...73)( - [DefNode(46...73)( - :blah, - (50...54), - nil, - nil, - nil, - [], - (46...49), - nil, - nil, - nil, - nil, - (70...73) - )] - ), - (74...77), - :X - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/multiline_hash_declaration.txt b/test/yarp/snapshots/seattlerb/multiline_hash_declaration.txt deleted file mode 100644 index e6e341fc7ce1f1..00000000000000 --- a/test/yarp/snapshots/seattlerb/multiline_hash_declaration.txt +++ /dev/null @@ -1,62 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CallNode(0...14)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...13)( - [KeywordHashNode(2...13)( - [AssocNode(2...13)( - SymbolNode(2...8)(nil, (2...7), (7...8), "state"), - HashNode(10...13)((10...11), [], (12...13)), - nil - )] - )] - ), - (13...14), - nil, - 0, - "f" - ), - CallNode(16...29)( - nil, - nil, - (16...17), - (17...18), - ArgumentsNode(18...28)( - [KeywordHashNode(18...28)( - [AssocNode(18...28)( - SymbolNode(18...24)(nil, (18...23), (23...24), "state"), - HashNode(25...28)((25...26), [], (27...28)), - nil - )] - )] - ), - (28...29), - nil, - 0, - "f" - ), - CallNode(31...43)( - nil, - nil, - (31...32), - (32...33), - ArgumentsNode(33...42)( - [KeywordHashNode(33...42)( - [AssocNode(33...42)( - SymbolNode(33...39)(nil, (33...38), (38...39), "state"), - HashNode(40...42)((40...41), [], (41...42)), - nil - )] - )] - ), - (42...43), - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt b/test/yarp/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt deleted file mode 100644 index 0a779610a699c8..00000000000000 --- a/test/yarp/snapshots/seattlerb/non_interpolated_symbol_array_line_breaks.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...9)( - [SymbolNode(4...5)(nil, (4...5), nil, "a"), - SymbolNode(6...7)(nil, (6...7), nil, "b")], - (0...3), - (8...9) - ), - IntegerNode(10...11)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt b/test/yarp/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt deleted file mode 100644 index 901575f9a8dde8..00000000000000 --- a/test/yarp/snapshots/seattlerb/non_interpolated_word_array_line_breaks.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...9)( - [StringNode(4...5)(nil, (4...5), nil, "a"), - StringNode(6...7)(nil, (6...7), nil, "b")], - (0...3), - (8...9) - ), - IntegerNode(10...11)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_command_call.txt deleted file mode 100644 index cf092dd5de2cfc..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_command_call.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...11)( - [:a], - StatementsNode(0...11)( - [LocalVariableOrWriteNode(0...11)( - (0...1), - (2...5), - CallNode(6...11)( - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"), - (7...8), - (8...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "c" - ), - :a, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt deleted file mode 100644 index 00aa4338642209..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_dot_ident_command_call.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallOrWriteNode(0...11)( - ConstantReadNode(0...1)(:A), - (1...2), - (2...3), - nil, - nil, - nil, - 0, - "B", - "B=", - (4...7), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "c" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_index_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_index_command_call.txt deleted file mode 100644 index e166f958a4f78c..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_index_command_call.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallOrWriteNode(0...16)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - nil, - (1...5), - (1...2), - ArgumentsNode(2...4)([SymbolNode(2...4)((2...3), (3...4), nil, "b")]), - (4...5), - 0, - "[]", - "[]=", - (6...9), - CallNode(10...16)( - nil, - nil, - (10...11), - nil, - ArgumentsNode(12...16)( - [IntegerNode(12...13)(), IntegerNode(15...16)()] - ), - nil, - nil, - 0, - "c" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt deleted file mode 100644 index 9459bf5ce52bc2..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_const_command_call.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ConstantPathOperatorWriteNode(0...11)( - ConstantPathNode(0...4)( - ConstantReadNode(0...1)(:A), - ConstantReadNode(3...4)(:B), - (1...3) - ), - (5...7), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)( - [CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d")] - ), - nil, - nil, - 0, - "c" - ), - :* - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt b/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt deleted file mode 100644 index d2703a3e48d8d0..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier1.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallOperatorWriteNode(0...9)( - ConstantReadNode(0...1)(:A), - (1...3), - (3...4), - nil, - nil, - nil, - 0, - "b", - "b=", - :+, - (5...7), - IntegerNode(8...9)() - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt deleted file mode 100644 index 845e0c30a0c2ad..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_primary_colon_identifier_command_call.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallOperatorWriteNode(0...11)( - ConstantReadNode(0...1)(:A), - (1...3), - (3...4), - nil, - nil, - nil, - 0, - "b", - "b=", - :*, - (5...7), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)( - [CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d")] - ), - nil, - nil, - 0, - "c" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt b/test/yarp/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt deleted file mode 100644 index f075b4bb95f0ff..00000000000000 --- a/test/yarp/snapshots/seattlerb/op_asgn_val_dot_ident_command_call.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallOrWriteNode(0...11)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - nil, - nil, - 0, - "b", - "b=", - (4...7), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "c" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_def_special_name.txt b/test/yarp/snapshots/seattlerb/parse_def_special_name.txt deleted file mode 100644 index 0b6b0eae7fb7ab..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_def_special_name.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [DefNode(0...13)( - :next, - (4...8), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (10...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_if_not_canonical.txt b/test/yarp/snapshots/seattlerb/parse_if_not_canonical.txt deleted file mode 100644 index 223ede6af85291..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_if_not_canonical.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [IfNode(0...41)( - (0...2), - CallNode(3...15)( - CallNode(7...15)( - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "var"), - (10...11), - (11...15), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (3...6), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - ElseNode(27...41)( - (27...31), - StatementsNode(32...37)( - [StringNode(32...37)((32...33), (33...36), (36...37), "bar")] - ), - (38...41) - ), - (38...41) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_if_not_noncanonical.txt b/test/yarp/snapshots/seattlerb/parse_if_not_noncanonical.txt deleted file mode 100644 index 223ede6af85291..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_if_not_noncanonical.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [IfNode(0...41)( - (0...2), - CallNode(3...15)( - CallNode(7...15)( - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "var"), - (10...11), - (11...15), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (3...6), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - ElseNode(27...41)( - (27...31), - StatementsNode(32...37)( - [StringNode(32...37)((32...33), (33...36), (36...37), "bar")] - ), - (38...41) - ), - (38...41) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_block.txt b/test/yarp/snapshots/seattlerb/parse_line_block.txt deleted file mode 100644 index 7ca169a86b5cec..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_block.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...10)( - [:a], - StatementsNode(0...10)( - [LocalVariableWriteNode(0...6)( - :a, - 0, - (0...1), - IntegerNode(4...6)(), - (2...3) - ), - CallNode(7...10)( - nil, - nil, - (7...8), - nil, - ArgumentsNode(9...10)([LocalVariableReadNode(9...10)(:a, 0)]), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment.txt b/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment.txt deleted file mode 100644 index f6f0333e91df56..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment.txt +++ /dev/null @@ -1,8 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt b/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt deleted file mode 100644 index 2650fb5c12a1b9..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_block_inline_comment_leading_newlines.txt +++ /dev/null @@ -1,8 +0,0 @@ -ProgramNode(3...36)( - [], - StatementsNode(3...36)( - [CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a"), - CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b"), - CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt b/test/yarp/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt deleted file mode 100644 index 0a01c627fbb74a..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_block_inline_multiline_comment.txt +++ /dev/null @@ -1,8 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"), - CallNode(32...33)(nil, nil, (32...33), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt b/test/yarp/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt deleted file mode 100644 index 84ee2d450bd7aa..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_call_ivar_arg_no_parens_line_break.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([InstanceVariableReadNode(2...4)(:@b)]), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt b/test/yarp/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt deleted file mode 100644 index 1f9d067c76bf7d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_call_ivar_line_break_paren.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...4)([InstanceVariableReadNode(2...4)(:@b)]), - (5...6), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_call_no_args.txt b/test/yarp/snapshots/seattlerb/parse_line_call_no_args.txt deleted file mode 100644 index 229bfdaa9fa284..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_call_no_args.txt +++ /dev/null @@ -1,48 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [CallNode(0...23)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...23)( - [:x, :y], - BlockParametersNode(5...11)( - ParametersNode(6...10)( - [RequiredParameterNode(6...7)(:x), - RequiredParameterNode(9...10)(:y)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (5...6), - (10...11) - ), - StatementsNode(14...19)( - [CallNode(14...19)( - LocalVariableReadNode(14...15)(:x, 0), - nil, - (16...17), - nil, - ArgumentsNode(18...19)([LocalVariableReadNode(18...19)(:y, 0)]), - nil, - nil, - 0, - "+" - )] - ), - (2...4), - (20...23) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt deleted file mode 100644 index 7e1ea50f46a6b3..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt +++ /dev/null @@ -1,51 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [DefNode(0...40)( - :x, - (4...5), - nil, - ParametersNode(6...7)( - [RequiredParameterNode(6...7)(:y)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(11...35)( - [CallNode(11...15)( - nil, - nil, - (11...12), - (12...13), - ArgumentsNode(13...14)([LocalVariableReadNode(13...14)(:y, 0)]), - (14...15), - nil, - 0, - "p" - ), - LocalVariableOperatorWriteNode(18...24)( - (18...19), - (20...22), - IntegerNode(23...24)(), - :y, - :*, - 0 - ), - ReturnNode(27...35)( - (27...33), - ArgumentsNode(34...35)([LocalVariableReadNode(34...35)(:y, 0)]) - )] - ), - [:y], - (0...3), - nil, - (5...6), - (7...8), - nil, - (37...40) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt deleted file mode 100644 index 3bbc2bf9cdb05d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [DefNode(0...10)( - :f, - (4...5), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (7...10) - ), - DefNode(12...21)( - :f, - (16...17), - nil, - nil, - nil, - [], - (12...15), - nil, - nil, - nil, - nil, - (18...21) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt deleted file mode 100644 index 2040cdca68621e..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [DefNode(0...11)( - :f, - (4...5), - nil, - ParametersNode(6...7)( - [RequiredParameterNode(6...7)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (0...3), - nil, - nil, - nil, - nil, - (8...11) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dot2.txt b/test/yarp/snapshots/seattlerb/parse_line_dot2.txt deleted file mode 100644 index 04d53e2c51759d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dot2.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [RangeNode(0...5)(IntegerNode(0...1)(), IntegerNode(4...5)(), (1...3), 0), - RangeNode(6...11)( - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "a"), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "b"), - (7...9), - 0 - ), - CallNode(12...13)(nil, nil, (12...13), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dot2_open.txt b/test/yarp/snapshots/seattlerb/parse_line_dot2_open.txt deleted file mode 100644 index 35faa728edc321..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dot2_open.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [RangeNode(0...3)(IntegerNode(0...1)(), nil, (1...3), 0), - RangeNode(6...9)( - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "a"), - nil, - (7...9), - 0 - ), - CallNode(12...13)(nil, nil, (12...13), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dot3.txt b/test/yarp/snapshots/seattlerb/parse_line_dot3.txt deleted file mode 100644 index 109bbadc623cf4..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dot3.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [RangeNode(0...6)(IntegerNode(0...1)(), IntegerNode(5...6)(), (1...4), 1), - RangeNode(7...13)( - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "a"), - CallNode(12...13)(nil, nil, (12...13), nil, nil, nil, nil, 2, "b"), - (8...11), - 1 - ), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dot3_open.txt b/test/yarp/snapshots/seattlerb/parse_line_dot3_open.txt deleted file mode 100644 index 558c430b6a69fa..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dot3_open.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [RangeNode(0...4)(IntegerNode(0...1)(), nil, (1...4), 1), - RangeNode(7...11)( - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "a"), - nil, - (8...11), - 1 - ), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt b/test/yarp/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt deleted file mode 100644 index b6f92191b6ed37..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dstr_escaped_newline.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedStringNode(0...9)( - (0...1), - [StringNode(1...4)(nil, (1...4), nil, "a\n"), - EmbeddedStatementsNode(4...8)((4...6), nil, (7...8))], - (8...9) - ), - TrueNode(10...14)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_dstr_soft_newline.txt b/test/yarp/snapshots/seattlerb/parse_line_dstr_soft_newline.txt deleted file mode 100644 index a22199b3acd36d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_dstr_soft_newline.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [InterpolatedStringNode(0...8)( - (0...1), - [StringNode(1...3)(nil, (1...3), nil, "a\n"), - EmbeddedStatementsNode(3...7)((3...5), nil, (6...7))], - (7...8) - ), - TrueNode(9...13)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_evstr_after_break.txt b/test/yarp/snapshots/seattlerb/parse_line_evstr_after_break.txt deleted file mode 100644 index ac4be36fcca71b..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_evstr_after_break.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [StringConcatNode(0...11)( - StringNode(0...3)((0...1), (1...2), (2...3), "a"), - InterpolatedStringNode(5...11)( - (5...6), - [EmbeddedStatementsNode(6...10)( - (6...8), - StatementsNode(8...9)( - [CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "b")] - ), - (9...10) - )], - (10...11) - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_hash_lit.txt b/test/yarp/snapshots/seattlerb/parse_line_hash_lit.txt deleted file mode 100644 index a7dd5a1f7b1216..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_hash_lit.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [HashNode(0...13)( - (0...1), - [AssocNode(2...10)( - SymbolNode(2...5)((2...3), (3...5), nil, "s1"), - IntegerNode(9...10)(), - (6...8) - )], - (12...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt deleted file mode 100644 index 955d94e98fb289..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_heredoc.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(6...88)( - [:string], - StatementsNode(6...88)( - [LocalVariableWriteNode(6...31)( - :string, - 0, - (6...12), - CallNode(15...31)( - InterpolatedStringNode(15...25)( - (15...25), - [StringNode(32...57)( - nil, - (32...57), - nil, - " very long string\n" - )], - (57...71) - ), - (25...26), - (26...31), - nil, - nil, - nil, - nil, - 0, - "strip" - ), - (13...14) - ), - CallNode(77...88)( - nil, - nil, - (77...81), - nil, - ArgumentsNode(82...88)([LocalVariableReadNode(82...88)(:string, 0)]), - nil, - nil, - 0, - "puts" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc_evstr.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc_evstr.txt deleted file mode 100644 index 8b95196e2d741d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_heredoc_evstr.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [InterpolatedStringNode(0...4)( - (0...4), - [StringNode(5...7)(nil, (5...7), nil, "a\n"), - EmbeddedStatementsNode(7...11)( - (7...9), - StatementsNode(9...10)( - [CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "b")] - ), - (10...11) - ), - StringNode(11...12)(nil, (11...12), nil, "\n")], - (12...14) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt deleted file mode 100644 index 4d1925d56a890f..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...48)( - [], - StatementsNode(0...48)( - [InterpolatedStringNode(0...8)( - (0...8), - [StringNode(9...28)( - nil, - (9...28), - nil, - "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" - )], - (28...34) - ), - ClassNode(35...48)( - [], - (35...40), - ConstantReadNode(41...44)(:Foo), - nil, - nil, - nil, - (45...48), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt deleted file mode 100644 index 3d52fcbff0cec7..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_heredoc_regexp_chars.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(6...74)( - [:string], - StatementsNode(6...74)( - [LocalVariableWriteNode(6...22)( - :string, - 0, - (6...12), - InterpolatedStringNode(15...22)( - (15...22), - [StringNode(23...48)( - nil, - (23...48), - nil, - " very long string\n" - )], - (48...57) - ), - (13...14) - ), - CallNode(63...74)( - nil, - nil, - (63...67), - nil, - ArgumentsNode(68...74)([LocalVariableReadNode(68...74)(:string, 0)]), - nil, - nil, - 0, - "puts" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_iter_call_no_parens.txt b/test/yarp/snapshots/seattlerb/parse_line_iter_call_no_parens.txt deleted file mode 100644 index 82dd3ce64f627e..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_iter_call_no_parens.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...3)( - [CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a")] - ), - nil, - BlockNode(4...25)( - [:x, :y], - BlockParametersNode(7...13)( - ParametersNode(8...12)( - [RequiredParameterNode(8...9)(:x), - RequiredParameterNode(11...12)(:y)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (7...8), - (12...13) - ), - StatementsNode(16...21)( - [CallNode(16...21)( - LocalVariableReadNode(16...17)(:x, 0), - nil, - (18...19), - nil, - ArgumentsNode(20...21)([LocalVariableReadNode(20...21)(:y, 0)]), - nil, - nil, - 0, - "+" - )] - ), - (4...6), - (22...25) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_iter_call_parens.txt b/test/yarp/snapshots/seattlerb/parse_line_iter_call_parens.txt deleted file mode 100644 index db09ae12d0bf4c..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_iter_call_parens.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CallNode(0...26)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...3)( - [CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a")] - ), - (3...4), - BlockNode(5...26)( - [:x, :y], - BlockParametersNode(8...14)( - ParametersNode(9...13)( - [RequiredParameterNode(9...10)(:x), - RequiredParameterNode(12...13)(:y)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (8...9), - (13...14) - ), - StatementsNode(17...22)( - [CallNode(17...22)( - LocalVariableReadNode(17...18)(:x, 0), - nil, - (19...20), - nil, - ArgumentsNode(21...22)([LocalVariableReadNode(21...22)(:y, 0)]), - nil, - nil, - 0, - "+" - )] - ), - (5...7), - (23...26) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_multiline_str.txt b/test/yarp/snapshots/seattlerb/parse_line_multiline_str.txt deleted file mode 100644 index e12f68cfb22197..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_multiline_str.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [StringNode(0...5)((0...1), (1...4), (4...5), "a\n" + "b"), - IntegerNode(6...7)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt b/test/yarp/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt deleted file mode 100644 index 92a7b9fed1d809..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_multiline_str_literal_n.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [StringNode(0...6)((0...1), (1...5), (5...6), "a\n" + "b"), - IntegerNode(7...8)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_newlines.txt b/test/yarp/snapshots/seattlerb/parse_line_newlines.txt deleted file mode 100644 index 14b0c8cecccd16..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_newlines.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...4)([], StatementsNode(0...4)([TrueNode(0...4)()])) diff --git a/test/yarp/snapshots/seattlerb/parse_line_op_asgn.txt b/test/yarp/snapshots/seattlerb/parse_line_op_asgn.txt deleted file mode 100644 index d3aa84c9869457..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_op_asgn.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(6...34)( - [:foo], - StatementsNode(6...34)( - [LocalVariableOperatorWriteNode(6...24)( - (6...9), - (10...12), - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "bar"), - :foo, - :+, - 0 - ), - CallNode(31...34)(nil, nil, (31...34), nil, nil, nil, nil, 2, "baz")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_postexe.txt b/test/yarp/snapshots/seattlerb/parse_line_postexe.txt deleted file mode 100644 index 9e527ea587c932..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_postexe.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [PostExecutionNode(0...11)( - StatementsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo")] - ), - (0...3), - (4...5), - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_preexe.txt b/test/yarp/snapshots/seattlerb/parse_line_preexe.txt deleted file mode 100644 index 49f485c79fc3e1..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_preexe.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [PreExecutionNode(0...13)( - StatementsNode(8...11)( - [CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 2, "foo")] - ), - (0...5), - (6...7), - (12...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_rescue.txt b/test/yarp/snapshots/seattlerb/parse_line_rescue.txt deleted file mode 100644 index 02704b5790fb32..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_rescue.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [BeginNode(0...35)( - (0...5), - StatementsNode(8...9)( - [CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(10...31)( - (10...16), - [], - nil, - nil, - StatementsNode(19...20)( - [CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "b")] - ), - RescueNode(21...31)( - (21...27), - [], - nil, - nil, - StatementsNode(30...31)( - [CallNode(30...31)( - nil, - nil, - (30...31), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - nil - ) - ), - nil, - nil, - (32...35) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_return.txt b/test/yarp/snapshots/seattlerb/parse_line_return.txt deleted file mode 100644 index 87016474356b3d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_return.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(6...77)( - [], - StatementsNode(6...77)( - [DefNode(6...77)( - :blah, - (10...14), - nil, - nil, - StatementsNode(23...67)( - [IfNode(23...67)( - (23...25), - TrueNode(26...30)(), - StatementsNode(46...55)( - [ReturnNode(46...55)( - (46...52), - ArgumentsNode(53...55)([IntegerNode(53...55)()]) - )] - ), - nil, - (64...67) - )] - ), - [], - (6...9), - nil, - nil, - nil, - nil, - (74...77) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_str_with_newline_escape.txt b/test/yarp/snapshots/seattlerb/parse_line_str_with_newline_escape.txt deleted file mode 100644 index e75463a0e3073d..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_str_with_newline_escape.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...12)( - [StringNode(2...6)((2...3), (3...5), (5...6), "\n"), - TrueNode(8...12)()] - ), - (12...13), - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt deleted file mode 100644 index e8736976c78a9c..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...10)( - [:a, :b], - StatementsNode(0...10)( - [MultiWriteNode(0...8)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], - nil, - nil, - (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "c") - ), - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_line_trailing_newlines.txt b/test/yarp/snapshots/seattlerb/parse_line_trailing_newlines.txt deleted file mode 100644 index 7617e15479c07b..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_line_trailing_newlines.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt b/test/yarp/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt deleted file mode 100644 index 9a84d358bca42c..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_opt_call_args_assocs_comma.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - IntegerNode(0...1)(), - nil, - (1...8), - (1...2), - ArgumentsNode(2...6)( - [KeywordHashNode(2...6)( - [AssocNode(2...6)( - IntegerNode(2...3)(), - IntegerNode(5...6)(), - (3...5) - )] - )] - ), - (7...8), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt b/test/yarp/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt deleted file mode 100644 index a058d012841102..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_opt_call_args_lit_comma.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - IntegerNode(0...1)(), - nil, - (1...5), - (1...2), - ArgumentsNode(2...3)([IntegerNode(2...3)()]), - (4...5), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_019.txt b/test/yarp/snapshots/seattlerb/parse_pattern_019.txt deleted file mode 100644 index d6f5d2977abd8a..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_019.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CaseNode(0...26)( - IntegerNode(5...6)(), - [InNode(7...22)( - RangeNode(10...15)( - IntegerNode(10...12)(), - IntegerNode(14...15)(), - (12...14), - 0 - ), - StatementsNode(18...22)([TrueNode(18...22)()]), - (7...9), - nil - )], - nil, - (0...4), - (23...26) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_044.txt b/test/yarp/snapshots/seattlerb/parse_pattern_044.txt deleted file mode 100644 index 09d0143eff5561..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_044.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CaseNode(0...31)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "obj"), - [InNode(9...27)( - ArrayPatternNode(12...20)( - ConstantReadNode(12...18)(:Object), - [], - nil, - [], - (18...19), - (19...20) - ), - StatementsNode(23...27)([TrueNode(23...27)()]), - (9...11), - nil - )], - nil, - (0...4), - (28...31) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_051.txt b/test/yarp/snapshots/seattlerb/parse_pattern_051.txt deleted file mode 100644 index 7f2410212d0abb..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_051.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...36)( - [], - StatementsNode(0...36)( - [CaseNode(0...36)( - ArrayNode(5...14)( - [IntegerNode(6...7)(), IntegerNode(9...10)(), IntegerNode(12...13)()], - (5...6), - (13...14) - ), - [InNode(15...32)( - ArrayPatternNode(18...25)( - nil, - [IntegerNode(19...20)(), IntegerNode(22...23)()], - nil, - [], - (18...19), - (24...25) - ), - StatementsNode(28...32)([TrueNode(28...32)()]), - (15...17), - nil - )], - nil, - (0...4), - (33...36) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_058.txt b/test/yarp/snapshots/seattlerb/parse_pattern_058.txt deleted file mode 100644 index d9416d4a61c613..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_058.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...43)( - [:a, :rest], - StatementsNode(0...43)( - [CaseNode(0...43)( - HashNode(5...11)( - (5...6), - [AssocNode(6...10)( - SymbolNode(6...8)(nil, (6...7), (7...8), "a"), - IntegerNode(9...10)(), - nil - )], - (10...11) - ), - [InNode(12...39)( - HashPatternNode(15...27)( - nil, - [AssocNode(16...18)( - SymbolNode(16...18)(nil, (16...17), (17...18), "a"), - nil, - nil - ), - AssocSplatNode(20...26)( - LocalVariableTargetNode(22...26)(:rest, 0), - (20...22) - )], - nil, - (15...16), - (26...27) - ), - StatementsNode(30...39)( - [ArrayNode(30...39)( - [LocalVariableReadNode(31...32)(:a, 0), - LocalVariableReadNode(34...38)(:rest, 0)], - (30...31), - (38...39) - )] - ), - (12...14), - nil - )], - nil, - (0...4), - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_058_2.txt b/test/yarp/snapshots/seattlerb/parse_pattern_058_2.txt deleted file mode 100644 index c1ba037a626cfd..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_058_2.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...33)( - [:a], - StatementsNode(0...33)( - [CaseNode(0...33)( - HashNode(5...11)( - (5...6), - [AssocNode(6...10)( - SymbolNode(6...8)(nil, (6...7), (7...8), "a"), - IntegerNode(9...10)(), - nil - )], - (10...11) - ), - [InNode(12...29)( - HashPatternNode(15...23)( - nil, - [AssocNode(16...18)( - SymbolNode(16...18)(nil, (16...17), (17...18), "a"), - nil, - nil - ), - AssocSplatNode(20...22)(nil, (20...22))], - nil, - (15...16), - (22...23) - ), - StatementsNode(26...29)( - [ArrayNode(26...29)( - [LocalVariableReadNode(27...28)(:a, 0)], - (26...27), - (28...29) - )] - ), - (12...14), - nil - )], - nil, - (0...4), - (30...33) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_069.txt b/test/yarp/snapshots/seattlerb/parse_pattern_069.txt deleted file mode 100644 index b704851937c9fd..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_069.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CaseNode(0...31)( - SymbolNode(5...7)((5...6), (6...7), nil, "a"), - [InNode(8...27)( - HashPatternNode(11...23)( - ConstantReadNode(11...17)(:Object), - [AssocNode(18...22)( - SymbolNode(18...20)(nil, (18...19), (19...20), "b"), - IntegerNode(21...22)(), - nil - )], - nil, - (17...18), - (22...23) - ), - StatementsNode(26...27)([IntegerNode(26...27)()]), - (8...10), - nil - )], - nil, - (0...4), - (28...31) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_pattern_076.txt b/test/yarp/snapshots/seattlerb/parse_pattern_076.txt deleted file mode 100644 index 493223169b11fd..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_pattern_076.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [CaseNode(0...39)( - HashNode(5...11)( - (5...6), - [AssocNode(6...10)( - SymbolNode(6...8)(nil, (6...7), (7...8), "a"), - IntegerNode(9...10)(), - nil - )], - (10...11) - ), - [InNode(12...35)( - HashPatternNode(15...28)( - nil, - [AssocNode(16...20)( - SymbolNode(16...18)(nil, (16...17), (17...18), "a"), - IntegerNode(19...20)(), - nil - ), - NoKeywordsParameterNode(22...27)((22...24), (24...27))], - nil, - (15...16), - (27...28) - ), - StatementsNode(31...35)([TrueNode(31...35)()]), - (12...14), - nil - )], - nil, - (0...4), - (36...39) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_until_not_canonical.txt b/test/yarp/snapshots/seattlerb/parse_until_not_canonical.txt deleted file mode 100644 index e84c4bf8a92476..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_until_not_canonical.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [UntilNode(0...30)( - (0...5), - (27...30), - CallNode(6...18)( - CallNode(10...18)( - CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "var" - ), - (13...14), - (14...18), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (6...9), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_until_not_noncanonical.txt b/test/yarp/snapshots/seattlerb/parse_until_not_noncanonical.txt deleted file mode 100644 index e84c4bf8a92476..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_until_not_noncanonical.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [UntilNode(0...30)( - (0...5), - (27...30), - CallNode(6...18)( - CallNode(10...18)( - CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "var" - ), - (13...14), - (14...18), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (6...9), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_while_not_canonical.txt b/test/yarp/snapshots/seattlerb/parse_while_not_canonical.txt deleted file mode 100644 index 8d152ba76ec6f6..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_while_not_canonical.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [WhileNode(0...30)( - (0...5), - (27...30), - CallNode(6...18)( - CallNode(10...18)( - CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "var" - ), - (13...14), - (14...18), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (6...9), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/parse_while_not_noncanonical.txt b/test/yarp/snapshots/seattlerb/parse_while_not_noncanonical.txt deleted file mode 100644 index 8d152ba76ec6f6..00000000000000 --- a/test/yarp/snapshots/seattlerb/parse_while_not_noncanonical.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [WhileNode(0...30)( - (0...5), - (27...30), - CallNode(6...18)( - CallNode(10...18)( - CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "var" - ), - (13...14), - (14...18), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - nil, - (6...9), - nil, - nil, - nil, - nil, - 0, - "!" - ), - StatementsNode(21...26)( - [StringNode(21...26)((21...22), (22...25), (25...26), "foo")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pctW_lineno.txt b/test/yarp/snapshots/seattlerb/pctW_lineno.txt deleted file mode 100644 index d03e41c0f2f4a8..00000000000000 --- a/test/yarp/snapshots/seattlerb/pctW_lineno.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [ArrayNode(0...28)( - [StringNode(3...7)(nil, (3...7), nil, "a\n" + "b"), - StringNode(8...9)(nil, (8...9), nil, "c"), - StringNode(10...11)(nil, (10...11), nil, "d"), - StringNode(12...16)(nil, (12...16), nil, "ef"), - StringNode(17...19)(nil, (17...19), nil, "gy"), - StringNode(20...23)(nil, (20...23), nil, "hy"), - StringNode(24...27)(nil, (24...27), nil, "iy")], - (0...3), - (27...28) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pct_Q_backslash_nl.txt b/test/yarp/snapshots/seattlerb/pct_Q_backslash_nl.txt deleted file mode 100644 index 0725aaee499427..00000000000000 --- a/test/yarp/snapshots/seattlerb/pct_Q_backslash_nl.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [StringNode(0...7)((0...3), (3...6), (6...7), " \\\n")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pct_nl.txt b/test/yarp/snapshots/seattlerb/pct_nl.txt deleted file mode 100644 index 4cdba9d6d621ee..00000000000000 --- a/test/yarp/snapshots/seattlerb/pct_nl.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...7)( - [:x], - StatementsNode(0...7)( - [LocalVariableWriteNode(0...7)( - :x, - 0, - (0...1), - StringNode(4...7)((4...6), (6...6), (6...7), ""), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt b/test/yarp/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt deleted file mode 100644 index 8c9604e40d9c85..00000000000000 --- a/test/yarp/snapshots/seattlerb/pct_w_heredoc_interp_nested.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [ArrayNode(0...30)( - [StringNode(4...5)(nil, (4...5), nil, "1"), - InterpolatedStringNode(6...12)( - nil, - [EmbeddedStatementsNode(6...12)( - (6...8), - StatementsNode(8...11)( - [InterpolatedStringNode(8...11)( - (8...11), - [StringNode(15...17)(nil, (15...17), nil, "2\n")], - (17...19) - )] - ), - (11...12) - )], - nil - ), - StringNode(13...14)(nil, (13...14), nil, "3"), - StringNode(25...26)(nil, (25...26), nil, "4"), - StringNode(27...28)(nil, (27...28), nil, "5")], - (0...3), - (29...30) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pipe_semicolon.txt b/test/yarp/snapshots/seattlerb/pipe_semicolon.txt deleted file mode 100644 index 14dc672e1c2339..00000000000000 --- a/test/yarp/snapshots/seattlerb/pipe_semicolon.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallNode(0...18)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - nil, - nil, - BlockNode(4...18)( - [:c], - BlockParametersNode(7...14)( - nil, - [BlockLocalVariableNode(11...12)(:c)], - (7...8), - (13...14) - ), - nil, - (4...6), - (15...18) - ), - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/pipe_space.txt b/test/yarp/snapshots/seattlerb/pipe_space.txt deleted file mode 100644 index 8c66905d04c8a8..00000000000000 --- a/test/yarp/snapshots/seattlerb/pipe_space.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...2), - (2...3), - nil, - nil, - nil, - BlockNode(4...14)( - [], - BlockParametersNode(7...10)(nil, [], (7...8), (9...10)), - nil, - (4...6), - (11...14) - ), - 0, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/qWords_space.txt b/test/yarp/snapshots/seattlerb/qWords_space.txt deleted file mode 100644 index 6713c4ba71612f..00000000000000 --- a/test/yarp/snapshots/seattlerb/qWords_space.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)([ArrayNode(0...5)([], (0...3), (4...5))]) -) diff --git a/test/yarp/snapshots/seattlerb/qsymbols.txt b/test/yarp/snapshots/seattlerb/qsymbols.txt deleted file mode 100644 index 7cf54611c2b5aa..00000000000000 --- a/test/yarp/snapshots/seattlerb/qsymbols.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [ArrayNode(0...9)( - [SymbolNode(3...4)(nil, (3...4), nil, "a"), - SymbolNode(5...6)(nil, (5...6), nil, "b"), - SymbolNode(7...8)(nil, (7...8), nil, "c")], - (0...3), - (8...9) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/qsymbols_empty.txt b/test/yarp/snapshots/seattlerb/qsymbols_empty.txt deleted file mode 100644 index cad298895b68c9..00000000000000 --- a/test/yarp/snapshots/seattlerb/qsymbols_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([ArrayNode(0...4)([], (0...3), (3...4))]) -) diff --git a/test/yarp/snapshots/seattlerb/qsymbols_empty_space.txt b/test/yarp/snapshots/seattlerb/qsymbols_empty_space.txt deleted file mode 100644 index 6713c4ba71612f..00000000000000 --- a/test/yarp/snapshots/seattlerb/qsymbols_empty_space.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)([ArrayNode(0...5)([], (0...3), (4...5))]) -) diff --git a/test/yarp/snapshots/seattlerb/qsymbols_interp.txt b/test/yarp/snapshots/seattlerb/qsymbols_interp.txt deleted file mode 100644 index 2f4a44fc233a56..00000000000000 --- a/test/yarp/snapshots/seattlerb/qsymbols_interp.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [ArrayNode(0...15)( - [SymbolNode(3...4)(nil, (3...4), nil, "a"), - InterpolatedSymbolNode(5...12)( - nil, - [StringNode(5...6)(nil, (5...6), nil, "b"), - EmbeddedStatementsNode(6...12)( - (6...8), - StatementsNode(8...11)( - [CallNode(8...11)( - IntegerNode(8...9)(), - nil, - (9...10), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "+" - )] - ), - (11...12) - )], - nil - ), - SymbolNode(13...14)(nil, (13...14), nil, "c")], - (0...3), - (14...15) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/quoted_symbol_hash_arg.txt b/test/yarp/snapshots/seattlerb/quoted_symbol_hash_arg.txt deleted file mode 100644 index 861fcaa6a2b1bd..00000000000000 --- a/test/yarp/snapshots/seattlerb/quoted_symbol_hash_arg.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...4), - nil, - ArgumentsNode(5...12)( - [KeywordHashNode(5...12)( - [AssocNode(5...12)( - SymbolNode(5...9)((5...6), (6...7), (7...9), "a"), - HashNode(10...12)((10...11), [], (11...12)), - nil - )] - )] - ), - nil, - nil, - 0, - "puts" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/quoted_symbol_keys.txt b/test/yarp/snapshots/seattlerb/quoted_symbol_keys.txt deleted file mode 100644 index 59b2b5d62d92f2..00000000000000 --- a/test/yarp/snapshots/seattlerb/quoted_symbol_keys.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [HashNode(0...11)( - (0...1), - [AssocNode(2...9)( - SymbolNode(2...6)((2...3), (3...4), (4...6), "a"), - SymbolNode(7...9)((7...8), (8...9), nil, "b"), - nil - )], - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/qw_escape.txt b/test/yarp/snapshots/seattlerb/qw_escape.txt deleted file mode 100644 index 0bf3fd8d8b730e..00000000000000 --- a/test/yarp/snapshots/seattlerb/qw_escape.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [StringNode(0...7)((0...3), (3...6), (6...7), "\u0001'")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/qw_escape_term.txt b/test/yarp/snapshots/seattlerb/qw_escape_term.txt deleted file mode 100644 index 2c9eb48c3d8b2c..00000000000000 --- a/test/yarp/snapshots/seattlerb/qw_escape_term.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [StringNode(0...26)( - (0...3), - (3...25), - (25...26), - "blah blah \\| blah blah" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/qwords_empty.txt b/test/yarp/snapshots/seattlerb/qwords_empty.txt deleted file mode 100644 index cad298895b68c9..00000000000000 --- a/test/yarp/snapshots/seattlerb/qwords_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([ArrayNode(0...4)([], (0...3), (3...4))]) -) diff --git a/test/yarp/snapshots/seattlerb/read_escape_unicode_curlies.txt b/test/yarp/snapshots/seattlerb/read_escape_unicode_curlies.txt deleted file mode 100644 index 26583c05a1b447..00000000000000 --- a/test/yarp/snapshots/seattlerb/read_escape_unicode_curlies.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)([StringNode(0...9)((0...1), (1...9), nil, " ")]) -) diff --git a/test/yarp/snapshots/seattlerb/read_escape_unicode_h4.txt b/test/yarp/snapshots/seattlerb/read_escape_unicode_h4.txt deleted file mode 100644 index b17128c620ed5a..00000000000000 --- a/test/yarp/snapshots/seattlerb/read_escape_unicode_h4.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)([StringNode(0...7)((0...1), (1...7), nil, " ")]) -) diff --git a/test/yarp/snapshots/seattlerb/regexp.txt b/test/yarp/snapshots/seattlerb/regexp.txt deleted file mode 100644 index 122d26a249fcc4..00000000000000 --- a/test/yarp/snapshots/seattlerb/regexp.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...45)( - [], - StatementsNode(0...45)( - [RegularExpressionNode(0...5)((0...1), (1...4), (4...5), "wtf", 0), - RegularExpressionNode(7...13)((7...8), (8...11), (11...13), "wtf", 2), - RegularExpressionNode(15...21)( - (15...16), - (16...19), - (19...21), - "wtf", - 16 - ), - RegularExpressionNode(23...30)( - (23...24), - (24...27), - (27...30), - "wtf", - 18 - ), - RegularExpressionNode(32...45)( - (32...33), - (33...36), - (36...45), - "wtf", - 18 - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/regexp_esc_C_slash.txt b/test/yarp/snapshots/seattlerb/regexp_esc_C_slash.txt deleted file mode 100644 index 2605080304bc4c..00000000000000 --- a/test/yarp/snapshots/seattlerb/regexp_esc_C_slash.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [RegularExpressionNode(0...7)((0...1), (1...6), (6...7), "\u0003d", 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/regexp_esc_u.txt b/test/yarp/snapshots/seattlerb/regexp_esc_u.txt deleted file mode 100644 index 8b13368704f3cd..00000000000000 --- a/test/yarp/snapshots/seattlerb/regexp_esc_u.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [RegularExpressionNode(0...17)((0...1), (1...16), (16...17), "[!-']", 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/regexp_escape_extended.txt b/test/yarp/snapshots/seattlerb/regexp_escape_extended.txt deleted file mode 100644 index 699de5a196957f..00000000000000 --- a/test/yarp/snapshots/seattlerb/regexp_escape_extended.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [RegularExpressionNode(0...6)((0...1), (1...5), (5...6), "“", 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/regexp_unicode_curlies.txt b/test/yarp/snapshots/seattlerb/regexp_unicode_curlies.txt deleted file mode 100644 index e4502db3f74f31..00000000000000 --- a/test/yarp/snapshots/seattlerb/regexp_unicode_curlies.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [RegularExpressionNode(0...15)((0...1), (1...14), (14...15), "샞몾", 0), - RegularExpressionNode(17...25)((17...18), (18...24), (24...25), "ß", 0)] - ) -) diff --git a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt deleted file mode 100644 index 942400bfa12d4f..00000000000000 --- a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [DefNode(0...16)( - :x, - (4...5), - nil, - ParametersNode(6...12)( - [], - [], - [], - nil, - [KeywordParameterNode(6...8)(:a, (6...8), nil), - KeywordParameterNode(10...12)(:b, (10...12), nil)], - nil, - nil - ), - nil, - [:a, :b], - (0...3), - nil, - nil, - nil, - nil, - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_do_end_ensure_result.txt b/test/yarp/snapshots/seattlerb/rescue_do_end_ensure_result.txt deleted file mode 100644 index 52721053a8249a..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_do_end_ensure_result.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [CallNode(0...42)( - CallNode(0...37)( - nil, - nil, - (0...4), - nil, - nil, - nil, - BlockNode(5...37)( - [], - nil, - BeginNode(10...37)( - nil, - StatementsNode(10...16)( - [SymbolNode(10...16)((10...11), (11...16), nil, "begin")] - ), - nil, - nil, - EnsureNode(17...37)( - (17...23), - StatementsNode(26...33)( - [SymbolNode(26...33)((26...27), (27...33), nil, "ensure")] - ), - (34...37) - ), - (34...37) - ), - (5...7), - (34...37) - ), - 0, - "proc" - ), - (37...38), - (38...42), - nil, - nil, - nil, - nil, - 0, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_do_end_no_raise.txt b/test/yarp/snapshots/seattlerb/rescue_do_end_no_raise.txt deleted file mode 100644 index c4d46c2f7a9533..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_do_end_no_raise.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...66)( - [], - StatementsNode(0...66)( - [CallNode(0...66)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...66)( - [], - nil, - BeginNode(9...66)( - nil, - StatementsNode(9...15)( - [SymbolNode(9...15)((9...10), (10...15), nil, "begin")] - ), - RescueNode(16...32)( - (16...22), - [], - nil, - nil, - StatementsNode(25...32)( - [SymbolNode(25...32)((25...26), (26...32), nil, "rescue")] - ), - nil - ), - ElseNode(33...52)( - (33...37), - StatementsNode(40...45)( - [SymbolNode(40...45)((40...41), (41...45), nil, "else")] - ), - (46...52) - ), - EnsureNode(46...66)( - (46...52), - StatementsNode(55...62)( - [SymbolNode(55...62)((55...56), (56...62), nil, "ensure")] - ), - (63...66) - ), - (63...66) - ), - (4...6), - (63...66) - ), - 0, - "tap" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_do_end_raised.txt b/test/yarp/snapshots/seattlerb/rescue_do_end_raised.txt deleted file mode 100644 index f4e4cda3ee3261..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_do_end_raised.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [CallNode(0...35)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...35)( - [], - nil, - BeginNode(9...35)( - nil, - StatementsNode(9...14)( - [CallNode(9...14)( - nil, - nil, - (9...14), - nil, - nil, - nil, - nil, - 2, - "raise" - )] - ), - nil, - nil, - EnsureNode(15...35)( - (15...21), - StatementsNode(24...31)( - [SymbolNode(24...31)((24...25), (25...31), nil, "ensure")] - ), - (32...35) - ), - (32...35) - ), - (4...6), - (32...35) - ), - 0, - "tap" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_do_end_rescued.txt b/test/yarp/snapshots/seattlerb/rescue_do_end_rescued.txt deleted file mode 100644 index 5376935a827006..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_do_end_rescued.txt +++ /dev/null @@ -1,62 +0,0 @@ -ProgramNode(0...65)( - [], - StatementsNode(0...65)( - [CallNode(0...65)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...65)( - [], - nil, - BeginNode(9...65)( - nil, - StatementsNode(9...14)( - [CallNode(9...14)( - nil, - nil, - (9...14), - nil, - nil, - nil, - nil, - 2, - "raise" - )] - ), - RescueNode(15...31)( - (15...21), - [], - nil, - nil, - StatementsNode(24...31)( - [SymbolNode(24...31)((24...25), (25...31), nil, "rescue")] - ), - nil - ), - ElseNode(32...51)( - (32...36), - StatementsNode(39...44)( - [SymbolNode(39...44)((39...40), (40...44), nil, "else")] - ), - (45...51) - ), - EnsureNode(45...65)( - (45...51), - StatementsNode(54...61)( - [SymbolNode(54...61)((54...55), (55...61), nil, "ensure")] - ), - (62...65) - ), - (62...65) - ), - (4...6), - (62...65) - ), - 0, - "tap" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_in_block.txt b/test/yarp/snapshots/seattlerb/rescue_in_block.txt deleted file mode 100644 index 2f096cdf741b7b..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_in_block.txt +++ /dev/null @@ -1,48 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CallNode(0...26)( - nil, - nil, - (0...4), - nil, - nil, - nil, - BlockNode(5...26)( - [], - nil, - BeginNode(8...26)( - nil, - nil, - RescueNode(8...22)( - (8...14), - [], - nil, - nil, - StatementsNode(17...22)( - [CallNode(17...22)( - nil, - nil, - (17...22), - nil, - nil, - nil, - nil, - 2, - "stuff" - )] - ), - nil - ), - nil, - nil, - (23...26) - ), - (5...7), - (23...26) - ), - 0, - "blah" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rescue_parens.txt b/test/yarp/snapshots/seattlerb/rescue_parens.txt deleted file mode 100644 index c672e59e6f65d9..00000000000000 --- a/test/yarp/snapshots/seattlerb/rescue_parens.txt +++ /dev/null @@ -1,48 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...14)( - [ParenthesesNode(2...14)( - StatementsNode(3...13)( - [RescueModifierNode(3...13)( - CallNode(3...4)( - nil, - nil, - (3...4), - nil, - nil, - nil, - nil, - 2, - "b" - ), - (5...11), - CallNode(12...13)( - nil, - nil, - (12...13), - nil, - nil, - nil, - nil, - 2, - "c" - ) - )] - ), - (2...3), - (13...14) - )] - ), - nil, - nil, - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/return_call_assocs.txt b/test/yarp/snapshots/seattlerb/return_call_assocs.txt deleted file mode 100644 index 9698080b5e9918..00000000000000 --- a/test/yarp/snapshots/seattlerb/return_call_assocs.txt +++ /dev/null @@ -1,142 +0,0 @@ -ProgramNode(0...106)( - [], - StatementsNode(0...106)( - [ReturnNode(0...17)( - (0...6), - ArgumentsNode(7...17)( - [IntegerNode(7...8)(), - KeywordHashNode(10...17)( - [AssocNode(10...17)( - SymbolNode(10...12)((10...11), (11...12), nil, "z"), - IntegerNode(16...17)(), - (13...15) - )] - )] - ) - ), - ReturnNode(19...45)( - (19...25), - ArgumentsNode(26...45)( - [IntegerNode(26...27)(), - KeywordHashNode(29...45)( - [AssocNode(29...36)( - SymbolNode(29...31)((29...30), (30...31), nil, "z"), - IntegerNode(35...36)(), - (32...34) - ), - AssocNode(38...45)( - SymbolNode(38...40)((38...39), (39...40), nil, "w"), - IntegerNode(44...45)(), - (41...43) - )] - )] - ) - ), - ReturnNode(47...61)( - (47...53), - ArgumentsNode(54...61)( - [CallNode(54...61)( - nil, - nil, - (54...55), - nil, - ArgumentsNode(56...61)( - [KeywordHashNode(56...61)( - [AssocNode(56...61)( - SymbolNode(56...58)((56...57), (57...58), nil, "z"), - IntegerNode(60...61)(), - (58...60) - )] - )] - ), - nil, - nil, - 0, - "y" - )] - ) - ), - ReturnNode(63...75)( - (63...69), - ArgumentsNode(70...75)( - [CallNode(70...75)( - nil, - nil, - (70...71), - nil, - ArgumentsNode(72...75)( - [KeywordHashNode(72...75)( - [AssocNode(72...75)( - SymbolNode(72...74)(nil, (72...73), (73...74), "z"), - IntegerNode(74...75)(), - nil - )] - )] - ), - nil, - nil, - 0, - "y" - )] - ) - ), - ReturnNode(77...90)( - (77...83), - ArgumentsNode(84...90)( - [CallNode(84...90)( - nil, - nil, - (84...85), - (85...86), - ArgumentsNode(86...89)( - [KeywordHashNode(86...89)( - [AssocNode(86...89)( - SymbolNode(86...88)(nil, (86...87), (87...88), "z"), - IntegerNode(88...89)(), - nil - )] - )] - ), - (89...90), - nil, - 0, - "y" - )] - ) - ), - ReturnNode(92...106)( - (92...98), - ArgumentsNode(99...106)( - [CallNode(99...106)( - nil, - nil, - (99...100), - (100...101), - ArgumentsNode(101...105)( - [KeywordHashNode(101...105)( - [AssocNode(101...105)( - CallNode(101...102)( - nil, - nil, - (101...102), - nil, - nil, - nil, - nil, - 2, - "z" - ), - IntegerNode(104...105)(), - (102...104) - )] - )] - ), - (105...106), - nil, - 0, - "y" - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/rhs_asgn.txt b/test/yarp/snapshots/seattlerb/rhs_asgn.txt deleted file mode 100644 index 604a14667b1e6d..00000000000000 --- a/test/yarp/snapshots/seattlerb/rhs_asgn.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...7)( - [:n], - StatementsNode(0...7)( - [MatchRequiredNode(0...7)( - IntegerNode(0...2)(), - LocalVariableTargetNode(6...7)(:n, 0), - (3...5) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/ruby21_numbers.txt b/test/yarp/snapshots/seattlerb/ruby21_numbers.txt deleted file mode 100644 index f250397d152d72..00000000000000 --- a/test/yarp/snapshots/seattlerb/ruby21_numbers.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [ArrayNode(0...13)( - [ImaginaryNode(1...3)(IntegerNode(1...2)()), - RationalNode(5...7)(IntegerNode(5...6)()), - ImaginaryNode(9...12)(RationalNode(9...11)(IntegerNode(9...10)()))], - (0...1), - (12...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_attrasgn.txt b/test/yarp/snapshots/seattlerb/safe_attrasgn.txt deleted file mode 100644 index a48f189f41a122..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_attrasgn.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - ArgumentsNode(7...8)([IntegerNode(7...8)()]), - nil, - nil, - 1, - "b=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_attrasgn_constant.txt b/test/yarp/snapshots/seattlerb/safe_attrasgn_constant.txt deleted file mode 100644 index 8f51d308631869..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_attrasgn_constant.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - ArgumentsNode(7...8)([IntegerNode(7...8)()]), - nil, - nil, - 1, - "B=" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call.txt b/test/yarp/snapshots/seattlerb/safe_call.txt deleted file mode 100644 index d170db0f559f59..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - nil, - 1, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call_after_newline.txt b/test/yarp/snapshots/seattlerb/safe_call_after_newline.txt deleted file mode 100644 index 0f48cd9867ac30..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call_after_newline.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (2...4), - (4...5), - nil, - nil, - nil, - nil, - 1, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call_dot_parens.txt b/test/yarp/snapshots/seattlerb/safe_call_dot_parens.txt deleted file mode 100644 index 5800090fbbb9d5..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call_dot_parens.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [CallNode(0...5)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - nil, - (3...4), - nil, - (4...5), - nil, - 1, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call_newline.txt b/test/yarp/snapshots/seattlerb/safe_call_newline.txt deleted file mode 100644 index d170db0f559f59..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call_newline.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - nil, - 1, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call_operator.txt b/test/yarp/snapshots/seattlerb/safe_call_operator.txt deleted file mode 100644 index 58df15db4ae8e1..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call_operator.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - nil, - 1, - ">" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt b/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt deleted file mode 100644 index 7785c7921ece14..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_call_rhs_newline.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...8)( - [:c], - StatementsNode(0...8)( - [LocalVariableWriteNode(0...8)( - :c, - 0, - (0...1), - CallNode(4...8)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"), - (5...7), - (7...8), - nil, - nil, - nil, - nil, - 1, - "b" - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_calls.txt b/test/yarp/snapshots/seattlerb/safe_calls.txt deleted file mode 100644 index 400667a3544a28..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_calls.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - nil, - 1, - "b" - ), - (4...6), - (6...7), - (7...8), - ArgumentsNode(8...9)([IntegerNode(8...9)()]), - (9...10), - nil, - 1, - "c" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_op_asgn.txt b/test/yarp/snapshots/seattlerb/safe_op_asgn.txt deleted file mode 100644 index e5bc617610354b..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_op_asgn.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallOperatorWriteNode(0...11)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - 1, - "b", - "b=", - :+, - (5...7), - CallNode(8...11)( - nil, - nil, - (8...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "x" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/safe_op_asgn2.txt b/test/yarp/snapshots/seattlerb/safe_op_asgn2.txt deleted file mode 100644 index c1175989aec8bd..00000000000000 --- a/test/yarp/snapshots/seattlerb/safe_op_asgn2.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallOrWriteNode(0...10)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - 1, - "b", - "b=", - (5...8), - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "x") - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/slashy_newlines_within_string.txt b/test/yarp/snapshots/seattlerb/slashy_newlines_within_string.txt deleted file mode 100644 index 1ef9123f4c8f5d..00000000000000 --- a/test/yarp/snapshots/seattlerb/slashy_newlines_within_string.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [CallNode(0...33)( - nil, - nil, - (0...4), - nil, - ArgumentsNode(5...33)( - [StringNode(5...33)( - (5...6), - (6...32), - (32...33), - "hello my dear friend" - )] - ), - nil, - nil, - 0, - "puts" - ), - CallNode(35...40)( - CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 2, "a"), - nil, - (37...38), - nil, - ArgumentsNode(39...40)( - [CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 2, "b")] - ), - nil, - nil, - 0, - "+" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_arg_no_paren.txt b/test/yarp/snapshots/seattlerb/stabby_arg_no_paren.txt deleted file mode 100644 index d999e4ea4729ba..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_arg_no_paren.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [LambdaNode(0...5)( - [:a], - (0...2), - (3...4), - (4...5), - BlockParametersNode(2...3)( - ParametersNode(2...3)( - [RequiredParameterNode(2...3)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - nil, - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt deleted file mode 100644 index fa7b9fe5a4f165..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [LambdaNode(0...23)( - [:b, :c, :d, :e, :f], - (0...2), - (21...22), - (22...23), - BlockParametersNode(2...21)( - ParametersNode(3...20)( - [RequiredParameterNode(3...4)(:b)], - [OptionalParameterNode(6...9)( - :c, - (6...7), - (7...8), - IntegerNode(8...9)() - )], - [RequiredParameterNode(15...16)(:e)], - RestParameterNode(11...13)(:d, (12...13), (11...12)), - [], - nil, - BlockParameterNode(18...20)(:f, (19...20), (18...19)) - ), - [], - (2...3), - (20...21) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_block_iter_call.txt b/test/yarp/snapshots/seattlerb/stabby_block_iter_call.txt deleted file mode 100644 index 719c895b99b89c..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_block_iter_call.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...25)( - [LambdaNode(2...25)( - [], - (2...4), - (8...10), - (22...25), - BlockParametersNode(5...7)(nil, [], (5...6), (6...7)), - StatementsNode(11...21)( - [CallNode(11...21)( - CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (12...13), - (13...14), - nil, - nil, - nil, - BlockNode(15...21)([], nil, nil, (15...17), (18...21)), - 0, - "b" - )] - ) - )] - ), - nil, - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt b/test/yarp/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt deleted file mode 100644 index 14b7a3eb982ed5..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_block_iter_call_no_target_with_arg.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CallNode(0...26)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...26)( - [LambdaNode(2...26)( - [], - (2...4), - (8...10), - (23...26), - BlockParametersNode(5...7)(nil, [], (5...6), (6...7)), - StatementsNode(11...22)( - [CallNode(11...22)( - nil, - nil, - (11...12), - (12...13), - ArgumentsNode(13...14)([IntegerNode(13...14)()]), - (14...15), - BlockNode(16...22)([], nil, nil, (16...18), (19...22)), - 0, - "a" - )] - ) - )] - ), - nil, - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_block_kw.txt b/test/yarp/snapshots/seattlerb/stabby_block_kw.txt deleted file mode 100644 index ffb20333869f54..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_block_kw.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [LambdaNode(0...13)( - [:k], - (0...2), - (10...11), - (12...13), - BlockParametersNode(3...9)( - ParametersNode(4...8)( - [], - [], - [], - nil, - [KeywordParameterNode(4...8)(:k, (4...6), IntegerNode(6...8)())], - nil, - nil - ), - [], - (3...4), - (8...9) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt b/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt deleted file mode 100644 index 3b1ba23e9d01c3..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [LambdaNode(0...11)( - [:k], - (0...2), - (8...9), - (10...11), - BlockParametersNode(3...7)( - ParametersNode(4...6)( - [], - [], - [], - nil, - [KeywordParameterNode(4...6)(:k, (4...6), nil)], - nil, - nil - ), - [], - (3...4), - (6...7) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/stabby_proc_scope.txt b/test/yarp/snapshots/seattlerb/stabby_proc_scope.txt deleted file mode 100644 index d8e06afa0fadec..00000000000000 --- a/test/yarp/snapshots/seattlerb/stabby_proc_scope.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [LambdaNode(0...11)( - [:a, :b], - (0...2), - (9...10), - (10...11), - BlockParametersNode(2...8)( - ParametersNode(3...4)( - [RequiredParameterNode(3...4)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(6...7)(:b)], - (2...3), - (7...8) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_backslashes.txt b/test/yarp/snapshots/seattlerb/str_backslashes.txt deleted file mode 100644 index 8ad69066113f76..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_backslashes.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...204)( - [], - StatementsNode(0...204)( - [CallNode(0...204)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...204)( - [StringNode(2...204)( - (2...3), - (3...203), - (203...204), - "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n" - )] - ), - nil, - nil, - 0, - "x" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_double_double_escaped_newline.txt b/test/yarp/snapshots/seattlerb/str_double_double_escaped_newline.txt deleted file mode 100644 index 2be5ea34e95522..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_double_double_escaped_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...7)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...7)( - [StringNode(2...7)((2...3), (3...6), (6...7), "\\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_double_escaped_newline.txt b/test/yarp/snapshots/seattlerb/str_double_escaped_newline.txt deleted file mode 100644 index 7b724c6b80e167..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_double_escaped_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...6)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...6)( - [StringNode(2...6)((2...3), (3...5), (5...6), "\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_double_newline.txt b/test/yarp/snapshots/seattlerb/str_double_newline.txt deleted file mode 100644 index 6b7a3afb32542c..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_double_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...5)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...5)( - [StringNode(2...5)((2...3), (3...4), (4...5), "\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_evstr.txt b/test/yarp/snapshots/seattlerb/str_evstr.txt deleted file mode 100644 index 18d41a9b6aa79f..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_evstr.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...1), - [StringNode(1...3)(nil, (1...3), nil, "a "), - EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)( - [CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b")] - ), - (6...7) - )], - (7...8) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_evstr_escape.txt b/test/yarp/snapshots/seattlerb/str_evstr_escape.txt deleted file mode 100644 index e95335e227861d..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_evstr_escape.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [InterpolatedStringNode(0...16)( - (0...1), - [StringNode(1...3)(nil, (1...3), nil, "a "), - EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)( - [CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b")] - ), - (6...7) - ), - StringNode(7...15)(nil, (7...15), nil, "½")], - (15...16) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_heredoc_interp.txt b/test/yarp/snapshots/seattlerb/str_heredoc_interp.txt deleted file mode 100644 index 22f5a96755a83f..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_heredoc_interp.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [InterpolatedStringNode(0...4)( - (0...4), - [EmbeddedStatementsNode(5...9)( - (5...7), - StatementsNode(7...8)( - [CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "x")] - ), - (8...9) - ), - StringNode(9...16)(nil, (9...16), nil, "\n" + "blah2\n")], - (16...17) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_interp_ternary_or_label.txt b/test/yarp/snapshots/seattlerb/str_interp_ternary_or_label.txt deleted file mode 100644 index d2ec64657fbd61..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_interp_ternary_or_label.txt +++ /dev/null @@ -1,89 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [InterpolatedStringNode(0...23)( - (0...1), - [EmbeddedStatementsNode(1...22)( - (1...3), - StatementsNode(3...21)( - [IfNode(3...21)( - nil, - CallNode(3...7)( - CallNode(3...4)( - nil, - nil, - (3...4), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (4...5), - (5...7), - nil, - nil, - nil, - nil, - 0, - "b?" - ), - StatementsNode(10...17)( - [CallNode(10...17)( - CallNode(10...14)( - StringNode(10...12)((10...11), (11...11), (11...12), ""), - nil, - (12...13), - nil, - ArgumentsNode(13...14)( - [CallNode(13...14)( - nil, - nil, - (13...14), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - nil, - nil, - 0, - "+" - ), - nil, - (14...15), - nil, - ArgumentsNode(15...17)( - [StringNode(15...17)( - (15...16), - (16...16), - (16...17), - "" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - ElseNode(17...21)( - (17...18), - StatementsNode(19...21)( - [StringNode(19...21)((19...20), (20...20), (20...21), "")] - ), - nil - ), - nil - )] - ), - (21...22) - )], - (22...23) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_lit_concat_bad_encodings.txt b/test/yarp/snapshots/seattlerb/str_lit_concat_bad_encodings.txt deleted file mode 100644 index 350cc6b6b9f3e7..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_lit_concat_bad_encodings.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...131)( - [], - StatementsNode(0...131)( - [StringConcatNode(0...131)( - StringNode(0...62)( - (0...1), - (1...61), - (61...62), - "\xE3Ӌー\x83\xE3\x83コ\xA3\x82\x99" - ), - StringNode(73...131)( - (73...74), - (74...130), - (130...131), - "ンパý;foo@bar.com" - ) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_newline_hash_line_number.txt b/test/yarp/snapshots/seattlerb/str_newline_hash_line_number.txt deleted file mode 100644 index e56d74eed79790..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_newline_hash_line_number.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [StringNode(0...11)( - (0...1), - (1...10), - (10...11), - "\n" + "\n" + "\n" + "\n" + "#" - ), - IntegerNode(12...13)()] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_pct_Q_nested.txt b/test/yarp/snapshots/seattlerb/str_pct_Q_nested.txt deleted file mode 100644 index 613e85a088a0d9..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_pct_Q_nested.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [InterpolatedStringNode(0...26)( - (0...3), - [StringNode(3...11)(nil, (3...11), nil, "before ["), - EmbeddedStatementsNode(11...18)( - (11...13), - StatementsNode(13...17)( - [CallNode(13...17)( - nil, - nil, - (13...17), - nil, - nil, - nil, - nil, - 2, - "nest" - )] - ), - (17...18) - ), - StringNode(18...25)(nil, (18...25), nil, "] after")], - (25...26) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_pct_nested_nested.txt b/test/yarp/snapshots/seattlerb/str_pct_nested_nested.txt deleted file mode 100644 index b615b691cc2e7a..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_pct_nested_nested.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [InterpolatedStringNode(0...20)( - (0...2), - [StringNode(2...5)(nil, (2...5), nil, " { "), - EmbeddedStatementsNode(5...16)( - (5...7), - StatementsNode(8...14)( - [InterpolatedStringNode(8...14)( - (8...9), - [EmbeddedStatementsNode(9...13)( - (9...11), - StatementsNode(11...12)([IntegerNode(11...12)()]), - (12...13) - )], - (13...14) - )] - ), - (15...16) - ), - StringNode(16...19)(nil, (16...19), nil, " } ")], - (19...20) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_pct_q.txt b/test/yarp/snapshots/seattlerb/str_pct_q.txt deleted file mode 100644 index be3f92365cbc9e..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_pct_q.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [StringNode(0...9)((0...3), (3...8), (8...9), "a b c")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_single_double_escaped_newline.txt b/test/yarp/snapshots/seattlerb/str_single_double_escaped_newline.txt deleted file mode 100644 index 2be5ea34e95522..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_single_double_escaped_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...7)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...7)( - [StringNode(2...7)((2...3), (3...6), (6...7), "\\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_single_escaped_newline.txt b/test/yarp/snapshots/seattlerb/str_single_escaped_newline.txt deleted file mode 100644 index d97f1ce0169ef4..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_single_escaped_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...6)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...6)( - [StringNode(2...6)((2...3), (3...5), (5...6), "\\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_single_newline.txt b/test/yarp/snapshots/seattlerb/str_single_newline.txt deleted file mode 100644 index 6b7a3afb32542c..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_single_newline.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...5)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...5)( - [StringNode(2...5)((2...3), (3...4), (4...5), "\n")] - ), - nil, - nil, - 0, - "a" - ), - CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b")] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_str.txt b/test/yarp/snapshots/seattlerb/str_str.txt deleted file mode 100644 index 964ac52f5ff7a6..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_str.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [InterpolatedStringNode(0...10)( - (0...1), - [StringNode(1...3)(nil, (1...3), nil, "a "), - EmbeddedStatementsNode(3...9)( - (3...5), - StatementsNode(5...8)( - [StringNode(5...8)((5...6), (6...7), (7...8), "b")] - ), - (8...9) - )], - (9...10) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/str_str_str.txt b/test/yarp/snapshots/seattlerb/str_str_str.txt deleted file mode 100644 index f7ca61b9503491..00000000000000 --- a/test/yarp/snapshots/seattlerb/str_str_str.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [InterpolatedStringNode(0...12)( - (0...1), - [StringNode(1...3)(nil, (1...3), nil, "a "), - EmbeddedStatementsNode(3...9)( - (3...5), - StatementsNode(5...8)( - [StringNode(5...8)((5...6), (6...7), (7...8), "b")] - ), - (8...9) - ), - StringNode(9...11)(nil, (9...11), nil, " c")], - (11...12) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/super_arg.txt b/test/yarp/snapshots/seattlerb/super_arg.txt deleted file mode 100644 index 3885dbac1450fc..00000000000000 --- a/test/yarp/snapshots/seattlerb/super_arg.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [SuperNode(0...8)( - (0...5), - nil, - ArgumentsNode(6...8)([IntegerNode(6...8)()]), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/symbol_empty.txt b/test/yarp/snapshots/seattlerb/symbol_empty.txt deleted file mode 100644 index f299d176420194..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbol_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)([SymbolNode(0...3)((0...2), (2...2), (2...3), "")]) -) diff --git a/test/yarp/snapshots/seattlerb/symbol_list.txt b/test/yarp/snapshots/seattlerb/symbol_list.txt deleted file mode 100644 index 386ac609dffd7f..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbol_list.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [ArrayNode(0...13)( - [InterpolatedSymbolNode(3...7)( - nil, - [EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)( - [CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "a")] - ), - (6...7) - )], - nil - ), - InterpolatedSymbolNode(8...12)( - nil, - [EmbeddedStatementsNode(8...12)( - (8...10), - StatementsNode(10...11)( - [CallNode(10...11)( - nil, - nil, - (10...11), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (11...12) - )], - nil - )], - (0...3), - (12...13) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/symbols.txt b/test/yarp/snapshots/seattlerb/symbols.txt deleted file mode 100644 index 7cf54611c2b5aa..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbols.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [ArrayNode(0...9)( - [SymbolNode(3...4)(nil, (3...4), nil, "a"), - SymbolNode(5...6)(nil, (5...6), nil, "b"), - SymbolNode(7...8)(nil, (7...8), nil, "c")], - (0...3), - (8...9) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/symbols_empty.txt b/test/yarp/snapshots/seattlerb/symbols_empty.txt deleted file mode 100644 index cad298895b68c9..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbols_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([ArrayNode(0...4)([], (0...3), (3...4))]) -) diff --git a/test/yarp/snapshots/seattlerb/symbols_empty_space.txt b/test/yarp/snapshots/seattlerb/symbols_empty_space.txt deleted file mode 100644 index 6713c4ba71612f..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbols_empty_space.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)([ArrayNode(0...5)([], (0...3), (4...5))]) -) diff --git a/test/yarp/snapshots/seattlerb/symbols_interp.txt b/test/yarp/snapshots/seattlerb/symbols_interp.txt deleted file mode 100644 index 2aa29143120faa..00000000000000 --- a/test/yarp/snapshots/seattlerb/symbols_interp.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [ArrayNode(0...15)( - [SymbolNode(3...4)(nil, (3...4), nil, "a"), - SymbolNode(5...12)(nil, (5...12), nil, "b\#{1+1}"), - SymbolNode(13...14)(nil, (13...14), nil, "c")], - (0...3), - (14...15) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/thingy.txt b/test/yarp/snapshots/seattlerb/thingy.txt deleted file mode 100644 index 929dd9fd96899e..00000000000000 --- a/test/yarp/snapshots/seattlerb/thingy.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...6)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "f"), - (1...2), - nil, - (2...3), - ArgumentsNode(3...5)([IntegerNode(3...5)()]), - (5...6), - nil, - 0, - "call" - ), - CallNode(8...15)( - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "f"), - (9...11), - nil, - (11...12), - ArgumentsNode(12...14)([IntegerNode(12...14)()]), - (14...15), - nil, - 0, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/uminus_float.txt b/test/yarp/snapshots/seattlerb/uminus_float.txt deleted file mode 100644 index fe6bbc4150ff47..00000000000000 --- a/test/yarp/snapshots/seattlerb/uminus_float.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...4)([], StatementsNode(0...4)([FloatNode(0...4)()])) diff --git a/test/yarp/snapshots/seattlerb/unary_minus.txt b/test/yarp/snapshots/seattlerb/unary_minus.txt deleted file mode 100644 index 8f5ed5003ca9d1..00000000000000 --- a/test/yarp/snapshots/seattlerb/unary_minus.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)( - [CallNode(0...2)( - CallNode(1...2)(nil, nil, (1...2), nil, nil, nil, nil, 2, "a"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "-@" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/unary_plus.txt b/test/yarp/snapshots/seattlerb/unary_plus.txt deleted file mode 100644 index 6d74a2b362c4ae..00000000000000 --- a/test/yarp/snapshots/seattlerb/unary_plus.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)( - [CallNode(0...2)( - CallNode(1...2)(nil, nil, (1...2), nil, nil, nil, nil, 2, "a"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "+@" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/unary_plus_on_literal.txt b/test/yarp/snapshots/seattlerb/unary_plus_on_literal.txt deleted file mode 100644 index 08370e47e931f7..00000000000000 --- a/test/yarp/snapshots/seattlerb/unary_plus_on_literal.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)( - [CallNode(0...3)( - SymbolNode(1...3)((1...2), (2...3), nil, "a"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "+@" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/unary_tilde.txt b/test/yarp/snapshots/seattlerb/unary_tilde.txt deleted file mode 100644 index 8ec6e9145f434c..00000000000000 --- a/test/yarp/snapshots/seattlerb/unary_tilde.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)( - [CallNode(0...2)( - CallNode(1...2)(nil, nil, (1...2), nil, nil, nil, nil, 2, "a"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "~" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/utf8_bom.txt b/test/yarp/snapshots/seattlerb/utf8_bom.txt deleted file mode 100644 index 81f12276885164..00000000000000 --- a/test/yarp/snapshots/seattlerb/utf8_bom.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(26...29)( - [], - StatementsNode(26...29)( - [CallNode(26...29)( - nil, - nil, - (26...27), - nil, - ArgumentsNode(28...29)([IntegerNode(28...29)()]), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/when_splat.txt b/test/yarp/snapshots/seattlerb/when_splat.txt deleted file mode 100644 index 75e44cd75df0bf..00000000000000 --- a/test/yarp/snapshots/seattlerb/when_splat.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CaseNode(0...25)( - CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "a"), - [WhenNode(8...15)( - (8...12), - [SplatNode(13...15)( - (13...14), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "b") - )], - nil - )], - nil, - (0...4), - (22...25) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/words_interp.txt b/test/yarp/snapshots/seattlerb/words_interp.txt deleted file mode 100644 index 982de5f8069958..00000000000000 --- a/test/yarp/snapshots/seattlerb/words_interp.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [ArrayNode(0...9)( - [InterpolatedStringNode(3...8)( - nil, - [EmbeddedStatementsNode(3...7)( - (3...5), - StatementsNode(5...6)([IntegerNode(5...6)()]), - (6...7) - ), - StringNode(7...8)(nil, (7...8), nil, "b")], - nil - )], - (0...3), - (8...9) - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/yield_arg.txt b/test/yarp/snapshots/seattlerb/yield_arg.txt deleted file mode 100644 index 8fa353561709d4..00000000000000 --- a/test/yarp/snapshots/seattlerb/yield_arg.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [YieldNode(0...8)( - (0...5), - nil, - ArgumentsNode(6...8)([IntegerNode(6...8)()]), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/yield_call_assocs.txt b/test/yarp/snapshots/seattlerb/yield_call_assocs.txt deleted file mode 100644 index 820afa6c08d37f..00000000000000 --- a/test/yarp/snapshots/seattlerb/yield_call_assocs.txt +++ /dev/null @@ -1,154 +0,0 @@ -ProgramNode(0...100)( - [], - StatementsNode(0...100)( - [YieldNode(0...16)( - (0...5), - nil, - ArgumentsNode(6...16)( - [IntegerNode(6...7)(), - KeywordHashNode(9...16)( - [AssocNode(9...16)( - SymbolNode(9...11)((9...10), (10...11), nil, "z"), - IntegerNode(15...16)(), - (12...14) - )] - )] - ), - nil - ), - YieldNode(18...43)( - (18...23), - nil, - ArgumentsNode(24...43)( - [IntegerNode(24...25)(), - KeywordHashNode(27...43)( - [AssocNode(27...34)( - SymbolNode(27...29)((27...28), (28...29), nil, "z"), - IntegerNode(33...34)(), - (30...32) - ), - AssocNode(36...43)( - SymbolNode(36...38)((36...37), (37...38), nil, "w"), - IntegerNode(42...43)(), - (39...41) - )] - )] - ), - nil - ), - YieldNode(45...58)( - (45...50), - nil, - ArgumentsNode(51...58)( - [CallNode(51...58)( - nil, - nil, - (51...52), - nil, - ArgumentsNode(53...58)( - [KeywordHashNode(53...58)( - [AssocNode(53...58)( - SymbolNode(53...55)((53...54), (54...55), nil, "z"), - IntegerNode(57...58)(), - (55...57) - )] - )] - ), - nil, - nil, - 0, - "y" - )] - ), - nil - ), - YieldNode(60...71)( - (60...65), - nil, - ArgumentsNode(66...71)( - [CallNode(66...71)( - nil, - nil, - (66...67), - nil, - ArgumentsNode(68...71)( - [KeywordHashNode(68...71)( - [AssocNode(68...71)( - SymbolNode(68...70)(nil, (68...69), (69...70), "z"), - IntegerNode(70...71)(), - nil - )] - )] - ), - nil, - nil, - 0, - "y" - )] - ), - nil - ), - YieldNode(73...85)( - (73...78), - nil, - ArgumentsNode(79...85)( - [CallNode(79...85)( - nil, - nil, - (79...80), - (80...81), - ArgumentsNode(81...84)( - [KeywordHashNode(81...84)( - [AssocNode(81...84)( - SymbolNode(81...83)(nil, (81...82), (82...83), "z"), - IntegerNode(83...84)(), - nil - )] - )] - ), - (84...85), - nil, - 0, - "y" - )] - ), - nil - ), - YieldNode(87...100)( - (87...92), - nil, - ArgumentsNode(93...100)( - [CallNode(93...100)( - nil, - nil, - (93...94), - (94...95), - ArgumentsNode(95...99)( - [KeywordHashNode(95...99)( - [AssocNode(95...99)( - CallNode(95...96)( - nil, - nil, - (95...96), - nil, - nil, - nil, - nil, - 2, - "z" - ), - IntegerNode(98...99)(), - (96...98) - )] - )] - ), - (99...100), - nil, - 0, - "y" - )] - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/seattlerb/yield_empty_parens.txt b/test/yarp/snapshots/seattlerb/yield_empty_parens.txt deleted file mode 100644 index 14871f50e77680..00000000000000 --- a/test/yarp/snapshots/seattlerb/yield_empty_parens.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)([YieldNode(0...7)((0...5), (5...6), nil, (6...7))]) -) diff --git a/test/yarp/snapshots/single_quote_heredocs.txt b/test/yarp/snapshots/single_quote_heredocs.txt deleted file mode 100644 index 13e0f12fac5dc0..00000000000000 --- a/test/yarp/snapshots/single_quote_heredocs.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...8), - [StringNode(9...44)( - nil, - (9...44), - nil, - " cd L:\\Work\\MG3710IQPro\\Develop\n" - )], - (44...48) - )] - ) -) diff --git a/test/yarp/snapshots/spanning_heredoc.txt b/test/yarp/snapshots/spanning_heredoc.txt deleted file mode 100644 index 301c70adf2a67c..00000000000000 --- a/test/yarp/snapshots/spanning_heredoc.txt +++ /dev/null @@ -1,215 +0,0 @@ -ProgramNode(164...964)( - [], - StatementsNode(164...964)( - [CallNode(164...192)( - nil, - nil, - (164...166), - nil, - ArgumentsNode(167...192)( - [CallNode(167...192)( - InterpolatedStringNode(167...171)( - (167...171), - [StringNode(181...183)(nil, (181...183), nil, "a\n")], - (183...185) - ), - (171...172), - (172...176), - (176...177), - ArgumentsNode(177...191)( - [InterpolatedRegularExpressionNode(177...187)( - (177...178), - [StringNode(178...181)(nil, (178...181), nil, "b"), - StringNode(185...186)(nil, (185...186), nil, "b")], - (186...187), - 0 - ), - StringNode(189...191)( - (189...190), - (190...190), - (190...191), - "" - )] - ), - (191...192), - nil, - 0, - "gsub" - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(276...295)( - nil, - nil, - (276...278), - nil, - ArgumentsNode(279...295)( - [InterpolatedStringNode(279...283)( - (279...283), - [StringNode(289...291)(nil, (289...291), nil, "c\n")], - (291...293) - ), - InterpolatedStringNode(285...295)( - (285...286), - [StringNode(286...289)(nil, (286...289), nil, "d"), - StringNode(293...294)(nil, (293...294), nil, "d")], - (294...295) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(322...343)( - nil, - nil, - (322...324), - nil, - ArgumentsNode(325...343)( - [InterpolatedStringNode(325...329)( - (325...329), - [StringNode(337...339)(nil, (337...339), nil, "e\n")], - (339...341) - ), - InterpolatedStringNode(331...343)( - (331...334), - [StringNode(334...337)(nil, (334...337), nil, "f\\\n"), - StringNode(341...342)(nil, (341...342), nil, "f")], - (342...343) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(427...448)( - nil, - nil, - (427...429), - nil, - ArgumentsNode(430...448)( - [InterpolatedStringNode(430...434)( - (430...434), - [StringNode(442...444)(nil, (442...444), nil, "g\n")], - (444...446) - ), - InterpolatedStringNode(436...448)( - (436...439), - [StringNode(439...442)(nil, (439...442), nil, "h"), - StringNode(446...447)(nil, (446...447), nil, "h")], - (447...448) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(520...541)( - nil, - nil, - (520...522), - nil, - ArgumentsNode(523...541)( - [InterpolatedStringNode(523...527)( - (523...527), - [StringNode(535...537)(nil, (535...537), nil, "i\n")], - (537...539) - ), - ArrayNode(529...541)( - [StringNode(532...535)(nil, (532...535), nil, "j\\\n"), - StringNode(539...540)(nil, (539...540), nil, "j")], - (529...532), - (540...541) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(688...709)( - nil, - nil, - (688...690), - nil, - ArgumentsNode(691...709)( - [InterpolatedStringNode(691...695)( - (691...695), - [StringNode(703...705)(nil, (703...705), nil, "k\n")], - (705...707) - ), - ArrayNode(697...709)( - [InterpolatedStringNode(700...708)( - nil, - [StringNode(700...703)(nil, (700...703), nil, "l"), - StringNode(707...708)(nil, (707...708), nil, "l")], - nil - )], - (697...700), - (708...709) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(781...802)( - nil, - nil, - (781...783), - nil, - ArgumentsNode(784...802)( - [InterpolatedStringNode(784...788)( - (784...788), - [StringNode(796...798)(nil, (796...798), nil, "m\n")], - (798...800) - ), - ArrayNode(790...802)( - [SymbolNode(793...796)(nil, (793...796), nil, "n\\\n"), - SymbolNode(800...801)(nil, (800...801), nil, "n")], - (790...793), - (801...802) - )] - ), - nil, - nil, - 0, - "pp" - ), - CallNode(943...964)( - nil, - nil, - (943...945), - nil, - ArgumentsNode(946...964)( - [InterpolatedStringNode(946...950)( - (946...950), - [StringNode(958...960)(nil, (958...960), nil, "o\n")], - (960...962) - ), - ArrayNode(952...964)( - [InterpolatedSymbolNode(955...963)( - nil, - [SymbolNode(955...958)(nil, (955...958), nil, "p"), - StringNode(962...963)(nil, (962...963), nil, "p")], - nil - )], - (952...955), - (963...964) - )] - ), - nil, - nil, - 0, - "pp" - )] - ) -) diff --git a/test/yarp/snapshots/strings.txt b/test/yarp/snapshots/strings.txt deleted file mode 100644 index ca98151c140183..00000000000000 --- a/test/yarp/snapshots/strings.txt +++ /dev/null @@ -1,201 +0,0 @@ -ProgramNode(0...498)( - [], - StatementsNode(0...498)( - [StringNode(0...6)((0...2), (2...5), (5...6), "abc"), - StringNode(8...14)((8...10), (10...13), (13...14), "abc"), - StringNode(16...22)((16...18), (18...21), (21...22), "abc"), - StringNode(24...30)((24...26), (26...29), (29...30), "abc"), - StringNode(32...38)((32...34), (34...37), (37...38), "abc"), - StringNode(40...46)((40...42), (42...45), (45...46), "abc"), - StringNode(48...54)((48...50), (50...53), (53...54), "abc"), - StringNode(56...62)((56...58), (58...61), (61...62), "abc"), - StringNode(64...70)((64...66), (66...69), (69...70), "abc"), - StringNode(72...78)((72...74), (74...77), (77...78), "abc"), - StringNode(80...86)((80...82), (82...85), (85...86), "abc"), - StringNode(88...94)((88...90), (90...93), (93...94), "abc"), - ArrayNode(96...104)([], (96...99), (103...104)), - StringNode(106...112)((106...108), (108...111), (111...112), "abc"), - StringNode(114...120)((114...116), (116...119), (119...120), "abc"), - InterpolatedStringNode(122...130)( - (122...123), - [EmbeddedVariableNode(123...129)( - (123...124), - ClassVariableReadNode(124...129)(:@@foo) - )], - (129...130) - ), - StringNode(132...138)((132...134), (134...137), (137...138), "abc"), - InterpolatedStringNode(140...157)( - (140...142), - [StringNode(142...146)(nil, (142...146), nil, "aaa "), - EmbeddedStatementsNode(146...152)( - (146...148), - StatementsNode(148...151)( - [CallNode(148...151)( - nil, - nil, - (148...151), - nil, - nil, - nil, - nil, - 2, - "bbb" - )] - ), - (151...152) - ), - StringNode(152...156)(nil, (152...156), nil, " ccc")], - (156...157) - ), - StringNode(159...167)((159...161), (161...166), (166...167), "foo[]"), - CallNode(169...184)( - StringNode(169...174)((169...170), (170...173), (173...174), "foo"), - nil, - (175...176), - nil, - ArgumentsNode(179...184)( - [StringNode(179...184)((179...180), (180...183), (183...184), "bar")] - ), - nil, - nil, - 0, - "+" - ), - StringNode(186...193)((186...189), (189...192), (192...193), "abc"), - SymbolNode(195...202)((195...198), (198...201), (201...202), "abc"), - StringNode(204...210)((204...206), (206...209), (209...210), "abc"), - StringNode(212...214)((212...213), (213...213), (213...214), ""), - StringNode(216...221)((216...217), (217...220), (220...221), "abc"), - StringNode(223...230)((223...224), (224...229), (229...230), "\#@---"), - InterpolatedStringNode(232...248)( - (232...233), - [StringNode(233...237)(nil, (233...237), nil, "aaa "), - EmbeddedStatementsNode(237...243)( - (237...239), - StatementsNode(239...242)( - [CallNode(239...242)( - nil, - nil, - (239...242), - nil, - nil, - nil, - nil, - 2, - "bbb" - )] - ), - (242...243) - ), - StringNode(243...247)(nil, (243...247), nil, " ccc")], - (247...248) - ), - StringNode(250...255)((250...251), (251...254), (254...255), "abc"), - ArrayNode(257...266)( - [StringNode(260...261)(nil, (260...261), nil, "a"), - StringNode(262...263)(nil, (262...263), nil, "b"), - StringNode(264...265)(nil, (264...265), nil, "c")], - (257...260), - (265...266) - ), - ArrayNode(268...285)( - [StringNode(271...274)(nil, (271...274), nil, "a[]"), - StringNode(275...280)(nil, (275...280), nil, "b[[]]"), - StringNode(281...284)(nil, (281...284), nil, "c[]")], - (268...271), - (284...285) - ), - ArrayNode(287...305)( - [StringNode(290...298)(nil, (290...298), nil, "foo\\ bar"), - StringNode(299...304)(nil, (299...304), nil, "\\\#{1}")], - (287...290), - (304...305) - ), - ArrayNode(307...323)( - [StringNode(310...318)(nil, (310...318), nil, "foo\\ bar"), - StringNode(319...322)(nil, (319...322), nil, "baz")], - (307...310), - (322...323) - ), - ArrayNode(325...339)( - [StringNode(328...329)(nil, (328...329), nil, "a"), - InterpolatedStringNode(330...336)( - nil, - [StringNode(330...331)(nil, (330...331), nil, "b"), - EmbeddedStatementsNode(331...335)( - (331...333), - StatementsNode(333...334)( - [CallNode(333...334)( - nil, - nil, - (333...334), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (334...335) - ), - StringNode(335...336)(nil, (335...336), nil, "d")], - nil - ), - StringNode(337...338)(nil, (337...338), nil, "e")], - (325...328), - (338...339) - ), - ArrayNode(341...350)( - [StringNode(344...345)(nil, (344...345), nil, "a"), - StringNode(346...347)(nil, (346...347), nil, "b"), - StringNode(348...349)(nil, (348...349), nil, "c")], - (341...344), - (349...350) - ), - ArrayNode(352...369)( - [StringNode(358...359)(nil, (358...359), nil, "a"), - StringNode(362...363)(nil, (362...363), nil, "b"), - StringNode(366...367)(nil, (366...367), nil, "c")], - (352...355), - (368...369) - ), - StringNode(371...386)( - (371...372), - (372...385), - (385...386), - "' foo ' bar" - ), - StringNode(388...403)( - (388...389), - (389...402), - (402...403), - "\\ foo \\ bar" - ), - InterpolatedStringNode(405...412)( - (405...406), - [EmbeddedVariableNode(406...411)( - (406...407), - GlobalVariableReadNode(407...411)(:$foo) - )], - (411...412) - ), - InterpolatedStringNode(414...421)( - (414...415), - [EmbeddedVariableNode(415...420)( - (415...416), - InstanceVariableReadNode(416...420)(:@foo) - )], - (420...421) - ), - StringNode(423...438)((423...424), (424...437), (437...438), "\a # a"), - StringNode(440...453)((440...441), (441...452), (452...453), "\a # a"), - StringNode(455...461)((455...457), (457...460), (460...461), "abc"), - StringNode(463...469)((463...465), (465...468), (468...469), "abc"), - StringNode(471...477)((471...473), (473...476), (476...477), "abc"), - StringNode(479...485)((479...481), (481...484), (484...485), "abc"), - StringNode(487...489)((487...488), (488...489), nil, "a"), - StringNode(491...498)((491...494), (494...497), (497...498), "abc")] - ) -) diff --git a/test/yarp/snapshots/super.txt b/test/yarp/snapshots/super.txt deleted file mode 100644 index e9d32d14bdc6bc..00000000000000 --- a/test/yarp/snapshots/super.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [ForwardingSuperNode(0...5)(nil), - SuperNode(7...14)((7...12), (12...13), nil, (13...14), nil), - SuperNode(16...24)( - (16...21), - (21...22), - ArgumentsNode(22...23)([IntegerNode(22...23)()]), - (23...24), - nil - ), - SuperNode(26...40)( - (26...31), - (31...32), - ArgumentsNode(32...39)( - [IntegerNode(32...33)(), - IntegerNode(35...36)(), - IntegerNode(38...39)()] - ), - (39...40), - nil - )] - ) -) diff --git a/test/yarp/snapshots/symbols.txt b/test/yarp/snapshots/symbols.txt deleted file mode 100644 index f53a208bcec752..00000000000000 --- a/test/yarp/snapshots/symbols.txt +++ /dev/null @@ -1,147 +0,0 @@ -ProgramNode(0...345)( - [], - StatementsNode(0...345)( - [SymbolNode(0...6)((0...2), (2...5), (5...6), "abc"), - InterpolatedSymbolNode(8...17)( - (8...10), - [EmbeddedStatementsNode(10...16)( - (10...12), - StatementsNode(12...15)( - [CallNode(12...15)( - nil, - nil, - (12...15), - nil, - nil, - nil, - nil, - 2, - "var" - )] - ), - (15...16) - )], - (16...17) - ), - InterpolatedSymbolNode(19...29)( - (19...21), - [StringNode(21...24)(nil, (21...24), nil, "abc"), - EmbeddedStatementsNode(24...28)( - (24...26), - StatementsNode(26...27)([IntegerNode(26...27)()]), - (27...28) - )], - (28...29) - ), - ArrayNode(31...51)( - [SymbolNode(32...35)((32...33), (33...35), nil, "Υ"), - SymbolNode(37...40)((37...38), (38...40), nil, "ά"), - SymbolNode(42...45)((42...43), (43...45), nil, "ŗ"), - SymbolNode(47...50)((47...48), (48...50), nil, "ρ")], - (31...32), - (50...51) - ), - SymbolNode(53...56)((53...54), (54...56), nil, "-@"), - SymbolNode(58...60)((58...59), (59...60), nil, "-"), - SymbolNode(62...64)((62...63), (63...64), nil, "%"), - SymbolNode(66...68)((66...67), (67...68), nil, "|"), - SymbolNode(70...73)((70...71), (71...73), nil, "+@"), - SymbolNode(75...77)((75...76), (76...77), nil, "+"), - SymbolNode(79...81)((79...80), (80...81), nil, "/"), - SymbolNode(83...86)((83...84), (84...86), nil, "**"), - SymbolNode(88...90)((88...89), (89...90), nil, "*"), - SymbolNode(92...95)((92...93), (93...95), nil, "~@"), - ArrayNode(97...113)( - [IntegerNode(98...99)(), - FloatNode(101...104)(), - RationalNode(106...108)(IntegerNode(106...107)()), - ImaginaryNode(110...112)(IntegerNode(110...111)())], - (97...98), - (112...113) - ), - SymbolNode(115...117)((115...116), (116...117), nil, "~"), - SymbolNode(119...121)((119...120), (120...121), nil, "a"), - ArrayNode(123...132)( - [SymbolNode(126...127)(nil, (126...127), nil, "a"), - SymbolNode(128...129)(nil, (128...129), nil, "b"), - SymbolNode(130...131)(nil, (130...131), nil, "c")], - (123...126), - (131...132) - ), - ArrayNode(134...158)( - [SymbolNode(137...138)(nil, (137...138), nil, "a"), - SymbolNode(139...144)(nil, (139...144), nil, "b\#{1}"), - SymbolNode(145...150)(nil, (145...150), nil, "\#{2}c"), - SymbolNode(151...157)(nil, (151...157), nil, "d\#{3}f")], - (134...137), - (157...158) - ), - ArrayNode(160...184)( - [SymbolNode(163...164)(nil, (163...164), nil, "a"), - InterpolatedSymbolNode(165...170)( - nil, - [StringNode(165...166)(nil, (165...166), nil, "b"), - EmbeddedStatementsNode(166...170)( - (166...168), - StatementsNode(168...169)([IntegerNode(168...169)()]), - (169...170) - )], - nil - ), - InterpolatedSymbolNode(171...176)( - nil, - [EmbeddedStatementsNode(171...175)( - (171...173), - StatementsNode(173...174)([IntegerNode(173...174)()]), - (174...175) - ), - StringNode(175...176)(nil, (175...176), nil, "c")], - nil - ), - InterpolatedSymbolNode(177...183)( - nil, - [StringNode(177...178)(nil, (177...178), nil, "d"), - EmbeddedStatementsNode(178...182)( - (178...180), - StatementsNode(180...181)([IntegerNode(180...181)()]), - (181...182) - ), - StringNode(182...183)(nil, (182...183), nil, "f")], - nil - )], - (160...163), - (183...184) - ), - SymbolNode(186...190)((186...187), (187...190), nil, "@@a"), - SymbolNode(192...197)((192...193), (193...197), nil, "👍"), - ArrayNode(199...206)( - [SymbolNode(202...205)(nil, (202...205), nil, "a\\b")], - (199...202), - (205...206) - ), - SymbolNode(208...211)((208...209), (209...211), nil, "$a"), - SymbolNode(213...216)((213...214), (214...216), nil, "@a"), - SymbolNode(218...221)((218...219), (219...221), nil, "do"), - SymbolNode(223...225)((223...224), (224...225), nil, "&"), - SymbolNode(227...229)((227...228), (228...229), nil, "`"), - SymbolNode(231...234)((231...232), (232...234), nil, "!@"), - SymbolNode(236...239)((236...237), (237...239), nil, "!~"), - SymbolNode(241...243)((241...242), (242...243), nil, "!"), - SymbolNode(245...248)((245...246), (246...248), nil, "[]"), - SymbolNode(250...254)((250...251), (251...254), nil, "[]="), - SymbolNode(256...258)((256...257), (257...258), nil, "^"), - SymbolNode(260...263)((260...261), (261...263), nil, "=="), - SymbolNode(265...269)((265...266), (266...269), nil, "==="), - SymbolNode(271...274)((271...272), (272...274), nil, "=~"), - SymbolNode(276...279)((276...277), (277...279), nil, ">="), - SymbolNode(281...284)((281...282), (282...284), nil, ">>"), - SymbolNode(286...288)((286...287), (287...288), nil, ">"), - SymbolNode(290...294)((290...291), (291...294), nil, "<=>"), - SymbolNode(296...299)((296...297), (297...299), nil, "<="), - SymbolNode(301...304)((301...302), (302...304), nil, "<<"), - SymbolNode(306...308)((306...307), (307...308), nil, "<"), - SymbolNode(310...319)((310...311), (311...319), nil, "__LINE__"), - SymbolNode(321...330)((321...322), (322...330), nil, "__FILE__"), - SymbolNode(332...345)((332...333), (333...345), nil, "__ENCODING__")] - ) -) diff --git a/test/yarp/snapshots/ternary_operator.txt b/test/yarp/snapshots/ternary_operator.txt deleted file mode 100644 index 9751d53a317c21..00000000000000 --- a/test/yarp/snapshots/ternary_operator.txt +++ /dev/null @@ -1,163 +0,0 @@ -ProgramNode(0...131)( - [:_a], - StatementsNode(0...131)( - [IfNode(0...9)( - nil, - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - StatementsNode(4...5)( - [CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b")] - ), - ElseNode(6...9)( - (6...7), - StatementsNode(8...9)( - [CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c")] - ), - nil - ), - nil - ), - IfNode(11...38)( - nil, - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"), - StatementsNode(15...25)( - [DefinedNode(15...25)( - nil, - CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "b"), - nil, - (15...23) - )] - ), - ElseNode(26...38)( - (26...27), - StatementsNode(28...38)( - [DefinedNode(28...38)( - nil, - CallNode(37...38)( - nil, - nil, - (37...38), - nil, - nil, - nil, - nil, - 2, - "c" - ), - nil, - (28...36) - )] - ), - nil - ), - nil - ), - IfNode(40...55)( - nil, - CallNode(40...46)(nil, nil, (40...46), nil, nil, nil, nil, 0, "empty?"), - StatementsNode(47...51)([TrueNode(47...51)()]), - ElseNode(51...55)( - (51...52), - StatementsNode(52...55)([NilNode(52...55)()]), - nil - ), - nil - ), - IfNode(57...73)( - nil, - CallNode(57...63)(nil, nil, (57...63), nil, nil, nil, nil, 0, "empty?"), - StatementsNode(64...69)([FalseNode(64...69)()]), - ElseNode(69...73)( - (69...70), - StatementsNode(70...73)([NilNode(70...73)()]), - nil - ), - nil - ), - IfNode(75...89)( - nil, - CallNode(75...81)(nil, nil, (75...81), nil, nil, nil, nil, 0, "empty?"), - StatementsNode(82...85)([NilNode(82...85)()]), - ElseNode(85...89)( - (85...86), - StatementsNode(86...89)([NilNode(86...89)()]), - nil - ), - nil - ), - IfNode(91...101)( - nil, - CallNode(91...93)(nil, nil, (91...93), nil, nil, nil, nil, 0, "a?"), - StatementsNode(94...97)([NilNode(94...97)()]), - ElseNode(97...101)( - (97...98), - StatementsNode(98...101)([NilNode(98...101)()]), - nil - ), - nil - ), - IfNode(103...117)( - nil, - CallNode(103...104)(nil, nil, (103...104), nil, nil, nil, nil, 2, "a"), - StatementsNode(106...110)( - [CallNode(106...110)( - nil, - nil, - (106...110), - nil, - nil, - nil, - nil, - 2, - "var1" - )] - ), - ElseNode(111...117)( - (111...112), - StatementsNode(113...117)( - [CallNode(113...117)( - nil, - nil, - (113...117), - nil, - nil, - nil, - nil, - 2, - "var2" - )] - ), - nil - ), - nil - ), - IfNode(119...131)( - nil, - CallNode(119...123)( - nil, - nil, - (119...123), - nil, - nil, - nil, - nil, - 0, - "nil?" - ), - StatementsNode(124...129)( - [LocalVariableWriteNode(124...129)( - :_a, - 0, - (124...126), - IntegerNode(128...129)(), - (127...128) - )] - ), - ElseNode(129...131)( - (129...130), - StatementsNode(130...131)([IntegerNode(130...131)()]), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/tilde_heredocs.txt b/test/yarp/snapshots/tilde_heredocs.txt deleted file mode 100644 index 864ea645b3de30..00000000000000 --- a/test/yarp/snapshots/tilde_heredocs.txt +++ /dev/null @@ -1,134 +0,0 @@ -ProgramNode(0...372)( - [], - StatementsNode(0...372)( - [InterpolatedStringNode(0...6)( - (0...6), - [StringNode(7...11)(nil, (7...11), nil, "a\n")], - (11...15) - ), - InterpolatedStringNode(16...22)( - (16...22), - [StringNode(23...34)(nil, (23...34), nil, "\ta\n" + "b\n" + "\t\tc\n")], - (34...38) - ), - InterpolatedStringNode(39...45)( - (39...45), - [EmbeddedStatementsNode(48...52)( - (48...50), - StatementsNode(50...51)([IntegerNode(50...51)()]), - (51...52) - ), - StringNode(52...55)(nil, (52...55), nil, " a\n")], - (55...59) - ), - InterpolatedStringNode(60...66)( - (60...66), - [StringNode(67...71)(nil, (67...71), nil, "a "), - EmbeddedStatementsNode(71...75)( - (71...73), - StatementsNode(73...74)([IntegerNode(73...74)()]), - (74...75) - ), - StringNode(75...76)(nil, (75...76), nil, "\n")], - (76...80) - ), - InterpolatedStringNode(81...87)( - (81...87), - [StringNode(88...93)(nil, (88...93), nil, " a\n"), - EmbeddedStatementsNode(93...97)( - (93...95), - StatementsNode(95...96)([IntegerNode(95...96)()]), - (96...97) - ), - StringNode(97...98)(nil, (97...98), nil, "\n")], - (98...102) - ), - InterpolatedStringNode(103...109)( - (103...109), - [StringNode(110...116)(nil, (110...116), nil, "a\n"), - EmbeddedStatementsNode(116...120)( - (116...118), - StatementsNode(118...119)([IntegerNode(118...119)()]), - (119...120) - ), - StringNode(120...121)(nil, (120...121), nil, "\n")], - (121...125) - ), - InterpolatedStringNode(126...132)( - (126...132), - [StringNode(133...141)(nil, (133...141), nil, "a\n" + "b\n")], - (141...145) - ), - InterpolatedStringNode(146...152)( - (146...152), - [StringNode(153...162)(nil, (153...162), nil, "a\n" + " b\n")], - (162...166) - ), - InterpolatedStringNode(167...173)( - (167...173), - [StringNode(174...183)(nil, (174...183), nil, "\ta\n" + "b\n")], - (183...187) - ), - InterpolatedStringNode(188...196)( - (188...196), - [StringNode(197...206)(nil, (197...206), nil, "a \#{1}\n")], - (206...210) - ), - InterpolatedStringNode(211...217)( - (211...217), - [StringNode(218...225)(nil, (218...225), nil, "a\n" + " b\n")], - (225...229) - ), - InterpolatedStringNode(230...236)( - (230...236), - [StringNode(237...244)(nil, (237...244), nil, " a\n" + "b\n")], - (244...248) - ), - InterpolatedStringNode(249...255)( - (249...255), - [StringNode(256...271)(nil, (256...271), nil, "a\n" + "b\n")], - (271...275) - ), - InterpolatedStringNode(276...282)( - (276...282), - [StringNode(283...292)(nil, (283...292), nil, "a\n" + "\n" + "b\n")], - (292...296) - ), - InterpolatedStringNode(297...303)( - (297...303), - [StringNode(304...313)(nil, (304...313), nil, "a\n" + "\n" + "b\n")], - (313...317) - ), - InterpolatedStringNode(318...324)( - (318...324), - [StringNode(325...336)( - nil, - (325...336), - nil, - "a\n" + "\n" + "\n" + "\n" + "b\n" - )], - (336...340) - ), - InterpolatedStringNode(341...347)( - (341...347), - [StringNode(348...351)(nil, (348...351), nil, "\n"), - EmbeddedStatementsNode(351...355)( - (351...353), - StatementsNode(353...354)([IntegerNode(353...354)()]), - (354...355) - ), - StringNode(355...357)(nil, (355...357), nil, "a\n")], - (357...365) - ), - InterpolatedStringNode(366...372)( - (366...372), - [EmbeddedStatementsNode(375...379)( - (375...377), - StatementsNode(377...378)([IntegerNode(377...378)()]), - (378...379) - ), - StringNode(379...383)(nil, (379...383), nil, "\n" + "\tb\n")], - (383...387) - )] - ) -) diff --git a/test/yarp/snapshots/undef.txt b/test/yarp/snapshots/undef.txt deleted file mode 100644 index d3173a3f1c7be7..00000000000000 --- a/test/yarp/snapshots/undef.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...116)( - [], - StatementsNode(0...116)( - [UndefNode(0...7)([SymbolNode(6...7)(nil, (6...7), nil, "a")], (0...5)), - UndefNode(9...19)( - [SymbolNode(15...16)(nil, (15...16), nil, "a"), - SymbolNode(18...19)(nil, (18...19), nil, "b")], - (9...14) - ), - UndefNode(21...29)( - [SymbolNode(27...29)(nil, (27...29), nil, "if")], - (21...26) - ), - UndefNode(31...40)( - [SymbolNode(37...40)(nil, (37...40), nil, "<=>")], - (31...36) - ), - UndefNode(42...50)( - [SymbolNode(48...50)((48...49), (49...50), nil, "a")], - (42...47) - ), - UndefNode(52...68)( - [SymbolNode(58...60)((58...59), (59...60), nil, "a"), - SymbolNode(62...64)((62...63), (63...64), nil, "b"), - SymbolNode(66...68)((66...67), (67...68), nil, "c")], - (52...57) - ), - UndefNode(70...82)( - [SymbolNode(76...82)((76...78), (78...81), (81...82), "abc")], - (70...75) - ), - UndefNode(84...100)( - [InterpolatedSymbolNode(90...100)( - (90...92), - [StringNode(92...95)(nil, (92...95), nil, "abc"), - EmbeddedStatementsNode(95...99)( - (95...97), - StatementsNode(97...98)([IntegerNode(97...98)()]), - (98...99) - )], - (99...100) - )], - (84...89) - ), - UndefNode(102...116)( - [SymbolNode(108...116)(nil, (108...116), nil, "Constant")], - (102...107) - )] - ) -) diff --git a/test/yarp/snapshots/unescaping.txt b/test/yarp/snapshots/unescaping.txt deleted file mode 100644 index 17387dbc6cdf7c..00000000000000 --- a/test/yarp/snapshots/unescaping.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [ArrayNode(0...10)( - [StringNode(1...9)((1...2), (2...8), (8...9), "\u0003{1}")], - (0...1), - (9...10) - ), - RegularExpressionNode(12...20)( - (12...13), - (13...19), - (19...20), - "\u0003{1}", - 0 - ), - StringNode(22...30)((22...23), (23...29), (29...30), "\u0003{1}"), - InterpolatedStringNode(32...39)( - (32...39), - [StringNode(40...50)(nil, (40...50), nil, "\u0003{1}\n")], - (50...55) - )] - ) -) diff --git a/test/yarp/snapshots/unless.txt b/test/yarp/snapshots/unless.txt deleted file mode 100644 index 66d61a7307380d..00000000000000 --- a/test/yarp/snapshots/unless.txt +++ /dev/null @@ -1,83 +0,0 @@ -ProgramNode(0...141)( - [], - StatementsNode(0...141)( - [UnlessNode(0...19)( - (0...6), - TrueNode(7...11)(), - StatementsNode(13...14)([IntegerNode(13...14)()]), - nil, - (16...19) - ), - UnlessNode(21...45)( - (21...27), - TrueNode(28...32)(), - StatementsNode(33...34)([IntegerNode(33...34)()]), - ElseNode(35...45)( - (35...39), - StatementsNode(40...41)([IntegerNode(40...41)()]), - (42...45) - ), - (42...45) - ), - UnlessNode(47...60)( - (49...55), - TrueNode(56...60)(), - StatementsNode(47...48)([IntegerNode(47...48)()]), - nil, - nil - ), - UnlessNode(62...79)( - (68...74), - TrueNode(75...79)(), - StatementsNode(62...67)([BreakNode(62...67)(nil, (62...67))]), - nil, - nil - ), - UnlessNode(81...97)( - (86...92), - TrueNode(93...97)(), - StatementsNode(81...85)([NextNode(81...85)(nil, (81...85))]), - nil, - nil - ), - UnlessNode(99...117)( - (106...112), - TrueNode(113...117)(), - StatementsNode(99...105)([ReturnNode(99...105)((99...105), nil)]), - nil, - nil - ), - UnlessNode(119...141)( - (130...136), - CallNode(137...141)( - nil, - nil, - (137...141), - nil, - nil, - nil, - nil, - 0, - "bar?" - ), - StatementsNode(119...129)( - [CallNode(119...129)( - nil, - nil, - (119...122), - nil, - ArgumentsNode(123...129)( - [SymbolNode(123...125)((123...124), (124...125), nil, "a"), - SymbolNode(127...129)((127...128), (128...129), nil, "b")] - ), - nil, - nil, - 0, - "foo" - )] - ), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/alias.txt b/test/yarp/snapshots/unparser/corpus/literal/alias.txt deleted file mode 100644 index 18e16e1dd949d5..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/alias.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [AliasNode(0...15)( - GlobalVariableReadNode(6...10)(:$foo), - GlobalVariableReadNode(11...15)(:$bar), - (0...5) - ), - AliasNode(16...31)( - SymbolNode(22...26)((22...23), (23...26), nil, "foo"), - SymbolNode(27...31)((27...28), (28...31), nil, "bar"), - (16...21) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt deleted file mode 100644 index 3f82c3a8e40bac..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt +++ /dev/null @@ -1,690 +0,0 @@ -ProgramNode(0...704)( - [:a, :b, :foo, :c, :x], - StatementsNode(0...704)( - [GlobalVariableWriteNode(0...6)( - :$a, - (0...2), - IntegerNode(5...6)(), - (3...4) - ), - MultiWriteNode(7...24)( - [GlobalVariableTargetNode(8...10)(:$a), - GlobalVariableTargetNode(12...14)(:$b)], - (7...8), - (14...15), - (16...17), - ArrayNode(18...24)( - [IntegerNode(19...20)(), IntegerNode(22...23)()], - (18...19), - (23...24) - ) - ), - MultiWriteNode(25...38)( - [MultiTargetNode(26...30)( - [LocalVariableTargetNode(27...28)(:a, 0), - SplatNode(28...29)((28...29), nil)], - (26...27), - (29...30) - ), - LocalVariableTargetNode(32...33)(:b, 0)], - (25...26), - (33...34), - (35...36), - IntegerNode(37...38)() - ), - MultiWriteNode(39...48)( - [SplatNode(40...42)( - (40...41), - LocalVariableTargetNode(41...42)(:a, 0) - )], - (39...40), - (42...43), - (44...45), - ArrayNode(46...48)([], (46...47), (47...48)) - ), - MultiWriteNode(49...64)( - [SplatNode(50...54)( - (50...51), - LocalVariableTargetNode(51...54)(:foo, 0) - )], - (49...50), - (54...55), - (56...57), - ArrayNode(58...64)( - [IntegerNode(59...60)(), IntegerNode(62...63)()], - (58...59), - (63...64) - ) - ), - MultiWriteNode(65...84)( - [ClassVariableTargetNode(66...69)(:@@a), - ClassVariableTargetNode(71...74)(:@@b)], - (65...66), - (74...75), - (76...77), - ArrayNode(78...84)( - [IntegerNode(79...80)(), IntegerNode(82...83)()], - (78...79), - (83...84) - ) - ), - MultiWriteNode(85...102)( - [InstanceVariableTargetNode(86...88)(:@a), - InstanceVariableTargetNode(90...92)(:@b)], - (85...86), - (92...93), - (94...95), - ArrayNode(96...102)( - [IntegerNode(97...98)(), IntegerNode(100...101)()], - (96...97), - (101...102) - ) - ), - MultiWriteNode(103...128)( - [LocalVariableTargetNode(104...105)(:a, 0), - MultiTargetNode(107...113)( - [LocalVariableTargetNode(108...109)(:b, 0), - LocalVariableTargetNode(111...112)(:c, 0)], - (107...108), - (112...113) - )], - (103...104), - (113...114), - (115...116), - ArrayNode(117...128)( - [IntegerNode(118...119)(), - ArrayNode(121...127)( - [IntegerNode(122...123)(), IntegerNode(125...126)()], - (121...122), - (126...127) - )], - (117...118), - (127...128) - ) - ), - MultiWriteNode(129...144)( - [LocalVariableTargetNode(130...131)(:a, 0), - SplatNode(133...134)((133...134), nil)], - (129...130), - (134...135), - (136...137), - ArrayNode(138...144)( - [IntegerNode(139...140)(), IntegerNode(142...143)()], - (138...139), - (143...144) - ) - ), - MultiWriteNode(145...163)( - [LocalVariableTargetNode(146...147)(:a, 0), - SplatNode(149...153)( - (149...150), - LocalVariableTargetNode(150...153)(:foo, 0) - )], - (145...146), - (153...154), - (155...156), - ArrayNode(157...163)( - [IntegerNode(158...159)(), IntegerNode(161...162)()], - (157...158), - (162...163) - ) - ), - MultiWriteNode(164...179)( - [LocalVariableTargetNode(165...166)(:a, 0), - LocalVariableTargetNode(168...169)(:b, 0)], - (164...165), - (169...170), - (171...172), - ArrayNode(173...179)( - [IntegerNode(174...175)(), IntegerNode(177...178)()], - (173...174), - (178...179) - ) - ), - MultiWriteNode(180...192)( - [LocalVariableTargetNode(181...182)(:a, 0), - LocalVariableTargetNode(184...185)(:b, 0)], - (180...181), - (185...186), - (187...188), - LocalVariableReadNode(189...192)(:foo, 0) - ), - MultiWriteNode(193...203)( - [LocalVariableTargetNode(194...195)(:a, 0), - SplatNode(195...196)((195...196), nil)], - (193...194), - (196...197), - (198...199), - LocalVariableReadNode(200...203)(:foo, 0) - ), - MultiWriteNode(204...227)( - [CallNode(205...210)( - LocalVariableReadNode(205...206)(:a, 0), - (206...207), - (207...210), - nil, - nil, - nil, - nil, - 0, - "foo=" - ), - CallNode(212...217)( - LocalVariableReadNode(212...213)(:a, 0), - (213...214), - (214...217), - nil, - nil, - nil, - nil, - 0, - "bar=" - )], - (204...205), - (217...218), - (219...220), - ArrayNode(221...227)( - [IntegerNode(222...223)(), IntegerNode(225...226)()], - (221...222), - (226...227) - ) - ), - MultiWriteNode(228...252)( - [CallNode(229...236)( - LocalVariableReadNode(229...230)(:a, 0), - nil, - (230...236), - (230...231), - ArgumentsNode(231...235)( - [SplatNode(231...235)( - (231...232), - LocalVariableReadNode(232...235)(:foo, 0) - )] - ), - (235...236), - nil, - 0, - "[]=" - ), - CallNode(238...242)( - LocalVariableReadNode(238...239)(:a, 0), - nil, - (239...242), - (239...240), - ArgumentsNode(240...241)([IntegerNode(240...241)()]), - (241...242), - nil, - 0, - "[]=" - )], - (228...229), - (242...243), - (244...245), - ArrayNode(246...252)( - [IntegerNode(247...248)(), IntegerNode(250...251)()], - (246...247), - (251...252) - ) - ), - MultiWriteNode(253...274)( - [CallNode(254...258)( - LocalVariableReadNode(254...255)(:a, 0), - nil, - (255...258), - (255...256), - ArgumentsNode(256...257)([IntegerNode(256...257)()]), - (257...258), - nil, - 0, - "[]=" - ), - CallNode(260...264)( - LocalVariableReadNode(260...261)(:a, 0), - nil, - (261...264), - (261...262), - ArgumentsNode(262...263)([IntegerNode(262...263)()]), - (263...264), - nil, - 0, - "[]=" - )], - (253...254), - (264...265), - (266...267), - ArrayNode(268...274)( - [IntegerNode(269...270)(), IntegerNode(272...273)()], - (268...269), - (273...274) - ) - ), - MultiWriteNode(275...287)( - [SplatNode(276...282)( - (276...277), - CallNode(277...282)( - LocalVariableReadNode(277...278)(:c, 0), - (278...279), - (279...282), - nil, - nil, - nil, - nil, - 0, - "foo=" - ) - )], - (275...276), - (282...283), - (284...285), - IntegerNode(286...287)() - ), - ConstantPathWriteNode(288...301)( - ConstantPathNode(288...293)( - nil, - ConstantReadNode(290...293)(:Foo), - (288...290) - ), - (294...295), - ConstantPathNode(296...301)( - nil, - ConstantReadNode(298...301)(:Bar), - (296...298) - ) - ), - ClassVariableWriteNode(302...309)( - :@@a, - (302...305), - IntegerNode(308...309)(), - (306...307) - ), - InstanceVariableWriteNode(310...316)( - :@a, - (310...312), - IntegerNode(315...316)(), - (313...314) - ), - ConstantWriteNode(317...326)( - :CONST, - (317...322), - IntegerNode(325...326)(), - (323...324) - ), - ConstantPathWriteNode(327...350)( - ConstantPathNode(327...346)( - ConstantPathNode(327...339)( - ConstantReadNode(327...331)(:Name), - ConstantReadNode(333...339)(:Spaced), - (331...333) - ), - ConstantReadNode(341...346)(:CONST), - (339...341) - ), - (347...348), - IntegerNode(349...350)() - ), - LocalVariableWriteNode(351...367)( - :a, - 0, - (351...352), - ParenthesesNode(355...367)( - StatementsNode(356...366)( - [MultiWriteNode(356...366)( - [LocalVariableTargetNode(357...358)(:b, 0), - LocalVariableTargetNode(360...361)(:c, 0)], - (356...357), - (361...362), - (363...364), - IntegerNode(365...366)() - )] - ), - (355...356), - (366...367) - ), - (353...354) - ), - LocalVariableWriteNode(368...373)( - :a, - 0, - (368...369), - IntegerNode(372...373)(), - (370...371) - ), - LocalVariableWriteNode(374...385)( - :foo, - 0, - (374...377), - CallNode(380...385)( - nil, - nil, - (380...383), - (383...384), - nil, - (384...385), - nil, - 0, - "foo" - ), - (378...379) - ), - CallNode(386...395)( - LocalVariableReadNode(386...389)(:foo, 0), - (389...390), - (390...393), - (393...394), - nil, - (394...395), - nil, - 0, - "[]=" - ), - CallNode(396...409)( - LocalVariableReadNode(396...399)(:foo, 0), - (399...400), - (400...403), - (403...404), - ArgumentsNode(404...408)( - [IntegerNode(404...405)(), IntegerNode(407...408)()] - ), - (408...409), - nil, - 0, - "[]=" - ), - CallNode(410...421)( - LocalVariableReadNode(410...413)(:foo, 0), - (413...414), - (414...417), - nil, - ArgumentsNode(417...421)([TrueNode(417...421)()]), - nil, - nil, - 0, - "[]=" - ), - CallNode(422...441)( - LocalVariableReadNode(422...425)(:foo, 0), - nil, - (425...433), - (425...426), - ArgumentsNode(426...441)( - [SplatNode(426...432)( - (426...427), - CallNode(427...432)( - nil, - nil, - (427...432), - nil, - nil, - nil, - nil, - 2, - "index" - ) - ), - CallNode(436...441)( - nil, - nil, - (436...441), - nil, - nil, - nil, - nil, - 2, - "value" - )] - ), - (432...433), - nil, - 0, - "[]=" - ), - CallNode(442...459)( - LocalVariableReadNode(442...445)(:foo, 0), - nil, - (445...451), - (445...446), - ArgumentsNode(446...459)( - [RangeNode(446...450)( - IntegerNode(446...447)(), - IntegerNode(449...450)(), - (447...449), - 0 - ), - CallNode(454...459)( - nil, - nil, - (454...459), - nil, - nil, - nil, - nil, - 2, - "value" - )] - ), - (450...451), - nil, - 0, - "[]=" - ), - CallNode(460...469)( - LocalVariableReadNode(460...463)(:foo, 0), - nil, - (463...465), - (463...464), - ArgumentsNode(468...469)([IntegerNode(468...469)()]), - (464...465), - nil, - 0, - "[]=" - ), - CallNode(470...487)( - LocalVariableReadNode(470...473)(:foo, 0), - nil, - (473...479), - (473...474), - ArgumentsNode(474...487)( - [LocalVariableReadNode(474...475)(:a, 0), - LocalVariableReadNode(477...478)(:b, 0), - CallNode(482...487)( - nil, - nil, - (482...487), - nil, - nil, - nil, - nil, - 2, - "value" - )] - ), - (478...479), - nil, - 0, - "[]=" - ), - CallNode(488...506)( - LocalVariableReadNode(488...491)(:foo, 0), - nil, - (491...498), - (491...492), - ArgumentsNode(492...506)( - [CallNode(492...497)( - nil, - nil, - (492...497), - nil, - nil, - nil, - nil, - 2, - "index" - ), - CallNode(501...506)( - nil, - nil, - (501...506), - nil, - nil, - nil, - nil, - 2, - "value" - )] - ), - (497...498), - nil, - 0, - "[]=" - ), - LocalVariableWriteNode(507...514)( - :x, - 0, - (507...508), - StringNode(511...514)((511...513), (513...513), (513...514), ""), - (509...510) - ), - CallNode(515...522)( - LocalVariableReadNode(515...516)(:x, 0), - (516...517), - (517...518), - nil, - ArgumentsNode(519...522)( - [StringNode(519...522)((519...521), (521...521), (521...522), "")] - ), - nil, - nil, - 0, - "x=" - ), - CallNode(523...535)( - LocalVariableReadNode(523...524)(:x, 0), - nil, - (524...529), - (524...525), - ArgumentsNode(525...535)( - [StringNode(525...528)((525...527), (527...527), (527...528), ""), - CallNode(532...535)( - nil, - nil, - (532...535), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (528...529), - nil, - 0, - "[]=" - ), - CallOrWriteNode(536...550)( - LocalVariableReadNode(536...537)(:a, 0), - nil, - (537...542), - (537...538), - ArgumentsNode(538...541)( - [StringNode(538...541)((538...540), (540...540), (540...541), "")] - ), - (541...542), - 0, - "[]", - "[]=", - (543...546), - CallNode(547...550)(nil, nil, (547...550), nil, nil, nil, nil, 2, "bar") - ), - InstanceVariableOrWriteNode(551...561)( - :@a, - (551...553), - (554...557), - StringNode(558...561)((558...560), (560...560), (560...561), "") - ), - LocalVariableWriteNode(562...576)( - :x, - 0, - (562...563), - InterpolatedStringNode(566...576)( - (566...576), - [StringNode(577...579)(nil, (577...579), nil, " "), - EmbeddedStatementsNode(579...582)((579...581), nil, (581...582)), - StringNode(582...583)(nil, (582...583), nil, "\n")], - (583...591) - ), - (564...565) - ), - CallNode(591...605)( - LocalVariableReadNode(591...592)(:x, 0), - (592...593), - (593...594), - nil, - ArgumentsNode(595...605)( - [InterpolatedStringNode(595...605)( - (595...605), - [StringNode(606...608)(nil, (606...608), nil, " "), - EmbeddedStatementsNode(608...611)((608...610), nil, (610...611)), - StringNode(611...612)(nil, (611...612), nil, "\n")], - (612...620) - )] - ), - nil, - nil, - 0, - "x=" - ), - CallNode(620...636)( - LocalVariableReadNode(620...621)(:x, 0), - nil, - (621...623), - (621...622), - ArgumentsNode(626...636)( - [InterpolatedStringNode(626...636)( - (626...636), - [StringNode(637...639)(nil, (637...639), nil, " "), - EmbeddedStatementsNode(639...642)((639...641), nil, (641...642)), - StringNode(642...643)(nil, (642...643), nil, "\n")], - (643...651) - )] - ), - (622...623), - nil, - 0, - "[]=" - ), - CallOrWriteNode(651...672)( - LocalVariableReadNode(651...652)(:a, 0), - nil, - (652...664), - (652...653), - ArgumentsNode(653...663)( - [InterpolatedStringNode(653...663)( - (653...663), - [StringNode(673...675)(nil, (673...675), nil, " "), - EmbeddedStatementsNode(675...678)((675...677), nil, (677...678)), - StringNode(678...679)(nil, (678...679), nil, "\n")], - (679...687) - )] - ), - (663...664), - 0, - "[]", - "[]=", - (665...668), - CallNode(669...672)(nil, nil, (669...672), nil, nil, nil, nil, 2, "bar") - ), - InstanceVariableOrWriteNode(687...704)( - :@a, - (687...689), - (690...693), - InterpolatedStringNode(694...704)( - (694...704), - [StringNode(705...707)(nil, (705...707), nil, " "), - EmbeddedStatementsNode(707...710)((707...709), nil, (709...710)), - StringNode(710...711)(nil, (710...711), nil, "\n")], - (711...719) - ) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/block.txt b/test/yarp/snapshots/unparser/corpus/literal/block.txt deleted file mode 100644 index 43a1ead2e80f9e..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/block.txt +++ /dev/null @@ -1,1275 +0,0 @@ -ProgramNode(0...737)( - [], - StatementsNode(0...737)( - [CallNode(0...7)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...7)([], nil, nil, (4...5), (6...7)), - 0, - "foo" - ), - CallNode(8...19)( - nil, - nil, - (8...11), - nil, - nil, - nil, - BlockNode(12...19)( - [:a], - BlockParametersNode(14...17)( - ParametersNode(15...16)( - [RequiredParameterNode(15...16)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (14...15), - (16...17) - ), - nil, - (12...13), - (18...19) - ), - 0, - "foo" - ), - CallNode(20...32)( - nil, - nil, - (20...23), - nil, - nil, - nil, - BlockNode(24...32)( - [:a], - BlockParametersNode(26...30)( - ParametersNode(27...29)( - [RequiredParameterNode(27...28)(:a)], - [], - [], - RestParameterNode(28...29)(nil, nil, (28...29)), - [], - nil, - nil - ), - [], - (26...27), - (29...30) - ), - nil, - (24...25), - (31...32) - ), - 0, - "foo" - ), - CallNode(33...48)( - nil, - nil, - (33...36), - nil, - nil, - nil, - BlockNode(37...48)( - [:a, :x], - BlockParametersNode(39...46)( - ParametersNode(40...42)( - [RequiredParameterNode(40...41)(:a)], - [], - [], - RestParameterNode(41...42)(nil, nil, (41...42)), - [], - nil, - nil - ), - [BlockLocalVariableNode(44...45)(:x)], - (39...40), - (45...46) - ), - nil, - (37...38), - (47...48) - ), - 0, - "foo" - ), - CallNode(49...63)( - nil, - nil, - (49...52), - nil, - nil, - nil, - BlockNode(53...63)( - [:a, :b], - BlockParametersNode(55...61)( - ParametersNode(56...60)( - [RequiredParameterNode(56...57)(:a), - RequiredParameterNode(59...60)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (55...56), - (60...61) - ), - nil, - (53...54), - (62...63) - ), - 0, - "foo" - ), - CallNode(64...80)( - nil, - nil, - (64...67), - (67...68), - ArgumentsNode(68...69)([IntegerNode(68...69)()]), - (69...70), - BlockNode(71...80)( - [], - nil, - StatementsNode(75...78)([NilNode(75...78)()]), - (71...72), - (79...80) - ), - 0, - "foo" - ), - CallNode(81...102)( - nil, - nil, - (81...84), - nil, - nil, - nil, - BlockNode(85...102)( - [:a, :b], - BlockParametersNode(87...94)( - ParametersNode(88...93)( - [RequiredParameterNode(88...89)(:a)], - [], - [], - RestParameterNode(91...93)(:b, (92...93), (91...92)), - [], - nil, - nil - ), - [], - (87...88), - (93...94) - ), - StatementsNode(97...100)([NilNode(97...100)()]), - (85...86), - (101...102) - ), - 0, - "foo" - ), - CallNode(103...123)( - nil, - nil, - (103...106), - nil, - nil, - nil, - BlockNode(107...123)( - [:a, :*], - BlockParametersNode(109...115)( - ParametersNode(110...114)( - [RequiredParameterNode(110...111)(:a)], - [], - [], - RestParameterNode(113...114)(nil, nil, (113...114)), - [], - nil, - nil - ), - [], - (109...110), - (114...115) - ), - StatementsNode(118...121)([NilNode(118...121)()]), - (107...108), - (122...123) - ), - 0, - "foo" - ), - CallNode(124...137)( - nil, - nil, - (124...127), - nil, - nil, - nil, - BlockNode(128...137)( - [], - nil, - StatementsNode(132...135)( - [CallNode(132...135)( - nil, - nil, - (132...135), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (128...129), - (136...137) - ), - 0, - "foo" - ), - CallNode(138...165)( - CallNode(138...141)( - nil, - nil, - (138...141), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (141...142), - (142...145), - nil, - nil, - nil, - BlockNode(146...165)( - [:a, :b, :c], - BlockParametersNode(148...159)( - ParametersNode(149...158)( - [RequiredDestructuredParameterNode(149...155)( - [RequiredParameterNode(150...151)(:a), - RequiredParameterNode(153...154)(:b)], - (149...150), - (154...155) - ), - RequiredParameterNode(157...158)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (148...149), - (158...159) - ), - StatementsNode(162...163)( - [CallNode(162...163)( - nil, - nil, - (162...163), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (146...147), - (164...165) - ), - 0, - "bar" - ), - CallNode(166...185)( - CallNode(166...169)( - nil, - nil, - (166...169), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (169...170), - (170...173), - nil, - nil, - nil, - BlockNode(174...185)( - [:a, :b], - BlockParametersNode(176...183)( - ParametersNode(177...179)( - [], - [], - [], - RestParameterNode(177...179)(:a, (178...179), (177...178)), - [], - nil, - nil - ), - [BlockLocalVariableNode(181...182)(:b)], - (176...177), - (182...183) - ), - nil, - (174...175), - (184...185) - ), - 0, - "bar" - ), - CallNode(186...204)( - CallNode(186...189)( - nil, - nil, - (186...189), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (189...190), - (190...193), - nil, - nil, - nil, - BlockNode(194...204)( - [:a, :b], - BlockParametersNode(196...202)( - ParametersNode(197...198)( - [RequiredParameterNode(197...198)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(200...201)(:b)], - (196...197), - (201...202) - ), - nil, - (194...195), - (203...204) - ), - 0, - "bar" - ), - CallNode(205...225)( - CallNode(205...208)( - nil, - nil, - (205...208), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (208...209), - (209...212), - nil, - nil, - nil, - BlockNode(213...225)( - [:a, :b], - BlockParametersNode(215...223)( - nil, - [BlockLocalVariableNode(218...219)(:a), - BlockLocalVariableNode(221...222)(:b)], - (215...216), - (222...223) - ), - nil, - (213...214), - (224...225) - ), - 0, - "bar" - ), - CallNode(226...245)( - CallNode(226...229)( - nil, - nil, - (226...229), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (229...230), - (230...233), - nil, - nil, - nil, - BlockNode(234...245)( - [:*], - BlockParametersNode(236...239)( - ParametersNode(237...238)( - [], - [], - [], - RestParameterNode(237...238)(nil, nil, (237...238)), - [], - nil, - nil - ), - [], - (236...237), - (238...239) - ), - StatementsNode(242...243)( - [CallNode(242...243)( - nil, - nil, - (242...243), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (234...235), - (244...245) - ), - 0, - "bar" - ), - CallNode(246...267)( - CallNode(246...249)( - nil, - nil, - (246...249), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (249...250), - (250...253), - nil, - nil, - nil, - BlockNode(254...267)( - [], - BlockParametersNode(256...261)( - ParametersNode(257...260)( - [RequiredDestructuredParameterNode(257...260)( - [SplatNode(258...259)((258...259), nil)], - (257...258), - (259...260) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (256...257), - (260...261) - ), - StatementsNode(264...265)( - [CallNode(264...265)( - nil, - nil, - (264...265), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (254...255), - (266...267) - ), - 0, - "bar" - ), - CallNode(268...291)( - CallNode(268...271)( - nil, - nil, - (268...271), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (271...272), - (272...275), - nil, - nil, - nil, - BlockNode(276...291)( - [], - BlockParametersNode(278...285)( - ParametersNode(279...284)( - [RequiredDestructuredParameterNode(279...284)( - [RequiredDestructuredParameterNode(280...283)( - [SplatNode(281...282)((281...282), nil)], - (280...281), - (282...283) - )], - (279...280), - (283...284) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (278...279), - (284...285) - ), - StatementsNode(288...289)( - [CallNode(288...289)( - nil, - nil, - (288...289), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (276...277), - (290...291) - ), - 0, - "bar" - ), - CallNode(292...318)( - CallNode(292...295)( - nil, - nil, - (292...295), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (295...296), - (296...299), - nil, - nil, - nil, - BlockNode(300...318)( - [:a], - BlockParametersNode(302...312)( - ParametersNode(303...311)( - [RequiredDestructuredParameterNode(303...311)( - [RequiredParameterNode(304...305)(:a), - RequiredDestructuredParameterNode(307...310)( - [SplatNode(308...309)((308...309), nil)], - (307...308), - (309...310) - )], - (303...304), - (310...311) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (302...303), - (311...312) - ), - StatementsNode(315...316)( - [CallNode(315...316)( - nil, - nil, - (315...316), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (300...301), - (317...318) - ), - 0, - "bar" - ), - CallNode(319...343)( - CallNode(319...322)( - nil, - nil, - (319...322), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (322...323), - (323...326), - nil, - nil, - nil, - BlockNode(327...343)( - [:a, :b], - BlockParametersNode(329...337)( - ParametersNode(330...336)( - [RequiredDestructuredParameterNode(330...336)( - [RequiredParameterNode(331...332)(:a), - RequiredParameterNode(334...335)(:b)], - (330...331), - (335...336) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (329...330), - (336...337) - ), - StatementsNode(340...341)( - [CallNode(340...341)( - nil, - nil, - (340...341), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (327...328), - (342...343) - ), - 0, - "bar" - ), - CallNode(344...359)( - CallNode(344...355)( - CallNode(344...347)( - nil, - nil, - (344...347), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (347...348), - (348...351), - nil, - nil, - nil, - BlockNode(352...355)([], nil, nil, (352...353), (354...355)), - 0, - "bar" - ), - (355...356), - (356...359), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - CallNode(360...390)( - nil, - nil, - (360...361), - nil, - nil, - nil, - BlockNode(362...390)( - [:e], - nil, - BeginNode(365...390)( - nil, - nil, - RescueNode(365...386)( - (365...371), - [ConstantReadNode(372...381)(:Exception)], - (382...384), - LocalVariableTargetNode(385...386)(:e, 0), - nil, - nil - ), - nil, - nil, - (387...390) - ), - (362...364), - (387...390) - ), - 0, - "m" - ), - CallNode(391...435)( - nil, - nil, - (391...392), - nil, - nil, - nil, - BlockNode(393...435)( - [:bar], - nil, - BeginNode(398...435)( - nil, - StatementsNode(398...401)( - [CallNode(398...401)( - nil, - nil, - (398...401), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - RescueNode(402...431)( - (402...408), - [ConstantReadNode(409...418)(:Exception)], - (419...421), - LocalVariableTargetNode(422...425)(:bar, 0), - StatementsNode(428...431)( - [LocalVariableReadNode(428...431)(:bar, 0)] - ), - nil - ), - nil, - nil, - (432...435) - ), - (393...395), - (432...435) - ), - 0, - "m" - ), - CallNode(436...479)( - nil, - nil, - (436...437), - nil, - nil, - nil, - BlockNode(438...479)( - [], - nil, - BeginNode(443...479)( - nil, - StatementsNode(443...446)( - [CallNode(443...446)( - nil, - nil, - (443...446), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(447...475)( - (447...453), - [ConstantReadNode(454...463)(:SomeError), - SplatNode(465...469)( - (465...466), - CallNode(466...469)( - nil, - nil, - (466...469), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - nil, - nil, - StatementsNode(472...475)( - [CallNode(472...475)( - nil, - nil, - (472...475), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (476...479) - ), - (438...440), - (476...479) - ), - 0, - "m" - ), - CallNode(480...536)( - nil, - nil, - (480...481), - nil, - nil, - nil, - BlockNode(482...536)( - [:exception], - nil, - BeginNode(487...536)( - nil, - StatementsNode(487...490)( - [CallNode(487...490)( - nil, - nil, - (487...490), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(491...532)( - (491...497), - [ConstantReadNode(498...507)(:SomeError), - SplatNode(509...513)( - (509...510), - CallNode(510...513)( - nil, - nil, - (510...513), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - (514...516), - LocalVariableTargetNode(517...526)(:exception, 0), - StatementsNode(529...532)( - [CallNode(529...532)( - nil, - nil, - (529...532), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (533...536) - ), - (482...484), - (533...536) - ), - 0, - "m" - ), - CallNode(537...569)( - nil, - nil, - (537...538), - nil, - nil, - nil, - BlockNode(539...569)( - [], - nil, - BeginNode(544...569)( - nil, - StatementsNode(544...547)( - [CallNode(544...547)( - nil, - nil, - (544...547), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(548...565)( - (548...554), - [SplatNode(555...559)( - (555...556), - CallNode(556...559)( - nil, - nil, - (556...559), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - nil, - nil, - StatementsNode(562...565)( - [CallNode(562...565)( - nil, - nil, - (562...565), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (566...569) - ), - (539...541), - (566...569) - ), - 0, - "m" - ), - CallNode(570...601)( - nil, - nil, - (570...571), - nil, - nil, - nil, - BlockNode(572...601)( - [], - nil, - BeginNode(577...601)( - nil, - StatementsNode(577...580)( - [CallNode(577...580)( - nil, - nil, - (577...580), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(581...597)( - (581...587), - [ConstantReadNode(588...597)(:LoadError)], - nil, - nil, - nil, - nil - ), - nil, - nil, - (598...601) - ), - (572...574), - (598...601) - ), - 0, - "m" - ), - CallNode(602...634)( - nil, - nil, - (602...603), - nil, - nil, - nil, - BlockNode(604...634)( - [], - nil, - BeginNode(609...634)( - nil, - StatementsNode(609...612)( - [CallNode(609...612)( - nil, - nil, - (609...612), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(613...619)((613...619), [], nil, nil, nil, nil), - ElseNode(620...634)( - (620...624), - StatementsNode(627...630)( - [CallNode(627...630)( - nil, - nil, - (627...630), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (631...634) - ), - nil, - (631...634) - ), - (604...606), - (631...634) - ), - 0, - "m" - ), - CallNode(635...680)( - nil, - nil, - (635...636), - nil, - nil, - nil, - BlockNode(637...680)( - [:exception], - nil, - BeginNode(642...680)( - nil, - StatementsNode(642...645)( - [CallNode(642...645)( - nil, - nil, - (642...645), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(646...676)( - (646...652), - [SplatNode(653...657)( - (653...654), - CallNode(654...657)( - nil, - nil, - (654...657), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - (658...660), - LocalVariableTargetNode(661...670)(:exception, 0), - StatementsNode(673...676)( - [CallNode(673...676)( - nil, - nil, - (673...676), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (677...680) - ), - (637...639), - (677...680) - ), - 0, - "m" - ), - CallNode(681...696)( - nil, - nil, - (681...682), - nil, - nil, - nil, - BlockNode(683...696)( - [], - nil, - BeginNode(686...696)( - nil, - nil, - nil, - nil, - EnsureNode(686...696)((686...692), nil, (693...696)), - (693...696) - ), - (683...685), - (693...696) - ), - 0, - "m" - ), - CallNode(697...719)( - nil, - nil, - (697...698), - nil, - nil, - nil, - BlockNode(699...719)( - [], - nil, - BeginNode(702...719)( - nil, - nil, - RescueNode(702...708)((702...708), [], nil, nil, nil, nil), - nil, - EnsureNode(709...719)((709...715), nil, (716...719)), - (716...719) - ), - (699...701), - (716...719) - ), - 0, - "m" - ), - CallNode(720...737)( - nil, - nil, - (720...723), - nil, - nil, - nil, - BlockNode(724...737)( - [], - nil, - StatementsNode(728...735)( - [CallNode(728...735)( - CallNode(728...730)( - nil, - nil, - (728...730), - nil, - nil, - nil, - nil, - 2, - "_1" - ), - nil, - (731...732), - nil, - ArgumentsNode(733...735)( - [CallNode(733...735)( - nil, - nil, - (733...735), - nil, - nil, - nil, - nil, - 2, - "_2" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (724...725), - (736...737) - ), - 0, - "bar" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/case.txt b/test/yarp/snapshots/unparser/corpus/literal/case.txt deleted file mode 100644 index 8470bd39aaf631..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/case.txt +++ /dev/null @@ -1,402 +0,0 @@ -ProgramNode(0...284)( - [], - StatementsNode(0...284)( - [CaseNode(0...38)( - nil, - [WhenNode(5...19)( - (5...9), - [CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - StatementsNode(16...19)( - [CallNode(16...19)( - nil, - nil, - (16...19), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ) - ), - WhenNode(20...34)( - (20...24), - [CallNode(25...28)( - nil, - nil, - (25...28), - nil, - nil, - nil, - nil, - 2, - "baz" - )], - StatementsNode(31...34)( - [CallNode(31...34)( - nil, - nil, - (31...34), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (0...4), - (35...38) - ), - CaseNode(39...75)( - CallNode(44...47)(nil, nil, (44...47), nil, nil, nil, nil, 2, "foo"), - [WhenNode(48...56)( - (48...52), - [CallNode(53...56)( - nil, - nil, - (53...56), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - nil - ), - WhenNode(57...71)( - (57...61), - [CallNode(62...65)( - nil, - nil, - (62...65), - nil, - nil, - nil, - nil, - 2, - "baz" - )], - StatementsNode(68...71)( - [CallNode(68...71)( - nil, - nil, - (68...71), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (39...43), - (72...75) - ), - CaseNode(76...118)( - CallNode(81...84)(nil, nil, (81...84), nil, nil, nil, nil, 2, "foo"), - [WhenNode(85...99)( - (85...89), - [CallNode(90...93)( - nil, - nil, - (90...93), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - StatementsNode(96...99)( - [CallNode(96...99)( - nil, - nil, - (96...99), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ) - ), - WhenNode(100...114)( - (100...104), - [CallNode(105...108)( - nil, - nil, - (105...108), - nil, - nil, - nil, - nil, - 2, - "baz" - )], - StatementsNode(111...114)( - [CallNode(111...114)( - nil, - nil, - (111...114), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (76...80), - (115...118) - ), - CaseNode(119...154)( - CallNode(124...127)( - nil, - nil, - (124...127), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(128...150)( - (128...132), - [CallNode(133...136)( - nil, - nil, - (133...136), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - CallNode(138...141)( - nil, - nil, - (138...141), - nil, - nil, - nil, - nil, - 2, - "baz" - )], - StatementsNode(144...150)( - [SymbolNode(144...150)((144...145), (145...150), nil, "other")] - ) - )], - nil, - (119...123), - (151...154) - ), - CaseNode(155...186)( - CallNode(160...163)( - nil, - nil, - (160...163), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(164...182)( - (164...168), - [SplatNode(169...173)( - (169...170), - CallNode(170...173)( - nil, - nil, - (170...173), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - StatementsNode(176...182)( - [SymbolNode(176...182)((176...177), (177...182), nil, "value")] - ) - )], - nil, - (155...159), - (183...186) - ), - CaseNode(187...226)( - CallNode(192...195)( - nil, - nil, - (192...195), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(196...210)( - (196...200), - [CallNode(201...204)( - nil, - nil, - (201...204), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - StatementsNode(207...210)( - [CallNode(207...210)( - nil, - nil, - (207...210), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ) - )], - ElseNode(211...226)( - (211...215), - StatementsNode(218...222)( - [SymbolNode(218...222)((218...219), (219...222), nil, "foo")] - ), - (223...226) - ), - (187...191), - (223...226) - ), - CaseNode(227...255)( - CallNode(232...235)( - nil, - nil, - (232...235), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(236...251)( - (236...240), - [SplatNode(241...251)( - (241...242), - CallNode(242...251)( - CallNode(242...245)( - nil, - nil, - (242...245), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (246...247), - nil, - ArgumentsNode(248...251)( - [CallNode(248...251)( - nil, - nil, - (248...251), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil, - nil, - 0, - "|" - ) - )], - nil - )], - nil, - (227...231), - (252...255) - ), - CaseNode(256...284)( - CallNode(261...264)( - nil, - nil, - (261...264), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(265...280)( - (265...269), - [SplatNode(270...280)( - (270...271), - CallNode(271...280)( - CallNode(271...274)( - nil, - nil, - (271...274), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (274...275), - (275...278), - nil, - ArgumentsNode(279...280)([IntegerNode(279...280)()]), - nil, - nil, - 0, - "baz=" - ) - )], - nil - )], - nil, - (256...260), - (281...284) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/class.txt b/test/yarp/snapshots/unparser/corpus/literal/class.txt deleted file mode 100644 index 5d0ca9da7bb9c5..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/class.txt +++ /dev/null @@ -1,171 +0,0 @@ -ProgramNode(0...213)( - [], - StatementsNode(0...213)( - [ClassNode(0...11)( - [], - (0...5), - ConstantReadNode(6...7)(:A), - nil, - nil, - nil, - (8...11), - :A - ), - SingletonClassNode(13...27)( - [], - (13...18), - (19...21), - CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "a"), - nil, - (24...27) - ), - SingletonClassNode(29...47)( - [], - (29...34), - (35...37), - CallNode(38...39)(nil, nil, (38...39), nil, nil, nil, nil, 2, "a"), - StatementsNode(42...43)( - [CallNode(42...43)(nil, nil, (42...43), nil, nil, nil, nil, 2, "b")] - ), - (44...47) - ), - ClassNode(49...63)( - [], - (49...54), - ConstantPathNode(55...59)( - ConstantReadNode(55...56)(:A), - ConstantReadNode(58...59)(:B), - (56...58) - ), - nil, - nil, - nil, - (60...63), - :B - ), - ClassNode(65...82)( - [], - (65...70), - ConstantPathNode(71...78)( - ConstantPathNode(71...75)( - ConstantReadNode(71...72)(:A), - ConstantReadNode(74...75)(:B), - (72...74) - ), - ConstantReadNode(77...78)(:C), - (75...77) - ), - nil, - nil, - nil, - (79...82), - :C - ), - ClassNode(84...99)( - [], - (84...89), - ConstantReadNode(90...91)(:A), - (92...93), - ConstantReadNode(94...95)(:B), - nil, - (96...99), - :A - ), - ClassNode(101...119)( - [], - (101...106), - ConstantReadNode(107...108)(:A), - (109...110), - ConstantPathNode(111...115)( - ConstantReadNode(111...112)(:B), - ConstantReadNode(114...115)(:C), - (112...114) - ), - nil, - (116...119), - :A - ), - ClassNode(121...142)( - [], - (121...126), - ConstantPathNode(127...131)( - ConstantReadNode(127...128)(:A), - ConstantReadNode(130...131)(:B), - (128...130) - ), - (132...133), - ConstantPathNode(134...138)( - ConstantReadNode(134...135)(:C), - ConstantReadNode(137...138)(:D), - (135...137) - ), - nil, - (139...142), - :B - ), - ClassNode(144...198)( - [], - (144...149), - ConstantReadNode(150...151)(:A), - nil, - nil, - StatementsNode(154...194)( - [CallNode(154...168)( - nil, - nil, - (154...161), - (161...162), - ArgumentsNode(162...167)( - [CallNode(162...167)( - ConstantReadNode(162...163)(:B), - (163...164), - (164...167), - nil, - nil, - nil, - nil, - 0, - "new" - )] - ), - (167...168), - nil, - 0, - "include" - ), - DefNode(172...194)( - :foo, - (176...179), - nil, - nil, - StatementsNode(184...188)( - [SymbolNode(184...188)((184...185), (185...188), nil, "bar")] - ), - [], - (172...175), - nil, - nil, - nil, - nil, - (191...194) - )] - ), - (195...198), - :A - ), - ClassNode(200...213)( - [], - (200...205), - ConstantPathNode(206...209)( - nil, - ConstantReadNode(208...209)(:A), - (206...208) - ), - nil, - nil, - nil, - (210...213), - :A - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/control.txt b/test/yarp/snapshots/unparser/corpus/literal/control.txt deleted file mode 100644 index 182bddab6002ee..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/control.txt +++ /dev/null @@ -1,83 +0,0 @@ -ProgramNode(0...144)( - [], - StatementsNode(0...144)( - [NextNode(0...4)(nil, (0...4)), - ReturnNode(5...11)((5...11), nil), - BreakNode(12...17)(nil, (12...17)), - RetryNode(18...23)(), - RedoNode(24...28)(), - ReturnNode(29...37)( - (29...35), - ArgumentsNode(36...37)([IntegerNode(36...37)()]) - ), - ReturnNode(38...49)( - (38...44), - ArgumentsNode(45...49)([IntegerNode(45...46)(), IntegerNode(48...49)()]) - ), - ReturnNode(50...69)( - (50...56), - ArgumentsNode(57...69)( - [IfNode(57...69)( - nil, - TrueNode(57...61)(), - StatementsNode(64...65)([IntegerNode(64...65)()]), - ElseNode(66...69)( - (66...67), - StatementsNode(68...69)([IntegerNode(68...69)()]), - nil - ), - nil - )] - ) - ), - BreakNode(70...88)( - ArgumentsNode(76...88)( - [IfNode(76...88)( - nil, - TrueNode(76...80)(), - StatementsNode(83...84)([IntegerNode(83...84)()]), - ElseNode(85...88)( - (85...86), - StatementsNode(87...88)([IntegerNode(87...88)()]), - nil - ), - nil - )] - ), - (70...75) - ), - NextNode(89...106)( - ArgumentsNode(94...106)( - [IfNode(94...106)( - nil, - TrueNode(94...98)(), - StatementsNode(101...102)([IntegerNode(101...102)()]), - ElseNode(103...106)( - (103...104), - StatementsNode(105...106)([IntegerNode(105...106)()]), - nil - ), - nil - )] - ), - (89...93) - ), - ReturnNode(107...144)( - (107...113), - ArgumentsNode(114...144)( - [TrueNode(114...118)(), - IfNode(120...144)( - (120...122), - TrueNode(123...127)(), - StatementsNode(130...131)([IntegerNode(130...131)()]), - ElseNode(132...144)( - (132...136), - StatementsNode(139...140)([IntegerNode(139...140)()]), - (141...144) - ), - (141...144) - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/def.txt b/test/yarp/snapshots/unparser/corpus/literal/def.txt deleted file mode 100644 index 9bb03d20f2eb54..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/def.txt +++ /dev/null @@ -1,1053 +0,0 @@ -ProgramNode(0...913)( - [], - StatementsNode(0...913)( - [DefNode(0...46)( - :foo, - (4...7), - nil, - nil, - BeginNode(10...46)( - nil, - StatementsNode(10...11)( - [CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(12...22)( - (12...18), - [], - nil, - nil, - StatementsNode(21...22)( - [CallNode(21...22)( - nil, - nil, - (21...22), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - ElseNode(23...38)( - (23...27), - StatementsNode(30...31)( - [CallNode(30...31)( - nil, - nil, - (30...31), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (32...38) - ), - EnsureNode(32...46)( - (32...38), - StatementsNode(41...42)( - [CallNode(41...42)( - nil, - nil, - (41...42), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (43...46) - ), - (43...46) - ), - [], - (0...3), - nil, - nil, - nil, - nil, - (43...46) - ), - DefNode(48...103)( - :foo, - (52...55), - nil, - nil, - BeginNode(58...103)( - nil, - StatementsNode(58...68)( - [RescueModifierNode(58...68)( - CallNode(58...59)( - nil, - nil, - (58...59), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (60...66), - CallNode(67...68)( - nil, - nil, - (67...68), - nil, - nil, - nil, - nil, - 2, - "b" - ) - )] - ), - RescueNode(69...79)( - (69...75), - [], - nil, - nil, - StatementsNode(78...79)( - [CallNode(78...79)( - nil, - nil, - (78...79), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - ElseNode(80...95)( - (80...84), - StatementsNode(87...88)( - [CallNode(87...88)( - nil, - nil, - (87...88), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (89...95) - ), - EnsureNode(89...103)( - (89...95), - StatementsNode(98...99)( - [CallNode(98...99)( - nil, - nil, - (98...99), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (100...103) - ), - (100...103) - ), - [], - (48...51), - nil, - nil, - nil, - nil, - (100...103) - ), - DefNode(105...128)( - :foo, - (109...112), - nil, - ParametersNode(113...123)( - [], - [], - [], - nil, - [KeywordParameterNode(113...117)(:bar, (113...117), nil), - KeywordParameterNode(119...123)(:baz, (119...123), nil)], - nil, - nil - ), - nil, - [:bar, :baz], - (105...108), - nil, - (112...113), - (123...124), - nil, - (125...128) - ), - DefNode(130...141)( - :foo, - (134...137), - nil, - nil, - nil, - [], - (130...133), - nil, - nil, - nil, - nil, - (138...141) - ), - DefNode(143...160)( - :foo, - (147...150), - nil, - nil, - StatementsNode(153...156)( - [CallNode(153...156)( - nil, - nil, - (153...156), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [], - (143...146), - nil, - nil, - nil, - nil, - (157...160) - ), - DefNode(162...205)( - :foo, - (166...169), - nil, - nil, - BeginNode(172...205)( - nil, - StatementsNode(172...175)( - [CallNode(172...175)( - nil, - nil, - (172...175), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - RescueNode(176...188)( - (176...182), - [], - nil, - nil, - StatementsNode(185...188)( - [CallNode(185...188)( - nil, - nil, - (185...188), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - EnsureNode(189...205)( - (189...195), - StatementsNode(198...201)( - [CallNode(198...201)( - nil, - nil, - (198...201), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (202...205) - ), - (202...205) - ), - [], - (162...165), - nil, - nil, - nil, - nil, - (202...205) - ), - DefNode(207...237)( - :foo, - (211...214), - nil, - nil, - BeginNode(217...237)( - nil, - StatementsNode(217...220)( - [CallNode(217...220)( - nil, - nil, - (217...220), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - EnsureNode(221...237)( - (221...227), - StatementsNode(230...233)( - [CallNode(230...233)( - nil, - nil, - (230...233), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (234...237) - ), - (234...237) - ), - [], - (207...210), - nil, - nil, - nil, - nil, - (234...237) - ), - DefNode(239...269)( - :foo, - (243...246), - nil, - nil, - BeginNode(249...269)( - nil, - StatementsNode(249...252)( - [CallNode(249...252)( - nil, - nil, - (249...252), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(253...265)( - (253...259), - [], - nil, - nil, - StatementsNode(262...265)( - [CallNode(262...265)( - nil, - nil, - (262...265), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (266...269) - ), - [], - (239...242), - nil, - nil, - nil, - nil, - (266...269) - ), - DefNode(271...293)( - :foo, - (275...278), - nil, - ParametersNode(279...282)( - [RequiredParameterNode(279...282)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(286...289)([LocalVariableReadNode(286...289)(:bar, 0)]), - [:bar], - (271...274), - nil, - (278...279), - (282...283), - nil, - (290...293) - ), - DefNode(295...322)( - :foo, - (299...302), - nil, - ParametersNode(303...311)( - [RequiredParameterNode(303...306)(:bar), - RequiredParameterNode(308...311)(:baz)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(315...318)([LocalVariableReadNode(315...318)(:bar, 0)]), - [:bar, :baz], - (295...298), - nil, - (302...303), - (311...312), - nil, - (319...322) - ), - DefNode(324...351)( - :foo, - (328...331), - nil, - ParametersNode(332...340)( - [], - [OptionalParameterNode(332...340)( - :bar, - (332...335), - (336...337), - ParenthesesNode(338...340)(nil, (338...339), (339...340)) - )], - [], - nil, - [], - nil, - nil - ), - StatementsNode(344...347)([LocalVariableReadNode(344...347)(:bar, 0)]), - [:bar], - (324...327), - nil, - (331...332), - (340...341), - nil, - (348...351) - ), - DefNode(353...382)( - :foo, - (357...360), - nil, - ParametersNode(361...377)( - [], - [OptionalParameterNode(361...377)( - :bar, - (361...364), - (365...366), - ParenthesesNode(367...377)( - StatementsNode(368...376)( - [CallNode(368...371)( - nil, - nil, - (368...371), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - NilNode(373...376)()] - ), - (367...368), - (376...377) - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:bar], - (353...356), - nil, - (360...361), - (377...378), - nil, - (379...382) - ), - DefNode(384...413)( - :foo, - (388...391), - nil, - ParametersNode(392...402)( - [], - [OptionalParameterNode(392...402)( - :bar, - (392...395), - (396...397), - TrueNode(398...402)() - )], - [], - nil, - [], - nil, - nil - ), - StatementsNode(406...409)([LocalVariableReadNode(406...409)(:bar, 0)]), - [:bar], - (384...387), - nil, - (391...392), - (402...403), - nil, - (410...413) - ), - DefNode(415...449)( - :foo, - (419...422), - nil, - ParametersNode(423...438)( - [RequiredParameterNode(423...426)(:bar)], - [OptionalParameterNode(428...438)( - :baz, - (428...431), - (432...433), - TrueNode(434...438)() - )], - [], - nil, - [], - nil, - nil - ), - StatementsNode(442...445)([LocalVariableReadNode(442...445)(:bar, 0)]), - [:bar, :baz], - (415...418), - nil, - (422...423), - (438...439), - nil, - (446...449) - ), - DefNode(451...470)( - :foo, - (455...458), - nil, - ParametersNode(459...465)( - [], - [], - [], - nil, - [KeywordParameterNode(459...465)( - :bar, - (459...463), - IntegerNode(464...465)() - )], - nil, - nil - ), - nil, - [:bar], - (451...454), - nil, - (458...459), - (465...466), - nil, - (467...470) - ), - DefNode(472...493)( - :foo, - (476...479), - nil, - ParametersNode(480...488)( - [], - [], - [], - nil, - [KeywordParameterNode(480...488)( - :bar, - (480...484), - CallNode(485...488)( - nil, - nil, - (485...488), - nil, - nil, - nil, - nil, - 2, - "baz" - ) - )], - nil, - nil - ), - nil, - [:bar], - (472...475), - nil, - (479...480), - (488...489), - nil, - (490...493) - ), - DefNode(495...518)( - :foo, - (499...502), - nil, - ParametersNode(503...513)( - [], - [], - [], - nil, - [KeywordParameterNode(503...513)( - :bar, - (503...507), - CallNode(508...513)( - nil, - nil, - (508...511), - (511...512), - nil, - (512...513), - nil, - 0, - "bar" - ) - )], - nil, - nil - ), - nil, - [:bar], - (495...498), - nil, - (502...503), - (513...514), - nil, - (515...518) - ), - DefNode(520...540)( - :foo, - (524...527), - nil, - ParametersNode(528...529)( - [], - [], - [], - RestParameterNode(528...529)(nil, nil, (528...529)), - [], - nil, - nil - ), - StatementsNode(533...536)( - [CallNode(533...536)( - nil, - nil, - (533...536), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [:*], - (520...523), - nil, - (527...528), - (529...530), - nil, - (537...540) - ), - DefNode(542...565)( - :foo, - (546...549), - nil, - ParametersNode(550...554)( - [], - [], - [], - RestParameterNode(550...554)(:bar, (551...554), (550...551)), - [], - nil, - nil - ), - StatementsNode(558...561)([LocalVariableReadNode(558...561)(:bar, 0)]), - [:bar], - (542...545), - nil, - (549...550), - (554...555), - nil, - (562...565) - ), - DefNode(567...595)( - :foo, - (571...574), - nil, - ParametersNode(575...584)( - [RequiredParameterNode(575...578)(:bar)], - [], - [], - RestParameterNode(580...584)(:baz, (581...584), (580...581)), - [], - nil, - nil - ), - StatementsNode(588...591)([LocalVariableReadNode(588...591)(:bar, 0)]), - [:bar, :baz], - (567...570), - nil, - (574...575), - (584...585), - nil, - (592...595) - ), - DefNode(597...632)( - :foo, - (601...604), - nil, - ParametersNode(605...621)( - [], - [OptionalParameterNode(605...615)( - :baz, - (605...608), - (609...610), - TrueNode(611...615)() - )], - [], - RestParameterNode(617...621)(:bor, (618...621), (617...618)), - [], - nil, - nil - ), - StatementsNode(625...628)( - [CallNode(625...628)( - nil, - nil, - (625...628), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [:baz, :bor], - (597...600), - nil, - (604...605), - (621...622), - nil, - (629...632) - ), - DefNode(634...677)( - :foo, - (638...641), - nil, - ParametersNode(642...666)( - [], - [OptionalParameterNode(642...652)( - :baz, - (642...645), - (646...647), - TrueNode(648...652)() - )], - [], - RestParameterNode(654...658)(:bor, (655...658), (654...655)), - [], - nil, - BlockParameterNode(660...666)(:block, (661...666), (660...661)) - ), - StatementsNode(670...673)( - [CallNode(670...673)( - nil, - nil, - (670...673), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [:baz, :bor, :block], - (634...637), - nil, - (641...642), - (666...667), - nil, - (674...677) - ), - DefNode(679...719)( - :foo, - (683...686), - nil, - ParametersNode(687...708)( - [RequiredParameterNode(687...690)(:bar)], - [OptionalParameterNode(692...702)( - :baz, - (692...695), - (696...697), - TrueNode(698...702)() - )], - [], - RestParameterNode(704...708)(:bor, (705...708), (704...705)), - [], - nil, - nil - ), - StatementsNode(712...715)([LocalVariableReadNode(712...715)(:bar, 0)]), - [:bar, :baz, :bor], - (679...682), - nil, - (686...687), - (708...709), - nil, - (716...719) - ), - DefNode(721...746)( - :foo, - (725...728), - nil, - ParametersNode(729...735)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(729...735)(:block, (730...735), (729...730)) - ), - StatementsNode(739...742)( - [CallNode(739...742)( - nil, - nil, - (739...742), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [:block], - (721...724), - nil, - (728...729), - (735...736), - nil, - (743...746) - ), - DefNode(748...778)( - :foo, - (752...755), - nil, - ParametersNode(756...767)( - [RequiredParameterNode(756...759)(:bar)], - [], - [], - nil, - [], - nil, - BlockParameterNode(761...767)(:block, (762...767), (761...762)) - ), - StatementsNode(771...774)([LocalVariableReadNode(771...774)(:bar, 0)]), - [:bar, :block], - (748...751), - nil, - (755...756), - (767...768), - nil, - (775...778) - ), - DefNode(780...803)( - :foo, - (784...787), - nil, - nil, - StatementsNode(790...799)( - [CallNode(790...793)( - nil, - nil, - (790...793), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - CallNode(796...799)( - nil, - nil, - (796...799), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - [], - (780...783), - nil, - nil, - nil, - nil, - (800...803) - ), - DefNode(805...821)( - :f, - (809...810), - nil, - ParametersNode(811...816)( - [RequiredDestructuredParameterNode(811...816)( - [RequiredDestructuredParameterNode(812...815)( - [RequiredParameterNode(813...814)(:a)], - (812...813), - (814...815) - )], - (811...812), - (815...816) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (805...808), - nil, - (810...811), - (816...817), - nil, - (818...821) - ), - DefNode(823...854)( - :foo, - (827...830), - nil, - ParametersNode(831...849)( - [], - [], - [], - nil, - [KeywordParameterNode(831...835)(:bar, (831...835), nil), - KeywordParameterNode(837...849)( - :baz, - (837...841), - StringNode(842...849)( - (842...843), - (843...848), - (848...849), - "value" - ) - )], - nil, - nil - ), - nil, - [:bar, :baz], - (823...826), - nil, - (830...831), - (849...850), - nil, - (851...854) - ), - DefNode(856...896)( - :f, - (860...861), - nil, - nil, - StatementsNode(864...874)( - [InterpolatedStringNode(864...874)( - (864...874), - [StringNode(875...879)(nil, (875...879), nil, " "), - EmbeddedStatementsNode(879...882)((879...881), nil, (881...882)), - StringNode(882...883)(nil, (882...883), nil, "\n")], - (883...893) - )] - ), - [], - (856...859), - nil, - nil, - nil, - nil, - (893...896) - ), - DefNode(898...913)( - :f, - (902...903), - nil, - nil, - StatementsNode(906...909)( - [StringNode(906...909)((906...908), (908...908), (908...909), "")] - ), - [], - (898...901), - nil, - nil, - nil, - nil, - (910...913) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/defined.txt b/test/yarp/snapshots/unparser/corpus/literal/defined.txt deleted file mode 100644 index 58816ee742a8fd..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/defined.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...56)( - [:a, :b], - StatementsNode(0...56)( - [DefinedNode(0...14)( - (8...9), - InstanceVariableReadNode(9...13)(:@foo), - (13...14), - (0...8) - ), - DefinedNode(15...28)( - (23...24), - ConstantReadNode(24...27)(:Foo), - (27...28), - (15...23) - ), - DefinedNode(29...56)( - (37...38), - ParenthesesNode(38...55)( - StatementsNode(39...54)( - [MultiWriteNode(39...54)( - [LocalVariableTargetNode(40...41)(:a, 0), - LocalVariableTargetNode(43...44)(:b, 0)], - (39...40), - (44...45), - (46...47), - ArrayNode(48...54)( - [IntegerNode(49...50)(), IntegerNode(52...53)()], - (48...49), - (53...54) - ) - )] - ), - (38...39), - (54...55) - ), - (55...56), - (29...37) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/defs.txt b/test/yarp/snapshots/unparser/corpus/literal/defs.txt deleted file mode 100644 index fdc08dcc593218..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/defs.txt +++ /dev/null @@ -1,307 +0,0 @@ -ProgramNode(0...266)( - [], - StatementsNode(0...266)( - [DefNode(0...16)( - :foo, - (9...12), - SelfNode(4...8)(), - nil, - nil, - [], - (0...3), - (8...9), - nil, - nil, - nil, - (13...16) - ), - DefNode(18...40)( - :foo, - (27...30), - SelfNode(22...26)(), - nil, - StatementsNode(33...36)( - [CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 2, "bar")] - ), - [], - (18...21), - (26...27), - nil, - nil, - nil, - (37...40) - ), - DefNode(42...70)( - :foo, - (51...54), - SelfNode(46...50)(), - nil, - StatementsNode(57...66)( - [CallNode(57...60)(nil, nil, (57...60), nil, nil, nil, nil, 2, "bar"), - CallNode(63...66)(nil, nil, (63...66), nil, nil, nil, nil, 2, "baz")] - ), - [], - (42...45), - (50...51), - nil, - nil, - nil, - (67...70) - ), - DefNode(72...93)( - :bar, - (80...83), - ConstantReadNode(76...79)(:Foo), - nil, - StatementsNode(86...89)( - [CallNode(86...89)(nil, nil, (86...89), nil, nil, nil, nil, 2, "bar")] - ), - [], - (72...75), - (79...80), - nil, - nil, - nil, - (90...93) - ), - DefNode(95...128)( - :bar, - (115...118), - ParenthesesNode(99...114)( - CallNode(100...113)( - nil, - nil, - (100...103), - nil, - nil, - nil, - BlockNode(104...113)( - [:bar], - BlockParametersNode(106...111)( - ParametersNode(107...110)( - [RequiredParameterNode(107...110)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (106...107), - (110...111) - ), - nil, - (104...105), - (112...113) - ), - 0, - "foo" - ), - (99...100), - (113...114) - ), - nil, - StatementsNode(121...124)( - [CallNode(121...124)( - nil, - nil, - (121...124), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [], - (95...98), - (114...115), - nil, - nil, - nil, - (125...128) - ), - DefNode(130...156)( - :bar, - (143...146), - ParenthesesNode(134...142)( - CallNode(135...141)( - nil, - nil, - (135...138), - (138...139), - ArgumentsNode(139...140)([IntegerNode(139...140)()]), - (140...141), - nil, - 0, - "foo" - ), - (134...135), - (141...142) - ), - nil, - StatementsNode(149...152)( - [CallNode(149...152)( - nil, - nil, - (149...152), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - [], - (130...133), - (142...143), - nil, - nil, - nil, - (153...156) - ), - DefNode(158...190)( - :bar, - (177...180), - ParenthesesNode(162...176)( - CallNode(163...175)( - ConstantPathNode(163...171)( - ConstantReadNode(163...166)(:Foo), - ConstantReadNode(168...171)(:Bar), - (166...168) - ), - (171...172), - (172...175), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - (162...163), - (175...176) - ), - nil, - StatementsNode(183...186)( - [CallNode(183...186)( - nil, - nil, - (183...186), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - [], - (158...161), - (176...177), - nil, - nil, - nil, - (187...190) - ), - DefNode(192...220)( - :bar, - (207...210), - ParenthesesNode(196...206)( - ConstantPathNode(197...205)( - ConstantReadNode(197...200)(:Foo), - ConstantReadNode(202...205)(:Bar), - (200...202) - ), - (196...197), - (205...206) - ), - nil, - StatementsNode(213...216)( - [CallNode(213...216)( - nil, - nil, - (213...216), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - [], - (192...195), - (206...207), - nil, - nil, - nil, - (217...220) - ), - DefNode(222...243)( - :bar, - (230...233), - ConstantReadNode(226...229)(:Foo), - nil, - StatementsNode(236...239)( - [CallNode(236...239)( - nil, - nil, - (236...239), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - [], - (222...225), - (229...230), - nil, - nil, - nil, - (240...243) - ), - DefNode(245...266)( - :bar, - (253...256), - CallNode(249...252)( - nil, - nil, - (249...252), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - StatementsNode(259...262)( - [CallNode(259...262)( - nil, - nil, - (259...262), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - [], - (245...248), - (252...253), - nil, - nil, - nil, - (263...266) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/dstr.txt b/test/yarp/snapshots/unparser/corpus/literal/dstr.txt deleted file mode 100644 index 369e1491e524b0..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/dstr.txt +++ /dev/null @@ -1,205 +0,0 @@ -ProgramNode(0...299)( - [], - StatementsNode(0...299)( - [IfNode(0...20)( - (0...2), - TrueNode(3...7)(), - StatementsNode(10...16)( - [InterpolatedStringNode(10...16)( - (10...11), - [EmbeddedStatementsNode(11...14)((11...13), nil, (13...14)), - StringNode(14...15)(nil, (14...15), nil, "a")], - (15...16) - )] - ), - nil, - (17...20) - ), - IfNode(21...68)( - (21...23), - TrueNode(24...28)(), - StatementsNode(31...64)( - [InterpolatedStringNode(31...41)( - (31...41), - [StringNode(42...44)(nil, (42...44), nil, "a\n"), - EmbeddedStatementsNode(44...47)((44...46), nil, (46...47)), - StringNode(47...51)(nil, (47...51), nil, "a\n" + "b\n")], - (51...61) - ), - CallNode(63...64)(nil, nil, (63...64), nil, nil, nil, nil, 2, "x")] - ), - nil, - (65...68) - ), - InterpolatedStringNode(69...79)( - (69...79), - [StringNode(80...89)(nil, (80...89), nil, "\#{}\#{}\n"), - EmbeddedStatementsNode(89...92)((89...91), nil, (91...92)), - StringNode(92...93)(nil, (92...93), nil, "\n"), - EmbeddedStatementsNode(93...96)((93...95), nil, (95...96)), - StringNode(96...97)(nil, (96...97), nil, "\n"), - EmbeddedStatementsNode(97...100)((97...99), nil, (99...100)), - StringNode(100...101)(nil, (100...101), nil, "\n")], - (101...109) - ), - RescueModifierNode(109...130)( - InterpolatedStringNode(109...119)( - (109...119), - [EmbeddedStatementsNode(131...134)((131...133), nil, (133...134)), - StringNode(134...137)(nil, (134...137), nil, "\n" + "a\n")], - (137...145) - ), - (120...126), - NilNode(127...130)() - ), - InterpolatedStringNode(145...151)( - (145...146), - [StringNode(146...147)(nil, (146...147), nil, "a"), - EmbeddedVariableNode(147...150)( - (147...148), - NumberedReferenceReadNode(148...150)(1) - )], - (150...151) - ), - InterpolatedStringNode(152...158)( - (152...153), - [StringNode(153...154)(nil, (153...154), nil, "a"), - EmbeddedVariableNode(154...157)( - (154...155), - GlobalVariableReadNode(155...157)(:$a) - )], - (157...158) - ), - InterpolatedStringNode(159...165)( - (159...160), - [StringNode(160...161)(nil, (160...161), nil, "a"), - EmbeddedVariableNode(161...164)( - (161...162), - InstanceVariableReadNode(162...164)(:@a) - )], - (164...165) - ), - InterpolatedStringNode(166...173)( - (166...167), - [StringNode(167...168)(nil, (167...168), nil, "a"), - EmbeddedVariableNode(168...172)( - (168...169), - ClassVariableReadNode(169...172)(:@@a) - )], - (172...173) - ), - IfNode(174...225)( - (174...176), - TrueNode(177...181)(), - StatementsNode(184...201)( - [ReturnNode(184...201)( - (184...190), - ArgumentsNode(191...201)( - [InterpolatedStringNode(191...201)( - (191...201), - [StringNode(202...206)(nil, (202...206), nil, " "), - EmbeddedStatementsNode(206...211)( - (206...208), - StatementsNode(208...210)([IntegerNode(208...210)()]), - (210...211) - ), - StringNode(211...212)(nil, (211...212), nil, "\n")], - (212...222) - )] - ) - )] - ), - nil, - (222...225) - ), - CallNode(226...241)( - nil, - nil, - (226...229), - (229...230), - ArgumentsNode(230...240)( - [InterpolatedStringNode(230...240)( - (230...240), - [StringNode(242...244)(nil, (242...244), nil, " "), - EmbeddedStatementsNode(244...250)( - (244...246), - StatementsNode(246...249)( - [CallNode(246...249)( - nil, - nil, - (246...249), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (249...250) - ), - StringNode(250...251)(nil, (250...251), nil, "\n")], - (251...259) - )] - ), - (240...241), - nil, - 0, - "foo" - ), - CallNode(259...299)( - nil, - nil, - (259...262), - (262...263), - ArgumentsNode(263...273)( - [InterpolatedStringNode(263...273)( - (263...273), - [StringNode(281...283)(nil, (281...283), nil, " "), - EmbeddedStatementsNode(283...289)( - (283...285), - StatementsNode(285...288)( - [CallNode(285...288)( - nil, - nil, - (285...288), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (288...289) - ), - StringNode(289...290)(nil, (289...290), nil, "\n")], - (290...298) - )] - ), - (273...274), - BlockNode(275...299)( - [:x], - BlockParametersNode(277...280)( - ParametersNode(278...279)( - [RequiredParameterNode(278...279)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (277...278), - (279...280) - ), - nil, - (275...276), - (298...299) - ), - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/empty.txt b/test/yarp/snapshots/unparser/corpus/literal/empty.txt deleted file mode 100644 index bd3eaf5ff49bc2..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/empty.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...0)([], StatementsNode(0...0)([])) diff --git a/test/yarp/snapshots/unparser/corpus/literal/empty_begin.txt b/test/yarp/snapshots/unparser/corpus/literal/empty_begin.txt deleted file mode 100644 index d998f704cfd2c5..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/empty_begin.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)([ParenthesesNode(0...2)(nil, (0...1), (1...2))]) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt b/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt deleted file mode 100644 index b08835a4c37ad1..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/flipflop.txt +++ /dev/null @@ -1,149 +0,0 @@ -ProgramNode(0...68)( - [], - StatementsNode(0...68)( - [IfNode(0...33)( - (0...2), - ParenthesesNode(3...23)( - StatementsNode(4...22)( - [FlipFlopNode(4...22)( - ParenthesesNode(4...12)( - StatementsNode(5...11)( - [CallNode(5...11)( - CallNode(5...6)( - nil, - nil, - (5...6), - nil, - nil, - nil, - nil, - 2, - "i" - ), - nil, - (7...9), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "==" - )] - ), - (4...5), - (11...12) - ), - ParenthesesNode(14...22)( - StatementsNode(15...21)( - [CallNode(15...21)( - CallNode(15...16)( - nil, - nil, - (15...16), - nil, - nil, - nil, - nil, - 2, - "i" - ), - nil, - (17...19), - nil, - ArgumentsNode(20...21)([IntegerNode(20...21)()]), - nil, - nil, - 0, - "==" - )] - ), - (14...15), - (21...22) - ), - (12...14), - 0 - )] - ), - (3...4), - (22...23) - ), - StatementsNode(26...29)( - [CallNode(26...29)(nil, nil, (26...29), nil, nil, nil, nil, 2, "foo")] - ), - nil, - (30...33) - ), - IfNode(34...68)( - (34...36), - ParenthesesNode(37...58)( - StatementsNode(38...57)( - [FlipFlopNode(38...57)( - ParenthesesNode(38...46)( - StatementsNode(39...45)( - [CallNode(39...45)( - CallNode(39...40)( - nil, - nil, - (39...40), - nil, - nil, - nil, - nil, - 2, - "i" - ), - nil, - (41...43), - nil, - ArgumentsNode(44...45)([IntegerNode(44...45)()]), - nil, - nil, - 0, - "==" - )] - ), - (38...39), - (45...46) - ), - ParenthesesNode(49...57)( - StatementsNode(50...56)( - [CallNode(50...56)( - CallNode(50...51)( - nil, - nil, - (50...51), - nil, - nil, - nil, - nil, - 2, - "i" - ), - nil, - (52...54), - nil, - ArgumentsNode(55...56)([IntegerNode(55...56)()]), - nil, - nil, - 0, - "==" - )] - ), - (49...50), - (56...57) - ), - (46...49), - 1 - )] - ), - (37...38), - (57...58) - ), - StatementsNode(61...64)( - [CallNode(61...64)(nil, nil, (61...64), nil, nil, nil, nil, 2, "foo")] - ), - nil, - (65...68) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/for.txt b/test/yarp/snapshots/unparser/corpus/literal/for.txt deleted file mode 100644 index 7ede529a814716..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/for.txt +++ /dev/null @@ -1,122 +0,0 @@ -ProgramNode(0...119)( - [:a, :b], - StatementsNode(0...119)( - [CallNode(0...30)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...29)( - [ForNode(4...29)( - MultiTargetNode(8...9)( - [LocalVariableTargetNode(8...9)(:a, 0)], - nil, - nil - ), - CallNode(13...16)( - nil, - nil, - (13...16), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - StatementsNode(22...25)( - [CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (4...7), - (10...12), - (17...19), - (26...29) - )] - ), - (29...30), - nil, - 0, - "bar" - ), - ForNode(31...56)( - MultiTargetNode(35...36)( - [LocalVariableTargetNode(35...36)(:a, 0)], - nil, - nil - ), - CallNode(40...43)(nil, nil, (40...43), nil, nil, nil, nil, 2, "bar"), - StatementsNode(49...52)( - [CallNode(49...52)(nil, nil, (49...52), nil, nil, nil, nil, 2, "baz")] - ), - (31...34), - (37...39), - (44...46), - (53...56) - ), - ForNode(57...88)( - MultiTargetNode(61...68)( - [LocalVariableTargetNode(62...63)(:a, 0), - SplatNode(65...67)( - (65...66), - LocalVariableTargetNode(66...67)(:b, 0) - )], - (61...62), - (67...68) - ), - CallNode(72...75)(nil, nil, (72...75), nil, nil, nil, nil, 2, "bar"), - StatementsNode(81...84)( - [CallNode(81...84)(nil, nil, (81...84), nil, nil, nil, nil, 2, "baz")] - ), - (57...60), - (69...71), - (76...78), - (85...88) - ), - ForNode(89...119)( - MultiTargetNode(93...99)( - [LocalVariableTargetNode(94...95)(:a, 0), - LocalVariableTargetNode(97...98)(:b, 0)], - (93...94), - (98...99) - ), - CallNode(103...106)( - nil, - nil, - (103...106), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - StatementsNode(112...115)( - [CallNode(112...115)( - nil, - nil, - (112...115), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (89...92), - (100...102), - (107...109), - (116...119) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/hookexe.txt b/test/yarp/snapshots/unparser/corpus/literal/hookexe.txt deleted file mode 100644 index b97bd65ad1722e..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/hookexe.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [PreExecutionNode(0...15)( - StatementsNode(10...13)( - [CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo")] - ), - (0...5), - (6...7), - (14...15) - ), - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "bar"), - PostExecutionNode(20...33)( - StatementsNode(28...31)( - [CallNode(28...31)(nil, nil, (28...31), nil, nil, nil, nil, 2, "baz")] - ), - (20...23), - (24...25), - (32...33) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/if.txt b/test/yarp/snapshots/unparser/corpus/literal/if.txt deleted file mode 100644 index 610dac8d92a5b1..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/if.txt +++ /dev/null @@ -1,203 +0,0 @@ -ProgramNode(0...246)( - [:foo, :pair], - StatementsNode(0...246)( - [IfNode(0...18)( - (0...2), - RegularExpressionNode(3...8)((3...4), (4...7), (7...8), "foo", 0), - StatementsNode(11...14)( - [CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (15...18) - ), - IfNode(19...31)( - (19...21), - IntegerNode(22...23)(), - StatementsNode(26...27)([IntegerNode(26...27)()]), - nil, - (28...31) - ), - IfNode(32...53)( - (32...34), - IntegerNode(35...36)(), - StatementsNode(39...40)([IntegerNode(39...40)()]), - ElseNode(41...53)( - (41...45), - StatementsNode(48...49)([IntegerNode(48...49)()]), - (50...53) - ), - (50...53) - ), - UnlessNode(54...72)( - (54...60), - IntegerNode(61...62)(), - StatementsNode(65...68)([NilNode(65...68)()]), - nil, - (69...72) - ), - UnlessNode(73...89)( - (73...79), - IntegerNode(80...81)(), - StatementsNode(84...85)([IntegerNode(84...85)()]), - nil, - (86...89) - ), - IfNode(90...100)( - (90...92), - CallNode(93...96)(nil, nil, (93...96), nil, nil, nil, nil, 2, "foo"), - nil, - nil, - (97...100) - ), - ModuleNode(102...133)( - [:foo], - (102...108), - ConstantReadNode(109...110)(:A), - StatementsNode(113...129)( - [IfNode(113...129)( - (123...125), - LocalVariableReadNode(126...129)(:foo, 0), - StatementsNode(113...122)( - [LocalVariableWriteNode(113...122)( - :foo, - 0, - (113...116), - CallNode(119...122)( - nil, - nil, - (119...122), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (117...118) - )] - ), - nil, - nil - )] - ), - (130...133), - :A - ), - ModuleNode(135...170)( - [:foo], - (135...141), - ConstantReadNode(142...143)(:B), - StatementsNode(146...166)( - [UnlessNode(146...166)( - (156...162), - LocalVariableReadNode(163...166)(:foo, 0), - StatementsNode(146...155)( - [LocalVariableWriteNode(146...155)( - :foo, - 0, - (146...149), - CallNode(152...155)( - nil, - nil, - (152...155), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (150...151) - )] - ), - nil, - nil - )] - ), - (167...170), - :B - ), - UnlessNode(171...197)( - (171...177), - CallNode(178...181)( - nil, - nil, - (178...181), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StatementsNode(184...193)( - [LocalVariableWriteNode(184...193)( - :foo, - 0, - (184...187), - CallNode(190...193)( - nil, - nil, - (190...193), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (188...189) - )] - ), - nil, - (194...197) - ), - IfNode(198...246)( - (198...200), - CallNode(201...222)( - nil, - nil, - (201...204), - nil, - nil, - nil, - BlockNode(205...222)( - [:pair], - BlockParametersNode(207...213)( - ParametersNode(208...212)( - [RequiredParameterNode(208...212)(:pair)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (207...208), - (212...213) - ), - StatementsNode(216...220)( - [LocalVariableReadNode(216...220)(:pair, 0)] - ), - (205...206), - (221...222) - ), - 0, - "foo" - ), - StatementsNode(225...242)( - [LocalVariableWriteNode(225...236)( - :pair, - 0, - (225...229), - SymbolNode(232...236)((232...233), (233...236), nil, "foo"), - (230...231) - ), - LocalVariableReadNode(239...242)(:foo, 0)] - ), - nil, - (243...246) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt b/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt deleted file mode 100644 index 79f4c36be646ee..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/kwbegin.txt +++ /dev/null @@ -1,376 +0,0 @@ -ProgramNode(0...530)( - [:foo, :bar, :exception], - StatementsNode(0...530)( - [BeginNode(0...16)( - (0...5), - nil, - RescueNode(6...12)((6...12), [], nil, nil, nil, nil), - nil, - nil, - (13...16) - ), - BeginNode(18...34)( - (18...23), - nil, - nil, - nil, - EnsureNode(24...34)((24...30), nil, (31...34)), - (31...34) - ), - BeginNode(36...49)( - (36...41), - StatementsNode(44...45)( - [CallNode(44...45)(nil, nil, (44...45), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - nil, - (46...49) - ), - BeginNode(51...75)( - (51...56), - StatementsNode(59...60)( - [CallNode(59...60)(nil, nil, (59...60), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(61...71)( - (61...67), - [], - nil, - nil, - StatementsNode(70...71)( - [CallNode(70...71)(nil, nil, (70...71), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - nil, - nil, - (72...75) - ), - BeginNode(77...105)( - (77...82), - StatementsNode(85...90)( - [CallNode(85...86)(nil, nil, (85...86), nil, nil, nil, nil, 2, "a"), - CallNode(89...90)(nil, nil, (89...90), nil, nil, nil, nil, 2, "b")] - ), - RescueNode(91...101)( - (91...97), - [], - nil, - nil, - StatementsNode(100...101)( - [CallNode(100...101)( - nil, - nil, - (100...101), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (102...105) - ), - BeginNode(107...125)( - (107...112), - nil, - RescueNode(113...121)( - (113...119), - [ConstantReadNode(120...121)(:A)], - nil, - nil, - nil, - nil - ), - nil, - nil, - (122...125) - ), - BeginNode(127...152)( - (127...132), - nil, - RescueNode(133...148)( - (133...139), - [ConstantReadNode(140...141)(:A)], - (142...144), - LocalVariableTargetNode(145...148)(:foo, 0), - nil, - nil - ), - nil, - nil, - (149...152) - ), - BeginNode(154...204)( - (154...159), - StatementsNode(162...163)( - [CallNode(162...163)( - nil, - nil, - (162...163), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(164...189)( - (164...170), - [ConstantReadNode(171...172)(:A)], - nil, - nil, - StatementsNode(175...176)( - [CallNode(175...176)( - nil, - nil, - (175...176), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - RescueNode(177...189)( - (177...183), - [ConstantReadNode(184...185)(:B)], - nil, - nil, - StatementsNode(188...189)( - [CallNode(188...189)( - nil, - nil, - (188...189), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - nil - ) - ), - nil, - EnsureNode(190...204)( - (190...196), - StatementsNode(199...200)( - [CallNode(199...200)( - nil, - nil, - (199...200), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (201...204) - ), - (201...204) - ), - BeginNode(206...273)( - (206...211), - StatementsNode(214...250)( - [BeginNode(214...250)( - (214...219), - StatementsNode(224...235)( - [LocalVariableReadNode(224...227)(:foo, 0), - CallNode(232...235)( - nil, - nil, - (232...235), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - RescueNode(238...244)((238...244), [], nil, nil, nil, nil), - nil, - nil, - (247...250) - )] - ), - RescueNode(251...269)( - (251...257), - [], - nil, - nil, - StatementsNode(260...269)( - [CallNode(260...263)( - nil, - nil, - (260...263), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - CallNode(266...269)( - nil, - nil, - (266...269), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (270...273) - ), - BeginNode(275...337)( - (275...280), - StatementsNode(283...316)( - [RescueModifierNode(283...316)( - CallNode(283...299)( - nil, - nil, - (283...288), - (288...289), - ArgumentsNode(289...298)( - [ConstantReadNode(289...298)(:Exception)] - ), - (298...299), - nil, - 0, - "raise" - ), - (300...306), - LocalVariableWriteNode(307...316)( - :foo, - 0, - (307...310), - CallNode(313...316)( - nil, - nil, - (313...316), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (311...312) - ) - )] - ), - RescueNode(317...333)( - (317...323), - [ConstantReadNode(324...333)(:Exception)], - nil, - nil, - nil, - nil - ), - nil, - nil, - (334...337) - ), - BeginNode(339...374)( - (339...344), - StatementsNode(347...350)([LocalVariableReadNode(347...350)(:foo, 0)]), - RescueNode(351...370)( - (351...357), - [], - (358...360), - LocalVariableTargetNode(361...364)(:bar, 0), - StatementsNode(367...370)( - [LocalVariableReadNode(367...370)(:bar, 0)] - ), - nil - ), - nil, - nil, - (371...374) - ), - BeginNode(376...428)( - (376...381), - StatementsNode(384...387)([LocalVariableReadNode(384...387)(:foo, 0)]), - RescueNode(388...424)( - (388...394), - [ConstantReadNode(395...404)(:Exception), - ConstantReadNode(406...411)(:Other)], - (412...414), - LocalVariableTargetNode(415...418)(:bar, 0), - StatementsNode(421...424)( - [LocalVariableReadNode(421...424)(:bar, 0)] - ), - nil - ), - nil, - nil, - (425...428) - ), - BeginNode(430...487)( - (430...435), - StatementsNode(438...441)([LocalVariableReadNode(438...441)(:bar, 0)]), - RescueNode(442...483)( - (442...448), - [ConstantReadNode(449...458)(:SomeError), - SplatNode(460...464)( - (460...461), - LocalVariableReadNode(461...464)(:bar, 0) - )], - (465...467), - LocalVariableTargetNode(468...477)(:exception, 0), - StatementsNode(480...483)( - [CallNode(480...483)( - nil, - nil, - (480...483), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - nil, - (484...487) - ), - SingletonClassNode(489...530)( - [], - (489...494), - (495...497), - SelfNode(498...502)(), - StatementsNode(505...526)( - [RescueModifierNode(505...526)( - UndefNode(505...515)( - [SymbolNode(511...515)((511...512), (512...515), nil, "bar")], - (505...510) - ), - (516...522), - NilNode(523...526)() - )] - ), - (527...530) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/lambda.txt b/test/yarp/snapshots/unparser/corpus/literal/lambda.txt deleted file mode 100644 index 8c036bd70dfe60..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/lambda.txt +++ /dev/null @@ -1,120 +0,0 @@ -ProgramNode(0...80)( - [], - StatementsNode(0...80)( - [CallNode(0...10)( - nil, - nil, - (0...6), - nil, - nil, - nil, - BlockNode(7...10)([], nil, nil, (7...8), (9...10)), - 0, - "lambda" - ), - CallNode(11...32)( - nil, - nil, - (11...17), - nil, - nil, - nil, - BlockNode(18...32)( - [:a, :b], - BlockParametersNode(20...26)( - ParametersNode(21...25)( - [RequiredParameterNode(21...22)(:a), - RequiredParameterNode(24...25)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (20...21), - (25...26) - ), - StatementsNode(29...30)([LocalVariableReadNode(29...30)(:a, 0)]), - (18...19), - (31...32) - ), - 0, - "lambda" - ), - LambdaNode(33...41)( - [], - (33...35), - (38...39), - (40...41), - BlockParametersNode(35...37)(nil, [], (35...36), (36...37)), - nil - ), - LambdaNode(42...51)( - [:a], - (42...44), - (48...49), - (50...51), - BlockParametersNode(44...47)( - ParametersNode(45...46)( - [RequiredParameterNode(45...46)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (44...45), - (46...47) - ), - nil - ), - LambdaNode(52...64)( - [:a, :b], - (52...54), - (61...62), - (63...64), - BlockParametersNode(54...60)( - ParametersNode(55...59)( - [RequiredParameterNode(55...56)(:a), - RequiredParameterNode(58...59)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (54...55), - (59...60) - ), - nil - ), - LambdaNode(65...80)( - [:a, :b, :c], - (65...67), - (77...78), - (79...80), - BlockParametersNode(67...76)( - ParametersNode(68...72)( - [RequiredParameterNode(68...69)(:a), - RequiredParameterNode(71...72)(:b)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(74...75)(:c)], - (67...68), - (75...76) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/literal.txt b/test/yarp/snapshots/unparser/corpus/literal/literal.txt deleted file mode 100644 index 8af9ea3c5e0dce..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/literal.txt +++ /dev/null @@ -1,716 +0,0 @@ -ProgramNode(0...916)( - [], - StatementsNode(0...916)( - [HashNode(0...38)( - (0...1), - [AssocNode(2...21)( - StringNode(2...7)((2...3), (3...6), (6...7), "foo"), - InterpolatedStringNode(11...21)( - (11...21), - [StringNode(39...41)(nil, (39...41), nil, " "), - EmbeddedStatementsNode(41...44)((41...43), nil, (43...44)), - StringNode(44...45)(nil, (44...45), nil, "\n")], - (45...53) - ), - (8...10) - ), - AssocNode(23...36)( - StringNode(23...28)((23...24), (24...27), (27...28), "bar"), - SymbolNode(32...36)((32...33), (33...36), nil, "baz"), - (29...31) - )], - (37...38) - ), - HashNode(53...84)( - (53...54), - [AssocNode(55...67)( - StringNode(55...60)((55...56), (56...59), (59...60), "foo"), - StringNode(64...67)((64...66), (66...66), (66...67), ""), - (61...63) - ), - AssocNode(69...82)( - StringNode(69...74)((69...70), (70...73), (73...74), "bar"), - SymbolNode(78...82)((78...79), (79...82), nil, "baz"), - (75...77) - )], - (83...84) - ), - ArrayNode(85...97)( - [StringNode(86...91)((86...87), (87...90), (90...91), "foo"), - StringNode(93...96)((93...95), (95...95), (95...96), "")], - (85...86), - (96...97) - ), - CallNode(98...113)( - CallNode(98...111)( - nil, - nil, - (98...99), - (99...100), - ArgumentsNode(100...110)( - [InterpolatedStringNode(100...110)( - (100...110), - [StringNode(114...116)(nil, (114...116), nil, " "), - EmbeddedStatementsNode(116...119)( - (116...118), - nil, - (118...119) - ), - StringNode(119...120)(nil, (119...120), nil, "\n")], - (120...128) - )] - ), - (110...111), - nil, - 0, - "a" - ), - (111...112), - (112...113), - nil, - nil, - nil, - nil, - 0, - "a" - ), - CallNode(128...136)( - CallNode(128...134)( - nil, - nil, - (128...129), - (129...130), - ArgumentsNode(130...133)( - [StringNode(130...133)((130...132), (132...132), (132...133), "")] - ), - (133...134), - nil, - 0, - "a" - ), - (134...135), - (135...136), - nil, - nil, - nil, - nil, - 0, - "a" - ), - HashNode(137...167)( - (137...138), - [AssocNode(139...158)( - StringNode(139...144)((139...140), (140...143), (143...144), "foo"), - InterpolatedStringNode(148...158)( - (148...158), - [StringNode(168...170)(nil, (168...170), nil, " "), - EmbeddedStatementsNode(170...173)((170...172), nil, (172...173)), - StringNode(173...174)(nil, (173...174), nil, "\n")], - (174...182) - ), - (145...147) - ), - AssocSplatNode(160...165)( - CallNode(162...165)( - nil, - nil, - (162...165), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (160...162) - )], - (166...167) - ), - HashNode(182...205)( - (182...183), - [AssocNode(184...196)( - StringNode(184...189)((184...185), (185...188), (188...189), "foo"), - StringNode(193...196)((193...195), (195...195), (195...196), ""), - (190...192) - ), - AssocSplatNode(198...203)( - CallNode(200...203)( - nil, - nil, - (200...203), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (198...200) - )], - (204...205) - ), - InterpolatedStringNode(206...220)( - (206...207), - [EmbeddedVariableNode(207...210)( - (207...208), - InstanceVariableReadNode(208...210)(:@a) - ), - StringNode(210...211)(nil, (210...211), nil, " "), - EmbeddedVariableNode(211...215)( - (211...212), - ClassVariableReadNode(212...215)(:@@a) - ), - StringNode(215...216)(nil, (215...216), nil, " "), - EmbeddedVariableNode(216...219)( - (216...217), - GlobalVariableReadNode(217...219)(:$a) - )], - (219...220) - ), - IntegerNode(221...222)(), - CallNode(223...226)( - IntegerNode(224...226)(), - nil, - (223...224), - nil, - nil, - nil, - nil, - 0, - "+@" - ), - IntegerNode(227...228)(), - IntegerNode(229...230)(), - RationalNode(231...233)(IntegerNode(231...232)()), - RationalNode(234...238)(FloatNode(234...237)()), - RationalNode(239...243)(FloatNode(239...242)()), - ImaginaryNode(244...246)(IntegerNode(244...245)()), - ImaginaryNode(247...250)(IntegerNode(247...249)()), - ImaginaryNode(251...255)(FloatNode(251...254)()), - ImaginaryNode(256...261)(FloatNode(256...260)()), - ImaginaryNode(262...294)(IntegerNode(262...293)()), - ImaginaryNode(295...298)( - RationalNode(295...297)(IntegerNode(295...296)()) - ), - StringConcatNode(299...310)( - StringNode(299...304)((299...300), (300...303), (303...304), "foo"), - StringNode(305...310)((305...306), (306...309), (309...310), "bar") - ), - InterpolatedStringNode(311...326)( - (311...312), - [StringNode(312...319)(nil, (312...319), nil, "foobar "), - EmbeddedStatementsNode(319...325)( - (319...321), - StatementsNode(321...324)( - [CallNode(321...324)( - nil, - nil, - (321...324), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (324...325) - )], - (325...326) - ), - InterpolatedStringNode(327...339)( - (327...328), - [StringNode(328...331)(nil, (328...331), nil, "foo"), - EmbeddedStatementsNode(331...335)( - (331...333), - StatementsNode(333...334)([IntegerNode(333...334)()]), - (334...335) - ), - StringNode(335...338)(nil, (335...338), nil, "bar")], - (338...339) - ), - InterpolatedStringNode(340...349)( - (340...341), - [StringNode(341...345)(nil, (341...345), nil, "\\\\"), - EmbeddedStatementsNode(345...348)((345...347), nil, (347...348))], - (348...349) - ), - InterpolatedStringNode(350...359)( - (350...351), - [EmbeddedStatementsNode(351...354)((351...353), nil, (353...354)), - StringNode(354...358)(nil, (354...358), nil, "\#{}")], - (358...359) - ), - InterpolatedStringNode(360...369)( - (360...361), - [StringNode(361...365)(nil, (361...365), nil, "\#{}"), - EmbeddedStatementsNode(365...368)((365...367), nil, (367...368))], - (368...369) - ), - StringNode(370...385)( - (370...371), - (371...384), - (384...385), - "foo\\\#{@bar}" - ), - StringNode(386...390)((386...387), (387...389), (389...390), "\""), - StringNode(391...400)((391...392), (392...399), (399...400), "foo bar"), - StringNode(401...411)( - (401...402), - (402...410), - (410...411), - "foo\n" + "bar" - ), - XStringNode(412...417)((412...413), (413...416), (416...417), "foo"), - InterpolatedXStringNode(418...430)( - (418...419), - [StringNode(419...422)(nil, (419...422), nil, "foo"), - EmbeddedStatementsNode(422...429)( - (422...424), - StatementsNode(424...428)( - [InstanceVariableReadNode(424...428)(:@bar)] - ), - (428...429) - )], - (429...430) - ), - XStringNode(431...434)((431...432), (432...433), (433...434), ")"), - XStringNode(435...439)((435...436), (436...438), (438...439), "`"), - XStringNode(440...443)((440...441), (441...442), (442...443), "\""), - SymbolNode(444...448)((444...445), (445...448), nil, "foo"), - SymbolNode(449...455)((449...451), (451...454), (454...455), "A B"), - SymbolNode(456...460)((456...457), (457...460), nil, "foo"), - SymbolNode(461...467)((461...463), (463...466), (466...467), "A B"), - SymbolNode(468...475)((468...470), (470...474), (474...475), "A\"B"), - SymbolNode(476...479)((476...478), (0...0), (478...479), ""), - RegularExpressionNode(480...485)( - (480...481), - (481...484), - (484...485), - "foo", - 0 - ), - RegularExpressionNode(486...514)( - (486...487), - (487...513), - (513...514), - "[^-+',./:@[:alnum:][]]+", - 0 - ), - InterpolatedRegularExpressionNode(515...527)( - (515...516), - [StringNode(516...519)(nil, (516...519), nil, "foo"), - EmbeddedStatementsNode(519...526)( - (519...521), - StatementsNode(521...525)( - [InstanceVariableReadNode(521...525)(:@bar)] - ), - (525...526) - )], - (526...527), - 0 - ), - InterpolatedRegularExpressionNode(528...543)( - (528...529), - [StringNode(529...532)(nil, (529...532), nil, "foo"), - EmbeddedStatementsNode(532...539)( - (532...534), - StatementsNode(534...538)( - [InstanceVariableReadNode(534...538)(:@bar)] - ), - (538...539) - )], - (539...543), - 7 - ), - InterpolatedRegularExpressionNode(544...557)( - (544...545), - [EmbeddedStatementsNode(545...556)( - (545...547), - StatementsNode(547...555)( - [StringNode(547...555)( - (547...548), - (548...554), - (554...555), - "\u0000" - )] - ), - (555...556) - )], - (556...557), - 0 - ), - RegularExpressionNode(558...562)( - (558...559), - (559...561), - (561...562), - "\n", - 0 - ), - RegularExpressionNode(563...567)( - (563...564), - (564...566), - (566...567), - "\n", - 0 - ), - RegularExpressionNode(568...573)( - (568...569), - (569...571), - (571...573), - "\n", - 4 - ), - RegularExpressionNode(574...581)( - (574...575), - (575...579), - (579...581), - "//", - 4 - ), - InterpolatedSymbolNode(582...597)( - (582...584), - [StringNode(584...587)(nil, (584...587), nil, "foo"), - EmbeddedStatementsNode(587...593)( - (587...589), - StatementsNode(589...592)( - [CallNode(589...592)( - nil, - nil, - (589...592), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (592...593) - ), - StringNode(593...596)(nil, (593...596), nil, "baz")], - (596...597) - ), - InterpolatedSymbolNode(598...609)( - (598...600), - [EmbeddedStatementsNode(600...608)( - (600...602), - StatementsNode(602...607)( - [StringNode(602...607)( - (602...603), - (603...606), - (606...607), - "foo" - )] - ), - (607...608) - )], - (608...609) - ), - RangeNode(610...624)( - ParenthesesNode(610...621)( - StatementsNode(611...620)( - [CallNode(611...620)( - FloatNode(611...614)(), - nil, - (615...616), - nil, - ArgumentsNode(617...620)([FloatNode(617...620)()]), - nil, - nil, - 0, - "/" - )] - ), - (610...611), - (620...621) - ), - IntegerNode(623...624)(), - (621...623), - 0 - ), - RangeNode(625...639)( - IntegerNode(625...626)(), - ParenthesesNode(628...639)( - StatementsNode(629...638)( - [CallNode(629...638)( - FloatNode(629...632)(), - nil, - (633...634), - nil, - ArgumentsNode(635...638)([FloatNode(635...638)()]), - nil, - nil, - 0, - "/" - )] - ), - (628...629), - (638...639) - ), - (626...628), - 0 - ), - RangeNode(640...656)( - ParenthesesNode(640...651)( - StatementsNode(641...650)( - [CallNode(641...650)( - FloatNode(641...644)(), - nil, - (645...646), - nil, - ArgumentsNode(647...650)([FloatNode(647...650)()]), - nil, - nil, - 0, - "/" - )] - ), - (640...641), - (650...651) - ), - IntegerNode(653...656)(), - (651...653), - 0 - ), - FloatNode(657...661)(), - FloatNode(662...665)(), - ArrayNode(666...672)( - [IntegerNode(667...668)(), IntegerNode(670...671)()], - (666...667), - (671...672) - ), - ArrayNode(673...684)( - [IntegerNode(674...675)(), - ParenthesesNode(677...679)(nil, (677...678), (678...679)), - CallNode(681...683)( - nil, - nil, - (681...683), - nil, - nil, - nil, - nil, - 2, - "n2" - )], - (673...674), - (683...684) - ), - ArrayNode(685...688)( - [IntegerNode(686...687)()], - (685...686), - (687...688) - ), - ArrayNode(689...691)([], (689...690), (690...691)), - ArrayNode(692...702)( - [IntegerNode(693...694)(), - SplatNode(696...701)( - (696...697), - InstanceVariableReadNode(697...701)(:@foo) - )], - (692...693), - (701...702) - ), - ArrayNode(703...713)( - [SplatNode(704...709)( - (704...705), - InstanceVariableReadNode(705...709)(:@foo) - ), - IntegerNode(711...712)()], - (703...704), - (712...713) - ), - ArrayNode(714...728)( - [SplatNode(715...720)( - (715...716), - InstanceVariableReadNode(716...720)(:@foo) - ), - SplatNode(722...727)( - (722...723), - InstanceVariableReadNode(723...727)(:@baz) - )], - (714...715), - (727...728) - ), - HashNode(729...731)((729...730), [], (730...731)), - HashNode(732...744)( - (732...733), - [AssocNode(734...742)( - ParenthesesNode(734...736)(nil, (734...735), (735...736)), - ParenthesesNode(740...742)(nil, (740...741), (741...742)), - (737...739) - )], - (743...744) - ), - HashNode(745...755)( - (745...746), - [AssocNode(747...753)( - IntegerNode(747...748)(), - IntegerNode(752...753)(), - (749...751) - )], - (754...755) - ), - HashNode(756...774)( - (756...757), - [AssocNode(758...764)( - IntegerNode(758...759)(), - IntegerNode(763...764)(), - (760...762) - ), - AssocNode(766...772)( - IntegerNode(766...767)(), - IntegerNode(771...772)(), - (768...770) - )], - (773...774) - ), - HashNode(775...802)( - (775...776), - [AssocNode(777...794)( - SymbolNode(777...779)(nil, (777...778), (778...779), "a"), - ParenthesesNode(780...794)( - StatementsNode(781...793)( - [RescueModifierNode(781...793)( - IntegerNode(781...782)(), - (783...789), - CallNode(790...793)( - nil, - nil, - (790...793), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )] - ), - (780...781), - (793...794) - ), - nil - ), - AssocNode(796...800)( - SymbolNode(796...798)(nil, (796...797), (797...798), "b"), - IntegerNode(799...800)(), - nil - )], - (801...802) - ), - HashNode(803...817)( - (803...804), - [AssocNode(805...809)( - SymbolNode(805...807)(nil, (805...806), (806...807), "a"), - IntegerNode(808...809)(), - nil - ), - AssocNode(811...815)( - SymbolNode(811...813)(nil, (811...812), (812...813), "b"), - IntegerNode(814...815)(), - nil - )], - (816...817) - ), - HashNode(818...827)( - (818...819), - [AssocNode(820...825)( - SymbolNode(820...822)(nil, (820...821), (821...822), "a"), - SymbolNode(823...825)((823...824), (824...825), nil, "a"), - nil - )], - (826...827) - ), - HashNode(828...843)( - (828...829), - [AssocNode(830...841)( - SymbolNode(830...836)((830...832), (832...835), (835...836), "a b"), - IntegerNode(840...841)(), - (837...839) - )], - (842...843) - ), - HashNode(844...856)( - (844...845), - [AssocNode(846...854)( - SymbolNode(846...849)((846...847), (847...849), nil, "-@"), - IntegerNode(853...854)(), - (850...852) - )], - (855...856) - ), - InterpolatedStringNode(857...869)( - (857...858), - [EmbeddedStatementsNode(858...861)((858...860), nil, (860...861)), - StringNode(861...862)(nil, (861...862), nil, "\n"), - EmbeddedStatementsNode(862...865)((862...864), nil, (864...865)), - StringNode(865...868)(nil, (865...868), nil, "\n" + "a")], - (868...869) - ), - CallNode(870...892)( - nil, - nil, - (870...873), - nil, - nil, - nil, - BlockNode(874...892)( - [], - nil, - StatementsNode(878...890)( - [InterpolatedStringNode(878...890)( - (878...879), - [EmbeddedStatementsNode(879...882)( - (879...881), - nil, - (881...882) - ), - StringNode(882...883)(nil, (882...883), nil, "\n"), - EmbeddedStatementsNode(883...886)( - (883...885), - nil, - (885...886) - ), - StringNode(886...889)(nil, (886...889), nil, "\n" + "a")], - (889...890) - )] - ), - (874...875), - (891...892) - ), - 0, - "foo" - ), - SymbolNode(893...901)( - (893...895), - (895...900), - (900...901), - "a\\\n" + "b" - ), - InterpolatedXStringNode(902...916)( - (902...903), - [StringNode(903...907)(nil, (903...907), nil, " x\n"), - EmbeddedStatementsNode(907...913)( - (907...909), - StatementsNode(909...912)( - [CallNode(909...912)( - nil, - nil, - (909...912), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (912...913) - ), - StringNode(913...915)(nil, (913...915), nil, "\n" + "#")], - (915...916) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/module.txt b/test/yarp/snapshots/unparser/corpus/literal/module.txt deleted file mode 100644 index 355b57ac531e21..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/module.txt +++ /dev/null @@ -1,89 +0,0 @@ -ProgramNode(0...106)( - [], - StatementsNode(0...106)( - [ModuleNode(0...12)( - [], - (0...6), - ConstantReadNode(7...8)(:A), - nil, - (9...12), - :A - ), - ModuleNode(14...29)( - [], - (14...20), - ConstantPathNode(21...25)( - ConstantReadNode(21...22)(:A), - ConstantReadNode(24...25)(:B), - (22...24) - ), - nil, - (26...29), - :B - ), - ModuleNode(31...49)( - [], - (31...37), - ConstantPathNode(38...45)( - ConstantPathNode(38...42)( - ConstantReadNode(38...39)(:A), - ConstantReadNode(41...42)(:B), - (39...41) - ), - ConstantReadNode(44...45)(:C), - (42...44) - ), - nil, - (46...49), - :C - ), - ModuleNode(51...106)( - [], - (51...57), - ConstantReadNode(58...59)(:A), - StatementsNode(62...102)( - [CallNode(62...76)( - nil, - nil, - (62...69), - (69...70), - ArgumentsNode(70...75)( - [CallNode(70...75)( - ConstantReadNode(70...71)(:B), - (71...72), - (72...75), - nil, - nil, - nil, - nil, - 0, - "new" - )] - ), - (75...76), - nil, - 0, - "include" - ), - DefNode(80...102)( - :foo, - (84...87), - nil, - nil, - StatementsNode(92...96)( - [SymbolNode(92...96)((92...93), (93...96), nil, "bar")] - ), - [], - (80...83), - nil, - nil, - nil, - nil, - (99...102) - )] - ), - (103...106), - :A - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/opasgn.txt b/test/yarp/snapshots/unparser/corpus/literal/opasgn.txt deleted file mode 100644 index 149bbc8b04f029..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/opasgn.txt +++ /dev/null @@ -1,408 +0,0 @@ -ProgramNode(0...233)( - [:a, :h], - StatementsNode(0...233)( - [LocalVariableOperatorWriteNode(0...6)( - (0...1), - (2...4), - IntegerNode(5...6)(), - :a, - :+, - 0 - ), - LocalVariableOperatorWriteNode(7...13)( - (7...8), - (9...11), - IntegerNode(12...13)(), - :a, - :-, - 0 - ), - LocalVariableOperatorWriteNode(14...21)( - (14...15), - (16...19), - IntegerNode(20...21)(), - :a, - :**, - 0 - ), - LocalVariableOperatorWriteNode(22...28)( - (22...23), - (24...26), - IntegerNode(27...28)(), - :a, - :*, - 0 - ), - LocalVariableOperatorWriteNode(29...35)( - (29...30), - (31...33), - IntegerNode(34...35)(), - :a, - :/, - 0 - ), - LocalVariableAndWriteNode(36...43)( - (36...37), - (38...41), - CallNode(42...43)(nil, nil, (42...43), nil, nil, nil, nil, 2, "b"), - :a, - 0 - ), - LocalVariableOrWriteNode(44...51)( - (44...45), - (46...49), - IntegerNode(50...51)(), - :a, - 0 - ), - CallNode(52...65)( - ParenthesesNode(52...61)( - StatementsNode(53...60)( - [LocalVariableOrWriteNode(53...60)( - (53...54), - (55...58), - IntegerNode(59...60)(), - :a, - 0 - )] - ), - (52...53), - (60...61) - ), - (61...62), - (62...65), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(66...83)( - ParenthesesNode(66...76)( - StatementsNode(67...75)( - [LocalVariableOrWriteNode(67...75)( - (67...68), - (69...72), - HashNode(73...75)((73...74), [], (74...75)), - :h, - 0 - )] - ), - (66...67), - (75...76) - ), - nil, - (76...79), - (76...77), - ArgumentsNode(77...83)( - [CallNode(77...78)(nil, nil, (77...78), nil, nil, nil, nil, 2, "k"), - CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "v")] - ), - (78...79), - nil, - 0, - "[]=" - ), - CallOperatorWriteNode(84...92)( - LocalVariableReadNode(84...85)(:a, 0), - (85...86), - (86...87), - nil, - nil, - nil, - 0, - "b", - "b=", - :+, - (88...90), - IntegerNode(91...92)() - ), - CallOperatorWriteNode(93...101)( - LocalVariableReadNode(93...94)(:a, 0), - (94...95), - (95...96), - nil, - nil, - nil, - 0, - "b", - "b=", - :-, - (97...99), - IntegerNode(100...101)() - ), - CallOperatorWriteNode(102...111)( - LocalVariableReadNode(102...103)(:a, 0), - (103...104), - (104...105), - nil, - nil, - nil, - 0, - "b", - "b=", - :**, - (106...109), - IntegerNode(110...111)() - ), - CallOperatorWriteNode(112...120)( - LocalVariableReadNode(112...113)(:a, 0), - (113...114), - (114...115), - nil, - nil, - nil, - 0, - "b", - "b=", - :*, - (116...118), - IntegerNode(119...120)() - ), - CallOperatorWriteNode(121...129)( - LocalVariableReadNode(121...122)(:a, 0), - (122...123), - (123...124), - nil, - nil, - nil, - 0, - "b", - "b=", - :/, - (125...127), - IntegerNode(128...129)() - ), - CallAndWriteNode(130...139)( - LocalVariableReadNode(130...131)(:a, 0), - (131...132), - (132...133), - nil, - nil, - nil, - 0, - "b", - "b=", - (134...137), - CallNode(138...139)(nil, nil, (138...139), nil, nil, nil, nil, 2, "b") - ), - CallOrWriteNode(140...149)( - LocalVariableReadNode(140...141)(:a, 0), - (141...142), - (142...143), - nil, - nil, - nil, - 0, - "b", - "b=", - (144...147), - IntegerNode(148...149)() - ), - CallOperatorWriteNode(150...159)( - LocalVariableReadNode(150...151)(:a, 0), - nil, - (151...154), - (151...152), - ArgumentsNode(152...153)( - [CallNode(152...153)( - nil, - nil, - (152...153), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (153...154), - 0, - "[]", - "[]=", - :+, - (155...157), - IntegerNode(158...159)() - ), - CallOperatorWriteNode(160...169)( - LocalVariableReadNode(160...161)(:a, 0), - nil, - (161...164), - (161...162), - ArgumentsNode(162...163)( - [CallNode(162...163)( - nil, - nil, - (162...163), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (163...164), - 0, - "[]", - "[]=", - :-, - (165...167), - IntegerNode(168...169)() - ), - CallOperatorWriteNode(170...180)( - LocalVariableReadNode(170...171)(:a, 0), - nil, - (171...174), - (171...172), - ArgumentsNode(172...173)( - [CallNode(172...173)( - nil, - nil, - (172...173), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (173...174), - 0, - "[]", - "[]=", - :**, - (175...178), - IntegerNode(179...180)() - ), - CallOperatorWriteNode(181...190)( - LocalVariableReadNode(181...182)(:a, 0), - nil, - (182...185), - (182...183), - ArgumentsNode(183...184)( - [CallNode(183...184)( - nil, - nil, - (183...184), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (184...185), - 0, - "[]", - "[]=", - :*, - (186...188), - IntegerNode(189...190)() - ), - CallOperatorWriteNode(191...200)( - LocalVariableReadNode(191...192)(:a, 0), - nil, - (192...195), - (192...193), - ArgumentsNode(193...194)( - [CallNode(193...194)( - nil, - nil, - (193...194), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (194...195), - 0, - "[]", - "[]=", - :/, - (196...198), - IntegerNode(199...200)() - ), - CallAndWriteNode(201...211)( - LocalVariableReadNode(201...202)(:a, 0), - nil, - (202...205), - (202...203), - ArgumentsNode(203...204)( - [CallNode(203...204)( - nil, - nil, - (203...204), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (204...205), - 0, - "[]", - "[]=", - (206...209), - CallNode(210...211)(nil, nil, (210...211), nil, nil, nil, nil, 2, "b") - ), - CallOrWriteNode(212...222)( - LocalVariableReadNode(212...213)(:a, 0), - nil, - (213...216), - (213...214), - ArgumentsNode(214...215)( - [CallNode(214...215)( - nil, - nil, - (214...215), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (215...216), - 0, - "[]", - "[]=", - (217...220), - IntegerNode(221...222)() - ), - CallOperatorWriteNode(223...233)( - CallNode(223...226)( - nil, - nil, - (223...226), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (226...227), - (227...228), - nil, - nil, - nil, - 0, - "A", - "A=", - :+, - (229...231), - IntegerNode(232...233)() - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/pattern.txt b/test/yarp/snapshots/unparser/corpus/literal/pattern.txt deleted file mode 100644 index 2d6ec772f44e8f..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/pattern.txt +++ /dev/null @@ -1,291 +0,0 @@ -ProgramNode(0...408)( - [:a, :x, :y], - StatementsNode(0...408)( - [CaseNode(0...345)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [InNode(9...38)( - ArrayPatternNode(12...26)( - ConstantReadNode(12...13)(:A), - [IntegerNode(14...15)(), IntegerNode(17...18)()], - SplatNode(20...22)( - (20...21), - LocalVariableTargetNode(21...22)(:a, 0) - ), - [IntegerNode(24...25)()], - (13...14), - (25...26) - ), - StatementsNode(34...38)([TrueNode(34...38)()]), - (9...11), - (27...31) - ), - InNode(39...59)( - ArrayPatternNode(42...50)( - nil, - [IntegerNode(43...44)(), IntegerNode(46...47)()], - nil, - [], - (42...43), - (49...50) - ), - StatementsNode(58...59)( - [CallNode(58...59)( - nil, - nil, - (58...59), - nil, - nil, - nil, - nil, - 2, - "y" - )] - ), - (39...41), - (51...55) - ), - InNode(60...80)( - HashPatternNode(63...68)( - ConstantReadNode(63...64)(:A), - [AssocNode(65...67)( - SymbolNode(65...67)(nil, (65...66), (66...67), "x"), - nil, - nil - )], - nil, - (64...65), - (67...68) - ), - StatementsNode(76...80)([TrueNode(76...80)()]), - (60...62), - (69...73) - ), - InNode(81...101)( - HashPatternNode(84...89)( - nil, - [AssocNode(85...88)( - AssocSplatNode(85...88)( - LocalVariableTargetNode(87...88)(:a, 0), - (85...87) - ), - nil, - nil - )], - nil, - (84...85), - (88...89) - ), - StatementsNode(97...101)([TrueNode(97...101)()]), - (81...83), - (90...94) - ), - InNode(102...127)( - IfNode(105...115)( - (108...110), - TrueNode(111...115)(), - StatementsNode(105...107)( - [HashPatternNode(105...107)( - nil, - [], - nil, - (105...106), - (106...107) - )] - ), - nil, - nil - ), - StatementsNode(123...127)([TrueNode(123...127)()]), - (102...104), - (116...120) - ), - InNode(128...152)( - ArrayPatternNode(131...140)( - nil, - [LocalVariableTargetNode(132...133)(:x, 0), - LocalVariableTargetNode(135...136)(:y, 0)], - SplatNode(138...139)((138...139), nil), - [], - (131...132), - (139...140) - ), - StatementsNode(148...152)([TrueNode(148...152)()]), - (128...130), - (141...145) - ), - InNode(153...181)( - HashPatternNode(156...169)( - nil, - [AssocNode(157...161)( - SymbolNode(157...159)(nil, (157...158), (158...159), "a"), - IntegerNode(160...161)(), - nil - ), - AssocNode(163...168)( - SymbolNode(163...166)(nil, (163...165), (165...166), "aa"), - IntegerNode(167...168)(), - nil - )], - nil, - (156...157), - (168...169) - ), - StatementsNode(177...181)([TrueNode(177...181)()]), - (153...155), - (170...174) - ), - InNode(182...199)( - HashPatternNode(185...187)(nil, [], nil, (185...186), (186...187)), - StatementsNode(195...199)([TrueNode(195...199)()]), - (182...184), - (188...192) - ), - InNode(200...222)( - HashPatternNode(203...210)( - nil, - [AssocNode(204...209)( - NoKeywordsParameterNode(204...209)((204...206), (206...209)), - nil, - nil - )], - nil, - (203...204), - (209...210) - ), - StatementsNode(218...222)([TrueNode(218...222)()]), - (200...202), - (211...215) - ), - InNode(223...246)( - HashPatternNode(226...234)( - nil, - [AssocNode(227...233)( - SymbolNode(227...231)( - (227...228), - (228...229), - (229...231), - "a" - ), - IntegerNode(232...233)(), - nil - )], - nil, - (226...227), - (233...234) - ), - StatementsNode(242...246)([TrueNode(242...246)()]), - (223...225), - (235...239) - ), - InNode(247...267)( - AlternationPatternNode(250...255)( - IntegerNode(250...251)(), - IntegerNode(254...255)(), - (252...253) - ), - StatementsNode(263...267)([TrueNode(263...267)()]), - (247...249), - (256...260) - ), - InNode(268...289)( - CapturePatternNode(271...277)( - IntegerNode(271...272)(), - LocalVariableTargetNode(276...277)(:a, 0), - (273...275) - ), - StatementsNode(285...289)([TrueNode(285...289)()]), - (268...270), - (278...282) - ), - InNode(290...307)( - PinnedVariableNode(293...295)( - LocalVariableReadNode(294...295)(:x, 0), - (293...294) - ), - StatementsNode(303...307)([TrueNode(303...307)()]), - (290...292), - (296...300) - ), - InNode(308...312)(IntegerNode(311...312)(), nil, (308...310), nil), - InNode(313...329)( - IntegerNode(316...317)(), - StatementsNode(325...329)([TrueNode(325...329)()]), - (313...315), - (318...322) - )], - ElseNode(330...345)( - (330...334), - StatementsNode(337...341)([TrueNode(337...341)()]), - (342...345) - ), - (0...4), - (342...345) - ), - CaseNode(346...376)( - CallNode(351...354)( - nil, - nil, - (351...354), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(355...372)( - ArrayPatternNode(358...372)( - ConstantReadNode(358...359)(:A), - [IntegerNode(360...361)(), IntegerNode(363...364)()], - SplatNode(366...368)( - (366...367), - LocalVariableTargetNode(367...368)(:a, 0) - ), - [IntegerNode(370...371)()], - (359...360), - (371...372) - ), - nil, - (355...357), - nil - )], - nil, - (346...350), - (373...376) - ), - CaseNode(377...399)( - CallNode(382...385)( - nil, - nil, - (382...385), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [InNode(386...390)( - ConstantReadNode(389...390)(:A), - nil, - (386...388), - nil - )], - ElseNode(391...399)((391...395), nil, (396...399)), - (377...381), - (396...399) - ), - MatchPredicateNode(400...408)( - IntegerNode(400...401)(), - ArrayPatternNode(405...408)( - nil, - [LocalVariableTargetNode(406...407)(:a, 0)], - nil, - [], - (405...406), - (407...408) - ), - (402...404) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/pragma.txt b/test/yarp/snapshots/unparser/corpus/literal/pragma.txt deleted file mode 100644 index 86c13274335adf..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/pragma.txt +++ /dev/null @@ -1,9 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [SourceEncodingNode(0...12)(), - SourceFileNode(13...21)("unparser/corpus/literal/pragma.txt"), - SourceLineNode(22...30)(), - CallNode(31...38)(nil, nil, (31...38), nil, nil, nil, nil, 2, "__dir__")] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/range.txt b/test/yarp/snapshots/unparser/corpus/literal/range.txt deleted file mode 100644 index ea2b362a32eb29..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/range.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [ParenthesesNode(0...5)( - StatementsNode(1...4)( - [RangeNode(1...4)(IntegerNode(1...2)(), nil, (2...4), 0)] - ), - (0...1), - (4...5) - ), - RangeNode(6...10)( - IntegerNode(6...7)(), - IntegerNode(9...10)(), - (7...9), - 0 - ), - ParenthesesNode(11...17)( - StatementsNode(12...16)( - [RangeNode(12...16)(IntegerNode(12...13)(), nil, (13...16), 1)] - ), - (11...12), - (16...17) - ), - RangeNode(18...23)( - IntegerNode(18...19)(), - IntegerNode(22...23)(), - (19...22), - 1 - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/rescue.txt b/test/yarp/snapshots/unparser/corpus/literal/rescue.txt deleted file mode 100644 index 8898a6e1a0db24..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/rescue.txt +++ /dev/null @@ -1,72 +0,0 @@ -ProgramNode(0...64)( - [:x], - StatementsNode(0...64)( - [RescueModifierNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (4...10), - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "bar") - ), - RescueModifierNode(15...36)( - CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "foo"), - (19...25), - ReturnNode(26...36)( - (26...32), - ArgumentsNode(33...36)( - [CallNode(33...36)( - nil, - nil, - (33...36), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - ) - ), - LocalVariableWriteNode(37...64)( - :x, - 0, - (37...38), - ParenthesesNode(41...64)( - StatementsNode(42...63)( - [RescueModifierNode(42...63)( - CallNode(42...45)( - nil, - nil, - (42...45), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (46...52), - ReturnNode(53...63)( - (53...59), - ArgumentsNode(60...63)( - [CallNode(60...63)( - nil, - nil, - (60...63), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - ) - )] - ), - (41...42), - (63...64) - ), - (39...40) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt deleted file mode 100644 index 858101f5a3a2c8..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ /dev/null @@ -1,2052 +0,0 @@ -ProgramNode(0...999)( - [], - StatementsNode(0...999)( - [ModuleNode(0...35)( - [:foo, :a, :_], - (0...6), - ConstantReadNode(7...8)(:A), - StatementsNode(11...31)( - [LocalVariableOrWriteNode(11...31)( - (11...14), - (15...18), - ParenthesesNode(19...31)( - StatementsNode(20...30)( - [MultiWriteNode(20...30)( - [LocalVariableTargetNode(21...22)(:a, 0), - LocalVariableTargetNode(24...25)(:_, 0)], - (20...21), - (25...26), - (27...28), - CallNode(29...30)( - nil, - nil, - (29...30), - nil, - nil, - nil, - nil, - 2, - "b" - ) - )] - ), - (19...20), - (30...31) - ), - :foo, - 0 - )] - ), - (32...35), - :A - ), - ModuleNode(37...73)( - [:local], - (37...43), - ConstantReadNode(44...45)(:A), - StatementsNode(48...69)( - [LocalVariableWriteNode(48...57)( - :local, - 0, - (48...53), - IntegerNode(56...57)(), - (54...55) - ), - CallNode(60...69)( - LocalVariableReadNode(60...65)(:local, 0), - (65...66), - (66...69), - nil, - nil, - nil, - nil, - 0, - "bar" - )] - ), - (70...73), - :A - ), - CallNode(74...89)( - ClassNode(74...85)( - [], - (74...79), - ConstantReadNode(80...81)(:A), - nil, - nil, - nil, - (82...85), - :A - ), - (85...86), - (86...89), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(90...106)( - ModuleNode(90...102)( - [], - (90...96), - ConstantReadNode(97...98)(:A), - nil, - (99...102), - :A - ), - (102...103), - (103...106), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(107...127)( - BeginNode(107...123)( - (107...112), - nil, - RescueNode(113...119)((113...119), [], nil, nil, nil, nil), - nil, - nil, - (120...123) - ), - (123...124), - (124...127), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(128...169)( - CaseNode(128...165)( - ParenthesesNode(133...152)( - StatementsNode(134...151)( - [DefNode(134...145)( - :foo, - (138...141), - nil, - nil, - nil, - [], - (134...137), - nil, - nil, - nil, - nil, - (142...145) - ), - SymbolNode(147...151)((147...148), (148...151), nil, "bar")] - ), - (133...134), - (151...152) - ), - [WhenNode(153...161)( - (153...157), - [CallNode(158...161)( - nil, - nil, - (158...161), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - nil - )], - nil, - (128...132), - (162...165) - ), - (165...166), - (166...169), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - CallNode(170...195)( - CaseNode(170...191)( - CallNode(175...178)( - nil, - nil, - (175...178), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - [WhenNode(179...187)( - (179...183), - [CallNode(184...187)( - nil, - nil, - (184...187), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - nil - )], - nil, - (170...174), - (188...191) - ), - (191...192), - (192...195), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - CallNode(196...217)( - SingletonClassNode(196...213)( - [], - (196...201), - (202...204), - SelfNode(205...209)(), - nil, - (210...213) - ), - (213...214), - (214...217), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(218...238)( - DefNode(218...234)( - :foo, - (227...230), - SelfNode(222...226)(), - nil, - nil, - [], - (218...221), - (226...227), - nil, - nil, - nil, - (231...234) - ), - (234...235), - (235...238), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(239...254)( - DefNode(239...250)( - :foo, - (243...246), - nil, - nil, - nil, - [], - (239...242), - nil, - nil, - nil, - nil, - (247...250) - ), - (250...251), - (251...254), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(255...272)( - UntilNode(255...268)( - (255...260), - (265...268), - CallNode(261...264)( - nil, - nil, - (261...264), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - 0 - ), - (268...269), - (269...272), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(273...290)( - WhileNode(273...286)( - (273...278), - (283...286), - CallNode(279...282)( - nil, - nil, - (279...282), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - 0 - ), - (286...287), - (287...290), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(291...303)( - CallNode(291...299)( - nil, - nil, - (291...295), - nil, - nil, - nil, - BlockNode(296...299)([], nil, nil, (296...297), (298...299)), - 0, - "loop" - ), - (299...300), - (300...303), - nil, - nil, - nil, - nil, - 0, - "bar" - ), - CallNode(304...318)( - IfNode(304...314)( - (304...306), - CallNode(307...310)( - nil, - nil, - (307...310), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - nil, - (311...314) - ), - (314...315), - (315...318), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - CallNode(319...338)( - ParenthesesNode(319...334)( - StatementsNode(320...333)( - [CallNode(320...333)( - RegularExpressionNode(320...325)( - (320...321), - (321...324), - (324...325), - "bar", - 0 - ), - nil, - (326...328), - nil, - ArgumentsNode(329...333)( - [SymbolNode(329...333)((329...330), (330...333), nil, "foo")] - ), - nil, - nil, - 0, - "=~" - )] - ), - (319...320), - (333...334) - ), - (334...335), - (335...338), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(339...349)( - ParenthesesNode(339...345)( - StatementsNode(340...344)( - [RangeNode(340...344)( - IntegerNode(340...341)(), - IntegerNode(343...344)(), - (341...343), - 0 - )] - ), - (339...340), - (344...345) - ), - (345...346), - (346...349), - nil, - nil, - nil, - nil, - 0, - "max" - ), - CallNode(350...368)( - ParenthesesNode(350...364)( - StatementsNode(351...363)( - [CallNode(351...363)( - CallNode(351...354)( - nil, - nil, - (351...354), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (355...357), - nil, - ArgumentsNode(358...363)( - [RegularExpressionNode(358...363)( - (358...359), - (359...362), - (362...363), - "bar", - 0 - )] - ), - nil, - nil, - 0, - "=~" - )] - ), - (350...351), - (363...364) - ), - (364...365), - (365...368), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(369...382)( - RegularExpressionNode(369...374)( - (369...370), - (370...373), - (373...374), - "bar", - 0 - ), - nil, - (375...377), - nil, - ArgumentsNode(378...382)( - [SymbolNode(378...382)((378...379), (379...382), nil, "foo")] - ), - nil, - nil, - 0, - "=~" - ), - CallNode(383...395)( - RegularExpressionNode(383...388)( - (383...384), - (384...387), - (387...388), - "bar", - 0 - ), - nil, - (389...391), - nil, - ArgumentsNode(392...395)( - [CallNode(392...395)( - nil, - nil, - (392...395), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "=~" - ), - RangeNode(396...404)( - IntegerNode(396...397)(), - CallNode(399...404)( - IntegerNode(399...400)(), - (400...401), - (401...404), - nil, - nil, - nil, - nil, - 0, - "max" - ), - (397...399), - 0 - ), - CallNode(405...410)( - ConstantReadNode(405...406)(:A), - (406...407), - (407...410), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(411...416)( - nil, - nil, - (411...414), - (414...415), - nil, - (415...416), - nil, - 0, - "FOO" - ), - CallNode(417...421)( - CallNode(417...418)(nil, nil, (417...418), nil, nil, nil, nil, 2, "a"), - (418...420), - (420...421), - nil, - nil, - nil, - nil, - 1, - "b" - ), - CallNode(422...427)( - CallNode(422...423)(nil, nil, (422...423), nil, nil, nil, nil, 2, "a"), - (423...424), - (424...427), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(428...431)(nil, nil, (428...431), nil, nil, nil, nil, 2, "foo"), - CallNode(432...450)( - CallNode(432...435)( - nil, - nil, - (432...435), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (436...438), - nil, - ArgumentsNode(439...450)( - [ParenthesesNode(439...450)( - StatementsNode(440...449)( - [CallNode(440...449)( - CallNode(440...443)( - nil, - nil, - (440...443), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - nil, - (444...445), - nil, - ArgumentsNode(446...449)( - [CallNode(446...449)( - nil, - nil, - (446...449), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil, - nil, - 0, - "*" - )] - ), - (439...440), - (449...450) - )] - ), - nil, - nil, - 0, - "<<" - ), - CallNode(451...463)( - CallNode(451...454)( - nil, - nil, - (451...454), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (455...457), - nil, - ArgumentsNode(458...463)( - [RegularExpressionNode(458...463)( - (458...459), - (459...462), - (462...463), - "bar", - 0 - )] - ), - nil, - nil, - 0, - "=~" - ), - CallNode(464...482)( - nil, - nil, - (464...467), - (467...468), - ArgumentsNode(468...481)( - [BlockArgumentNode(468...481)( - ParenthesesNode(469...481)( - StatementsNode(470...480)( - [OrNode(470...480)( - CallNode(470...473)( - nil, - nil, - (470...473), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(477...480)( - nil, - nil, - (477...480), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (474...476) - )] - ), - (469...470), - (480...481) - ), - (468...469) - )] - ), - (481...482), - nil, - 0, - "foo" - ), - CallNode(483...494)( - nil, - nil, - (483...486), - (486...487), - ArgumentsNode(487...493)( - [BlockArgumentNode(487...493)( - CallNode(488...493)( - nil, - nil, - (488...493), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (487...488) - )] - ), - (493...494), - nil, - 0, - "foo" - ), - CallNode(495...513)( - nil, - nil, - (495...498), - (498...499), - ArgumentsNode(499...512)( - [SplatNode(499...504)( - (499...500), - CallNode(500...504)( - nil, - nil, - (500...504), - nil, - nil, - nil, - nil, - 2, - "args" - ) - ), - BlockArgumentNode(506...512)( - CallNode(507...512)( - nil, - nil, - (507...512), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (506...507) - )] - ), - (512...513), - nil, - 0, - "foo" - ), - CallNode(514...529)( - nil, - nil, - (514...517), - (517...518), - ArgumentsNode(518...528)( - [SplatNode(518...528)( - (518...519), - CallNode(519...528)( - nil, - nil, - (519...528), - nil, - nil, - nil, - nil, - 2, - "arguments" - ) - )] - ), - (528...529), - nil, - 0, - "foo" - ), - CallNode(530...539)( - nil, - nil, - (530...533), - (533...534), - ArgumentsNode(534...538)( - [IntegerNode(534...535)(), IntegerNode(537...538)()] - ), - (538...539), - nil, - 0, - "foo" - ), - CallNode(540...548)( - nil, - nil, - (540...543), - (543...544), - ArgumentsNode(544...547)( - [CallNode(544...547)( - nil, - nil, - (544...547), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (547...548), - nil, - 0, - "foo" - ), - CallNode(549...564)( - nil, - nil, - (549...552), - (552...553), - ArgumentsNode(553...563)( - [CallNode(553...556)( - nil, - nil, - (553...556), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - SplatNode(558...563)( - (558...559), - CallNode(559...563)( - nil, - nil, - (559...563), - nil, - nil, - nil, - nil, - 2, - "args" - ) - )] - ), - (563...564), - nil, - 0, - "foo" - ), - CallNode(565...582)( - nil, - nil, - (565...568), - (568...569), - ArgumentsNode(569...581)( - [CallNode(569...581)( - CallNode(569...572)( - nil, - nil, - (569...572), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (573...575), - nil, - ArgumentsNode(576...581)( - [RegularExpressionNode(576...581)( - (576...577), - (577...580), - (580...581), - "bar", - 0 - )] - ), - nil, - nil, - 0, - "=~" - )] - ), - (581...582), - nil, - 0, - "foo" - ), - CallNode(583...596)( - CallNode(583...586)( - nil, - nil, - (583...586), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (586...587), - (587...590), - (590...591), - ArgumentsNode(591...595)( - [BlockArgumentNode(591...595)( - CallNode(592...595)( - nil, - nil, - (592...595), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (591...592) - )] - ), - (595...596), - nil, - 0, - "bar" - ), - CallNode(597...623)( - CallNode(597...600)( - nil, - nil, - (597...600), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (600...601), - (601...604), - (604...605), - ArgumentsNode(605...622)( - [SplatNode(605...610)( - (605...606), - CallNode(606...610)( - nil, - nil, - (606...610), - nil, - nil, - nil, - nil, - 2, - "arga" - ) - ), - CallNode(612...615)( - nil, - nil, - (612...615), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SplatNode(617...622)( - (617...618), - CallNode(618...622)( - nil, - nil, - (618...622), - nil, - nil, - nil, - nil, - 2, - "argb" - ) - )] - ), - (622...623), - nil, - 0, - "bar" - ), - CallNode(624...638)( - CallNode(624...627)( - nil, - nil, - (624...627), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (627...628), - (628...631), - (631...632), - ArgumentsNode(632...637)( - [SplatNode(632...637)( - (632...633), - CallNode(633...637)( - nil, - nil, - (633...637), - nil, - nil, - nil, - nil, - 2, - "args" - ) - )] - ), - (637...638), - nil, - 0, - "bar" - ), - CallNode(639...658)( - CallNode(639...642)( - nil, - nil, - (639...642), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (642...643), - (643...646), - (646...647), - ArgumentsNode(647...657)( - [SplatNode(647...652)( - (647...648), - CallNode(648...652)( - nil, - nil, - (648...652), - nil, - nil, - nil, - nil, - 2, - "args" - ) - ), - CallNode(654...657)( - nil, - nil, - (654...657), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (657...658), - nil, - 0, - "bar" - ), - CallNode(659...678)( - CallNode(659...662)( - nil, - nil, - (659...662), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (662...663), - (663...666), - (666...667), - ArgumentsNode(667...677)( - [SymbolNode(667...671)((667...668), (668...671), nil, "baz"), - BlockArgumentNode(673...677)( - CallNode(674...677)( - nil, - nil, - (674...677), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (673...674) - )] - ), - (677...678), - nil, - 0, - "bar" - ), - CallNode(679...696)( - CallNode(679...682)( - nil, - nil, - (679...682), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (682...683), - (683...686), - (686...687), - ArgumentsNode(687...695)( - [KeywordHashNode(687...695)( - [AssocNode(687...695)( - SymbolNode(687...691)(nil, (687...690), (690...691), "baz"), - CallNode(692...695)( - nil, - nil, - (692...695), - nil, - nil, - nil, - nil, - 2, - "boz" - ), - nil - )] - )] - ), - (695...696), - nil, - 0, - "bar" - ), - CallNode(697...723)( - CallNode(697...700)( - nil, - nil, - (697...700), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (700...701), - (701...704), - (704...705), - ArgumentsNode(705...722)( - [CallNode(705...708)( - nil, - nil, - (705...708), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - KeywordHashNode(710...722)( - [AssocNode(710...722)( - StringNode(710...715)( - (710...711), - (711...714), - (714...715), - "baz" - ), - CallNode(719...722)( - nil, - nil, - (719...722), - nil, - nil, - nil, - nil, - 2, - "boz" - ), - (716...718) - )] - )] - ), - (722...723), - nil, - 0, - "bar" - ), - CallNode(724...743)( - CallNode(724...727)( - nil, - nil, - (724...727), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (727...728), - (728...731), - (731...732), - ArgumentsNode(732...742)( - [CallNode(732...735)( - nil, - nil, - (732...735), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SplatNode(737...742)( - (737...738), - CallNode(738...742)( - nil, - nil, - (738...742), - nil, - nil, - nil, - nil, - 2, - "args" - ) - )] - ), - (742...743), - nil, - 0, - "bar" - ), - CallNode(744...771)( - CallNode(744...747)( - nil, - nil, - (744...747), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (747...748), - (748...751), - (751...752), - ArgumentsNode(752...770)( - [CallNode(752...755)( - nil, - nil, - (752...755), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - SplatNode(757...762)( - (757...758), - CallNode(758...762)( - nil, - nil, - (758...762), - nil, - nil, - nil, - nil, - 2, - "args" - ) - ), - BlockArgumentNode(764...770)( - CallNode(765...770)( - nil, - nil, - (765...770), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (764...765) - )] - ), - (770...771), - nil, - 0, - "bar" - ), - CallNode(772...788)( - CallNode(772...775)( - nil, - nil, - (772...775), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (775...776), - (776...779), - (779...780), - ArgumentsNode(780...787)( - [CallNode(780...783)( - nil, - nil, - (780...783), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - HashNode(785...787)((785...786), [], (786...787))] - ), - (787...788), - nil, - 0, - "bar" - ), - CallNode(789...815)( - CallNode(789...792)( - nil, - nil, - (789...792), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (792...793), - (793...796), - (796...797), - ArgumentsNode(797...814)( - [HashNode(797...809)( - (797...798), - [AssocNode(799...807)( - SymbolNode(799...803)(nil, (799...802), (802...803), "foo"), - CallNode(804...807)( - nil, - nil, - (804...807), - nil, - nil, - nil, - nil, - 2, - "boz" - ), - nil - )], - (808...809) - ), - CallNode(811...814)( - nil, - nil, - (811...814), - nil, - nil, - nil, - nil, - 2, - "boz" - )] - ), - (814...815), - nil, - 0, - "bar" - ), - CallNode(816...828)( - CallNode(816...819)( - nil, - nil, - (816...819), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (819...820), - (820...823), - nil, - ArgumentsNode(824...828)( - [SymbolNode(824...828)((824...825), (825...828), nil, "baz")] - ), - nil, - nil, - 0, - "bar=" - ), - CallNode(829...838)( - nil, - nil, - (829...832), - (832...833), - ArgumentsNode(833...837)( - [KeywordHashNode(833...837)( - [AssocNode(833...837)( - SymbolNode(833...835)(nil, (833...834), (834...835), "a"), - CallNode(836...837)( - nil, - nil, - (836...837), - nil, - nil, - nil, - nil, - 2, - "b" - ), - nil - )] - )] - ), - (837...838), - nil, - 0, - "foo" - ), - CallNode(839...850)( - CallNode(839...842)( - nil, - nil, - (839...842), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (842...843), - (843...844), - (844...845), - ArgumentsNode(845...849)( - [KeywordHashNode(845...849)( - [AssocNode(845...849)( - SymbolNode(845...847)(nil, (845...846), (846...847), "a"), - CallNode(848...849)( - nil, - nil, - (848...849), - nil, - nil, - nil, - nil, - 2, - "b" - ), - nil - )] - )] - ), - (849...850), - nil, - 0, - "&" - ), - CallNode(851...861)( - CallNode(851...854)( - nil, - nil, - (851...854), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (854...855), - (855...856), - (856...857), - ArgumentsNode(857...860)( - [KeywordHashNode(857...860)( - [AssocSplatNode(857...860)( - CallNode(859...860)( - nil, - nil, - (859...860), - nil, - nil, - nil, - nil, - 2, - "a" - ), - (857...859) - )] - )] - ), - (860...861), - nil, - 0, - "&" - ), - CallNode(862...871)( - CallNode(862...865)( - nil, - nil, - (862...865), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (865...871), - (865...866), - ArgumentsNode(866...870)( - [SplatNode(866...870)( - (866...867), - CallNode(867...870)( - nil, - nil, - (867...870), - nil, - nil, - nil, - nil, - 2, - "baz" - ) - )] - ), - (870...871), - nil, - 0, - "[]" - ), - CallNode(872...881)( - CallNode(872...875)( - nil, - nil, - (872...875), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (875...881), - (875...876), - ArgumentsNode(876...880)( - [IntegerNode(876...877)(), IntegerNode(879...880)()] - ), - (880...881), - nil, - 0, - "[]" - ), - CallNode(882...887)( - CallNode(882...885)( - nil, - nil, - (882...885), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (885...887), - (885...886), - nil, - (886...887), - nil, - 0, - "[]" - ), - CallNode(888...896)( - SelfNode(888...892)(), - (892...893), - (893...896), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(897...910)( - SelfNode(897...901)(), - (901...902), - (902...905), - nil, - ArgumentsNode(906...910)( - [SymbolNode(906...910)((906...907), (907...910), nil, "bar")] - ), - nil, - nil, - 0, - "foo=" - ), - CallNode(911...928)( - ParenthesesNode(911...918)( - StatementsNode(912...917)( - [CallNode(912...917)( - CallNode(912...913)( - nil, - nil, - (912...913), - nil, - nil, - nil, - nil, - 2, - "a" - ), - nil, - (914...915), - nil, - ArgumentsNode(916...917)( - [CallNode(916...917)( - nil, - nil, - (916...917), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (911...912), - (917...918) - ), - nil, - (919...920), - nil, - ArgumentsNode(921...928)( - [ParenthesesNode(921...928)( - StatementsNode(922...927)( - [CallNode(922...927)( - CallNode(922...923)( - nil, - nil, - (922...923), - nil, - nil, - nil, - nil, - 2, - "c" - ), - nil, - (924...925), - nil, - ArgumentsNode(926...927)( - [CallNode(926...927)( - nil, - nil, - (926...927), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "-" - )] - ), - (921...922), - (927...928) - )] - ), - nil, - nil, - 0, - "/" - ), - CallNode(929...948)( - ParenthesesNode(929...936)( - StatementsNode(930...935)( - [CallNode(930...935)( - CallNode(930...931)( - nil, - nil, - (930...931), - nil, - nil, - nil, - nil, - 2, - "a" - ), - nil, - (932...933), - nil, - ArgumentsNode(934...935)( - [CallNode(934...935)( - nil, - nil, - (934...935), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (929...930), - (935...936) - ), - nil, - (937...938), - nil, - ArgumentsNode(939...948)( - [CallNode(939...948)( - CallNode(939...940)( - nil, - nil, - (939...940), - nil, - nil, - nil, - nil, - 2, - "c" - ), - (940...941), - (941...942), - (942...943), - ArgumentsNode(943...947)( - [CallNode(943...944)( - nil, - nil, - (943...944), - nil, - nil, - nil, - nil, - 2, - "e" - ), - CallNode(946...947)( - nil, - nil, - (946...947), - nil, - nil, - nil, - nil, - 2, - "f" - )] - ), - (947...948), - nil, - 0, - "-" - )] - ), - nil, - nil, - 0, - "/" - ), - CallNode(949...966)( - ParenthesesNode(949...956)( - StatementsNode(950...955)( - [CallNode(950...955)( - CallNode(950...951)( - nil, - nil, - (950...951), - nil, - nil, - nil, - nil, - 2, - "a" - ), - nil, - (952...953), - nil, - ArgumentsNode(954...955)( - [CallNode(954...955)( - nil, - nil, - (954...955), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (949...950), - (955...956) - ), - nil, - (957...958), - nil, - ArgumentsNode(959...966)( - [CallNode(959...966)( - CallNode(959...960)( - nil, - nil, - (959...960), - nil, - nil, - nil, - nil, - 2, - "c" - ), - (960...961), - (961...962), - (962...963), - ArgumentsNode(963...965)( - [SplatNode(963...965)( - (963...964), - CallNode(964...965)( - nil, - nil, - (964...965), - nil, - nil, - nil, - nil, - 2, - "f" - ) - )] - ), - (965...966), - nil, - 0, - "-" - )] - ), - nil, - nil, - 0, - "/" - ), - CallNode(967...975)( - nil, - nil, - (967...968), - (968...969), - ArgumentsNode(969...974)( - [KeywordHashNode(969...974)( - [AssocSplatNode(969...974)( - CallNode(971...974)( - nil, - nil, - (971...974), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (969...971) - )] - )] - ), - (974...975), - nil, - 0, - "x" - ), - CallNode(976...982)( - CallNode(976...979)( - nil, - nil, - (976...979), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (979...981), - (981...982), - nil, - nil, - nil, - nil, - 1, - "!" - ), - CallNode(983...991)( - CallNode(983...986)( - nil, - nil, - (983...986), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (986...987), - (987...988), - (988...989), - ArgumentsNode(989...990)( - [CallNode(989...990)( - nil, - nil, - (989...990), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (990...991), - nil, - 0, - "~" - ), - CallNode(992...999)( - CallNode(992...993)(nil, nil, (992...993), nil, nil, nil, nil, 2, "a"), - (993...995), - (995...996), - (996...997), - ArgumentsNode(997...998)( - [CallNode(997...998)( - nil, - nil, - (997...998), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (998...999), - nil, - 1, - "+" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/27.txt b/test/yarp/snapshots/unparser/corpus/literal/since/27.txt deleted file mode 100644 index f8709ae21af282..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/since/27.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [LambdaNode(0...16)( - [], - (0...2), - (3...4), - (15...16), - nil, - StatementsNode(7...14)( - [CallNode(7...14)( - CallNode(7...9)(nil, nil, (7...9), nil, nil, nil, nil, 2, "_1"), - nil, - (10...11), - nil, - ArgumentsNode(12...14)( - [CallNode(12...14)( - nil, - nil, - (12...14), - nil, - nil, - nil, - nil, - 2, - "_2" - )] - ), - nil, - nil, - 0, - "+" - )] - ) - ), - ParenthesesNode(17...22)( - StatementsNode(18...21)( - [RangeNode(18...21)(nil, IntegerNode(20...21)(), (18...20), 0)] - ), - (17...18), - (21...22) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/30.txt b/test/yarp/snapshots/unparser/corpus/literal/since/30.txt deleted file mode 100644 index 4aba7677950132..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/since/30.txt +++ /dev/null @@ -1,56 +0,0 @@ -ProgramNode(0...51)( - [:a, :foo], - StatementsNode(0...51)( - [MatchRequiredNode(0...8)( - IntegerNode(0...1)(), - ArrayPatternNode(5...8)( - nil, - [LocalVariableTargetNode(6...7)(:a, 0)], - nil, - [], - (5...6), - (7...8) - ), - (2...4) - ), - MatchRequiredNode(9...17)( - IntegerNode(9...10)(), - ArrayPatternNode(14...17)( - nil, - [], - SplatNode(15...16)((15...16), nil), - [], - (14...15), - (16...17) - ), - (11...13) - ), - MatchPredicateNode(18...33)( - IntegerNode(18...19)(), - FindPatternNode(23...33)( - nil, - SplatNode(24...25)((24...25), nil), - [IntegerNode(27...29)()], - SplatNode(31...32)((31...32), nil), - (23...24), - (32...33) - ), - (20...22) - ), - MatchPredicateNode(34...51)( - IntegerNode(34...35)(), - FindPatternNode(39...51)( - nil, - SplatNode(40...41)((40...41), nil), - [LocalVariableTargetNode(43...44)(:a, 0)], - SplatNode(46...50)( - (46...47), - LocalVariableTargetNode(47...50)(:foo, 0) - ), - (39...40), - (50...51) - ), - (36...38) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt b/test/yarp/snapshots/unparser/corpus/literal/since/31.txt deleted file mode 100644 index c5f903bbeb431b..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt +++ /dev/null @@ -1,77 +0,0 @@ -ProgramNode(0...51)( - [], - StatementsNode(0...51)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - ParametersNode(8...9)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(8...9)(nil, nil, (8...9)) - ), - StatementsNode(13...19)( - [CallNode(13...19)( - nil, - nil, - (13...16), - (16...17), - ArgumentsNode(17...18)( - [BlockArgumentNode(17...18)(nil, (17...18))] - ), - (18...19), - nil, - 0, - "bar" - )] - ), - [:&], - (0...3), - nil, - (7...8), - (9...10), - nil, - (20...23) - ), - DefNode(25...51)( - :foo, - (29...32), - nil, - ParametersNode(33...37)( - [RequiredParameterNode(33...34)(:a)], - [], - [], - nil, - [], - nil, - BlockParameterNode(36...37)(nil, nil, (36...37)) - ), - StatementsNode(41...47)( - [CallNode(41...47)( - nil, - nil, - (41...44), - (44...45), - ArgumentsNode(45...46)( - [BlockArgumentNode(45...46)(nil, (45...46))] - ), - (46...47), - nil, - 0, - "bar" - )] - ), - [:a, :&], - (25...28), - nil, - (32...33), - (37...38), - nil, - (48...51) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt deleted file mode 100644 index b6335ced8668eb..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt +++ /dev/null @@ -1,81 +0,0 @@ -ProgramNode(0...90)( - [], - StatementsNode(0...90)( - [DefNode(0...45)( - :foo, - (4...7), - nil, - ParametersNode(8...20)( - [RequiredParameterNode(8...16)(:argument)], - [], - [], - nil, - [], - KeywordRestParameterNode(18...20)(nil, nil, (18...20)), - nil - ), - StatementsNode(24...41)( - [CallNode(24...41)( - nil, - nil, - (24...27), - (27...28), - ArgumentsNode(28...40)( - [LocalVariableReadNode(28...36)(:argument, 0), - KeywordHashNode(38...40)( - [AssocSplatNode(38...40)(nil, (38...40))] - )] - ), - (40...41), - nil, - 0, - "bar" - )] - ), - [:argument, :**], - (0...3), - nil, - (7...8), - (20...21), - nil, - (42...45) - ), - DefNode(47...90)( - :foo, - (51...54), - nil, - ParametersNode(55...66)( - [RequiredParameterNode(55...63)(:argument)], - [], - [], - RestParameterNode(65...66)(nil, nil, (65...66)), - [], - nil, - nil - ), - StatementsNode(70...86)( - [CallNode(70...86)( - nil, - nil, - (70...73), - (73...74), - ArgumentsNode(74...85)( - [LocalVariableReadNode(74...82)(:argument, 0), - SplatNode(84...85)((84...85), nil)] - ), - (85...86), - nil, - 0, - "bar" - )] - ), - [:argument, :*], - (47...50), - nil, - (54...55), - (66...67), - nil, - (87...90) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/singletons.txt b/test/yarp/snapshots/unparser/corpus/literal/singletons.txt deleted file mode 100644 index 53cc92e636b95c..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/singletons.txt +++ /dev/null @@ -1,9 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [FalseNode(0...5)(), - NilNode(6...9)(), - SelfNode(10...14)(), - TrueNode(15...19)()] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/super.txt b/test/yarp/snapshots/unparser/corpus/literal/super.txt deleted file mode 100644 index 191e0a5b918bfd..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/super.txt +++ /dev/null @@ -1,239 +0,0 @@ -ProgramNode(0...159)( - [], - StatementsNode(0...159)( - [ForwardingSuperNode(0...5)(nil), - SuperNode(6...13)((6...11), (11...12), nil, (12...13), nil), - SuperNode(14...22)( - (14...19), - (19...20), - ArgumentsNode(20...21)( - [CallNode(20...21)(nil, nil, (20...21), nil, nil, nil, nil, 2, "a")] - ), - (21...22), - nil - ), - SuperNode(23...34)( - (23...28), - (28...29), - ArgumentsNode(29...33)( - [CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "a"), - CallNode(32...33)(nil, nil, (32...33), nil, nil, nil, nil, 2, "b")] - ), - (33...34), - nil - ), - SuperNode(35...48)( - (35...40), - (40...41), - ArgumentsNode(41...47)( - [BlockArgumentNode(41...47)( - CallNode(42...47)( - nil, - nil, - (42...47), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (41...42) - )] - ), - (47...48), - nil - ), - SuperNode(49...65)( - (49...54), - (54...55), - ArgumentsNode(55...64)( - [CallNode(55...56)(nil, nil, (55...56), nil, nil, nil, nil, 2, "a"), - BlockArgumentNode(58...64)( - CallNode(59...64)( - nil, - nil, - (59...64), - nil, - nil, - nil, - nil, - 2, - "block" - ), - (58...59) - )] - ), - (64...65), - nil - ), - SuperNode(66...84)( - (66...71), - (71...72), - ArgumentsNode(72...83)( - [CallNode(72...83)( - nil, - nil, - (72...73), - nil, - nil, - nil, - BlockNode(74...83)( - [], - nil, - StatementsNode(78...81)( - [CallNode(78...81)( - nil, - nil, - (78...81), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (74...75), - (82...83) - ), - 0, - "a" - )] - ), - (83...84), - nil - ), - ForwardingSuperNode(85...100)( - BlockNode(91...100)( - [], - nil, - StatementsNode(95...98)( - [CallNode(95...98)( - nil, - nil, - (95...98), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (91...92), - (99...100) - ) - ), - SuperNode(101...119)( - (101...106), - (106...107), - ArgumentsNode(107...108)( - [CallNode(107...108)( - nil, - nil, - (107...108), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - (108...109), - BlockNode(110...119)( - [], - nil, - StatementsNode(114...117)( - [CallNode(114...117)( - nil, - nil, - (114...117), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (110...111), - (118...119) - ) - ), - SuperNode(120...137)( - (120...125), - (125...126), - nil, - (126...127), - BlockNode(128...137)( - [], - nil, - StatementsNode(132...135)( - [CallNode(132...135)( - nil, - nil, - (132...135), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (128...129), - (136...137) - ) - ), - SuperNode(138...159)( - (138...143), - (143...144), - ArgumentsNode(144...148)( - [CallNode(144...145)( - nil, - nil, - (144...145), - nil, - nil, - nil, - nil, - 2, - "a" - ), - CallNode(147...148)( - nil, - nil, - (147...148), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (148...149), - BlockNode(150...159)( - [], - nil, - StatementsNode(154...157)( - [CallNode(154...157)( - nil, - nil, - (154...157), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (150...151), - (158...159) - ) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/unary.txt b/test/yarp/snapshots/unparser/corpus/literal/unary.txt deleted file mode 100644 index d4279a42221f46..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/unary.txt +++ /dev/null @@ -1,217 +0,0 @@ -ProgramNode(0...54)( - [], - StatementsNode(0...54)( - [CallNode(0...2)( - IntegerNode(1...2)(), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(3...8)( - ParenthesesNode(4...8)( - StatementsNode(5...7)( - [CallNode(5...7)( - IntegerNode(6...7)(), - nil, - (5...6), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ), - (4...5), - (7...8) - ), - nil, - (3...4), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(9...25)( - ParenthesesNode(10...25)( - StatementsNode(11...24)( - [CallNode(11...24)( - ParenthesesNode(12...24)( - StatementsNode(13...23)( - [OrNode(13...23)( - CallNode(13...16)( - nil, - nil, - (13...16), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(20...23)( - nil, - nil, - (20...23), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (17...19) - )] - ), - (12...13), - (23...24) - ), - nil, - (11...12), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ), - (10...11), - (24...25) - ), - nil, - (9...10), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(26...35)( - CallNode(27...35)( - ParenthesesNode(27...31)( - StatementsNode(28...30)( - [CallNode(28...30)( - IntegerNode(29...30)(), - nil, - (28...29), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ), - (27...28), - (30...31) - ), - (31...32), - (32...35), - nil, - nil, - nil, - nil, - 0, - "baz" - ), - nil, - (26...27), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(36...38)( - CallNode(37...38)(nil, nil, (37...38), nil, nil, nil, nil, 2, "a"), - nil, - (36...37), - nil, - nil, - nil, - nil, - 0, - "~" - ), - CallNode(39...41)( - CallNode(40...41)(nil, nil, (40...41), nil, nil, nil, nil, 2, "a"), - nil, - (39...40), - nil, - nil, - nil, - nil, - 0, - "-@" - ), - CallNode(42...44)( - CallNode(43...44)(nil, nil, (43...44), nil, nil, nil, nil, 2, "a"), - nil, - (42...43), - nil, - nil, - nil, - nil, - 0, - "+@" - ), - CallNode(45...54)( - CallNode(46...54)( - ParenthesesNode(46...50)( - StatementsNode(47...49)( - [CallNode(47...49)( - CallNode(48...49)( - nil, - nil, - (48...49), - nil, - nil, - nil, - nil, - 2, - "a" - ), - nil, - (47...48), - nil, - nil, - nil, - nil, - 0, - "-@" - )] - ), - (46...47), - (49...50) - ), - (50...51), - (51...54), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - nil, - (45...46), - nil, - nil, - nil, - nil, - 0, - "-@" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/undef.txt b/test/yarp/snapshots/unparser/corpus/literal/undef.txt deleted file mode 100644 index 30e513d19e9fbd..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/undef.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [UndefNode(0...10)( - [SymbolNode(6...10)((6...7), (7...10), nil, "foo")], - (0...5) - ), - UndefNode(11...27)( - [SymbolNode(17...21)((17...18), (18...21), nil, "foo"), - SymbolNode(23...27)((23...24), (24...27), nil, "bar")], - (11...16) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/variables.txt b/test/yarp/snapshots/unparser/corpus/literal/variables.txt deleted file mode 100644 index f012dc900c2890..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/variables.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...66)( - [], - StatementsNode(0...66)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - InstanceVariableReadNode(2...4)(:@a), - ClassVariableReadNode(5...8)(:@@a), - GlobalVariableReadNode(9...11)(:$a), - NumberedReferenceReadNode(12...14)(1), - BackReferenceReadNode(15...17)(), - ConstantReadNode(18...23)(:CONST), - ConstantPathNode(24...37)( - ConstantReadNode(24...30)(:SCOPED), - ConstantReadNode(32...37)(:CONST), - (30...32) - ), - ConstantPathNode(38...48)( - nil, - ConstantReadNode(40...48)(:TOPLEVEL), - (38...40) - ), - ConstantPathNode(49...66)( - ConstantPathNode(49...59)( - nil, - ConstantReadNode(51...59)(:TOPLEVEL), - (49...51) - ), - ConstantReadNode(61...66)(:CONST), - (59...61) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/while.txt b/test/yarp/snapshots/unparser/corpus/literal/while.txt deleted file mode 100644 index f6dc399041a381..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/while.txt +++ /dev/null @@ -1,648 +0,0 @@ -ProgramNode(0...620)( - [:x], - StatementsNode(0...620)( - [ModuleNode(0...68)( - [], - (0...6), - ConstantReadNode(7...8)(:A), - StatementsNode(11...64)( - [CallNode(11...64)( - nil, - nil, - (11...14), - nil, - nil, - nil, - BlockNode(15...64)( - [:bar, :foo], - BlockParametersNode(17...22)( - ParametersNode(18...21)( - [RequiredParameterNode(18...21)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (17...18), - (21...22) - ), - StatementsNode(27...60)( - [WhileNode(27...60)( - (27...32), - (57...60), - CallNode(33...36)( - nil, - nil, - (33...36), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StatementsNode(43...52)( - [LocalVariableWriteNode(43...52)( - :foo, - 0, - (43...46), - LocalVariableReadNode(49...52)(:bar, 0), - (47...48) - )] - ), - 0 - )] - ), - (15...16), - (63...64) - ), - 0, - "foo" - )] - ), - (65...68), - :A - ), - DefNode(70...110)( - :foo, - (74...77), - nil, - nil, - StatementsNode(80...106)( - [WhileNode(80...106)( - (90...95), - nil, - CallNode(96...106)( - LocalVariableReadNode(96...99)(:foo, 0), - nil, - (100...102), - nil, - ArgumentsNode(103...106)( - [CallNode(103...106)( - nil, - nil, - (103...106), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil, - nil, - 0, - "!=" - ), - StatementsNode(80...89)( - [LocalVariableWriteNode(80...89)( - :foo, - 0, - (80...83), - CallNode(86...89)( - nil, - nil, - (86...89), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (84...85) - )] - ), - 0 - )] - ), - [:foo], - (70...73), - nil, - nil, - nil, - nil, - (107...110) - ), - ModuleNode(112...146)( - [:foo], - (112...118), - ConstantReadNode(119...120)(:A), - StatementsNode(123...142)( - [WhileNode(123...142)( - (133...138), - nil, - LocalVariableReadNode(139...142)(:foo, 0), - StatementsNode(123...132)( - [LocalVariableWriteNode(123...132)( - :foo, - 0, - (123...126), - CallNode(129...132)( - nil, - nil, - (129...132), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (127...128) - )] - ), - 0 - )] - ), - (143...146), - :A - ), - ModuleNode(148...182)( - [:foo], - (148...154), - ConstantReadNode(155...156)(:A), - StatementsNode(159...178)( - [UntilNode(159...178)( - (169...174), - nil, - LocalVariableReadNode(175...178)(:foo, 0), - StatementsNode(159...168)( - [LocalVariableWriteNode(159...168)( - :foo, - 0, - (159...162), - CallNode(165...168)( - nil, - nil, - (165...168), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (163...164) - )] - ), - 0 - )] - ), - (179...182), - :A - ), - ModuleNode(184...228)( - [:foo], - (184...190), - ConstantReadNode(191...192)(:A), - StatementsNode(195...224)( - [WhileNode(195...224)( - (195...200), - (221...224), - CallNode(201...204)( - nil, - nil, - (201...204), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StatementsNode(209...218)( - [LocalVariableWriteNode(209...218)( - :foo, - 0, - (209...212), - CallNode(215...218)( - nil, - nil, - (215...218), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (213...214) - )] - ), - 0 - )] - ), - (225...228), - :A - ), - ModuleNode(230...299)( - [], - (230...236), - ConstantReadNode(237...238)(:A), - StatementsNode(241...295)( - [CallNode(241...295)( - nil, - nil, - (241...245), - nil, - nil, - nil, - BlockNode(246...295)( - [:baz, :foo], - BlockParametersNode(248...253)( - ParametersNode(249...252)( - [RequiredParameterNode(249...252)(:baz)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (248...249), - (252...253) - ), - StatementsNode(258...291)( - [WhileNode(258...291)( - (258...263), - (288...291), - CallNode(264...267)( - nil, - nil, - (264...267), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - StatementsNode(274...283)( - [LocalVariableWriteNode(274...283)( - :foo, - 0, - (274...277), - CallNode(280...283)( - nil, - nil, - (280...283), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (278...279) - )] - ), - 0 - )] - ), - (246...247), - (294...295) - ), - 0, - "each" - )] - ), - (296...299), - :A - ), - ModuleNode(301...370)( - [], - (301...307), - ConstantReadNode(308...309)(:A), - StatementsNode(312...366)( - [CallNode(312...366)( - nil, - nil, - (312...316), - nil, - nil, - nil, - BlockNode(317...366)( - [:foo], - BlockParametersNode(319...324)( - ParametersNode(320...323)( - [RequiredParameterNode(320...323)(:foo)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (319...320), - (323...324) - ), - StatementsNode(329...362)( - [WhileNode(329...362)( - (329...334), - (359...362), - LocalVariableReadNode(335...338)(:foo, 0), - StatementsNode(345...354)( - [LocalVariableWriteNode(345...354)( - :foo, - 0, - (345...348), - CallNode(351...354)( - nil, - nil, - (351...354), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (349...350) - )] - ), - 0 - )] - ), - (317...318), - (365...366) - ), - 0, - "each" - )] - ), - (367...370), - :A - ), - LocalVariableWriteNode(371...402)( - :x, - 0, - (371...372), - ParenthesesNode(375...402)( - StatementsNode(376...401)( - [WhileNode(376...401)( - (392...397), - nil, - CallNode(398...401)( - nil, - nil, - (398...401), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - StatementsNode(376...391)( - [BeginNode(376...391)( - (376...381), - StatementsNode(384...387)( - [CallNode(384...387)( - nil, - nil, - (384...387), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - nil, - (388...391) - )] - ), - 1 - )] - ), - (375...376), - (401...402) - ), - (373...374) - ), - WhileNode(403...428)( - (419...424), - nil, - CallNode(425...428)( - nil, - nil, - (425...428), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - StatementsNode(403...418)( - [BeginNode(403...418)( - (403...408), - StatementsNode(411...414)( - [CallNode(411...414)( - nil, - nil, - (411...414), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - nil, - (415...418) - )] - ), - 1 - ), - UntilNode(429...460)( - (451...456), - nil, - CallNode(457...460)( - nil, - nil, - (457...460), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - StatementsNode(429...450)( - [BeginNode(429...450)( - (429...434), - StatementsNode(437...446)( - [CallNode(437...440)( - nil, - nil, - (437...440), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(443...446)( - nil, - nil, - (443...446), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - nil, - (447...450) - )] - ), - 1 - ), - WhileNode(461...492)( - (483...488), - nil, - CallNode(489...492)( - nil, - nil, - (489...492), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - StatementsNode(461...482)( - [BeginNode(461...482)( - (461...466), - StatementsNode(469...478)( - [CallNode(469...472)( - nil, - nil, - (469...472), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - CallNode(475...478)( - nil, - nil, - (475...478), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - nil, - (479...482) - )] - ), - 1 - ), - WhileNode(493...508)( - (493...498), - (505...508), - FalseNode(499...504)(), - nil, - 0 - ), - WhileNode(509...528)( - (509...514), - (525...528), - FalseNode(515...520)(), - StatementsNode(523...524)([IntegerNode(523...524)()]), - 0 - ), - WhileNode(529...556)( - (529...534), - (553...556), - ParenthesesNode(535...544)( - StatementsNode(536...543)( - [CallNode(536...543)( - nil, - nil, - (536...539), - nil, - nil, - nil, - BlockNode(540...543)([], nil, nil, (540...541), (542...543)), - 0, - "foo" - )] - ), - (535...536), - (543...544) - ), - StatementsNode(547...552)( - [SymbolNode(547...552)((547...548), (548...552), nil, "body")] - ), - 0 - ), - UntilNode(557...572)( - (557...562), - (569...572), - FalseNode(563...568)(), - nil, - 0 - ), - UntilNode(573...592)( - (573...578), - (589...592), - FalseNode(579...584)(), - StatementsNode(587...588)([IntegerNode(587...588)()]), - 0 - ), - UntilNode(593...620)( - (593...598), - (617...620), - ParenthesesNode(599...608)( - StatementsNode(600...607)( - [CallNode(600...607)( - nil, - nil, - (600...603), - nil, - nil, - nil, - BlockNode(604...607)([], nil, nil, (604...605), (606...607)), - 0, - "foo" - )] - ), - (599...600), - (607...608) - ), - StatementsNode(611...616)( - [SymbolNode(611...616)((611...612), (612...616), nil, "body")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/literal/yield.txt b/test/yarp/snapshots/unparser/corpus/literal/yield.txt deleted file mode 100644 index 4ccd79e2dd1c22..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/literal/yield.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [YieldNode(0...5)((0...5), nil, nil, nil), - YieldNode(6...14)( - (6...11), - (11...12), - ArgumentsNode(12...13)( - [CallNode(12...13)(nil, nil, (12...13), nil, nil, nil, nil, 2, "a")] - ), - (13...14) - ), - YieldNode(15...26)( - (15...20), - (20...21), - ArgumentsNode(21...25)( - [CallNode(21...22)(nil, nil, (21...22), nil, nil, nil, nil, 2, "a"), - CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "b")] - ), - (25...26) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/and.txt b/test/yarp/snapshots/unparser/corpus/semantic/and.txt deleted file mode 100644 index de40267054e840..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/and.txt +++ /dev/null @@ -1,77 +0,0 @@ -ProgramNode(0...77)( - [], - StatementsNode(0...77)( - [OrNode(0...14)( - RangeNode(0...5)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"), - (1...4), - 1 - ), - RangeNode(9...14)( - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "c"), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "d"), - (10...13), - 1 - ), - (6...8) - ), - AndNode(15...30)( - RangeNode(15...20)( - CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "a"), - CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "b"), - (16...19), - 1 - ), - RangeNode(25...30)( - CallNode(25...26)(nil, nil, (25...26), nil, nil, nil, nil, 2, "c"), - CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "d"), - (26...29), - 1 - ), - (21...24) - ), - IfNode(32...53)( - (32...34), - OrNode(35...49)( - FlipFlopNode(35...40)( - CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 2, "a"), - CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 2, "b"), - (36...39), - 1 - ), - FlipFlopNode(44...49)( - CallNode(44...45)(nil, nil, (44...45), nil, nil, nil, nil, 2, "c"), - CallNode(48...49)(nil, nil, (48...49), nil, nil, nil, nil, 2, "d"), - (45...48), - 1 - ), - (41...43) - ), - nil, - nil, - (50...53) - ), - IfNode(55...77)( - (55...57), - AndNode(58...73)( - FlipFlopNode(58...63)( - CallNode(58...59)(nil, nil, (58...59), nil, nil, nil, nil, 2, "a"), - CallNode(62...63)(nil, nil, (62...63), nil, nil, nil, nil, 2, "b"), - (59...62), - 1 - ), - FlipFlopNode(68...73)( - CallNode(68...69)(nil, nil, (68...69), nil, nil, nil, nil, 2, "c"), - CallNode(72...73)(nil, nil, (72...73), nil, nil, nil, nil, 2, "d"), - (69...72), - 1 - ), - (64...67) - ), - nil, - nil, - (74...77) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/block.txt b/test/yarp/snapshots/unparser/corpus/semantic/block.txt deleted file mode 100644 index 16524948974d20..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/block.txt +++ /dev/null @@ -1,165 +0,0 @@ -ProgramNode(0...148)( - [], - StatementsNode(0...148)( - [CallNode(0...10)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...10)([], nil, nil, (4...6), (7...10)), - 0, - "foo" - ), - CallNode(12...29)( - nil, - nil, - (12...15), - nil, - nil, - nil, - BlockNode(16...29)( - [], - nil, - BeginNode(19...29)( - nil, - nil, - RescueNode(19...25)((19...25), [], nil, nil, nil, nil), - nil, - nil, - (26...29) - ), - (16...18), - (26...29) - ), - 0, - "foo" - ), - CallNode(31...64)( - nil, - nil, - (31...34), - nil, - nil, - nil, - BlockNode(35...64)( - [], - nil, - StatementsNode(40...60)( - [RescueModifierNode(40...54)( - NilNode(40...43)(), - (44...50), - NilNode(51...54)() - ), - NilNode(57...60)()] - ), - (35...37), - (61...64) - ), - 0, - "foo" - ), - CallNode(66...80)( - nil, - nil, - (66...69), - nil, - nil, - nil, - BlockNode(70...80)( - [:a], - BlockParametersNode(73...76)( - ParametersNode(74...75)( - [RequiredParameterNode(74...75)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (73...74), - (75...76) - ), - nil, - (70...72), - (77...80) - ), - 0, - "foo" - ), - CallNode(82...116)( - nil, - nil, - (82...85), - (85...86), - ArgumentsNode(86...92)( - [InterpolatedStringNode(86...92)( - (86...92), - [StringNode(101...105)(nil, (101...105), nil, " b\n")], - (105...109) - )] - ), - (92...93), - BlockNode(94...116)( - [:a], - BlockParametersNode(97...100)( - ParametersNode(98...99)( - [RequiredParameterNode(98...99)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (97...98), - (99...100) - ), - StatementsNode(111...112)([LocalVariableReadNode(111...112)(:a, 0)]), - (94...96), - (113...116) - ), - 0, - "foo" - ), - CallNode(118...148)( - nil, - nil, - (118...121), - (121...122), - ArgumentsNode(122...128)( - [InterpolatedStringNode(122...128)( - (122...128), - [StringNode(133...137)(nil, (133...137), nil, " b\n")], - (137...141) - )] - ), - (128...129), - BlockNode(130...148)( - [], - nil, - StatementsNode(143...144)( - [CallNode(143...144)( - nil, - nil, - (143...144), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - (130...132), - (145...148) - ), - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/def.txt b/test/yarp/snapshots/unparser/corpus/semantic/def.txt deleted file mode 100644 index 428b7138cb4051..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/def.txt +++ /dev/null @@ -1,79 +0,0 @@ -ProgramNode(0...55)( - [], - StatementsNode(0...55)( - [DefNode(0...21)( - :foo, - (4...7), - nil, - nil, - StatementsNode(10...17)( - [ParenthesesNode(10...17)( - StatementsNode(11...16)( - [CallNode(11...16)( - CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "a" - ), - nil, - (13...14), - nil, - ArgumentsNode(15...16)( - [CallNode(15...16)( - nil, - nil, - (15...16), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil, - nil, - 0, - "-" - )] - ), - (10...11), - (16...17) - )] - ), - [], - (0...3), - nil, - nil, - nil, - nil, - (18...21) - ), - DefNode(23...55)( - :foo, - (27...30), - nil, - nil, - StatementsNode(33...51)( - [RescueModifierNode(33...51)( - CallNode(33...34)(nil, nil, (33...34), nil, nil, nil, nil, 2, "a"), - (35...41), - ConstantReadNode(42...51)(:Exception) - )] - ), - [], - (23...26), - nil, - nil, - nil, - nil, - (52...55) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/dstr.txt b/test/yarp/snapshots/unparser/corpus/semantic/dstr.txt deleted file mode 100644 index 8edb0134b1c58f..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/dstr.txt +++ /dev/null @@ -1,256 +0,0 @@ -ProgramNode(0...608)( - [], - StatementsNode(0...608)( - [InterpolatedStringNode(0...5)((0...5), [], (6...10)), - InterpolatedStringNode(11...18)((11...18), [], (19...23)), - InterpolatedStringNode(24...30)((24...30), [], (31...35)), - InterpolatedStringNode(36...44)((36...44), [], (45...49)), - InterpolatedStringNode(50...55)( - (50...55), - [StringNode(56...60)(nil, (56...60), nil, " a\n")], - (60...64) - ), - InterpolatedStringNode(65...72)( - (65...72), - [StringNode(73...77)(nil, (73...77), nil, " a\n")], - (77...81) - ), - InterpolatedStringNode(82...87)( - (82...87), - [StringNode(88...94)(nil, (88...94), nil, " a\n" + " "), - EmbeddedStatementsNode(94...97)((94...96), nil, (96...97)), - StringNode(97...98)(nil, (97...98), nil, "\n")], - (98...102) - ), - InterpolatedStringNode(103...109)( - (103...109), - [StringNode(110...116)(nil, (110...116), nil, "a\n"), - EmbeddedStatementsNode(116...119)((116...118), nil, (118...119)), - StringNode(119...120)(nil, (119...120), nil, "\n")], - (120...124) - ), - InterpolatedStringNode(125...131)( - (125...131), - [StringNode(132...138)(nil, (132...138), nil, "a\n"), - EmbeddedStatementsNode(138...141)((138...140), nil, (140...141)), - StringNode(141...146)(nil, (141...146), nil, "\n" + "b\n")], - (146...150) - ), - InterpolatedStringNode(151...157)( - (151...157), - [StringNode(158...168)(nil, (158...168), nil, "a\n" + " b\n")], - (168...172) - ), - InterpolatedStringNode(173...180)( - (173...180), - [StringNode(181...186)(nil, (181...186), nil, "a\n" + "\n" + "b\n")], - (186...190) - ), - InterpolatedStringNode(191...198)( - (191...198), - [StringNode(199...206)(nil, (199...206), nil, " a\n" + "\n" + " b\n")], - (206...210) - ), - InterpolatedStringNode(211...218)( - (211...218), - [StringNode(219...225)(nil, (219...225), nil, " a\\nb\n")], - (225...229) - ), - InterpolatedStringNode(230...235)( - (230...235), - [EmbeddedStatementsNode(236...239)((236...238), nil, (238...239)), - StringNode(239...242)(nil, (239...242), nil, "a\n" + " "), - EmbeddedStatementsNode(242...245)((242...244), nil, (244...245)), - StringNode(245...247)(nil, (245...247), nil, "a\n")], - (247...251) - ), - InterpolatedStringNode(252...257)( - (252...257), - [StringNode(258...260)(nil, (258...260), nil, " "), - EmbeddedStatementsNode(260...263)((260...262), nil, (262...263)), - StringNode(263...271)(nil, (263...271), nil, "\n" + " \#{}\n")], - (271...275) - ), - InterpolatedStringNode(276...281)( - (276...281), - [StringNode(282...284)(nil, (282...284), nil, " a"), - EmbeddedStatementsNode(284...287)((284...286), nil, (286...287)), - StringNode(287...292)(nil, (287...292), nil, "b\n" + " c\n")], - (292...296) - ), - InterpolatedStringNode(297...303)( - (297...303), - [EmbeddedStatementsNode(306...309)((306...308), nil, (308...309)), - StringNode(309...310)(nil, (309...310), nil, "\n")], - (310...314) - ), - IfNode(315...349)( - (315...317), - TrueNode(318...322)(), - StatementsNode(325...331)( - [InterpolatedStringNode(325...331)( - (325...331), - [EmbeddedStatementsNode(336...339)((336...338), nil, (338...339)), - StringNode(339...340)(nil, (339...340), nil, "\n")], - (340...346) - )] - ), - nil, - (346...349) - ), - IfNode(351...386)( - (351...353), - TrueNode(354...358)(), - StatementsNode(361...367)( - [InterpolatedStringNode(361...367)( - (361...367), - [StringNode(368...373)(nil, (368...373), nil, "b"), - EmbeddedStatementsNode(373...376)((373...375), nil, (375...376)), - StringNode(376...377)(nil, (376...377), nil, "\n")], - (377...383) - )] - ), - nil, - (383...386) - ), - IfNode(388...423)( - (388...390), - TrueNode(391...395)(), - StatementsNode(398...404)( - [InterpolatedStringNode(398...404)( - (398...404), - [EmbeddedStatementsNode(409...412)((409...411), nil, (411...412)), - StringNode(412...414)(nil, (412...414), nil, "a\n")], - (414...420) - )] - ), - nil, - (420...423) - ), - IfNode(425...464)( - (425...427), - TrueNode(428...432)(), - StatementsNode(435...443)( - [InterpolatedStringNode(435...443)( - (435...443), - [StringNode(444...455)( - nil, - (444...455), - nil, - " a\n" + "\n" + " b\n" - )], - (455...461) - )] - ), - nil, - (461...464) - ), - InterpolatedStringNode(466...472)( - (466...467), - [EmbeddedStatementsNode(467...470)((467...469), nil, (469...470)), - StringNode(470...471)(nil, (470...471), nil, "a")], - (471...472) - ), - InterpolatedStringNode(474...486)( - (474...476), - [StringNode(476...479)(nil, (476...479), nil, "\n" + "\""), - EmbeddedStatementsNode(479...482)((479...481), nil, (481...482)), - StringNode(482...485)(nil, (482...485), nil, "\"\n")], - (485...486) - ), - InterpolatedStringNode(488...502)( - (488...491), - [StringNode(491...495)(nil, (491...495), nil, "-\n" + "\""), - EmbeddedStatementsNode(495...498)((495...497), nil, (497...498)), - StringNode(498...501)(nil, (498...501), nil, "\"\n")], - (501...502) - ), - InterpolatedStringNode(504...513)( - (504...505), - [StringNode(505...507)(nil, (505...507), nil, "a\n"), - EmbeddedStatementsNode(507...510)((507...509), nil, (509...510)), - StringNode(510...512)(nil, (510...512), nil, "\n" + "b")], - (512...513) - ), - InterpolatedStringNode(515...525)( - (515...516), - [StringNode(516...519)(nil, (516...519), nil, "a\n"), - EmbeddedStatementsNode(519...522)((519...521), nil, (521...522)), - StringNode(522...524)(nil, (522...524), nil, "\n" + "b")], - (524...525) - ), - InterpolatedStringNode(527...537)( - (527...528), - [StringNode(528...530)(nil, (528...530), nil, "a\n"), - EmbeddedStatementsNode(530...533)((530...532), nil, (532...533)), - StringNode(533...536)(nil, (533...536), nil, "\n" + "b")], - (536...537) - ), - StringConcatNode(539...550)( - StringNode(539...542)((539...540), (540...541), (541...542), "a"), - InterpolatedStringNode(545...550)( - (545...546), - [EmbeddedStatementsNode(546...549)((546...548), nil, (548...549))], - (549...550) - ) - ), - StringConcatNode(552...560)( - StringConcatNode(552...557)( - StringNode(552...554)((552...553), (553...553), (553...554), ""), - StringNode(555...557)((555...556), (556...556), (556...557), "") - ), - StringNode(558...560)((558...559), (559...559), (559...560), "") - ), - StringConcatNode(562...574)( - InterpolatedStringNode(562...570)( - (562...563), - [StringNode(563...564)(nil, (563...564), nil, "a"), - EmbeddedStatementsNode(564...569)( - (564...566), - StatementsNode(566...568)( - [InstanceVariableReadNode(566...568)(:@a)] - ), - (568...569) - )], - (569...570) - ), - StringNode(571...574)((571...572), (572...573), (573...574), "b") - ), - StringConcatNode(575...585)( - InterpolatedStringNode(575...581)( - (575...576), - [StringNode(576...577)(nil, (576...577), nil, "a"), - EmbeddedVariableNode(577...580)( - (577...578), - InstanceVariableReadNode(578...580)(:@a) - )], - (580...581) - ), - StringNode(582...585)((582...583), (583...584), (584...585), "b") - ), - StringConcatNode(586...596)( - InterpolatedStringNode(586...592)( - (586...587), - [StringNode(587...588)(nil, (587...588), nil, "a"), - EmbeddedVariableNode(588...591)( - (588...589), - GlobalVariableReadNode(589...591)(:$a) - )], - (591...592) - ), - StringNode(593...596)((593...594), (594...595), (595...596), "b") - ), - StringConcatNode(597...608)( - InterpolatedStringNode(597...604)( - (597...598), - [StringNode(598...599)(nil, (598...599), nil, "a"), - EmbeddedVariableNode(599...603)( - (599...600), - ClassVariableReadNode(600...603)(:@@a) - )], - (603...604) - ), - StringNode(605...608)((605...606), (606...607), (607...608), "b") - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/kwbegin.txt b/test/yarp/snapshots/unparser/corpus/semantic/kwbegin.txt deleted file mode 100644 index 231ed767cf4ed8..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/kwbegin.txt +++ /dev/null @@ -1,184 +0,0 @@ -ProgramNode(0...215)( - [], - StatementsNode(0...215)( - [BeginNode(0...16)( - (0...5), - nil, - RescueNode(6...12)((6...12), [], nil, nil, nil, nil), - nil, - nil, - (13...16) - ), - BeginNode(18...39)( - (18...23), - nil, - RescueNode(24...30)((24...30), [], nil, nil, nil, nil), - ElseNode(31...39)((31...35), nil, (36...39)), - nil, - (36...39) - ), - BeginNode(41...54)( - (41...46), - StatementsNode(49...50)( - [CallNode(49...50)(nil, nil, (49...50), nil, nil, nil, nil, 2, "a")] - ), - nil, - nil, - nil, - (51...54) - ), - BeginNode(56...80)( - (56...61), - StatementsNode(64...65)( - [CallNode(64...65)(nil, nil, (64...65), nil, nil, nil, nil, 2, "a")] - ), - RescueNode(66...76)( - (66...72), - [], - nil, - nil, - StatementsNode(75...76)( - [CallNode(75...76)(nil, nil, (75...76), nil, nil, nil, nil, 2, "b")] - ), - nil - ), - nil, - nil, - (77...80) - ), - BeginNode(82...110)( - (82...87), - StatementsNode(90...95)( - [CallNode(90...91)(nil, nil, (90...91), nil, nil, nil, nil, 2, "a"), - CallNode(94...95)(nil, nil, (94...95), nil, nil, nil, nil, 2, "b")] - ), - RescueNode(96...106)( - (96...102), - [], - nil, - nil, - StatementsNode(105...106)( - [CallNode(105...106)( - nil, - nil, - (105...106), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - nil - ), - nil, - nil, - (107...110) - ), - BeginNode(112...135)( - (112...117), - nil, - RescueNode(118...126)( - (118...124), - [ConstantReadNode(125...126)(:A)], - nil, - nil, - nil, - nil - ), - ElseNode(127...135)((127...131), nil, (132...135)), - nil, - (132...135) - ), - BeginNode(137...163)( - (137...142), - nil, - RescueNode(144...152)( - (144...150), - [ConstantReadNode(151...152)(:A)], - nil, - nil, - nil, - nil - ), - ElseNode(154...163)((154...158), nil, (160...163)), - nil, - (160...163) - ), - BeginNode(165...215)( - (165...170), - StatementsNode(173...174)( - [CallNode(173...174)( - nil, - nil, - (173...174), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - RescueNode(175...200)( - (175...181), - [ConstantReadNode(182...183)(:A)], - nil, - nil, - StatementsNode(186...187)( - [CallNode(186...187)( - nil, - nil, - (186...187), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - RescueNode(188...200)( - (188...194), - [ConstantReadNode(195...196)(:B)], - nil, - nil, - StatementsNode(199...200)( - [CallNode(199...200)( - nil, - nil, - (199...200), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - nil - ) - ), - nil, - EnsureNode(201...215)( - (201...207), - StatementsNode(210...211)( - [CallNode(210...211)( - nil, - nil, - (210...211), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (212...215) - ), - (212...215) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/literal.txt b/test/yarp/snapshots/unparser/corpus/semantic/literal.txt deleted file mode 100644 index 5e18c54da412a6..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/literal.txt +++ /dev/null @@ -1,63 +0,0 @@ -ProgramNode(0...131)( - [], - StatementsNode(0...131)( - [RationalNode(0...4)(FloatNode(0...3)()), - RationalNode(5...8)(IntegerNode(5...7)()), - IntegerNode(9...12)(), - IntegerNode(13...18)(), - FloatNode(19...23)(), - FloatNode(24...38)(), - FloatNode(39...54)(), - StringNode(55...57)((55...56), (56...57), nil, "c"), - RegularExpressionNode(58...63)((58...61), (61...62), (62...63), "/", 0), - RegularExpressionNode(64...70)((64...67), (67...69), (69...70), ")", 0), - InterpolatedRegularExpressionNode(71...85)( - (71...74), - [EmbeddedStatementsNode(74...81)( - (74...76), - StatementsNode(76...80)([InstanceVariableReadNode(76...80)(:@bar)]), - (80...81) - ), - StringNode(81...84)(nil, (81...84), nil, "baz")], - (84...85), - 0 - ), - FloatNode(86...102)(), - FloatNode(103...120)(), - CallNode(121...131)( - nil, - nil, - (121...122), - (122...123), - ArgumentsNode(123...130)( - [CallNode(123...130)( - nil, - nil, - (123...126), - nil, - ArgumentsNode(127...130)( - [CallNode(127...130)( - nil, - nil, - (127...130), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "foo" - )] - ), - (130...131), - nil, - 0, - "w" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/send.txt b/test/yarp/snapshots/unparser/corpus/semantic/send.txt deleted file mode 100644 index b584fa06cf94ca..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/send.txt +++ /dev/null @@ -1,117 +0,0 @@ -ProgramNode(0...44)( - [], - StatementsNode(0...44)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - CallNode(4...10)( - nil, - nil, - (4...7), - (7...8), - ArgumentsNode(8...9)([IntegerNode(8...9)()]), - (9...10), - nil, - 0, - "foo" - ), - CallNode(12...27)( - CallNode(12...22)( - CallNode(12...20)( - CallNode(12...13)(nil, nil, (12...13), nil, nil, nil, nil, 2, "a"), - (13...14), - (14...17), - (17...18), - ArgumentsNode(18...19)( - [CallNode(18...19)( - nil, - nil, - (18...19), - nil, - nil, - nil, - nil, - 2, - "b" - )] - ), - (19...20), - nil, - 0, - "===" - ), - (20...21), - (21...22), - nil, - nil, - nil, - nil, - 0, - "c" - ), - nil, - (23...25), - nil, - ArgumentsNode(26...27)( - [CallNode(26...27)(nil, nil, (26...27), nil, nil, nil, nil, 2, "d")] - ), - nil, - nil, - 0, - "==" - ), - CallNode(29...44)( - CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "a"), - nil, - (31...33), - nil, - ArgumentsNode(34...44)( - [CallNode(34...44)( - CallNode(34...37)( - CallNode(34...35)( - nil, - nil, - (34...35), - nil, - nil, - nil, - nil, - 2, - "d" - ), - (35...36), - (36...37), - nil, - nil, - nil, - nil, - 0, - "c" - ), - (37...38), - (38...41), - (41...42), - ArgumentsNode(42...43)( - [CallNode(42...43)( - nil, - nil, - (42...43), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (43...44), - nil, - 0, - "===" - )] - ), - nil, - nil, - 0, - "==" - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/undef.txt b/test/yarp/snapshots/unparser/corpus/semantic/undef.txt deleted file mode 100644 index 429e9044819668..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/undef.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [UndefNode(0...9)([SymbolNode(6...9)(nil, (6...9), nil, "foo")], (0...5)), - UndefNode(10...24)( - [SymbolNode(16...19)(nil, (16...19), nil, "foo"), - SymbolNode(21...24)(nil, (21...24), nil, "bar")], - (10...15) - )] - ) -) diff --git a/test/yarp/snapshots/unparser/corpus/semantic/while.txt b/test/yarp/snapshots/unparser/corpus/semantic/while.txt deleted file mode 100644 index 6b29da7e48bf45..00000000000000 --- a/test/yarp/snapshots/unparser/corpus/semantic/while.txt +++ /dev/null @@ -1,192 +0,0 @@ -ProgramNode(0...188)( - [:foo, :a], - StatementsNode(0...188)( - [UntilNode(0...13)( - (2...7), - nil, - CallNode(8...13)( - nil, - nil, - (8...10), - nil, - nil, - nil, - BlockNode(11...13)([], nil, nil, (11...12), (12...13)), - 0, - "b?" - ), - StatementsNode(0...1)( - [CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a")] - ), - 0 - ), - UntilNode(15...34)( - (15...20), - (31...34), - CallNode(21...26)( - nil, - nil, - (21...23), - nil, - nil, - nil, - BlockNode(24...26)([], nil, nil, (24...25), (25...26)), - 0, - "b?" - ), - StatementsNode(29...30)( - [CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "a")] - ), - 0 - ), - WhileNode(36...55)( - (46...51), - nil, - LocalVariableReadNode(52...55)(:foo, 0), - StatementsNode(36...45)( - [LocalVariableWriteNode(36...45)( - :foo, - 0, - (36...39), - CallNode(42...45)( - nil, - nil, - (42...45), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (40...41) - )] - ), - 0 - ), - UntilNode(57...75)( - (59...64), - nil, - AndNode(65...75)( - CallNode(65...66)(nil, nil, (65...66), nil, nil, nil, nil, 2, "b"), - CallNode(70...75)( - nil, - nil, - (70...71), - nil, - nil, - nil, - BlockNode(72...75)([], nil, nil, (72...73), (74...75)), - 0, - "a" - ), - (67...69) - ), - StatementsNode(57...58)( - [CallNode(57...58)(nil, nil, (57...58), nil, nil, nil, nil, 2, "a")] - ), - 0 - ), - WhileNode(77...96)( - (77...82), - (93...96), - LocalVariableWriteNode(83...88)( - :a, - 0, - (83...84), - CallNode(87...88)(nil, nil, (87...88), nil, nil, nil, nil, 2, "b"), - (85...86) - ), - StatementsNode(91...92)([LocalVariableReadNode(91...92)(:a, 0)]), - 0 - ), - UntilNode(98...130)( - (100...105), - nil, - CallNode(106...130)( - nil, - nil, - (106...107), - (107...108), - ArgumentsNode(108...114)( - [InterpolatedStringNode(108...114)((108...114), [], (119...123))] - ), - (114...115), - BlockNode(116...130)( - [], - nil, - StatementsNode(125...126)( - [CallNode(125...126)( - nil, - nil, - (125...126), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (116...118), - (127...130) - ), - 0, - "b" - ), - StatementsNode(98...99)([LocalVariableReadNode(98...99)(:a, 0)]), - 0 - ), - ModuleNode(132...188)( - [:foo], - (132...138), - ConstantReadNode(139...140)(:A), - StatementsNode(143...184)( - [LocalVariableWriteNode(143...152)( - :foo, - 0, - (143...146), - CallNode(149...152)( - nil, - nil, - (149...152), - nil, - nil, - nil, - nil, - 2, - "exp" - ), - (147...148) - ), - WhileNode(155...184)( - (155...160), - (181...184), - LocalVariableReadNode(161...164)(:foo, 0), - StatementsNode(169...178)( - [LocalVariableWriteNode(169...178)( - :foo, - 0, - (169...172), - CallNode(175...178)( - nil, - nil, - (175...178), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (173...174) - )] - ), - 0 - )] - ), - (185...188), - :A - )] - ) -) diff --git a/test/yarp/snapshots/until.txt b/test/yarp/snapshots/until.txt deleted file mode 100644 index 6a93708e5b6da2..00000000000000 --- a/test/yarp/snapshots/until.txt +++ /dev/null @@ -1,72 +0,0 @@ -ProgramNode(0...109)( - [], - StatementsNode(0...109)( - [UntilNode(0...18)( - (0...5), - (15...18), - TrueNode(6...10)(), - StatementsNode(12...13)([IntegerNode(12...13)()]), - 0 - ), - UntilNode(20...32)( - (22...27), - nil, - TrueNode(28...32)(), - StatementsNode(20...21)([IntegerNode(20...21)()]), - 0 - ), - UntilNode(34...50)( - (40...45), - nil, - TrueNode(46...50)(), - StatementsNode(34...39)([BreakNode(34...39)(nil, (34...39))]), - 0 - ), - UntilNode(52...67)( - (57...62), - nil, - TrueNode(63...67)(), - StatementsNode(52...56)([NextNode(52...56)(nil, (52...56))]), - 0 - ), - UntilNode(69...86)( - (76...81), - nil, - TrueNode(82...86)(), - StatementsNode(69...75)([ReturnNode(69...75)((69...75), nil)]), - 0 - ), - UntilNode(88...109)( - (99...104), - nil, - CallNode(105...109)( - nil, - nil, - (105...109), - nil, - nil, - nil, - nil, - 0, - "bar?" - ), - StatementsNode(88...98)( - [CallNode(88...98)( - nil, - nil, - (88...91), - nil, - ArgumentsNode(92...98)( - [SymbolNode(92...94)((92...93), (93...94), nil, "a"), - SymbolNode(96...98)((96...97), (97...98), nil, "b")] - ), - nil, - nil, - 0, - "foo" - )] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/variables.txt b/test/yarp/snapshots/variables.txt deleted file mode 100644 index 29f5e44817e5b9..00000000000000 --- a/test/yarp/snapshots/variables.txt +++ /dev/null @@ -1,241 +0,0 @@ -ProgramNode(0...293)( - [:abc, :foo, :bar, :baz], - StatementsNode(0...293)( - [ClassVariableReadNode(0...5)(:@@abc), - ClassVariableWriteNode(7...16)( - :@@abc, - (7...12), - IntegerNode(15...16)(), - (13...14) - ), - MultiWriteNode(18...34)( - [ClassVariableTargetNode(18...23)(:@@foo), - ClassVariableTargetNode(25...30)(:@@bar)], - nil, - nil, - (31...32), - IntegerNode(33...34)() - ), - ClassVariableWriteNode(36...48)( - :@@foo, - (36...41), - ArrayNode(44...48)( - [IntegerNode(44...45)(), IntegerNode(47...48)()], - nil, - nil - ), - (42...43) - ), - GlobalVariableWriteNode(50...58)( - :$abc, - (50...54), - IntegerNode(57...58)(), - (55...56) - ), - GlobalVariableReadNode(60...64)(:$abc), - InstanceVariableReadNode(66...70)(:@abc), - InstanceVariableWriteNode(72...80)( - :@abc, - (72...76), - IntegerNode(79...80)(), - (77...78) - ), - CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "a"), - LocalVariableWriteNode(85...92)( - :abc, - 0, - (85...88), - IntegerNode(91...92)(), - (89...90) - ), - MultiWriteNode(94...108)( - [GlobalVariableTargetNode(94...98)(:$foo), - GlobalVariableTargetNode(100...104)(:$bar)], - nil, - nil, - (105...106), - IntegerNode(107...108)() - ), - GlobalVariableWriteNode(110...121)( - :$foo, - (110...114), - ArrayNode(117...121)( - [IntegerNode(117...118)(), IntegerNode(120...121)()], - nil, - nil - ), - (115...116) - ), - MultiWriteNode(123...137)( - [InstanceVariableTargetNode(123...127)(:@foo), - InstanceVariableTargetNode(129...133)(:@bar)], - nil, - nil, - (134...135), - IntegerNode(136...137)() - ), - InstanceVariableWriteNode(139...150)( - :@foo, - (139...143), - ArrayNode(146...150)( - [IntegerNode(146...147)(), IntegerNode(149...150)()], - nil, - nil - ), - (144...145) - ), - LocalVariableWriteNode(152...159)( - :foo, - 0, - (152...155), - IntegerNode(158...159)(), - (156...157) - ), - LocalVariableWriteNode(161...171)( - :foo, - 0, - (161...164), - ArrayNode(167...171)( - [IntegerNode(167...168)(), IntegerNode(170...171)()], - nil, - nil - ), - (165...166) - ), - LocalVariableWriteNode(173...183)( - :foo, - 0, - (173...176), - ArrayNode(179...183)( - [IntegerNode(179...180)(), IntegerNode(182...183)()], - nil, - nil - ), - (177...178) - ), - MultiWriteNode(185...198)( - [LocalVariableTargetNode(185...188)(:foo, 0), - SplatNode(190...191)((190...191), nil)], - nil, - nil, - (192...193), - ArrayNode(194...198)( - [IntegerNode(194...195)(), IntegerNode(197...198)()], - nil, - nil - ) - ), - MultiWriteNode(200...211)( - [LocalVariableTargetNode(200...203)(:foo, 0), - SplatNode(203...204)((203...204), nil)], - nil, - nil, - (205...206), - ArrayNode(207...211)( - [IntegerNode(207...208)(), IntegerNode(210...211)()], - nil, - nil - ) - ), - MultiWriteNode(213...229)( - [LocalVariableTargetNode(213...216)(:foo, 0), - SplatNode(218...222)( - (218...219), - LocalVariableTargetNode(219...222)(:bar, 0) - )], - nil, - nil, - (223...224), - ArrayNode(225...229)( - [IntegerNode(225...226)(), IntegerNode(228...229)()], - nil, - nil - ) - ), - MultiWriteNode(231...258)( - [LocalVariableTargetNode(231...234)(:foo, 0), - MultiTargetNode(236...246)( - [LocalVariableTargetNode(237...240)(:bar, 0), - LocalVariableTargetNode(242...245)(:baz, 0)], - (236...237), - (245...246) - )], - nil, - nil, - (247...248), - ArrayNode(249...258)( - [IntegerNode(249...250)(), - ArrayNode(252...258)( - [IntegerNode(253...254)(), IntegerNode(256...257)()], - (252...253), - (257...258) - )], - nil, - nil - ) - ), - LocalVariableWriteNode(260...270)( - :foo, - 0, - (260...263), - ArrayNode(266...270)( - [SplatNode(266...270)( - (266...267), - LocalVariableReadNode(267...270)(:bar, 0) - )], - nil, - nil - ), - (264...265) - ), - ConstantWriteNode(272...282)( - :Foo, - (272...275), - ArrayNode(278...282)( - [IntegerNode(278...279)(), IntegerNode(281...282)()], - nil, - nil - ), - (276...277) - ), - ParenthesesNode(284...293)( - StatementsNode(285...292)( - [CallNode(285...286)( - nil, - nil, - (285...286), - nil, - nil, - nil, - nil, - 2, - "a" - ), - CallNode(288...289)( - nil, - nil, - (288...289), - nil, - nil, - nil, - nil, - 2, - "b" - ), - CallNode(291...292)( - nil, - nil, - (291...292), - nil, - nil, - nil, - nil, - 2, - "c" - )] - ), - (284...285), - (292...293) - )] - ) -) diff --git a/test/yarp/snapshots/while.txt b/test/yarp/snapshots/while.txt deleted file mode 100644 index 078df5066c7aa2..00000000000000 --- a/test/yarp/snapshots/while.txt +++ /dev/null @@ -1,207 +0,0 @@ -ProgramNode(0...314)( - [], - StatementsNode(0...314)( - [WhileNode(0...18)( - (0...5), - (15...18), - TrueNode(6...10)(), - StatementsNode(12...13)([IntegerNode(12...13)()]), - 0 - ), - WhileNode(20...32)( - (22...27), - nil, - TrueNode(28...32)(), - StatementsNode(20...21)([IntegerNode(20...21)()]), - 0 - ), - WhileNode(34...50)( - (40...45), - nil, - TrueNode(46...50)(), - StatementsNode(34...39)([BreakNode(34...39)(nil, (34...39))]), - 0 - ), - WhileNode(52...67)( - (57...62), - nil, - TrueNode(63...67)(), - StatementsNode(52...56)([NextNode(52...56)(nil, (52...56))]), - 0 - ), - WhileNode(69...86)( - (76...81), - nil, - TrueNode(82...86)(), - StatementsNode(69...75)([ReturnNode(69...75)((69...75), nil)]), - 0 - ), - WhileNode(88...109)( - (99...104), - nil, - CallNode(105...109)( - nil, - nil, - (105...109), - nil, - nil, - nil, - nil, - 0, - "bar?" - ), - StatementsNode(88...98)( - [CallNode(88...98)( - nil, - nil, - (88...91), - nil, - ArgumentsNode(92...98)( - [SymbolNode(92...94)((92...93), (93...94), nil, "a"), - SymbolNode(96...98)((96...97), (97...98), nil, "b")] - ), - nil, - nil, - 0, - "foo" - )] - ), - 0 - ), - WhileNode(111...161)( - (111...116), - (158...161), - DefNode(117...149)( - :foo, - (126...129), - SelfNode(121...125)(), - ParametersNode(130...144)( - [], - [OptionalParameterNode(130...144)( - :a, - (130...131), - (132...133), - CallNode(134...144)( - nil, - nil, - (134...137), - nil, - nil, - nil, - BlockNode(138...144)([], nil, nil, (138...140), (141...144)), - 0, - "tap" - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (117...120), - (125...126), - nil, - nil, - nil, - (146...149) - ), - StatementsNode(151...156)([BreakNode(151...156)(nil, (151...156))]), - 0 - ), - WhileNode(163...210)( - (163...168), - (207...210), - ClassNode(169...198)( - [:a], - (169...174), - ConstantReadNode(175...178)(:Foo), - nil, - nil, - StatementsNode(179...193)( - [LocalVariableWriteNode(179...193)( - :a, - 0, - (179...180), - CallNode(183...193)( - nil, - nil, - (183...186), - nil, - nil, - nil, - BlockNode(187...193)([], nil, nil, (187...189), (190...193)), - 0, - "tap" - ), - (181...182) - )] - ), - (195...198), - :Foo - ), - StatementsNode(200...205)([BreakNode(200...205)(nil, (200...205))]), - 0 - ), - WhileNode(212...260)( - (212...217), - (257...260), - SingletonClassNode(218...248)( - [], - (218...223), - (224...226), - SelfNode(227...231)(), - StatementsNode(233...243)( - [CallNode(233...243)( - nil, - nil, - (233...236), - nil, - nil, - nil, - BlockNode(237...243)([], nil, nil, (237...239), (240...243)), - 0, - "tap" - )] - ), - (245...248) - ), - StatementsNode(250...255)([BreakNode(250...255)(nil, (250...255))]), - 0 - ), - WhileNode(262...314)( - (262...267), - (311...314), - SingletonClassNode(268...302)( - [:a], - (268...273), - (274...276), - SelfNode(277...281)(), - StatementsNode(283...297)( - [LocalVariableWriteNode(283...297)( - :a, - 0, - (283...284), - CallNode(287...297)( - nil, - nil, - (287...290), - nil, - nil, - nil, - BlockNode(291...297)([], nil, nil, (291...293), (294...297)), - 0, - "tap" - ), - (285...286) - )] - ), - (299...302) - ), - StatementsNode(304...309)([BreakNode(304...309)(nil, (304...309))]), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/__ENCODING__.txt b/test/yarp/snapshots/whitequark/__ENCODING__.txt deleted file mode 100644 index 2f5aaa5dfce1b2..00000000000000 --- a/test/yarp/snapshots/whitequark/__ENCODING__.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...12)([], StatementsNode(0...12)([SourceEncodingNode(0...12)()])) diff --git a/test/yarp/snapshots/whitequark/__ENCODING___legacy_.txt b/test/yarp/snapshots/whitequark/__ENCODING___legacy_.txt deleted file mode 100644 index 2f5aaa5dfce1b2..00000000000000 --- a/test/yarp/snapshots/whitequark/__ENCODING___legacy_.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...12)([], StatementsNode(0...12)([SourceEncodingNode(0...12)()])) diff --git a/test/yarp/snapshots/whitequark/alias.txt b/test/yarp/snapshots/whitequark/alias.txt deleted file mode 100644 index 3960bea48aeb90..00000000000000 --- a/test/yarp/snapshots/whitequark/alias.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [AliasNode(0...14)( - SymbolNode(6...10)((6...7), (7...10), nil, "foo"), - SymbolNode(11...14)(nil, (11...14), nil, "bar"), - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/alias_gvar.txt b/test/yarp/snapshots/whitequark/alias_gvar.txt deleted file mode 100644 index 06482181f4b10e..00000000000000 --- a/test/yarp/snapshots/whitequark/alias_gvar.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [AliasNode(0...11)( - GlobalVariableReadNode(6...8)(:$a), - BackReferenceReadNode(9...11)(), - (0...5) - ), - AliasNode(13...24)( - GlobalVariableReadNode(19...21)(:$a), - GlobalVariableReadNode(22...24)(:$b), - (13...18) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt b/test/yarp/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt deleted file mode 100644 index 5fc3ec49db1c6c..00000000000000 --- a/test/yarp/snapshots/whitequark/ambiuous_quoted_label_in_ternary_operator.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [IfNode(0...15)( - nil, - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - StatementsNode(4...10)( - [CallNode(4...10)( - CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b"), - nil, - (6...7), - nil, - ArgumentsNode(8...10)( - [StringNode(8...10)((8...9), (9...9), (9...10), "")] - ), - nil, - nil, - 0, - "&" - )] - ), - ElseNode(10...15)( - (10...11), - StatementsNode(12...15)([NilNode(12...15)()]), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/and.txt b/test/yarp/snapshots/whitequark/and.txt deleted file mode 100644 index c6641a692b991b..00000000000000 --- a/test/yarp/snapshots/whitequark/and.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [AndNode(0...10)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "bar"), - (4...6) - ), - AndNode(12...23)( - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "foo"), - CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "bar"), - (16...19) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/and_asgn.txt b/test/yarp/snapshots/whitequark/and_asgn.txt deleted file mode 100644 index fab12349c28e75..00000000000000 --- a/test/yarp/snapshots/whitequark/and_asgn.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallAndWriteNode(0...11)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...5), - nil, - nil, - nil, - 0, - "a", - "a=", - (6...9), - IntegerNode(10...11)() - ), - CallAndWriteNode(13...28)( - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo"), - nil, - (16...22), - (16...17), - ArgumentsNode(17...21)( - [IntegerNode(17...18)(), IntegerNode(20...21)()] - ), - (21...22), - 0, - "[]", - "[]=", - (23...26), - IntegerNode(27...28)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/and_or_masgn.txt b/test/yarp/snapshots/whitequark/and_or_masgn.txt deleted file mode 100644 index e34c3e19ee09ee..00000000000000 --- a/test/yarp/snapshots/whitequark/and_or_masgn.txt +++ /dev/null @@ -1,61 +0,0 @@ -ProgramNode(0...40)( - [:a, :b], - StatementsNode(0...40)( - [AndNode(0...19)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - ParenthesesNode(7...19)( - StatementsNode(8...18)( - [MultiWriteNode(8...18)( - [LocalVariableTargetNode(8...9)(:a, 0), - LocalVariableTargetNode(11...12)(:b, 0)], - nil, - nil, - (13...14), - CallNode(15...18)( - nil, - nil, - (15...18), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )] - ), - (7...8), - (18...19) - ), - (4...6) - ), - OrNode(21...40)( - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"), - ParenthesesNode(28...40)( - StatementsNode(29...39)( - [MultiWriteNode(29...39)( - [LocalVariableTargetNode(29...30)(:a, 0), - LocalVariableTargetNode(32...33)(:b, 0)], - nil, - nil, - (34...35), - CallNode(36...39)( - nil, - nil, - (36...39), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )] - ), - (28...29), - (39...40) - ), - (25...27) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt b/test/yarp/snapshots/whitequark/anonymous_blockarg.txt deleted file mode 100644 index af34a92864742f..00000000000000 --- a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - ParametersNode(8...9)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(8...9)(nil, nil, (8...9)) - ), - StatementsNode(12...18)( - [CallNode(12...18)( - nil, - nil, - (12...15), - (15...16), - ArgumentsNode(16...17)( - [BlockArgumentNode(16...17)(nil, (16...17))] - ), - (17...18), - nil, - 0, - "bar" - )] - ), - [:&], - (0...3), - nil, - (7...8), - (9...10), - nil, - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/arg.txt b/test/yarp/snapshots/whitequark/arg.txt deleted file mode 100644 index 037d3eb070782d..00000000000000 --- a/test/yarp/snapshots/whitequark/arg.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [DefNode(0...15)( - :f, - (4...5), - nil, - ParametersNode(6...9)( - [RequiredParameterNode(6...9)(:foo)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:foo], - (0...3), - nil, - (5...6), - (9...10), - nil, - (12...15) - ), - DefNode(17...37)( - :f, - (21...22), - nil, - ParametersNode(23...31)( - [RequiredParameterNode(23...26)(:foo), - RequiredParameterNode(28...31)(:bar)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:foo, :bar], - (17...20), - nil, - (22...23), - (31...32), - nil, - (34...37) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt b/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt deleted file mode 100644 index 304ca36eba773c..00000000000000 --- a/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt +++ /dev/null @@ -1,51 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [DefNode(0...18)( - :foo, - (4...7), - nil, - ParametersNode(8...12)( - [RequiredParameterNode(8...9)(:_), - RequiredParameterNode(11...12)(:_)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:_], - (0...3), - nil, - (7...8), - (12...13), - nil, - (15...18) - ), - DefNode(20...40)( - :foo, - (24...27), - nil, - ParametersNode(28...34)( - [RequiredParameterNode(28...30)(:_a), - RequiredParameterNode(32...34)(:_a)], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:_a], - (20...23), - nil, - (27...28), - (34...35), - nil, - (37...40) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/arg_label.txt b/test/yarp/snapshots/whitequark/arg_label.txt deleted file mode 100644 index 40014d7289896f..00000000000000 --- a/test/yarp/snapshots/whitequark/arg_label.txt +++ /dev/null @@ -1,92 +0,0 @@ -ProgramNode(0...49)( - [], - StatementsNode(0...49)( - [DefNode(0...16)( - :foo, - (4...7), - nil, - nil, - StatementsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...10), - nil, - ArgumentsNode(10...12)( - [SymbolNode(10...12)((10...11), (11...12), nil, "b")] - ), - nil, - nil, - 0, - "a" - )] - ), - [], - (0...3), - nil, - nil, - nil, - nil, - (13...16) - ), - DefNode(18...35)( - :foo, - (22...25), - nil, - nil, - StatementsNode(28...31)( - [CallNode(28...31)( - nil, - nil, - (28...29), - nil, - ArgumentsNode(29...31)( - [SymbolNode(29...31)((29...30), (30...31), nil, "b")] - ), - nil, - nil, - 0, - "a" - )] - ), - [], - (18...21), - nil, - (25...26), - (26...27), - nil, - (32...35) - ), - CallNode(37...49)( - nil, - nil, - (37...38), - nil, - nil, - nil, - BlockNode(39...49)( - [], - BlockParametersNode(41...43)(nil, [], (41...42), (42...43)), - StatementsNode(44...47)( - [CallNode(44...47)( - nil, - nil, - (44...45), - nil, - ArgumentsNode(45...47)( - [SymbolNode(45...47)((45...46), (46...47), nil, "b")] - ), - nil, - nil, - 0, - "a" - )] - ), - (39...40), - (48...49) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/arg_scope.txt b/test/yarp/snapshots/whitequark/arg_scope.txt deleted file mode 100644 index baa33596becad9..00000000000000 --- a/test/yarp/snapshots/whitequark/arg_scope.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - nil, - nil, - (0...6), - nil, - nil, - nil, - BlockNode(6...13)( - [:a], - BlockParametersNode(7...11)( - nil, - [BlockLocalVariableNode(9...10)(:a)], - (7...8), - (10...11) - ), - StatementsNode(11...12)([LocalVariableReadNode(11...12)(:a, 0)]), - (6...7), - (12...13) - ), - 0, - "lambda" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args.txt b/test/yarp/snapshots/whitequark/args.txt deleted file mode 100644 index 7ee971121e4319..00000000000000 --- a/test/yarp/snapshots/whitequark/args.txt +++ /dev/null @@ -1,801 +0,0 @@ -ProgramNode(0...690)( - [], - StatementsNode(0...690)( - [DefNode(0...13)( - :f, - (4...5), - nil, - ParametersNode(6...8)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(6...8)(:b, (7...8), (6...7)) - ), - nil, - [:b], - (0...3), - nil, - nil, - nil, - nil, - (10...13) - ), - DefNode(15...33)( - :f, - (19...20), - nil, - ParametersNode(22...27)( - [RequiredDestructuredParameterNode(22...27)( - [RequiredDestructuredParameterNode(23...26)( - [RequiredParameterNode(24...25)(:a)], - (23...24), - (25...26) - )], - (22...23), - (26...27) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (15...18), - nil, - (21...22), - (27...28), - nil, - (30...33) - ), - DefNode(35...51)( - :f, - (39...40), - nil, - ParametersNode(42...45)( - [RequiredDestructuredParameterNode(42...45)( - [SplatNode(43...44)((43...44), nil)], - (42...43), - (44...45) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [], - (35...38), - nil, - (41...42), - (45...46), - nil, - (48...51) - ), - DefNode(53...72)( - :f, - (57...58), - nil, - ParametersNode(60...66)( - [RequiredDestructuredParameterNode(60...66)( - [SplatNode(61...62)((61...62), nil), - RequiredParameterNode(64...65)(:p)], - (60...61), - (65...66) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:p], - (53...56), - nil, - (59...60), - (66...67), - nil, - (69...72) - ), - DefNode(74...91)( - :f, - (78...79), - nil, - ParametersNode(81...85)( - [RequiredDestructuredParameterNode(81...85)( - [SplatNode(82...84)( - (82...83), - RequiredParameterNode(83...84)(:r) - )], - (81...82), - (84...85) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:r], - (74...77), - nil, - (80...81), - (85...86), - nil, - (88...91) - ), - DefNode(93...113)( - :f, - (97...98), - nil, - ParametersNode(100...107)( - [RequiredDestructuredParameterNode(100...107)( - [SplatNode(101...103)( - (101...102), - RequiredParameterNode(102...103)(:r) - ), - RequiredParameterNode(105...106)(:p)], - (100...101), - (106...107) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:r, :p], - (93...96), - nil, - (99...100), - (107...108), - nil, - (110...113) - ), - DefNode(115...134)( - :f, - (119...120), - nil, - ParametersNode(122...128)( - [RequiredDestructuredParameterNode(122...128)( - [RequiredParameterNode(123...124)(:a), - SplatNode(126...127)((126...127), nil)], - (122...123), - (127...128) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (115...118), - nil, - (121...122), - (128...129), - nil, - (131...134) - ), - DefNode(136...158)( - :f, - (140...141), - nil, - ParametersNode(143...152)( - [RequiredDestructuredParameterNode(143...152)( - [RequiredParameterNode(144...145)(:a), - SplatNode(147...148)((147...148), nil), - RequiredParameterNode(150...151)(:p)], - (143...144), - (151...152) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a, :p], - (136...139), - nil, - (142...143), - (152...153), - nil, - (155...158) - ), - DefNode(160...180)( - :f, - (164...165), - nil, - ParametersNode(167...174)( - [RequiredDestructuredParameterNode(167...174)( - [RequiredParameterNode(168...169)(:a), - SplatNode(171...173)( - (171...172), - RequiredParameterNode(172...173)(:r) - )], - (167...168), - (173...174) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a, :r], - (160...163), - nil, - (166...167), - (174...175), - nil, - (177...180) - ), - DefNode(182...205)( - :f, - (186...187), - nil, - ParametersNode(189...199)( - [RequiredDestructuredParameterNode(189...199)( - [RequiredParameterNode(190...191)(:a), - SplatNode(193...195)( - (193...194), - RequiredParameterNode(194...195)(:r) - ), - RequiredParameterNode(197...198)(:p)], - (189...190), - (198...199) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a, :r, :p], - (182...185), - nil, - (188...189), - (199...200), - nil, - (202...205) - ), - DefNode(207...227)( - :f, - (211...212), - nil, - ParametersNode(214...221)( - [RequiredDestructuredParameterNode(214...221)( - [RequiredParameterNode(215...216)(:a), - RequiredParameterNode(218...220)(:a1)], - (214...215), - (220...221) - )], - [], - [], - nil, - [], - nil, - nil - ), - nil, - [:a, :a1], - (207...210), - nil, - (213...214), - (221...222), - nil, - (224...227) - ), - DefNode(229...252)( - :f, - (233...234), - nil, - ParametersNode(236...246)( - [], - [], - [], - nil, - [KeywordParameterNode(236...242)( - :foo, - (236...240), - IntegerNode(241...242)() - )], - nil, - BlockParameterNode(244...246)(:b, (245...246), (244...245)) - ), - nil, - [:foo, :b], - (229...232), - nil, - (235...236), - (246...247), - nil, - (249...252) - ), - DefNode(254...292)( - :f, - (258...259), - nil, - ParametersNode(261...286)( - [], - [], - [], - nil, - [KeywordParameterNode(261...267)( - :foo, - (261...265), - IntegerNode(266...267)() - ), - KeywordParameterNode(269...275)( - :bar, - (269...273), - IntegerNode(274...275)() - )], - KeywordRestParameterNode(277...282)(:baz, (279...282), (277...279)), - BlockParameterNode(284...286)(:b, (285...286), (284...285)) - ), - nil, - [:foo, :bar, :baz, :b], - (254...257), - nil, - (260...261), - (286...287), - nil, - (289...292) - ), - DefNode(294...314)( - :f, - (298...299), - nil, - ParametersNode(300...309)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(300...305)(:baz, (302...305), (300...302)), - BlockParameterNode(307...309)(:b, (308...309), (307...308)) - ), - nil, - [:baz, :b], - (294...297), - nil, - nil, - nil, - nil, - (311...314) - ), - DefNode(316...332)( - :f, - (320...321), - nil, - ParametersNode(322...327)( - [], - [], - [], - RestParameterNode(322...323)(nil, nil, (322...323)), - [], - KeywordRestParameterNode(325...327)(nil, nil, (325...327)), - nil - ), - nil, - [:*, :**], - (316...319), - nil, - nil, - nil, - nil, - (329...332) - ), - DefNode(334...351)( - :f, - (338...339), - nil, - ParametersNode(340...346)( - [], - [], - [], - RestParameterNode(340...342)(:r, (341...342), (340...341)), - [], - nil, - BlockParameterNode(344...346)(:b, (345...346), (344...345)) - ), - nil, - [:r, :b], - (334...337), - nil, - nil, - nil, - nil, - (348...351) - ), - DefNode(353...373)( - :f, - (357...358), - nil, - ParametersNode(359...368)( - [], - [], - [RequiredParameterNode(363...364)(:p)], - RestParameterNode(359...361)(:r, (360...361), (359...360)), - [], - nil, - BlockParameterNode(366...368)(:b, (367...368), (366...367)) - ), - nil, - [:r, :p, :b], - (353...356), - nil, - nil, - nil, - nil, - (370...373) - ), - DefNode(375...386)( - :f, - (379...380), - nil, - nil, - nil, - [], - (375...378), - nil, - nil, - nil, - nil, - (383...386) - ), - DefNode(388...404)( - :f, - (392...393), - nil, - ParametersNode(394...399)( - [RequiredParameterNode(394...395)(:a)], - [], - [], - nil, - [], - nil, - BlockParameterNode(397...399)(:b, (398...399), (397...398)) - ), - nil, - [:a, :b], - (388...391), - nil, - nil, - nil, - nil, - (401...404) - ), - DefNode(406...426)( - :f, - (410...411), - nil, - ParametersNode(412...421)( - [RequiredParameterNode(412...413)(:a)], - [], - [], - RestParameterNode(415...417)(:r, (416...417), (415...416)), - [], - nil, - BlockParameterNode(419...421)(:b, (420...421), (419...420)) - ), - nil, - [:a, :r, :b], - (406...409), - nil, - nil, - nil, - nil, - (423...426) - ), - DefNode(428...451)( - :f, - (432...433), - nil, - ParametersNode(434...446)( - [RequiredParameterNode(434...435)(:a)], - [], - [RequiredParameterNode(441...442)(:p)], - RestParameterNode(437...439)(:r, (438...439), (437...438)), - [], - nil, - BlockParameterNode(444...446)(:b, (445...446), (444...445)) - ), - nil, - [:a, :r, :p, :b], - (428...431), - nil, - nil, - nil, - nil, - (448...451) - ), - DefNode(453...474)( - :f, - (457...458), - nil, - ParametersNode(459...469)( - [RequiredParameterNode(459...460)(:a)], - [OptionalParameterNode(462...465)( - :o, - (462...463), - (463...464), - IntegerNode(464...465)() - )], - [], - nil, - [], - nil, - BlockParameterNode(467...469)(:b, (468...469), (467...468)) - ), - nil, - [:a, :o, :b], - (453...456), - nil, - nil, - nil, - nil, - (471...474) - ), - DefNode(476...501)( - :f, - (480...481), - nil, - ParametersNode(482...496)( - [RequiredParameterNode(482...483)(:a)], - [OptionalParameterNode(485...488)( - :o, - (485...486), - (486...487), - IntegerNode(487...488)() - )], - [], - RestParameterNode(490...492)(:r, (491...492), (490...491)), - [], - nil, - BlockParameterNode(494...496)(:b, (495...496), (494...495)) - ), - nil, - [:a, :o, :r, :b], - (476...479), - nil, - nil, - nil, - nil, - (498...501) - ), - DefNode(503...531)( - :f, - (507...508), - nil, - ParametersNode(509...526)( - [RequiredParameterNode(509...510)(:a)], - [OptionalParameterNode(512...515)( - :o, - (512...513), - (513...514), - IntegerNode(514...515)() - )], - [RequiredParameterNode(521...522)(:p)], - RestParameterNode(517...519)(:r, (518...519), (517...518)), - [], - nil, - BlockParameterNode(524...526)(:b, (525...526), (524...525)) - ), - nil, - [:a, :o, :r, :p, :b], - (503...506), - nil, - nil, - nil, - nil, - (528...531) - ), - DefNode(533...557)( - :f, - (537...538), - nil, - ParametersNode(539...552)( - [RequiredParameterNode(539...540)(:a)], - [OptionalParameterNode(542...545)( - :o, - (542...543), - (543...544), - IntegerNode(544...545)() - )], - [RequiredParameterNode(547...548)(:p)], - nil, - [], - nil, - BlockParameterNode(550...552)(:b, (551...552), (550...551)) - ), - nil, - [:a, :o, :p, :b], - (533...536), - nil, - nil, - nil, - nil, - (554...557) - ), - DefNode(559...575)( - :f, - (563...564), - nil, - ParametersNode(565...569)( - [], - [], - [], - nil, - [KeywordParameterNode(565...569)(:foo, (565...569), nil)], - nil, - nil - ), - nil, - [:foo], - (559...562), - nil, - nil, - nil, - nil, - (572...575) - ), - DefNode(577...596)( - :f, - (581...582), - nil, - ParametersNode(583...590)( - [], - [], - [], - nil, - [KeywordParameterNode(583...590)( - :foo, - (583...587), - IntegerNode(588...590)() - )], - nil, - nil - ), - nil, - [:foo], - (577...580), - nil, - nil, - nil, - nil, - (593...596) - ), - DefNode(598...616)( - :f, - (602...603), - nil, - ParametersNode(604...611)( - [], - [OptionalParameterNode(604...607)( - :o, - (604...605), - (605...606), - IntegerNode(606...607)() - )], - [], - nil, - [], - nil, - BlockParameterNode(609...611)(:b, (610...611), (609...610)) - ), - nil, - [:o, :b], - (598...601), - nil, - nil, - nil, - nil, - (613...616) - ), - DefNode(618...640)( - :f, - (622...623), - nil, - ParametersNode(624...635)( - [], - [OptionalParameterNode(624...627)( - :o, - (624...625), - (625...626), - IntegerNode(626...627)() - )], - [], - RestParameterNode(629...631)(:r, (630...631), (629...630)), - [], - nil, - BlockParameterNode(633...635)(:b, (634...635), (633...634)) - ), - nil, - [:o, :r, :b], - (618...621), - nil, - nil, - nil, - nil, - (637...640) - ), - DefNode(642...667)( - :f, - (646...647), - nil, - ParametersNode(648...662)( - [], - [OptionalParameterNode(648...651)( - :o, - (648...649), - (649...650), - IntegerNode(650...651)() - )], - [RequiredParameterNode(657...658)(:p)], - RestParameterNode(653...655)(:r, (654...655), (653...654)), - [], - nil, - BlockParameterNode(660...662)(:b, (661...662), (660...661)) - ), - nil, - [:o, :r, :p, :b], - (642...645), - nil, - nil, - nil, - nil, - (664...667) - ), - DefNode(669...690)( - :f, - (673...674), - nil, - ParametersNode(675...685)( - [], - [OptionalParameterNode(675...678)( - :o, - (675...676), - (676...677), - IntegerNode(677...678)() - )], - [RequiredParameterNode(680...681)(:p)], - nil, - [], - nil, - BlockParameterNode(683...685)(:b, (684...685), (683...684)) - ), - nil, - [:o, :p, :b], - (669...672), - nil, - nil, - nil, - nil, - (687...690) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_args_assocs.txt b/test/yarp/snapshots/whitequark/args_args_assocs.txt deleted file mode 100644 index 5363d6780d032d..00000000000000 --- a/test/yarp/snapshots/whitequark/args_args_assocs.txt +++ /dev/null @@ -1,59 +0,0 @@ -ProgramNode(0...46)( - [], - StatementsNode(0...46)( - [CallNode(0...19)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...18)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "foo"), - KeywordHashNode(9...18)( - [AssocNode(9...18)( - SymbolNode(9...13)((9...10), (10...13), nil, "foo"), - IntegerNode(17...18)(), - (14...16) - )] - )] - ), - (18...19), - nil, - 0, - "fun" - ), - CallNode(21...46)( - nil, - nil, - (21...24), - (24...25), - ArgumentsNode(25...45)( - [CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 2, "foo"), - KeywordHashNode(30...39)( - [AssocNode(30...39)( - SymbolNode(30...34)((30...31), (31...34), nil, "foo"), - IntegerNode(38...39)(), - (35...37) - )] - ), - BlockArgumentNode(41...45)( - CallNode(42...45)( - nil, - nil, - (42...45), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (41...42) - )] - ), - (45...46), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_args_assocs_comma.txt b/test/yarp/snapshots/whitequark/args_args_assocs_comma.txt deleted file mode 100644 index da9ea1bd810fd6..00000000000000 --- a/test/yarp/snapshots/whitequark/args_args_assocs_comma.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [CallNode(0...20)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...20), - (3...4), - ArgumentsNode(4...18)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), - KeywordHashNode(9...18)( - [AssocNode(9...18)( - SymbolNode(9...13)((9...10), (10...13), nil, "baz"), - IntegerNode(17...18)(), - (14...16) - )] - )] - ), - (19...20), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_args_comma.txt b/test/yarp/snapshots/whitequark/args_args_comma.txt deleted file mode 100644 index a6014eebc427f3..00000000000000 --- a/test/yarp/snapshots/whitequark/args_args_comma.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...7)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar")] - ), - (8...9), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_args_star.txt b/test/yarp/snapshots/whitequark/args_args_star.txt deleted file mode 100644 index ed007cfa5afccd..00000000000000 --- a/test/yarp/snapshots/whitequark/args_args_star.txt +++ /dev/null @@ -1,73 +0,0 @@ -ProgramNode(0...36)( - [], - StatementsNode(0...36)( - [CallNode(0...14)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...13)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "foo"), - SplatNode(9...13)( - (9...10), - CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )] - ), - (13...14), - nil, - 0, - "fun" - ), - CallNode(16...36)( - nil, - nil, - (16...19), - (19...20), - ArgumentsNode(20...35)( - [CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "foo"), - SplatNode(25...29)( - (25...26), - CallNode(26...29)( - nil, - nil, - (26...29), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - ), - BlockArgumentNode(31...35)( - CallNode(32...35)( - nil, - nil, - (32...35), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (31...32) - )] - ), - (35...36), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_assocs.txt b/test/yarp/snapshots/whitequark/args_assocs.txt deleted file mode 100644 index 8fa24ab4795964..00000000000000 --- a/test/yarp/snapshots/whitequark/args_assocs.txt +++ /dev/null @@ -1,125 +0,0 @@ -ProgramNode(0...114)( - [], - StatementsNode(0...114)( - [CallNode(0...14)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...13)( - [KeywordHashNode(4...13)( - [AssocNode(4...13)( - SymbolNode(4...8)((4...5), (5...8), nil, "foo"), - IntegerNode(12...13)(), - (9...11) - )] - )] - ), - (13...14), - nil, - 0, - "fun" - ), - CallNode(16...36)( - nil, - nil, - (16...19), - (19...20), - ArgumentsNode(20...35)( - [KeywordHashNode(20...29)( - [AssocNode(20...29)( - SymbolNode(20...24)((20...21), (21...24), nil, "foo"), - IntegerNode(28...29)(), - (25...27) - )] - ), - BlockArgumentNode(31...35)( - CallNode(32...35)( - nil, - nil, - (32...35), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (31...32) - )] - ), - (35...36), - nil, - 0, - "fun" - ), - CallNode(38...59)( - SelfNode(38...42)(), - (42...43), - (43...46), - nil, - ArgumentsNode(47...59)( - [CallNode(47...50)(nil, nil, (47...50), nil, nil, nil, nil, 2, "foo"), - KeywordHashNode(52...59)( - [AssocNode(52...59)( - SymbolNode(52...54)((52...53), (53...54), nil, "a"), - IntegerNode(58...59)(), - (55...57) - )] - )] - ), - nil, - nil, - 0, - "[]=" - ), - CallNode(61...76)( - SelfNode(61...65)(), - nil, - (65...76), - (65...66), - ArgumentsNode(66...75)( - [KeywordHashNode(66...75)( - [AssocNode(66...75)( - SymbolNode(66...70)((66...67), (67...70), nil, "bar"), - IntegerNode(74...75)(), - (71...73) - )] - )] - ), - (75...76), - nil, - 0, - "[]" - ), - SuperNode(78...95)( - (78...83), - (83...84), - ArgumentsNode(84...94)( - [KeywordHashNode(84...94)( - [AssocNode(84...94)( - SymbolNode(84...88)((84...85), (85...88), nil, "foo"), - IntegerNode(92...94)(), - (89...91) - )] - )] - ), - (94...95), - nil - ), - YieldNode(97...114)( - (97...102), - (102...103), - ArgumentsNode(103...113)( - [KeywordHashNode(103...113)( - [AssocNode(103...113)( - SymbolNode(103...107)((103...104), (104...107), nil, "foo"), - IntegerNode(111...113)(), - (108...110) - )] - )] - ), - (113...114) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_assocs_comma.txt b/test/yarp/snapshots/whitequark/args_assocs_comma.txt deleted file mode 100644 index 97de8d44ef9541..00000000000000 --- a/test/yarp/snapshots/whitequark/args_assocs_comma.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...15), - (3...4), - ArgumentsNode(4...13)( - [KeywordHashNode(4...13)( - [AssocNode(4...13)( - SymbolNode(4...8)((4...5), (5...8), nil, "baz"), - IntegerNode(12...13)(), - (9...11) - )] - )] - ), - (14...15), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_assocs_legacy.txt b/test/yarp/snapshots/whitequark/args_assocs_legacy.txt deleted file mode 100644 index 8fa24ab4795964..00000000000000 --- a/test/yarp/snapshots/whitequark/args_assocs_legacy.txt +++ /dev/null @@ -1,125 +0,0 @@ -ProgramNode(0...114)( - [], - StatementsNode(0...114)( - [CallNode(0...14)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...13)( - [KeywordHashNode(4...13)( - [AssocNode(4...13)( - SymbolNode(4...8)((4...5), (5...8), nil, "foo"), - IntegerNode(12...13)(), - (9...11) - )] - )] - ), - (13...14), - nil, - 0, - "fun" - ), - CallNode(16...36)( - nil, - nil, - (16...19), - (19...20), - ArgumentsNode(20...35)( - [KeywordHashNode(20...29)( - [AssocNode(20...29)( - SymbolNode(20...24)((20...21), (21...24), nil, "foo"), - IntegerNode(28...29)(), - (25...27) - )] - ), - BlockArgumentNode(31...35)( - CallNode(32...35)( - nil, - nil, - (32...35), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (31...32) - )] - ), - (35...36), - nil, - 0, - "fun" - ), - CallNode(38...59)( - SelfNode(38...42)(), - (42...43), - (43...46), - nil, - ArgumentsNode(47...59)( - [CallNode(47...50)(nil, nil, (47...50), nil, nil, nil, nil, 2, "foo"), - KeywordHashNode(52...59)( - [AssocNode(52...59)( - SymbolNode(52...54)((52...53), (53...54), nil, "a"), - IntegerNode(58...59)(), - (55...57) - )] - )] - ), - nil, - nil, - 0, - "[]=" - ), - CallNode(61...76)( - SelfNode(61...65)(), - nil, - (65...76), - (65...66), - ArgumentsNode(66...75)( - [KeywordHashNode(66...75)( - [AssocNode(66...75)( - SymbolNode(66...70)((66...67), (67...70), nil, "bar"), - IntegerNode(74...75)(), - (71...73) - )] - )] - ), - (75...76), - nil, - 0, - "[]" - ), - SuperNode(78...95)( - (78...83), - (83...84), - ArgumentsNode(84...94)( - [KeywordHashNode(84...94)( - [AssocNode(84...94)( - SymbolNode(84...88)((84...85), (85...88), nil, "foo"), - IntegerNode(92...94)(), - (89...91) - )] - )] - ), - (94...95), - nil - ), - YieldNode(97...114)( - (97...102), - (102...103), - ArgumentsNode(103...113)( - [KeywordHashNode(103...113)( - [AssocNode(103...113)( - SymbolNode(103...107)((103...104), (104...107), nil, "foo"), - IntegerNode(111...113)(), - (108...110) - )] - )] - ), - (113...114) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_block_pass.txt b/test/yarp/snapshots/whitequark/args_block_pass.txt deleted file mode 100644 index 50c51ba7b3cc56..00000000000000 --- a/test/yarp/snapshots/whitequark/args_block_pass.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...8)( - [BlockArgumentNode(4...8)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "bar"), - (4...5) - )] - ), - (8...9), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_cmd.txt b/test/yarp/snapshots/whitequark/args_cmd.txt deleted file mode 100644 index 9b0cfedb006b29..00000000000000 --- a/test/yarp/snapshots/whitequark/args_cmd.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...9)( - [CallNode(4...9)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...9)( - [CallNode(6...9)( - nil, - nil, - (6...9), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "f" - )] - ), - (9...10), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/args_star.txt b/test/yarp/snapshots/whitequark/args_star.txt deleted file mode 100644 index eaffafdd3d428f..00000000000000 --- a/test/yarp/snapshots/whitequark/args_star.txt +++ /dev/null @@ -1,61 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CallNode(0...9)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...8)( - [SplatNode(4...8)( - (4...5), - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "bar") - )] - ), - (8...9), - nil, - 0, - "fun" - ), - CallNode(11...26)( - nil, - nil, - (11...14), - (14...15), - ArgumentsNode(15...25)( - [SplatNode(15...19)( - (15...16), - CallNode(16...19)( - nil, - nil, - (16...19), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - ), - BlockArgumentNode(21...25)( - CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "baz" - ), - (21...22) - )] - ), - (25...26), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_assocs.txt b/test/yarp/snapshots/whitequark/array_assocs.txt deleted file mode 100644 index 6dc20662ca196c..00000000000000 --- a/test/yarp/snapshots/whitequark/array_assocs.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [ArrayNode(0...10)( - [KeywordHashNode(2...8)( - [AssocNode(2...8)( - IntegerNode(2...3)(), - IntegerNode(7...8)(), - (4...6) - )] - )], - (0...1), - (9...10) - ), - ArrayNode(12...25)( - [IntegerNode(14...15)(), - KeywordHashNode(17...23)( - [AssocNode(17...23)( - IntegerNode(17...18)(), - IntegerNode(22...23)(), - (19...21) - )] - )], - (12...13), - (24...25) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_plain.txt b/test/yarp/snapshots/whitequark/array_plain.txt deleted file mode 100644 index d8c89ba8b9f3e7..00000000000000 --- a/test/yarp/snapshots/whitequark/array_plain.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [ArrayNode(0...6)( - [IntegerNode(1...2)(), IntegerNode(4...5)()], - (0...1), - (5...6) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_splat.txt b/test/yarp/snapshots/whitequark/array_splat.txt deleted file mode 100644 index 770e42e8143280..00000000000000 --- a/test/yarp/snapshots/whitequark/array_splat.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [ArrayNode(0...6)( - [SplatNode(1...5)( - (1...2), - CallNode(2...5)(nil, nil, (2...5), nil, nil, nil, nil, 2, "foo") - )], - (0...1), - (5...6) - ), - ArrayNode(8...20)( - [IntegerNode(9...10)(), - SplatNode(12...16)( - (12...13), - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo") - ), - IntegerNode(18...19)()], - (8...9), - (19...20) - ), - ArrayNode(22...31)( - [IntegerNode(23...24)(), - SplatNode(26...30)( - (26...27), - CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo") - )], - (22...23), - (30...31) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_symbols.txt b/test/yarp/snapshots/whitequark/array_symbols.txt deleted file mode 100644 index 9d036af7cf9b32..00000000000000 --- a/test/yarp/snapshots/whitequark/array_symbols.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...11)( - [SymbolNode(3...6)(nil, (3...6), nil, "foo"), - SymbolNode(7...10)(nil, (7...10), nil, "bar")], - (0...3), - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_symbols_empty.txt b/test/yarp/snapshots/whitequark/array_symbols_empty.txt deleted file mode 100644 index ce2b82c914aadd..00000000000000 --- a/test/yarp/snapshots/whitequark/array_symbols_empty.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [ArrayNode(0...4)([], (0...3), (3...4)), - ArrayNode(6...10)([], (6...9), (9...10))] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_symbols_interp.txt b/test/yarp/snapshots/whitequark/array_symbols_interp.txt deleted file mode 100644 index 8488e7e9c233cb..00000000000000 --- a/test/yarp/snapshots/whitequark/array_symbols_interp.txt +++ /dev/null @@ -1,57 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [ArrayNode(0...14)( - [SymbolNode(3...6)(nil, (3...6), nil, "foo"), - InterpolatedSymbolNode(7...13)( - nil, - [EmbeddedStatementsNode(7...13)( - (7...9), - StatementsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (12...13) - )], - nil - )], - (0...3), - (13...14) - ), - ArrayNode(16...29)( - [InterpolatedSymbolNode(19...28)( - nil, - [StringNode(19...22)(nil, (19...22), nil, "foo"), - EmbeddedStatementsNode(22...28)( - (22...24), - StatementsNode(24...27)( - [CallNode(24...27)( - nil, - nil, - (24...27), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (27...28) - )], - nil - )], - (16...19), - (28...29) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_words.txt b/test/yarp/snapshots/whitequark/array_words.txt deleted file mode 100644 index 3308b6b7f27eda..00000000000000 --- a/test/yarp/snapshots/whitequark/array_words.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [ArrayNode(0...11)( - [StringNode(3...6)(nil, (3...6), nil, "foo"), - StringNode(7...10)(nil, (7...10), nil, "bar")], - (0...3), - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_words_empty.txt b/test/yarp/snapshots/whitequark/array_words_empty.txt deleted file mode 100644 index ce2b82c914aadd..00000000000000 --- a/test/yarp/snapshots/whitequark/array_words_empty.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [ArrayNode(0...4)([], (0...3), (3...4)), - ArrayNode(6...10)([], (6...9), (9...10))] - ) -) diff --git a/test/yarp/snapshots/whitequark/array_words_interp.txt b/test/yarp/snapshots/whitequark/array_words_interp.txt deleted file mode 100644 index d4bc9292e6ea64..00000000000000 --- a/test/yarp/snapshots/whitequark/array_words_interp.txt +++ /dev/null @@ -1,62 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [ArrayNode(0...14)( - [StringNode(3...6)(nil, (3...6), nil, "foo"), - InterpolatedStringNode(7...13)( - nil, - [EmbeddedStatementsNode(7...13)( - (7...9), - StatementsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (12...13) - )], - nil - )], - (0...3), - (13...14) - ), - ArrayNode(16...38)( - [StringNode(19...22)(nil, (19...22), nil, "foo"), - InterpolatedStringNode(23...37)( - nil, - [EmbeddedStatementsNode(23...29)( - (23...25), - StatementsNode(25...28)( - [CallNode(25...28)( - nil, - nil, - (25...28), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (28...29) - ), - StringNode(29...32)(nil, (29...32), nil, "foo"), - EmbeddedVariableNode(32...37)( - (32...33), - InstanceVariableReadNode(33...37)(:@baz) - )], - nil - )], - (16...19), - (37...38) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/asgn_cmd.txt b/test/yarp/snapshots/whitequark/asgn_cmd.txt deleted file mode 100644 index ef24cc0477f9e8..00000000000000 --- a/test/yarp/snapshots/whitequark/asgn_cmd.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...30)( - [:foo, :bar], - StatementsNode(0...30)( - [LocalVariableWriteNode(0...17)( - :foo, - 0, - (0...3), - LocalVariableWriteNode(6...17)( - :bar, - 0, - (6...9), - CallNode(12...17)( - nil, - nil, - (12...13), - nil, - ArgumentsNode(14...17)([LocalVariableReadNode(14...17)(:foo, 0)]), - nil, - nil, - 0, - "m" - ), - (10...11) - ), - (4...5) - ), - LocalVariableWriteNode(19...30)( - :foo, - 0, - (19...22), - CallNode(25...30)( - nil, - nil, - (25...26), - nil, - ArgumentsNode(27...30)([LocalVariableReadNode(27...30)(:foo, 0)]), - nil, - nil, - 0, - "m" - ), - (23...24) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/asgn_mrhs.txt b/test/yarp/snapshots/whitequark/asgn_mrhs.txt deleted file mode 100644 index aaf2bedb6f340c..00000000000000 --- a/test/yarp/snapshots/whitequark/asgn_mrhs.txt +++ /dev/null @@ -1,56 +0,0 @@ -ProgramNode(0...41)( - [:foo], - StatementsNode(0...41)( - [LocalVariableWriteNode(0...10)( - :foo, - 0, - (0...3), - ArrayNode(6...10)( - [SplatNode(6...10)( - (6...7), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "bar") - )], - nil, - nil - ), - (4...5) - ), - LocalVariableWriteNode(12...24)( - :foo, - 0, - (12...15), - ArrayNode(18...24)( - [CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "bar"), - IntegerNode(23...24)()], - nil, - nil - ), - (16...17) - ), - LocalVariableWriteNode(26...41)( - :foo, - 0, - (26...29), - ArrayNode(32...41)( - [CallNode(32...35)(nil, nil, (32...35), nil, nil, nil, nil, 2, "baz"), - SplatNode(37...41)( - (37...38), - CallNode(38...41)( - nil, - nil, - (38...41), - nil, - nil, - nil, - nil, - 2, - "bar" - ) - )], - nil, - nil - ), - (30...31) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/back_ref.txt b/test/yarp/snapshots/whitequark/back_ref.txt deleted file mode 100644 index d072409376ba7a..00000000000000 --- a/test/yarp/snapshots/whitequark/back_ref.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...2)([], StatementsNode(0...2)([BackReferenceReadNode(0...2)()])) diff --git a/test/yarp/snapshots/whitequark/bang.txt b/test/yarp/snapshots/whitequark/bang.txt deleted file mode 100644 index 65ea29dfd39010..00000000000000 --- a/test/yarp/snapshots/whitequark/bang.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - CallNode(1...4)(nil, nil, (1...4), nil, nil, nil, nil, 2, "foo"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bang_cmd.txt b/test/yarp/snapshots/whitequark/bang_cmd.txt deleted file mode 100644 index 23921cc1b3400d..00000000000000 --- a/test/yarp/snapshots/whitequark/bang_cmd.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [CallNode(0...6)( - CallNode(1...6)( - nil, - nil, - (1...2), - nil, - ArgumentsNode(3...6)( - [CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "foo")] - ), - nil, - nil, - 0, - "m" - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/begin_cmdarg.txt b/test/yarp/snapshots/whitequark/begin_cmdarg.txt deleted file mode 100644 index 2d1d4e53e5fbe3..00000000000000 --- a/test/yarp/snapshots/whitequark/begin_cmdarg.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...28)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...28)( - [BeginNode(2...28)( - (2...7), - StatementsNode(8...24)( - [CallNode(8...24)( - IntegerNode(8...9)(), - (9...10), - (10...15), - nil, - nil, - nil, - BlockNode(16...24)( - [], - nil, - StatementsNode(19...20)([IntegerNode(19...20)()]), - (16...18), - (21...24) - ), - 0, - "times" - )] - ), - nil, - nil, - nil, - (25...28) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/beginless_erange_after_newline.txt b/test/yarp/snapshots/whitequark/beginless_erange_after_newline.txt deleted file mode 100644 index dbe6e585a28e36..00000000000000 --- a/test/yarp/snapshots/whitequark/beginless_erange_after_newline.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - RangeNode(4...10)(nil, IntegerNode(7...10)(), (4...7), 1)] - ) -) diff --git a/test/yarp/snapshots/whitequark/beginless_irange_after_newline.txt b/test/yarp/snapshots/whitequark/beginless_irange_after_newline.txt deleted file mode 100644 index f784561012d3e0..00000000000000 --- a/test/yarp/snapshots/whitequark/beginless_irange_after_newline.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - RangeNode(4...9)(nil, IntegerNode(6...9)(), (4...6), 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/beginless_range.txt b/test/yarp/snapshots/whitequark/beginless_range.txt deleted file mode 100644 index 37505086297a06..00000000000000 --- a/test/yarp/snapshots/whitequark/beginless_range.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [RangeNode(0...6)(nil, IntegerNode(3...6)(), (0...3), 1), - RangeNode(8...13)(nil, IntegerNode(10...13)(), (8...10), 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/blockarg.txt b/test/yarp/snapshots/whitequark/blockarg.txt deleted file mode 100644 index 67e1db44df6148..00000000000000 --- a/test/yarp/snapshots/whitequark/blockarg.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [DefNode(0...18)( - :f, - (4...5), - nil, - ParametersNode(6...12)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(6...12)(:block, (7...12), (6...7)) - ), - nil, - [:block], - (0...3), - nil, - (5...6), - (12...13), - nil, - (15...18) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/blockargs.txt b/test/yarp/snapshots/whitequark/blockargs.txt deleted file mode 100644 index dd0b942a291c63..00000000000000 --- a/test/yarp/snapshots/whitequark/blockargs.txt +++ /dev/null @@ -1,1059 +0,0 @@ -ProgramNode(0...550)( - [], - StatementsNode(0...550)( - [CallNode(0...5)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(1...5)([], nil, nil, (1...2), (4...5)), - 0, - "f" - ), - CallNode(7...15)( - nil, - nil, - (7...8), - nil, - nil, - nil, - BlockNode(8...15)( - [], - BlockParametersNode(10...13)(nil, [], (10...11), (12...13)), - nil, - (8...9), - (14...15) - ), - 0, - "f" - ), - CallNode(17...26)( - nil, - nil, - (17...18), - nil, - nil, - nil, - BlockNode(18...26)( - [:b], - BlockParametersNode(20...24)( - ParametersNode(21...23)( - [], - [], - [], - nil, - [], - nil, - BlockParameterNode(21...23)(:b, (22...23), (21...22)) - ), - [], - (20...21), - (23...24) - ), - nil, - (18...19), - (25...26) - ), - 0, - "f" - ), - CallNode(28...44)( - nil, - nil, - (28...29), - nil, - nil, - nil, - BlockNode(29...44)( - [:baz, :b], - BlockParametersNode(31...42)( - ParametersNode(32...41)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(32...37)(:baz, (34...37), (32...34)), - BlockParameterNode(39...41)(:b, (40...41), (39...40)) - ), - [], - (31...32), - (41...42) - ), - nil, - (29...30), - (43...44) - ), - 0, - "f" - ), - CallNode(46...58)( - nil, - nil, - (46...47), - nil, - nil, - nil, - BlockNode(47...58)( - [:*, :b], - BlockParametersNode(49...56)( - ParametersNode(50...55)( - [], - [], - [], - RestParameterNode(50...51)(nil, nil, (50...51)), - [], - nil, - BlockParameterNode(53...55)(:b, (54...55), (53...54)) - ), - [], - (49...50), - (55...56) - ), - nil, - (47...48), - (57...58) - ), - 0, - "f" - ), - CallNode(60...76)( - nil, - nil, - (60...61), - nil, - nil, - nil, - BlockNode(61...76)( - [:r, :p, :b], - BlockParametersNode(63...74)( - ParametersNode(64...73)( - [], - [], - [RequiredParameterNode(68...69)(:p)], - RestParameterNode(64...66)(:r, (65...66), (64...65)), - [], - nil, - BlockParameterNode(71...73)(:b, (72...73), (71...72)) - ), - [], - (63...64), - (73...74) - ), - nil, - (61...62), - (75...76) - ), - 0, - "f" - ), - CallNode(78...91)( - nil, - nil, - (78...79), - nil, - nil, - nil, - BlockNode(79...91)( - [:s, :b], - BlockParametersNode(81...89)( - ParametersNode(82...88)( - [], - [], - [], - RestParameterNode(82...84)(:s, (83...84), (82...83)), - [], - nil, - BlockParameterNode(86...88)(:b, (87...88), (86...87)) - ), - [], - (81...82), - (88...89) - ), - nil, - (79...80), - (90...91) - ), - 0, - "f" - ), - CallNode(93...102)( - nil, - nil, - (93...94), - nil, - nil, - nil, - BlockNode(94...102)( - [:s], - BlockParametersNode(96...100)( - ParametersNode(97...99)( - [], - [], - [], - RestParameterNode(97...99)(:s, (98...99), (97...98)), - [], - nil, - nil - ), - [], - (96...97), - (99...100) - ), - nil, - (94...95), - (101...102) - ), - 0, - "f" - ), - CallNode(104...112)( - nil, - nil, - (104...105), - nil, - nil, - nil, - BlockNode(105...112)( - [:*], - BlockParametersNode(107...110)( - ParametersNode(108...109)( - [], - [], - [], - RestParameterNode(108...109)(nil, nil, (108...109)), - [], - nil, - nil - ), - [], - (107...108), - (109...110) - ), - nil, - (105...106), - (111...112) - ), - 0, - "f" - ), - CallNode(114...125)( - nil, - nil, - (114...115), - nil, - nil, - nil, - BlockNode(115...125)( - [:a], - BlockParametersNode(117...123)( - nil, - [BlockLocalVariableNode(120...121)(:a)], - (117...118), - (122...123) - ), - nil, - (115...116), - (124...125) - ), - 0, - "f" - ), - CallNode(127...136)( - nil, - nil, - (127...128), - nil, - nil, - nil, - BlockNode(128...136)( - [:a], - BlockParametersNode(130...134)( - nil, - [BlockLocalVariableNode(132...133)(:a)], - (130...131), - (133...134) - ), - nil, - (128...129), - (135...136) - ), - 0, - "f" - ), - CallNode(138...150)( - nil, - nil, - (138...139), - nil, - nil, - nil, - BlockNode(139...150)( - [:a, :b], - BlockParametersNode(141...148)( - ParametersNode(142...147)( - [RequiredParameterNode(142...143)(:a)], - [], - [], - nil, - [], - nil, - BlockParameterNode(145...147)(:b, (146...147), (145...146)) - ), - [], - (141...142), - (147...148) - ), - nil, - (139...140), - (149...150) - ), - 0, - "f" - ), - CallNode(152...167)( - nil, - nil, - (152...153), - nil, - nil, - nil, - BlockNode(153...167)( - [:a, :*, :b], - BlockParametersNode(155...165)( - ParametersNode(156...164)( - [RequiredParameterNode(156...157)(:a)], - [], - [], - RestParameterNode(159...160)(nil, nil, (159...160)), - [], - nil, - BlockParameterNode(162...164)(:b, (163...164), (162...163)) - ), - [], - (155...156), - (164...165) - ), - nil, - (153...154), - (166...167) - ), - 0, - "f" - ), - CallNode(169...188)( - nil, - nil, - (169...170), - nil, - nil, - nil, - BlockNode(170...188)( - [:a, :r, :p, :b], - BlockParametersNode(172...186)( - ParametersNode(173...185)( - [RequiredParameterNode(173...174)(:a)], - [], - [RequiredParameterNode(180...181)(:p)], - RestParameterNode(176...178)(:r, (177...178), (176...177)), - [], - nil, - BlockParameterNode(183...185)(:b, (184...185), (183...184)) - ), - [], - (172...173), - (185...186) - ), - nil, - (170...171), - (187...188) - ), - 0, - "f" - ), - CallNode(190...206)( - nil, - nil, - (190...191), - nil, - nil, - nil, - BlockNode(191...206)( - [:a, :s, :b], - BlockParametersNode(193...204)( - ParametersNode(194...203)( - [RequiredParameterNode(194...195)(:a)], - [], - [], - RestParameterNode(197...199)(:s, (198...199), (197...198)), - [], - nil, - BlockParameterNode(201...203)(:b, (202...203), (201...202)) - ), - [], - (193...194), - (203...204) - ), - nil, - (191...192), - (205...206) - ), - 0, - "f" - ), - CallNode(208...220)( - nil, - nil, - (208...209), - nil, - nil, - nil, - BlockNode(209...220)( - [:a, :s], - BlockParametersNode(211...218)( - ParametersNode(212...217)( - [RequiredParameterNode(212...213)(:a)], - [], - [], - RestParameterNode(215...217)(:s, (216...217), (215...216)), - [], - nil, - nil - ), - [], - (211...212), - (217...218) - ), - nil, - (209...210), - (219...220) - ), - 0, - "f" - ), - CallNode(222...233)( - nil, - nil, - (222...223), - nil, - nil, - nil, - BlockNode(223...233)( - [:a, :*], - BlockParametersNode(225...231)( - ParametersNode(226...230)( - [RequiredParameterNode(226...227)(:a)], - [], - [], - RestParameterNode(229...230)(nil, nil, (229...230)), - [], - nil, - nil - ), - [], - (225...226), - (230...231) - ), - nil, - (223...224), - (232...233) - ), - 0, - "f" - ), - CallNode(235...247)( - nil, - nil, - (235...236), - nil, - nil, - nil, - BlockNode(236...247)( - [:a, :b], - BlockParametersNode(238...245)( - ParametersNode(239...244)( - [RequiredParameterNode(239...240)(:a), - RequiredParameterNode(242...243)(:b)], - [], - [], - RestParameterNode(243...244)(nil, nil, (243...244)), - [], - nil, - nil - ), - [], - (238...239), - (244...245) - ), - nil, - (236...237), - (246...247) - ), - 0, - "f" - ), - CallNode(249...260)( - nil, - nil, - (249...250), - nil, - nil, - nil, - BlockNode(250...260)( - [:a, :c], - BlockParametersNode(252...258)( - ParametersNode(253...257)( - [RequiredParameterNode(253...254)(:a), - RequiredParameterNode(256...257)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (252...253), - (257...258) - ), - nil, - (250...251), - (259...260) - ), - 0, - "f" - ), - CallNode(262...279)( - nil, - nil, - (262...263), - nil, - nil, - nil, - BlockNode(263...279)( - [:a, :o, :b], - BlockParametersNode(265...277)( - ParametersNode(266...276)( - [RequiredParameterNode(266...267)(:a)], - [OptionalParameterNode(269...272)( - :o, - (269...270), - (270...271), - IntegerNode(271...272)() - )], - [], - nil, - [], - nil, - BlockParameterNode(274...276)(:b, (275...276), (274...275)) - ), - [], - (265...266), - (276...277) - ), - nil, - (263...264), - (278...279) - ), - 0, - "f" - ), - CallNode(281...305)( - nil, - nil, - (281...282), - nil, - nil, - nil, - BlockNode(282...305)( - [:a, :o, :r, :p, :b], - BlockParametersNode(284...303)( - ParametersNode(285...302)( - [RequiredParameterNode(285...286)(:a)], - [OptionalParameterNode(288...291)( - :o, - (288...289), - (289...290), - IntegerNode(290...291)() - )], - [RequiredParameterNode(297...298)(:p)], - RestParameterNode(293...295)(:r, (294...295), (293...294)), - [], - nil, - BlockParameterNode(300...302)(:b, (301...302), (300...301)) - ), - [], - (284...285), - (302...303) - ), - nil, - (282...283), - (304...305) - ), - 0, - "f" - ), - CallNode(307...334)( - nil, - nil, - (307...308), - nil, - nil, - nil, - BlockNode(308...334)( - [:a, :o, :o1, :r, :b], - BlockParametersNode(310...332)( - ParametersNode(311...331)( - [RequiredParameterNode(311...312)(:a)], - [OptionalParameterNode(314...317)( - :o, - (314...315), - (315...316), - IntegerNode(316...317)() - ), - OptionalParameterNode(319...323)( - :o1, - (319...321), - (321...322), - IntegerNode(322...323)() - )], - [], - RestParameterNode(325...327)(:r, (326...327), (325...326)), - [], - nil, - BlockParameterNode(329...331)(:b, (330...331), (329...330)) - ), - [], - (310...311), - (331...332) - ), - nil, - (308...309), - (333...334) - ), - 0, - "f" - ), - CallNode(336...356)( - nil, - nil, - (336...337), - nil, - nil, - nil, - BlockNode(337...356)( - [:a, :o, :p, :b], - BlockParametersNode(339...354)( - ParametersNode(340...353)( - [RequiredParameterNode(340...341)(:a)], - [OptionalParameterNode(343...346)( - :o, - (343...344), - (344...345), - IntegerNode(345...346)() - )], - [RequiredParameterNode(348...349)(:p)], - nil, - [], - nil, - BlockParameterNode(351...353)(:b, (352...353), (351...352)) - ), - [], - (339...340), - (353...354) - ), - nil, - (337...338), - (355...356) - ), - 0, - "f" - ), - CallNode(358...367)( - nil, - nil, - (358...359), - nil, - nil, - nil, - BlockNode(359...367)( - [:a], - BlockParametersNode(361...365)( - ParametersNode(362...364)( - [RequiredParameterNode(362...363)(:a)], - [], - [], - RestParameterNode(363...364)(nil, nil, (363...364)), - [], - nil, - nil - ), - [], - (361...362), - (364...365) - ), - nil, - (359...360), - (366...367) - ), - 0, - "f" - ), - CallNode(369...377)( - nil, - nil, - (369...370), - nil, - nil, - nil, - BlockNode(370...377)( - [:a], - BlockParametersNode(372...375)( - ParametersNode(373...374)( - [RequiredParameterNode(373...374)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (372...373), - (374...375) - ), - nil, - (370...371), - (376...377) - ), - 0, - "f" - ), - CallNode(379...387)( - nil, - nil, - (379...380), - nil, - nil, - nil, - BlockNode(380...387)( - [:a], - BlockParametersNode(382...385)( - ParametersNode(383...384)( - [RequiredParameterNode(383...384)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (382...383), - (384...385) - ), - nil, - (380...381), - (386...387) - ), - 0, - "f" - ), - CallNode(389...397)( - nil, - nil, - (389...390), - nil, - nil, - nil, - BlockNode(390...397)( - [:a], - BlockParametersNode(392...395)( - ParametersNode(393...394)( - [RequiredParameterNode(393...394)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (392...393), - (394...395) - ), - nil, - (390...391), - (396...397) - ), - 0, - "f" - ), - CallNode(399...416)( - nil, - nil, - (399...400), - nil, - nil, - nil, - BlockNode(400...416)( - [:foo, :b], - BlockParametersNode(402...414)( - ParametersNode(403...413)( - [], - [], - [], - nil, - [KeywordParameterNode(403...409)( - :foo, - (403...407), - IntegerNode(408...409)() - )], - nil, - BlockParameterNode(411...413)(:b, (412...413), (411...412)) - ), - [], - (402...403), - (413...414) - ), - nil, - (400...401), - (415...416) - ), - 0, - "f" - ), - CallNode(418...450)( - nil, - nil, - (418...419), - nil, - nil, - nil, - BlockNode(419...450)( - [:foo, :bar, :baz, :b], - BlockParametersNode(421...448)( - ParametersNode(422...447)( - [], - [], - [], - nil, - [KeywordParameterNode(422...428)( - :foo, - (422...426), - IntegerNode(427...428)() - ), - KeywordParameterNode(430...436)( - :bar, - (430...434), - IntegerNode(435...436)() - )], - KeywordRestParameterNode(438...443)( - :baz, - (440...443), - (438...440) - ), - BlockParameterNode(445...447)(:b, (446...447), (445...446)) - ), - [], - (421...422), - (447...448) - ), - nil, - (419...420), - (449...450) - ), - 0, - "f" - ), - CallNode(452...463)( - nil, - nil, - (452...453), - nil, - nil, - nil, - BlockNode(453...463)( - [:foo], - BlockParametersNode(455...461)( - ParametersNode(456...460)( - [], - [], - [], - nil, - [KeywordParameterNode(456...460)(:foo, (456...460), nil)], - nil, - nil - ), - [], - (455...456), - (460...461) - ), - nil, - (453...454), - (462...463) - ), - 0, - "f" - ), - CallNode(465...479)( - nil, - nil, - (465...466), - nil, - nil, - nil, - BlockNode(466...479)( - [:o, :b], - BlockParametersNode(468...477)( - ParametersNode(469...476)( - [], - [OptionalParameterNode(469...472)( - :o, - (469...470), - (470...471), - IntegerNode(471...472)() - )], - [], - nil, - [], - nil, - BlockParameterNode(474...476)(:b, (475...476), (474...475)) - ), - [], - (468...469), - (476...477) - ), - nil, - (466...467), - (478...479) - ), - 0, - "f" - ), - CallNode(481...499)( - nil, - nil, - (481...482), - nil, - nil, - nil, - BlockNode(482...499)( - [:o, :r, :b], - BlockParametersNode(484...497)( - ParametersNode(485...496)( - [], - [OptionalParameterNode(485...488)( - :o, - (485...486), - (486...487), - IntegerNode(487...488)() - )], - [], - RestParameterNode(490...492)(:r, (491...492), (490...491)), - [], - nil, - BlockParameterNode(494...496)(:b, (495...496), (494...495)) - ), - [], - (484...485), - (496...497) - ), - nil, - (482...483), - (498...499) - ), - 0, - "f" - ), - CallNode(501...522)( - nil, - nil, - (501...502), - nil, - nil, - nil, - BlockNode(502...522)( - [:o, :r, :p, :b], - BlockParametersNode(504...520)( - ParametersNode(505...519)( - [], - [OptionalParameterNode(505...508)( - :o, - (505...506), - (506...507), - IntegerNode(507...508)() - )], - [RequiredParameterNode(514...515)(:p)], - RestParameterNode(510...512)(:r, (511...512), (510...511)), - [], - nil, - BlockParameterNode(517...519)(:b, (518...519), (517...518)) - ), - [], - (504...505), - (519...520) - ), - nil, - (502...503), - (521...522) - ), - 0, - "f" - ), - CallNode(524...541)( - nil, - nil, - (524...525), - nil, - nil, - nil, - BlockNode(525...541)( - [:o, :p, :b], - BlockParametersNode(527...539)( - ParametersNode(528...538)( - [], - [OptionalParameterNode(528...531)( - :o, - (528...529), - (529...530), - IntegerNode(530...531)() - )], - [RequiredParameterNode(533...534)(:p)], - nil, - [], - nil, - BlockParameterNode(536...538)(:b, (537...538), (536...537)) - ), - [], - (527...528), - (538...539) - ), - nil, - (525...526), - (540...541) - ), - 0, - "f" - ), - CallNode(543...550)( - nil, - nil, - (543...544), - nil, - nil, - nil, - BlockNode(544...550)( - [], - BlockParametersNode(546...548)(nil, [], (546...547), (547...548)), - nil, - (544...545), - (549...550) - ), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/break.txt b/test/yarp/snapshots/whitequark/break.txt deleted file mode 100644 index 46d3b6a5703cf3..00000000000000 --- a/test/yarp/snapshots/whitequark/break.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [BreakNode(0...5)(nil, (0...5)), - BreakNode(7...16)( - ArgumentsNode(13...16)( - [CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo")] - ), - (7...12) - ), - BreakNode(18...25)( - ArgumentsNode(23...25)( - [ParenthesesNode(23...25)(nil, (23...24), (24...25))] - ), - (18...23) - ), - BreakNode(27...37)( - ArgumentsNode(32...37)( - [ParenthesesNode(32...37)( - StatementsNode(33...36)( - [CallNode(33...36)( - nil, - nil, - (33...36), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (32...33), - (36...37) - )] - ), - (27...32) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/break_block.txt b/test/yarp/snapshots/whitequark/break_block.txt deleted file mode 100644 index ad81bcf1637c9e..00000000000000 --- a/test/yarp/snapshots/whitequark/break_block.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [BreakNode(0...20)( - ArgumentsNode(6...20)( - [CallNode(6...20)( - nil, - nil, - (6...9), - nil, - ArgumentsNode(10...13)( - [CallNode(10...13)( - nil, - nil, - (10...13), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - BlockNode(14...20)([], nil, nil, (14...16), (17...20)), - 0, - "fun" - )] - ), - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_435.txt b/test/yarp/snapshots/whitequark/bug_435.txt deleted file mode 100644 index 7d74c8c8a2af64..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_435.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedStringNode(0...14)( - (0...1), - [EmbeddedStatementsNode(1...13)( - (1...3), - StatementsNode(3...12)( - [LambdaNode(3...12)( - [:foo], - (3...5), - (10...11), - (11...12), - BlockParametersNode(6...9)( - ParametersNode(6...9)( - [RequiredParameterNode(6...9)(:foo)], - [], - [], - nil, - [], - nil, - nil - ), - [], - nil, - nil - ), - nil - )] - ), - (12...13) - )], - (13...14) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_447.txt b/test/yarp/snapshots/whitequark/bug_447.txt deleted file mode 100644 index 3903748ceccfe2..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_447.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [CallNode(0...11)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([ArrayNode(2...4)([], (2...3), (3...4))]), - nil, - BlockNode(5...11)([], nil, nil, (5...7), (8...11)), - 0, - "m" - ), - CallNode(13...27)( - nil, - nil, - (13...14), - nil, - ArgumentsNode(15...20)( - [ArrayNode(15...17)([], (15...16), (16...17)), IntegerNode(19...20)()] - ), - nil, - BlockNode(21...27)([], nil, nil, (21...23), (24...27)), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_452.txt b/test/yarp/snapshots/whitequark/bug_452.txt deleted file mode 100644 index 31cf38cfc2e774..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_452.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [CallNode(0...21)( - nil, - nil, - (0...2), - nil, - ArgumentsNode(3...21)( - [CallNode(3...21)( - ParenthesesNode(3...10)( - StatementsNode(4...9)([IntegerNode(4...9)()]), - (3...4), - (9...10) - ), - (10...11), - (11...19), - (19...20), - nil, - (20...21), - nil, - 0, - "toString" - )] - ), - nil, - nil, - 0, - "td" - ), - CallNode(23...37)( - CallNode(23...25)(nil, nil, (23...25), nil, nil, nil, nil, 2, "td"), - (25...26), - (26...29), - nil, - nil, - nil, - BlockNode(30...37)([], nil, nil, (30...32), (34...37)), - 0, - "num" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_466.txt b/test/yarp/snapshots/whitequark/bug_466.txt deleted file mode 100644 index 3b153e4995312a..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_466.txt +++ /dev/null @@ -1,54 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [CallNode(0...27)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...19)( - [InterpolatedStringNode(4...19)( - (4...5), - [EmbeddedStatementsNode(5...18)( - (5...7), - StatementsNode(7...17)( - [CallNode(7...17)( - ParenthesesNode(7...12)( - StatementsNode(8...11)( - [CallNode(8...11)( - IntegerNode(8...9)(), - nil, - (9...10), - nil, - ArgumentsNode(10...11)([IntegerNode(10...11)()]), - nil, - nil, - 0, - "+" - )] - ), - (7...8), - (11...12) - ), - (12...13), - (13...17), - nil, - nil, - nil, - nil, - 0, - "to_i" - )] - ), - (17...18) - )], - (18...19) - )] - ), - nil, - BlockNode(20...27)([], nil, nil, (20...22), (24...27)), - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_473.txt b/test/yarp/snapshots/whitequark/bug_473.txt deleted file mode 100644 index a9978db50d24bf..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_473.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...9)( - [InterpolatedStringNode(2...9)( - (2...3), - [EmbeddedStatementsNode(3...8)( - (3...5), - StatementsNode(5...7)([ArrayNode(5...7)([], (5...6), (6...7))]), - (7...8) - )], - (8...9) - )] - ), - nil, - nil, - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_480.txt b/test/yarp/snapshots/whitequark/bug_480.txt deleted file mode 100644 index 8457cefa86f9b3..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_480.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...12)( - [InterpolatedStringNode(2...12)( - (2...3), - [EmbeddedStatementsNode(3...6)((3...5), nil, (5...6)), - EmbeddedStatementsNode(6...11)( - (6...8), - StatementsNode(8...10)( - [ParenthesesNode(8...10)(nil, (8...9), (9...10))] - ), - (10...11) - )], - (11...12) - )] - ), - nil, - nil, - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_481.txt b/test/yarp/snapshots/whitequark/bug_481.txt deleted file mode 100644 index 5bdeaf1d47b6fe..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_481.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...14)( - [DefNode(2...14)( - :x, - (6...7), - nil, - nil, - nil, - [], - (2...5), - nil, - (7...8), - (8...9), - nil, - (11...14) - )] - ), - nil, - nil, - 0, - "m" - ), - CallNode(16...28)( - IntegerNode(16...17)(), - (17...18), - (18...21), - nil, - nil, - nil, - BlockNode(22...28)([], nil, nil, (22...24), (25...28)), - 0, - "tap" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_ascii_8bit_in_literal.txt b/test/yarp/snapshots/whitequark/bug_ascii_8bit_in_literal.txt deleted file mode 100644 index 40251879fc8492..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_ascii_8bit_in_literal.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(24...90)( - [], - StatementsNode(24...90)( - [StringNode(24...90)((24...25), (25...89), (89...90), "проверка")] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_cmd_string_lookahead.txt b/test/yarp/snapshots/whitequark/bug_cmd_string_lookahead.txt deleted file mode 100644 index 0004e1a758bb09..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_cmd_string_lookahead.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...4), - nil, - ArgumentsNode(5...10)( - [StringNode(5...10)((5...6), (6...9), (9...10), "foo")] - ), - nil, - BlockNode(11...17)([], nil, nil, (11...13), (14...17)), - 0, - "desc" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_cmdarg.txt b/test/yarp/snapshots/whitequark/bug_cmdarg.txt deleted file mode 100644 index b3f79aafd460fc..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_cmdarg.txt +++ /dev/null @@ -1,85 +0,0 @@ -ProgramNode(0...56)( - [], - StatementsNode(0...56)( - [CallNode(0...15)( - nil, - nil, - (0...6), - nil, - ArgumentsNode(7...15)( - [KeywordHashNode(7...15)( - [AssocNode(7...15)( - SymbolNode(7...10)(nil, (7...9), (9...10), "do"), - TrueNode(11...15)(), - nil - )] - )] - ), - nil, - nil, - 0, - "assert" - ), - CallNode(17...28)( - nil, - nil, - (17...23), - nil, - ArgumentsNode(24...28)( - [CallNode(24...28)( - nil, - nil, - (24...28), - nil, - nil, - nil, - nil, - 2, - "dogs" - )] - ), - nil, - nil, - 0, - "assert" - ), - CallNode(30...56)( - nil, - nil, - (30...31), - nil, - ArgumentsNode(32...56)( - [KeywordHashNode(32...56)( - [AssocNode(32...56)( - SymbolNode(32...34)(nil, (32...33), (33...34), "x"), - LambdaNode(35...56)( - [], - (35...37), - (38...40), - (53...56), - nil, - StatementsNode(41...52)( - [CallNode(41...52)( - nil, - nil, - (41...45), - nil, - nil, - nil, - BlockNode(46...52)([], nil, nil, (46...48), (49...52)), - 0, - "meth" - )] - ) - ), - nil - )] - )] - ), - nil, - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt b/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt deleted file mode 100644 index 24159031ce2c6b..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt b/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt deleted file mode 100644 index 70ce5db09ba15c..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [CallNode(0...33)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...33)( - [DefNode(4...33)( - :foo, - (8...11), - nil, - nil, - StatementsNode(13...29)( - [CallNode(13...29)( - SelfNode(13...17)(), - (17...18), - (18...22), - nil, - nil, - nil, - BlockNode(23...29)([], nil, nil, (23...25), (26...29)), - 0, - "each" - )] - ), - [], - (4...7), - nil, - nil, - nil, - nil, - (30...33) - )] - ), - nil, - nil, - 0, - "bar" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_do_block_in_cmdarg.txt b/test/yarp/snapshots/whitequark/bug_do_block_in_cmdarg.txt deleted file mode 100644 index 81fa1d3609c415..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_do_block_in_cmdarg.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...17)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...17)( - [ParenthesesNode(4...17)( - StatementsNode(5...16)( - [CallNode(5...16)( - nil, - nil, - (5...9), - nil, - nil, - nil, - BlockNode(10...16)([], nil, nil, (10...12), (13...16)), - 0, - "proc" - )] - ), - (4...5), - (16...17) - )] - ), - nil, - nil, - 0, - "tap" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_do_block_in_hash_brace.txt b/test/yarp/snapshots/whitequark/bug_do_block_in_hash_brace.txt deleted file mode 100644 index bce92ea25b7d61..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_do_block_in_hash_brace.txt +++ /dev/null @@ -1,249 +0,0 @@ -ProgramNode(0...225)( - [], - StatementsNode(0...225)( - [CallNode(0...42)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...42)( - [SymbolNode(2...6)((2...3), (3...6), nil, "foo"), - HashNode(8...42)( - (8...9), - [AssocNode(9...25)( - SymbolNode(9...13)((9...10), (10...11), (11...13), "a"), - CallNode(14...25)( - nil, - nil, - (14...18), - nil, - nil, - nil, - BlockNode(19...25)([], nil, nil, (19...21), (22...25)), - 0, - "proc" - ), - nil - ), - AssocNode(27...41)( - SymbolNode(27...29)(nil, (27...28), (28...29), "b"), - CallNode(30...41)( - nil, - nil, - (30...34), - nil, - nil, - nil, - BlockNode(35...41)([], nil, nil, (35...37), (38...41)), - 0, - "proc" - ), - nil - )], - (41...42) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(44...84)( - nil, - nil, - (44...45), - nil, - ArgumentsNode(46...84)( - [SymbolNode(46...50)((46...47), (47...50), nil, "foo"), - HashNode(52...84)( - (52...53), - [AssocSplatNode(53...67)( - CallNode(56...67)( - nil, - nil, - (56...60), - nil, - nil, - nil, - BlockNode(61...67)([], nil, nil, (61...63), (64...67)), - 0, - "proc" - ), - (53...55) - ), - AssocNode(69...83)( - SymbolNode(69...71)(nil, (69...70), (70...71), "b"), - CallNode(72...83)( - nil, - nil, - (72...76), - nil, - nil, - nil, - BlockNode(77...83)([], nil, nil, (77...79), (80...83)), - 0, - "proc" - ), - nil - )], - (83...84) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(86...129)( - nil, - nil, - (86...87), - nil, - ArgumentsNode(88...129)( - [SymbolNode(88...92)((88...89), (89...92), nil, "foo"), - HashNode(94...129)( - (94...95), - [AssocNode(95...112)( - SymbolNode(95...97)((95...96), (96...97), nil, "a"), - CallNode(101...112)( - nil, - nil, - (101...105), - nil, - nil, - nil, - BlockNode(106...112)([], nil, nil, (106...108), (109...112)), - 0, - "proc" - ), - (98...100) - ), - AssocNode(114...128)( - SymbolNode(114...116)(nil, (114...115), (115...116), "b"), - CallNode(117...128)( - nil, - nil, - (117...121), - nil, - nil, - nil, - BlockNode(122...128)([], nil, nil, (122...124), (125...128)), - 0, - "proc" - ), - nil - )], - (128...129) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(131...171)( - nil, - nil, - (131...132), - nil, - ArgumentsNode(133...171)( - [SymbolNode(133...137)((133...134), (134...137), nil, "foo"), - HashNode(139...171)( - (139...140), - [AssocNode(140...154)( - SymbolNode(140...142)(nil, (140...141), (141...142), "a"), - CallNode(143...154)( - nil, - nil, - (143...147), - nil, - nil, - nil, - BlockNode(148...154)([], nil, nil, (148...150), (151...154)), - 0, - "proc" - ), - nil - ), - AssocNode(156...170)( - SymbolNode(156...158)(nil, (156...157), (157...158), "b"), - CallNode(159...170)( - nil, - nil, - (159...163), - nil, - nil, - nil, - BlockNode(164...170)([], nil, nil, (164...166), (167...170)), - 0, - "proc" - ), - nil - )], - (170...171) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(173...225)( - nil, - nil, - (173...174), - nil, - ArgumentsNode(175...225)( - [SymbolNode(175...179)((175...176), (176...179), nil, "foo"), - HashNode(181...225)( - (181...182), - [AssocNode(182...208)( - CallNode(182...193)( - nil, - nil, - (182...186), - nil, - nil, - nil, - BlockNode(187...193)([], nil, nil, (187...189), (190...193)), - 0, - "proc" - ), - CallNode(197...208)( - nil, - nil, - (197...201), - nil, - nil, - nil, - BlockNode(202...208)([], nil, nil, (202...204), (205...208)), - 0, - "proc" - ), - (194...196) - ), - AssocNode(210...224)( - SymbolNode(210...212)(nil, (210...211), (211...212), "b"), - CallNode(213...224)( - nil, - nil, - (213...217), - nil, - nil, - nil, - BlockNode(218...224)([], nil, nil, (218...220), (221...224)), - 0, - "proc" - ), - nil - )], - (224...225) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_heredoc_do.txt b/test/yarp/snapshots/whitequark/bug_heredoc_do.txt deleted file mode 100644 index 947af0ece7d74c..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_heredoc_do.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [CallNode(0...23)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...10)( - [InterpolatedStringNode(2...10)((2...10), [], (14...20))] - ), - nil, - BlockNode(11...23)([], nil, nil, (11...13), (20...23)), - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_interp_single.txt b/test/yarp/snapshots/whitequark/bug_interp_single.txt deleted file mode 100644 index bd56c9998ae95e..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_interp_single.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [InterpolatedStringNode(0...6)( - (0...1), - [EmbeddedStatementsNode(1...5)( - (1...3), - StatementsNode(3...4)([IntegerNode(3...4)()]), - (4...5) - )], - (5...6) - ), - ArrayNode(8...16)( - [InterpolatedStringNode(11...15)( - nil, - [EmbeddedStatementsNode(11...15)( - (11...13), - StatementsNode(13...14)([IntegerNode(13...14)()]), - (14...15) - )], - nil - )], - (8...11), - (15...16) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_lambda_leakage.txt b/test/yarp/snapshots/whitequark/bug_lambda_leakage.txt deleted file mode 100644 index 7792fa495af6ce..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_lambda_leakage.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [LambdaNode(0...12)( - [:scope], - (0...2), - (10...11), - (11...12), - BlockParametersNode(2...9)( - ParametersNode(3...8)( - [RequiredParameterNode(3...8)(:scope)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (2...3), - (8...9) - ), - nil - ), - CallNode(14...19)(nil, nil, (14...19), nil, nil, nil, nil, 2, "scope")] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_regex_verification.txt b/test/yarp/snapshots/whitequark/bug_regex_verification.txt deleted file mode 100644 index e1fc0ec0e69e0d..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_regex_verification.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [RegularExpressionNode(0...5)((0...1), (1...3), (3...5), "#)", 4)] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_rescue_empty_else.txt b/test/yarp/snapshots/whitequark/bug_rescue_empty_else.txt deleted file mode 100644 index 02c4736f8c6814..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_rescue_empty_else.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...34)( - [], - StatementsNode(0...34)( - [BeginNode(0...34)( - (0...5), - nil, - RescueNode(7...23)( - (7...13), - [ConstantReadNode(14...23)(:LoadError)], - nil, - nil, - nil, - nil - ), - ElseNode(25...34)((25...29), nil, (31...34)), - nil, - (31...34) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/bug_while_not_parens_do.txt b/test/yarp/snapshots/whitequark/bug_while_not_parens_do.txt deleted file mode 100644 index f5e086059a86c3..00000000000000 --- a/test/yarp/snapshots/whitequark/bug_while_not_parens_do.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [WhileNode(0...23)( - (0...5), - (20...23), - CallNode(6...16)( - ParenthesesNode(10...16)( - StatementsNode(11...15)([TrueNode(11...15)()]), - (10...11), - (15...16) - ), - nil, - (6...9), - nil, - nil, - nil, - nil, - 0, - "!" - ), - nil, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/case_cond.txt b/test/yarp/snapshots/whitequark/case_cond.txt deleted file mode 100644 index 207fbe9a48596f..00000000000000 --- a/test/yarp/snapshots/whitequark/case_cond.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CaseNode(0...26)( - nil, - [WhenNode(6...21)( - (6...10), - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "foo" - )], - StatementsNode(16...21)( - [StringNode(16...21)((16...17), (17...20), (20...21), "foo")] - ) - )], - nil, - (0...4), - (23...26) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/case_cond_else.txt b/test/yarp/snapshots/whitequark/case_cond_else.txt deleted file mode 100644 index 263c4d3a0812d3..00000000000000 --- a/test/yarp/snapshots/whitequark/case_cond_else.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [CaseNode(0...38)( - nil, - [WhenNode(6...21)( - (6...10), - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "foo" - )], - StatementsNode(16...21)( - [StringNode(16...21)((16...17), (17...20), (20...21), "foo")] - ) - )], - ElseNode(23...38)( - (23...27), - StatementsNode(28...33)( - [StringNode(28...33)((28...29), (29...32), (32...33), "bar")] - ), - (35...38) - ), - (0...4), - (35...38) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/case_expr.txt b/test/yarp/snapshots/whitequark/case_expr.txt deleted file mode 100644 index 8b01d8f81a5e22..00000000000000 --- a/test/yarp/snapshots/whitequark/case_expr.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [CaseNode(0...30)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [WhenNode(10...25)( - (10...14), - [StringNode(15...20)((15...16), (16...19), (19...20), "bar")], - StatementsNode(22...25)( - [CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (0...4), - (27...30) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/case_expr_else.txt b/test/yarp/snapshots/whitequark/case_expr_else.txt deleted file mode 100644 index 79356e6cf3990b..00000000000000 --- a/test/yarp/snapshots/whitequark/case_expr_else.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [CaseNode(0...40)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [WhenNode(10...25)( - (10...14), - [StringNode(15...20)((15...16), (16...19), (19...20), "bar")], - StatementsNode(22...25)( - [CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - ElseNode(27...40)( - (27...31), - StatementsNode(32...35)( - [CallNode(32...35)( - nil, - nil, - (32...35), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (37...40) - ), - (0...4), - (37...40) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/casgn_scoped.txt b/test/yarp/snapshots/whitequark/casgn_scoped.txt deleted file mode 100644 index b5e719abfc667c..00000000000000 --- a/test/yarp/snapshots/whitequark/casgn_scoped.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [ConstantPathWriteNode(0...13)( - ConstantPathNode(0...8)( - ConstantReadNode(0...3)(:Bar), - ConstantReadNode(5...8)(:Foo), - (3...5) - ), - (9...10), - IntegerNode(11...13)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/casgn_toplevel.txt b/test/yarp/snapshots/whitequark/casgn_toplevel.txt deleted file mode 100644 index 7fff870f8a2bd5..00000000000000 --- a/test/yarp/snapshots/whitequark/casgn_toplevel.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [ConstantPathWriteNode(0...10)( - ConstantPathNode(0...5)(nil, ConstantReadNode(2...5)(:Foo), (0...2)), - (6...7), - IntegerNode(8...10)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/casgn_unscoped.txt b/test/yarp/snapshots/whitequark/casgn_unscoped.txt deleted file mode 100644 index 7e778015b15334..00000000000000 --- a/test/yarp/snapshots/whitequark/casgn_unscoped.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [ConstantWriteNode(0...8)(:Foo, (0...3), IntegerNode(6...8)(), (4...5))] - ) -) diff --git a/test/yarp/snapshots/whitequark/character.txt b/test/yarp/snapshots/whitequark/character.txt deleted file mode 100644 index 7865df42fab3c4..00000000000000 --- a/test/yarp/snapshots/whitequark/character.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...2)( - [], - StatementsNode(0...2)([StringNode(0...2)((0...1), (1...2), nil, "a")]) -) diff --git a/test/yarp/snapshots/whitequark/class.txt b/test/yarp/snapshots/whitequark/class.txt deleted file mode 100644 index 692e70859d2cbf..00000000000000 --- a/test/yarp/snapshots/whitequark/class.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [ClassNode(0...13)( - [], - (0...5), - ConstantReadNode(6...9)(:Foo), - nil, - nil, - nil, - (10...13), - :Foo - ), - ClassNode(15...29)( - [], - (15...20), - ConstantReadNode(21...24)(:Foo), - nil, - nil, - nil, - (26...29), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt b/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt deleted file mode 100644 index 8fbb656c2c6950..00000000000000 --- a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt +++ /dev/null @@ -1,125 +0,0 @@ -ProgramNode(0...197)( - [], - StatementsNode(0...197)( - [WhileNode(0...52)( - (0...5), - (49...52), - SingletonClassNode(6...40)( - [:a], - (6...11), - (12...14), - SelfNode(15...19)(), - StatementsNode(21...35)( - [LocalVariableWriteNode(21...35)( - :a, - 0, - (21...22), - CallNode(25...35)( - nil, - nil, - (25...28), - nil, - nil, - nil, - BlockNode(29...35)([], nil, nil, (29...31), (32...35)), - 0, - "tap" - ), - (23...24) - )] - ), - (37...40) - ), - StatementsNode(42...47)([BreakNode(42...47)(nil, (42...47))]), - 0 - ), - WhileNode(54...102)( - (54...59), - (99...102), - SingletonClassNode(60...90)( - [], - (60...65), - (66...68), - SelfNode(69...73)(), - StatementsNode(75...85)( - [CallNode(75...85)( - nil, - nil, - (75...78), - nil, - nil, - nil, - BlockNode(79...85)([], nil, nil, (79...81), (82...85)), - 0, - "tap" - )] - ), - (87...90) - ), - StatementsNode(92...97)([BreakNode(92...97)(nil, (92...97))]), - 0 - ), - WhileNode(104...151)( - (104...109), - (148...151), - ClassNode(110...139)( - [:a], - (110...115), - ConstantReadNode(116...119)(:Foo), - nil, - nil, - StatementsNode(120...134)( - [LocalVariableWriteNode(120...134)( - :a, - 0, - (120...121), - CallNode(124...134)( - nil, - nil, - (124...127), - nil, - nil, - nil, - BlockNode(128...134)([], nil, nil, (128...130), (131...134)), - 0, - "tap" - ), - (122...123) - )] - ), - (136...139), - :Foo - ), - StatementsNode(141...146)([BreakNode(141...146)(nil, (141...146))]), - 0 - ), - WhileNode(153...197)( - (153...158), - (194...197), - ClassNode(159...185)( - [], - (159...164), - ConstantReadNode(165...168)(:Foo), - nil, - nil, - StatementsNode(170...180)( - [CallNode(170...180)( - nil, - nil, - (170...173), - nil, - nil, - nil, - BlockNode(174...180)([], nil, nil, (174...176), (177...180)), - 0, - "tap" - )] - ), - (182...185), - :Foo - ), - StatementsNode(187...192)([BreakNode(187...192)(nil, (187...192))]), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/class_super.txt b/test/yarp/snapshots/whitequark/class_super.txt deleted file mode 100644 index a2458fe128410a..00000000000000 --- a/test/yarp/snapshots/whitequark/class_super.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [ClassNode(0...20)( - [], - (0...5), - ConstantReadNode(6...9)(:Foo), - (10...11), - ConstantReadNode(12...15)(:Bar), - nil, - (17...20), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/class_super_label.txt b/test/yarp/snapshots/whitequark/class_super_label.txt deleted file mode 100644 index ab6bf568d82150..00000000000000 --- a/test/yarp/snapshots/whitequark/class_super_label.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [ClassNode(0...20)( - [], - (0...5), - ConstantReadNode(6...9)(:Foo), - (10...11), - CallNode(12...15)( - nil, - nil, - (12...13), - nil, - ArgumentsNode(13...15)( - [SymbolNode(13...15)((13...14), (14...15), nil, "b")] - ), - nil, - nil, - 0, - "a" - ), - nil, - (17...20), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/comments_before_leading_dot__27.txt b/test/yarp/snapshots/whitequark/comments_before_leading_dot__27.txt deleted file mode 100644 index b01a481eca0a5d..00000000000000 --- a/test/yarp/snapshots/whitequark/comments_before_leading_dot__27.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...55)( - [], - StatementsNode(0...55)( - [CallNode(0...13)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (8...10), - (10...13), - nil, - nil, - nil, - nil, - 1, - "foo" - ), - CallNode(16...28)( - CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "a"), - (24...25), - (25...28), - nil, - nil, - nil, - nil, - 0, - "foo" - ), - CallNode(31...42)( - CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 2, "a"), - (37...39), - (39...42), - nil, - nil, - nil, - nil, - 1, - "foo" - ), - CallNode(45...55)( - CallNode(45...46)(nil, nil, (45...46), nil, nil, nil, nil, 2, "a"), - (51...52), - (52...55), - nil, - nil, - nil, - nil, - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/complex.txt b/test/yarp/snapshots/whitequark/complex.txt deleted file mode 100644 index f8273f3806e41f..00000000000000 --- a/test/yarp/snapshots/whitequark/complex.txt +++ /dev/null @@ -1,9 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [ImaginaryNode(0...5)(FloatNode(0...4)()), - ImaginaryNode(7...13)(RationalNode(7...12)(FloatNode(7...11)())), - ImaginaryNode(15...18)(IntegerNode(15...17)()), - ImaginaryNode(20...24)(RationalNode(20...23)(IntegerNode(20...22)()))] - ) -) diff --git a/test/yarp/snapshots/whitequark/cond_begin.txt b/test/yarp/snapshots/whitequark/cond_begin.txt deleted file mode 100644 index e3e3650e484993..00000000000000 --- a/test/yarp/snapshots/whitequark/cond_begin.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [IfNode(0...18)( - (0...2), - ParenthesesNode(3...8)( - StatementsNode(4...7)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar")] - ), - (3...4), - (7...8) - ), - StatementsNode(10...13)( - [CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo")] - ), - nil, - (15...18) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt deleted file mode 100644 index 9a5e51bd10a57c..00000000000000 --- a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt +++ /dev/null @@ -1,36 +0,0 @@ -ProgramNode(0...25)( - [:a, :b], - StatementsNode(0...25)( - [IfNode(0...25)( - (0...2), - ParenthesesNode(3...20)( - StatementsNode(4...19)( - [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), - MultiWriteNode(9...19)( - [LocalVariableTargetNode(9...10)(:a, 0), - LocalVariableTargetNode(12...13)(:b, 0)], - nil, - nil, - (14...15), - CallNode(16...19)( - nil, - nil, - (16...19), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )] - ), - (3...4), - (19...20) - ), - nil, - nil, - (22...25) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/cond_eflipflop.txt b/test/yarp/snapshots/whitequark/cond_eflipflop.txt deleted file mode 100644 index 31ef52f1e95730..00000000000000 --- a/test/yarp/snapshots/whitequark/cond_eflipflop.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CallNode(0...12)( - ParenthesesNode(1...12)( - StatementsNode(2...11)( - [FlipFlopNode(2...11)( - CallNode(2...5)(nil, nil, (2...5), nil, nil, nil, nil, 2, "foo"), - CallNode(8...11)( - nil, - nil, - (8...11), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (5...8), - 1 - )] - ), - (1...2), - (11...12) - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - ), - IfNode(14...31)( - (14...16), - FlipFlopNode(17...26)( - CallNode(17...20)(nil, nil, (17...20), nil, nil, nil, nil, 2, "foo"), - CallNode(23...26)(nil, nil, (23...26), nil, nil, nil, nil, 2, "bar"), - (20...23), - 1 - ), - nil, - nil, - (28...31) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/cond_iflipflop.txt b/test/yarp/snapshots/whitequark/cond_iflipflop.txt deleted file mode 100644 index 4d1d42ed82092d..00000000000000 --- a/test/yarp/snapshots/whitequark/cond_iflipflop.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [CallNode(0...11)( - ParenthesesNode(1...11)( - StatementsNode(2...10)( - [FlipFlopNode(2...10)( - CallNode(2...5)(nil, nil, (2...5), nil, nil, nil, nil, 2, "foo"), - CallNode(7...10)( - nil, - nil, - (7...10), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (5...7), - 0 - )] - ), - (1...2), - (10...11) - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - ), - IfNode(13...29)( - (13...15), - FlipFlopNode(16...24)( - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "foo"), - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "bar"), - (19...21), - 0 - ), - nil, - nil, - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/cond_match_current_line.txt b/test/yarp/snapshots/whitequark/cond_match_current_line.txt deleted file mode 100644 index 02bceef3d7a3b3..00000000000000 --- a/test/yarp/snapshots/whitequark/cond_match_current_line.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [CallNode(0...6)( - RegularExpressionNode(1...6)((1...2), (2...5), (5...6), "wat", 0), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - ), - IfNode(8...21)( - (8...10), - RegularExpressionNode(11...16)( - (11...12), - (12...15), - (15...16), - "wat", - 0 - ), - nil, - nil, - (18...21) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/const_op_asgn.txt b/test/yarp/snapshots/whitequark/const_op_asgn.txt deleted file mode 100644 index 1b177334156c3e..00000000000000 --- a/test/yarp/snapshots/whitequark/const_op_asgn.txt +++ /dev/null @@ -1,76 +0,0 @@ -ProgramNode(0...77)( - [], - StatementsNode(0...77)( - [ConstantPathOperatorWriteNode(0...8)( - ConstantPathNode(0...3)(nil, ConstantReadNode(2...3)(:A), (0...2)), - (4...6), - IntegerNode(7...8)(), - :+ - ), - ConstantOperatorWriteNode(10...16)( - :A, - (10...11), - (12...14), - IntegerNode(15...16)(), - :+ - ), - ConstantPathOperatorWriteNode(18...27)( - ConstantPathNode(18...22)( - ConstantReadNode(18...19)(:B), - ConstantReadNode(21...22)(:A), - (19...21) - ), - (23...25), - IntegerNode(26...27)(), - :+ - ), - DefNode(29...50)( - :x, - (33...34), - nil, - nil, - StatementsNode(36...45)( - [ConstantPathOrWriteNode(36...45)( - ConstantPathNode(36...39)( - nil, - ConstantReadNode(38...39)(:A), - (36...38) - ), - (40...43), - IntegerNode(44...45)() - )] - ), - [], - (29...32), - nil, - nil, - nil, - nil, - (47...50) - ), - DefNode(52...77)( - :x, - (56...57), - nil, - nil, - StatementsNode(59...72)( - [ConstantPathOrWriteNode(59...72)( - ConstantPathNode(59...66)( - SelfNode(59...63)(), - ConstantReadNode(65...66)(:A), - (63...65) - ), - (67...70), - IntegerNode(71...72)() - )] - ), - [], - (52...55), - nil, - nil, - nil, - nil, - (74...77) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/const_scoped.txt b/test/yarp/snapshots/whitequark/const_scoped.txt deleted file mode 100644 index 2404bd05290faf..00000000000000 --- a/test/yarp/snapshots/whitequark/const_scoped.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [ConstantPathNode(0...8)( - ConstantReadNode(0...3)(:Bar), - ConstantReadNode(5...8)(:Foo), - (3...5) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/const_toplevel.txt b/test/yarp/snapshots/whitequark/const_toplevel.txt deleted file mode 100644 index 14647d31be8545..00000000000000 --- a/test/yarp/snapshots/whitequark/const_toplevel.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [ConstantPathNode(0...5)(nil, ConstantReadNode(2...5)(:Foo), (0...2))] - ) -) diff --git a/test/yarp/snapshots/whitequark/const_unscoped.txt b/test/yarp/snapshots/whitequark/const_unscoped.txt deleted file mode 100644 index 716cbf524973b9..00000000000000 --- a/test/yarp/snapshots/whitequark/const_unscoped.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...3)([], StatementsNode(0...3)([ConstantReadNode(0...3)(:Foo)])) diff --git a/test/yarp/snapshots/whitequark/cpath.txt b/test/yarp/snapshots/whitequark/cpath.txt deleted file mode 100644 index 7e3f62ee17b87a..00000000000000 --- a/test/yarp/snapshots/whitequark/cpath.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [ModuleNode(0...17)( - [], - (0...6), - ConstantPathNode(7...12)(nil, ConstantReadNode(9...12)(:Foo), (7...9)), - nil, - (14...17), - :Foo - ), - ModuleNode(19...39)( - [], - (19...25), - ConstantPathNode(26...34)( - ConstantReadNode(26...29)(:Bar), - ConstantReadNode(31...34)(:Foo), - (29...31) - ), - nil, - (36...39), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/cvar.txt b/test/yarp/snapshots/whitequark/cvar.txt deleted file mode 100644 index 6a1f2e50f48566..00000000000000 --- a/test/yarp/snapshots/whitequark/cvar.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)([ClassVariableReadNode(0...5)(:@@foo)]) -) diff --git a/test/yarp/snapshots/whitequark/cvasgn.txt b/test/yarp/snapshots/whitequark/cvasgn.txt deleted file mode 100644 index 7e07810eb6cc0f..00000000000000 --- a/test/yarp/snapshots/whitequark/cvasgn.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [ClassVariableWriteNode(0...10)( - :@@var, - (0...5), - IntegerNode(8...10)(), - (6...7) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/dedenting_heredoc.txt b/test/yarp/snapshots/whitequark/dedenting_heredoc.txt deleted file mode 100644 index d74deb09b08f56..00000000000000 --- a/test/yarp/snapshots/whitequark/dedenting_heredoc.txt +++ /dev/null @@ -1,323 +0,0 @@ -ProgramNode(0...313)( - [], - StatementsNode(0...313)( - [CallNode(0...8)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...8)( - [InterpolatedStringNode(2...8)( - (2...8), - [StringNode(9...17)(nil, (9...17), nil, " x\n"), - EmbeddedStatementsNode(17...25)( - (17...19), - StatementsNode(19...24)( - [StringNode(19...24)((19...20), (20...23), (23...24), " y")] - ), - (24...25) - ), - StringNode(25...26)(nil, (25...26), nil, "\n")], - (26...28) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(29...37)( - nil, - nil, - (29...30), - nil, - ArgumentsNode(31...37)( - [InterpolatedStringNode(31...37)( - (31...37), - [StringNode(38...46)(nil, (38...46), nil, " x\n"), - EmbeddedStatementsNode(46...52)( - (46...48), - StatementsNode(48...51)( - [CallNode(48...51)( - nil, - nil, - (48...51), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (51...52) - ), - StringNode(52...53)(nil, (52...53), nil, "\n")], - (53...55) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(56...62)( - nil, - nil, - (56...57), - nil, - ArgumentsNode(58...62)( - [InterpolatedStringNode(58...62)( - (58...62), - [StringNode(63...76)(nil, (63...76), nil, "x\n" + "y\n")], - (76...78) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(79...85)( - nil, - nil, - (79...80), - nil, - ArgumentsNode(81...85)( - [InterpolatedStringNode(81...85)( - (81...85), - [StringNode(86...95)(nil, (86...95), nil, "\tx\n" + "y\n")], - (95...97) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(98...104)( - nil, - nil, - (98...99), - nil, - ArgumentsNode(100...104)( - [InterpolatedStringNode(100...104)( - (100...104), - [StringNode(105...122)(nil, (105...122), nil, "x\n" + "y\n")], - (122...124) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(125...131)( - nil, - nil, - (125...126), - nil, - ArgumentsNode(127...131)( - [InterpolatedStringNode(127...131)( - (127...131), - [StringNode(132...146)(nil, (132...146), nil, "\tx\n" + "y\n")], - (146...148) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(149...155)( - nil, - nil, - (149...150), - nil, - ArgumentsNode(151...155)( - [InterpolatedStringNode(151...155)( - (151...155), - [StringNode(156...168)(nil, (156...168), nil, " x\n" + "\ty\n")], - (168...170) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(171...177)( - nil, - nil, - (171...172), - nil, - ArgumentsNode(173...177)( - [InterpolatedStringNode(173...177)( - (173...177), - [StringNode(178...191)(nil, (178...191), nil, " x\n" + " y\n")], - (191...193) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(194...200)( - nil, - nil, - (194...195), - nil, - ArgumentsNode(196...200)( - [InterpolatedStringNode(196...200)((196...200), [], (201...205))] - ), - nil, - nil, - 0, - "p" - ), - CallNode(206...212)( - nil, - nil, - (206...207), - nil, - ArgumentsNode(208...212)( - [InterpolatedStringNode(208...212)( - (208...212), - [StringNode(213...220)( - nil, - (213...220), - nil, - " x\n" + "\n" + "y\n" - )], - (220...222) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(223...229)( - nil, - nil, - (223...224), - nil, - ArgumentsNode(225...229)( - [InterpolatedStringNode(225...229)( - (225...229), - [StringNode(230...243)( - nil, - (230...243), - nil, - "x\n" + " \n" + "y\n" - )], - (243...245) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(246...252)( - nil, - nil, - (246...247), - nil, - ArgumentsNode(248...252)( - [InterpolatedStringNode(248...252)( - (248...252), - [StringNode(253...263)(nil, (253...263), nil, "x\n" + " y\n")], - (263...265) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(266...272)( - nil, - nil, - (266...267), - nil, - ArgumentsNode(268...272)( - [InterpolatedStringNode(268...272)( - (268...272), - [StringNode(273...277)(nil, (273...277), nil, "x\n")], - (277...279) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(280...286)( - nil, - nil, - (280...281), - nil, - ArgumentsNode(282...286)( - [InterpolatedStringNode(282...286)( - (282...286), - [StringNode(287...292)(nil, (287...292), nil, "ð\n")], - (292...294) - )] - ), - nil, - nil, - 0, - "p" - ), - CallNode(295...301)( - nil, - nil, - (295...296), - nil, - ArgumentsNode(297...301)( - [InterpolatedStringNode(297...301)((297...301), [], (302...304))] - ), - nil, - nil, - 0, - "p" - ), - CallNode(305...313)( - nil, - nil, - (305...306), - nil, - ArgumentsNode(307...313)( - [InterpolatedXStringNode(307...313)( - (307...313), - [StringNode(314...322)(nil, (314...322), nil, " x\n"), - EmbeddedStatementsNode(322...328)( - (322...324), - StatementsNode(324...327)( - [CallNode(324...327)( - nil, - nil, - (324...327), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (327...328) - ), - StringNode(328...329)(nil, (328...329), nil, "\n")], - (329...331) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt b/test/yarp/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt deleted file mode 100644 index f076eed1fec25a..00000000000000 --- a/test/yarp/snapshots/whitequark/dedenting_interpolating_heredoc_fake_line_continuation.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...8), - [StringNode(9...23)(nil, (9...23), nil, "baz\\\n" + "qux\n")], - (23...27) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt b/test/yarp/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt deleted file mode 100644 index ce1617b1ad3026..00000000000000 --- a/test/yarp/snapshots/whitequark/dedenting_non_interpolating_heredoc_line_continuation.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [InterpolatedStringNode(0...8)( - (0...8), - [StringNode(9...22)(nil, (9...22), nil, "baz\\\n" + "qux\n")], - (22...26) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/def.txt b/test/yarp/snapshots/whitequark/def.txt deleted file mode 100644 index 383b2a666cffbc..00000000000000 --- a/test/yarp/snapshots/whitequark/def.txt +++ /dev/null @@ -1,89 +0,0 @@ -ProgramNode(0...93)( - [], - StatementsNode(0...93)( - [DefNode(0...14)( - :BEGIN, - (4...9), - nil, - nil, - nil, - [], - (0...3), - nil, - nil, - nil, - nil, - (11...14) - ), - DefNode(16...28)( - :END, - (20...23), - nil, - nil, - nil, - [], - (16...19), - nil, - nil, - nil, - nil, - (25...28) - ), - DefNode(30...45)( - :String, - (34...40), - nil, - nil, - nil, - [], - (30...33), - nil, - nil, - nil, - nil, - (42...45) - ), - DefNode(47...63)( - :String=, - (51...58), - nil, - nil, - nil, - [], - (47...50), - nil, - nil, - nil, - nil, - (60...63) - ), - DefNode(65...77)( - :foo, - (69...72), - nil, - nil, - nil, - [], - (65...68), - nil, - nil, - nil, - nil, - (74...77) - ), - DefNode(79...93)( - :until, - (83...88), - nil, - nil, - nil, - [], - (79...82), - nil, - nil, - nil, - nil, - (90...93) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/defined.txt b/test/yarp/snapshots/whitequark/defined.txt deleted file mode 100644 index 3ddfdd84bbf5ea..00000000000000 --- a/test/yarp/snapshots/whitequark/defined.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [DefinedNode(0...13)( - nil, - InstanceVariableReadNode(9...13)(:@foo), - nil, - (0...8) - ), - DefinedNode(15...27)( - nil, - CallNode(24...27)(nil, nil, (24...27), nil, nil, nil, nil, 2, "foo"), - nil, - (15...23) - ), - DefinedNode(29...42)( - (37...38), - CallNode(38...41)(nil, nil, (38...41), nil, nil, nil, nil, 2, "foo"), - (41...42), - (29...37) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/defs.txt b/test/yarp/snapshots/whitequark/defs.txt deleted file mode 100644 index 6072d21645f4c7..00000000000000 --- a/test/yarp/snapshots/whitequark/defs.txt +++ /dev/null @@ -1,79 +0,0 @@ -ProgramNode(0...100)( - [], - StatementsNode(0...100)( - [DefNode(0...18)( - :foo, - (10...13), - ParenthesesNode(4...9)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - (4...5), - (8...9) - ), - nil, - nil, - [], - (0...3), - (9...10), - nil, - nil, - nil, - (15...18) - ), - DefNode(20...39)( - :foo, - (31...34), - ConstantReadNode(24...30)(:String), - nil, - nil, - [], - (20...23), - (30...31), - nil, - nil, - nil, - (36...39) - ), - DefNode(41...61)( - :foo, - (53...56), - ConstantReadNode(45...51)(:String), - nil, - nil, - [], - (41...44), - (51...53), - nil, - nil, - nil, - (58...61) - ), - DefNode(63...80)( - :foo, - (72...75), - SelfNode(67...71)(), - nil, - nil, - [], - (63...66), - (71...72), - nil, - nil, - nil, - (77...80) - ), - DefNode(82...100)( - :foo, - (92...95), - SelfNode(86...90)(), - nil, - nil, - [], - (82...85), - (90...92), - nil, - nil, - nil, - (97...100) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/empty_stmt.txt b/test/yarp/snapshots/whitequark/empty_stmt.txt deleted file mode 100644 index bd3eaf5ff49bc2..00000000000000 --- a/test/yarp/snapshots/whitequark/empty_stmt.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...0)([], StatementsNode(0...0)([])) diff --git a/test/yarp/snapshots/whitequark/endless_comparison_method.txt b/test/yarp/snapshots/whitequark/endless_comparison_method.txt deleted file mode 100644 index b0d3b33aca3106..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_comparison_method.txt +++ /dev/null @@ -1,209 +0,0 @@ -ProgramNode(0...179)( - [], - StatementsNode(0...179)( - [DefNode(0...28)( - :!=, - (4...6), - nil, - ParametersNode(7...12)( - [RequiredParameterNode(7...12)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(16...28)( - [CallNode(16...28)( - nil, - nil, - (16...28), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (0...3), - nil, - (6...7), - (12...13), - (14...15), - nil - ), - DefNode(30...58)( - :!=, - (34...36), - nil, - ParametersNode(37...42)( - [RequiredParameterNode(37...42)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(46...58)( - [CallNode(46...58)( - nil, - nil, - (46...58), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (30...33), - nil, - (36...37), - (42...43), - (44...45), - nil - ), - DefNode(60...88)( - :<=, - (64...66), - nil, - ParametersNode(67...72)( - [RequiredParameterNode(67...72)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(76...88)( - [CallNode(76...88)( - nil, - nil, - (76...88), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (60...63), - nil, - (66...67), - (72...73), - (74...75), - nil - ), - DefNode(90...118)( - :==, - (94...96), - nil, - ParametersNode(97...102)( - [RequiredParameterNode(97...102)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(106...118)( - [CallNode(106...118)( - nil, - nil, - (106...118), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (90...93), - nil, - (96...97), - (102...103), - (104...105), - nil - ), - DefNode(120...149)( - :===, - (124...127), - nil, - ParametersNode(128...133)( - [RequiredParameterNode(128...133)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(137...149)( - [CallNode(137...149)( - nil, - nil, - (137...149), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (120...123), - nil, - (127...128), - (133...134), - (135...136), - nil - ), - DefNode(151...179)( - :>=, - (155...157), - nil, - ParametersNode(158...163)( - [RequiredParameterNode(158...163)(:other)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(167...179)( - [CallNode(167...179)( - nil, - nil, - (167...179), - nil, - nil, - nil, - nil, - 2, - "do_something" - )] - ), - [:other], - (151...154), - nil, - (157...158), - (163...164), - (165...166), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/endless_method.txt b/test/yarp/snapshots/whitequark/endless_method.txt deleted file mode 100644 index c81dd69456c359..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_method.txt +++ /dev/null @@ -1,101 +0,0 @@ -ProgramNode(0...78)( - [], - StatementsNode(0...78)( - [DefNode(0...14)( - :foo, - (4...7), - nil, - nil, - StatementsNode(12...14)([IntegerNode(12...14)()]), - [], - (0...3), - nil, - (7...8), - (8...9), - (10...11), - nil - ), - DefNode(16...34)( - :inc, - (20...23), - nil, - ParametersNode(24...25)( - [RequiredParameterNode(24...25)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(29...34)( - [CallNode(29...34)( - LocalVariableReadNode(29...30)(:x, 0), - nil, - (31...32), - nil, - ArgumentsNode(33...34)([IntegerNode(33...34)()]), - nil, - nil, - 0, - "+" - )] - ), - [:x], - (16...19), - nil, - (23...24), - (25...26), - (27...28), - nil - ), - DefNode(36...54)( - :foo, - (44...47), - CallNode(40...43)(nil, nil, (40...43), nil, nil, nil, nil, 2, "obj"), - nil, - StatementsNode(52...54)([IntegerNode(52...54)()]), - [], - (36...39), - (43...44), - (47...48), - (48...49), - (50...51), - nil - ), - DefNode(56...78)( - :inc, - (64...67), - CallNode(60...63)(nil, nil, (60...63), nil, nil, nil, nil, 2, "obj"), - ParametersNode(68...69)( - [RequiredParameterNode(68...69)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(73...78)( - [CallNode(73...78)( - LocalVariableReadNode(73...74)(:x, 0), - nil, - (75...76), - nil, - ArgumentsNode(77...78)([IntegerNode(77...78)()]), - nil, - nil, - 0, - "+" - )] - ), - [:x], - (56...59), - (63...64), - (67...68), - (69...70), - (71...72), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt b/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt deleted file mode 100644 index 3015996dde90db..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt +++ /dev/null @@ -1,324 +0,0 @@ -ProgramNode(0...278)( - [], - StatementsNode(0...278)( - [DefNode(0...22)( - :foo, - (4...7), - nil, - nil, - StatementsNode(10...22)( - [CallNode(10...22)( - nil, - nil, - (10...14), - nil, - ArgumentsNode(15...22)( - [StringNode(15...22)((15...16), (16...21), (21...22), "Hello")] - ), - nil, - nil, - 0, - "puts" - )] - ), - [], - (0...3), - nil, - nil, - nil, - (8...9), - nil - ), - DefNode(24...48)( - :foo, - (28...31), - nil, - nil, - StatementsNode(36...48)( - [CallNode(36...48)( - nil, - nil, - (36...40), - nil, - ArgumentsNode(41...48)( - [StringNode(41...48)((41...42), (42...47), (47...48), "Hello")] - ), - nil, - nil, - 0, - "puts" - )] - ), - [], - (24...27), - nil, - (31...32), - (32...33), - (34...35), - nil - ), - DefNode(50...69)( - :foo, - (54...57), - nil, - ParametersNode(58...59)( - [RequiredParameterNode(58...59)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(63...69)( - [CallNode(63...69)( - nil, - nil, - (63...67), - nil, - ArgumentsNode(68...69)([LocalVariableReadNode(68...69)(:x, 0)]), - nil, - nil, - 0, - "puts" - )] - ), - [:x], - (50...53), - nil, - (57...58), - (59...60), - (61...62), - nil - ), - DefNode(71...97)( - :foo, - (79...82), - CallNode(75...78)(nil, nil, (75...78), nil, nil, nil, nil, 2, "obj"), - nil, - StatementsNode(85...97)( - [CallNode(85...97)( - nil, - nil, - (85...89), - nil, - ArgumentsNode(90...97)( - [StringNode(90...97)((90...91), (91...96), (96...97), "Hello")] - ), - nil, - nil, - 0, - "puts" - )] - ), - [], - (71...74), - (78...79), - nil, - nil, - (83...84), - nil - ), - DefNode(99...127)( - :foo, - (107...110), - CallNode(103...106)( - nil, - nil, - (103...106), - nil, - nil, - nil, - nil, - 2, - "obj" - ), - nil, - StatementsNode(115...127)( - [CallNode(115...127)( - nil, - nil, - (115...119), - nil, - ArgumentsNode(120...127)( - [StringNode(120...127)( - (120...121), - (121...126), - (126...127), - "Hello" - )] - ), - nil, - nil, - 0, - "puts" - )] - ), - [], - (99...102), - (106...107), - (110...111), - (111...112), - (113...114), - nil - ), - DefNode(129...152)( - :foo, - (137...140), - CallNode(133...136)( - nil, - nil, - (133...136), - nil, - nil, - nil, - nil, - 2, - "obj" - ), - ParametersNode(141...142)( - [RequiredParameterNode(141...142)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(146...152)( - [CallNode(146...152)( - nil, - nil, - (146...150), - nil, - ArgumentsNode(151...152)( - [LocalVariableReadNode(151...152)(:x, 0)] - ), - nil, - nil, - 0, - "puts" - )] - ), - [:x], - (129...132), - (136...137), - (140...141), - (142...143), - (144...145), - nil - ), - DefNode(154...214)( - :rescued, - (158...165), - nil, - ParametersNode(166...167)( - [RequiredParameterNode(166...167)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(171...214)( - [CallNode(171...214)( - nil, - nil, - (171...176), - nil, - ArgumentsNode(177...214)( - [RescueModifierNode(177...214)( - StringNode(177...191)( - (177...178), - (178...190), - (190...191), - "to be caught" - ), - (192...198), - InterpolatedStringNode(199...214)( - (199...200), - [StringNode(200...209)(nil, (200...209), nil, "instance "), - EmbeddedStatementsNode(209...213)( - (209...211), - StatementsNode(211...212)( - [LocalVariableReadNode(211...212)(:x, 0)] - ), - (212...213) - )], - (213...214) - ) - )] - ), - nil, - nil, - 0, - "raise" - )] - ), - [:x], - (154...157), - nil, - (165...166), - (167...168), - (169...170), - nil - ), - DefNode(216...278)( - :rescued, - (225...232), - SelfNode(220...224)(), - ParametersNode(233...234)( - [RequiredParameterNode(233...234)(:x)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(238...278)( - [CallNode(238...278)( - nil, - nil, - (238...243), - nil, - ArgumentsNode(244...278)( - [RescueModifierNode(244...278)( - StringNode(244...258)( - (244...245), - (245...257), - (257...258), - "to be caught" - ), - (259...265), - InterpolatedStringNode(266...278)( - (266...267), - [StringNode(267...273)(nil, (267...273), nil, "class "), - EmbeddedStatementsNode(273...277)( - (273...275), - StatementsNode(275...276)( - [LocalVariableReadNode(275...276)(:x, 0)] - ), - (276...277) - )], - (277...278) - ) - )] - ), - nil, - nil, - 0, - "raise" - )] - ), - [:x], - (216...219), - (224...225), - (232...233), - (234...235), - (236...237), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt b/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt deleted file mode 100644 index c60263dc9afbbb..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - ParametersNode(8...11)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(8...11)(), - nil - ), - StatementsNode(15...23)( - [CallNode(15...23)( - nil, - nil, - (15...18), - (18...19), - ArgumentsNode(19...22)([ForwardingArgumentsNode(19...22)()]), - (22...23), - nil, - 0, - "bar" - )] - ), - [:"..."], - (0...3), - nil, - (7...8), - (11...12), - (13...14), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt b/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt deleted file mode 100644 index 3f77cf8c238a3b..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...47)( - [], - StatementsNode(0...47)( - [DefNode(0...20)( - :m, - (4...5), - nil, - nil, - StatementsNode(10...20)( - [RescueModifierNode(10...20)( - IntegerNode(10...11)(), - (12...18), - IntegerNode(19...20)() - )] - ), - [], - (0...3), - nil, - (5...6), - (6...7), - (8...9), - nil - ), - DefNode(22...47)( - :m, - (31...32), - SelfNode(26...30)(), - nil, - StatementsNode(37...47)( - [RescueModifierNode(37...47)( - IntegerNode(37...38)(), - (39...45), - IntegerNode(46...47)() - )] - ), - [], - (22...25), - (30...31), - (32...33), - (33...34), - (35...36), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/endless_method_without_args.txt b/test/yarp/snapshots/whitequark/endless_method_without_args.txt deleted file mode 100644 index 7287c14cd8564a..00000000000000 --- a/test/yarp/snapshots/whitequark/endless_method_without_args.txt +++ /dev/null @@ -1,73 +0,0 @@ -ProgramNode(0...86)( - [], - StatementsNode(0...86)( - [DefNode(0...12)( - :foo, - (4...7), - nil, - nil, - StatementsNode(10...12)([IntegerNode(10...12)()]), - [], - (0...3), - nil, - nil, - nil, - (8...9), - nil - ), - DefNode(14...37)( - :foo, - (18...21), - nil, - nil, - StatementsNode(24...37)( - [RescueModifierNode(24...37)( - IntegerNode(24...26)(), - (27...33), - NilNode(34...37)() - )] - ), - [], - (14...17), - nil, - nil, - nil, - (22...23), - nil - ), - DefNode(39...56)( - :foo, - (48...51), - SelfNode(43...47)(), - nil, - StatementsNode(54...56)([IntegerNode(54...56)()]), - [], - (39...42), - (47...48), - nil, - nil, - (52...53), - nil - ), - DefNode(58...86)( - :foo, - (67...70), - SelfNode(62...66)(), - nil, - StatementsNode(73...86)( - [RescueModifierNode(73...86)( - IntegerNode(73...75)(), - (76...82), - NilNode(83...86)() - )] - ), - [], - (58...61), - (66...67), - nil, - nil, - (71...72), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ensure.txt b/test/yarp/snapshots/whitequark/ensure.txt deleted file mode 100644 index abc443a2bb2185..00000000000000 --- a/test/yarp/snapshots/whitequark/ensure.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [BeginNode(0...29)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - nil, - nil, - EnsureNode(13...29)( - (13...19), - StatementsNode(21...24)( - [CallNode(21...24)( - nil, - nil, - (21...24), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (26...29) - ), - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ensure_empty.txt b/test/yarp/snapshots/whitequark/ensure_empty.txt deleted file mode 100644 index 39ac8bfea17660..00000000000000 --- a/test/yarp/snapshots/whitequark/ensure_empty.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [BeginNode(0...16)( - (0...5), - nil, - nil, - nil, - EnsureNode(6...16)((6...12), nil, (13...16)), - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/false.txt b/test/yarp/snapshots/whitequark/false.txt deleted file mode 100644 index b435f45a625fea..00000000000000 --- a/test/yarp/snapshots/whitequark/false.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...5)([], StatementsNode(0...5)([FalseNode(0...5)()])) diff --git a/test/yarp/snapshots/whitequark/float.txt b/test/yarp/snapshots/whitequark/float.txt deleted file mode 100644 index dfeeb286974b4f..00000000000000 --- a/test/yarp/snapshots/whitequark/float.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)([FloatNode(0...5)(), FloatNode(7...11)()]) -) diff --git a/test/yarp/snapshots/whitequark/for.txt b/test/yarp/snapshots/whitequark/for.txt deleted file mode 100644 index 67c75dcc928b5f..00000000000000 --- a/test/yarp/snapshots/whitequark/for.txt +++ /dev/null @@ -1,55 +0,0 @@ -ProgramNode(0...48)( - [:a], - StatementsNode(0...48)( - [ForNode(0...24)( - MultiTargetNode(4...5)( - [LocalVariableTargetNode(4...5)(:a, 0)], - nil, - nil - ), - CallNode(9...12)(nil, nil, (9...12), nil, nil, nil, nil, 2, "foo"), - StatementsNode(16...19)( - [CallNode(16...19)( - nil, - nil, - (16...17), - nil, - ArgumentsNode(18...19)([LocalVariableReadNode(18...19)(:a, 0)]), - nil, - nil, - 0, - "p" - )] - ), - (0...3), - (6...8), - (13...15), - (21...24) - ), - ForNode(26...48)( - MultiTargetNode(30...31)( - [LocalVariableTargetNode(30...31)(:a, 0)], - nil, - nil - ), - CallNode(35...38)(nil, nil, (35...38), nil, nil, nil, nil, 2, "foo"), - StatementsNode(40...43)( - [CallNode(40...43)( - nil, - nil, - (40...41), - nil, - ArgumentsNode(42...43)([LocalVariableReadNode(42...43)(:a, 0)]), - nil, - nil, - 0, - "p" - )] - ), - (26...29), - (32...34), - nil, - (45...48) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/for_mlhs.txt b/test/yarp/snapshots/whitequark/for_mlhs.txt deleted file mode 100644 index 74b8f52e2c7e4a..00000000000000 --- a/test/yarp/snapshots/whitequark/for_mlhs.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...28)( - [:a, :b], - StatementsNode(0...28)( - [ForNode(0...28)( - MultiTargetNode(4...8)( - [LocalVariableTargetNode(4...5)(:a, 0), - LocalVariableTargetNode(7...8)(:b, 0)], - nil, - nil - ), - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "foo"), - StatementsNode(17...23)( - [CallNode(17...23)( - nil, - nil, - (17...18), - nil, - ArgumentsNode(19...23)( - [LocalVariableReadNode(19...20)(:a, 0), - LocalVariableReadNode(22...23)(:b, 0)] - ), - nil, - nil, - 0, - "p" - )] - ), - (0...3), - (9...11), - nil, - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forward_arg.txt b/test/yarp/snapshots/whitequark/forward_arg.txt deleted file mode 100644 index 896555a27e8979..00000000000000 --- a/test/yarp/snapshots/whitequark/forward_arg.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [DefNode(0...27)( - :foo, - (4...7), - nil, - ParametersNode(8...11)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(8...11)(), - nil - ), - StatementsNode(14...22)( - [CallNode(14...22)( - nil, - nil, - (14...17), - (17...18), - ArgumentsNode(18...21)([ForwardingArgumentsNode(18...21)()]), - (21...22), - nil, - 0, - "bar" - )] - ), - [:"..."], - (0...3), - nil, - (7...8), - (11...12), - nil, - (24...27) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt b/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt deleted file mode 100644 index e4ebb2d950c85b..00000000000000 --- a/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt +++ /dev/null @@ -1,348 +0,0 @@ -ProgramNode(0...292)( - [], - StatementsNode(0...292)( - [ParenthesesNode(0...28)( - StatementsNode(1...27)( - [DefNode(1...27)( - :foo, - (5...8), - nil, - ParametersNode(9...12)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(9...12)(), - nil - ), - StatementsNode(15...23)( - [CallNode(15...23)( - nil, - nil, - (15...18), - (18...19), - ArgumentsNode(19...22)([ForwardingArgumentsNode(19...22)()]), - (22...23), - nil, - 0, - "bar" - )] - ), - [:"..."], - (1...4), - nil, - nil, - nil, - nil, - (24...27) - )] - ), - (0...1), - (27...28) - ), - ParenthesesNode(30...58)( - StatementsNode(31...57)( - [DefNode(31...57)( - :foo, - (35...38), - nil, - ParametersNode(39...42)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(39...42)(), - nil - ), - StatementsNode(44...52)( - [CallNode(44...52)( - nil, - nil, - (44...47), - (47...48), - ArgumentsNode(48...51)([ForwardingArgumentsNode(48...51)()]), - (51...52), - nil, - 0, - "bar" - )] - ), - [:"..."], - (31...34), - nil, - nil, - nil, - nil, - (54...57) - )] - ), - (30...31), - (57...58) - ), - DefNode(60...75)( - :foo, - (64...67), - nil, - ParametersNode(68...71)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(68...71)(), - nil - ), - nil, - [:"..."], - (60...63), - nil, - nil, - nil, - nil, - (72...75) - ), - DefNode(77...103)( - :foo, - (81...84), - nil, - ParametersNode(85...88)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(85...88)(), - nil - ), - StatementsNode(90...98)( - [CallNode(90...98)( - nil, - nil, - (90...93), - (93...94), - ArgumentsNode(94...97)([ForwardingArgumentsNode(94...97)()]), - (97...98), - nil, - 0, - "bar" - )] - ), - [:"..."], - (77...80), - nil, - nil, - nil, - nil, - (100...103) - ), - DefNode(105...134)( - :foo, - (109...112), - nil, - ParametersNode(113...119)( - [RequiredParameterNode(113...114)(:a)], - [], - [], - nil, - [], - ForwardingParameterNode(116...119)(), - nil - ), - StatementsNode(122...130)( - [CallNode(122...130)( - nil, - nil, - (122...125), - (125...126), - ArgumentsNode(126...129)([ForwardingArgumentsNode(126...129)()]), - (129...130), - nil, - 0, - "bar" - )] - ), - [:a, :"..."], - (105...108), - nil, - nil, - nil, - nil, - (131...134) - ), - DefNode(136...165)( - :foo, - (140...143), - nil, - ParametersNode(144...150)( - [RequiredParameterNode(144...145)(:a)], - [], - [], - nil, - [], - ForwardingParameterNode(147...150)(), - nil - ), - StatementsNode(152...160)( - [CallNode(152...160)( - nil, - nil, - (152...155), - (155...156), - ArgumentsNode(156...159)([ForwardingArgumentsNode(156...159)()]), - (159...160), - nil, - 0, - "bar" - )] - ), - [:a, :"..."], - (136...139), - nil, - nil, - nil, - nil, - (162...165) - ), - DefNode(167...192)( - :foo, - (171...174), - nil, - ParametersNode(175...188)( - [RequiredParameterNode(175...176)(:a)], - [OptionalParameterNode(178...183)( - :b, - (178...179), - (180...181), - IntegerNode(182...183)() - )], - [], - nil, - [], - ForwardingParameterNode(185...188)(), - nil - ), - nil, - [:a, :b, :"..."], - (167...170), - nil, - nil, - nil, - nil, - (189...192) - ), - DefNode(194...227)( - :foo, - (198...201), - nil, - ParametersNode(202...212)( - [], - [OptionalParameterNode(202...207)( - :b, - (202...203), - (204...205), - IntegerNode(206...207)() - )], - [], - nil, - [], - ForwardingParameterNode(209...212)(), - nil - ), - StatementsNode(215...223)( - [CallNode(215...223)( - nil, - nil, - (215...218), - (218...219), - ArgumentsNode(219...222)([ForwardingArgumentsNode(219...222)()]), - (222...223), - nil, - 0, - "bar" - )] - ), - [:b, :"..."], - (194...197), - nil, - nil, - nil, - nil, - (224...227) - ), - DefNode(229...262)( - :foo, - (233...236), - nil, - ParametersNode(237...247)( - [], - [OptionalParameterNode(237...242)( - :b, - (237...238), - (239...240), - IntegerNode(241...242)() - )], - [], - nil, - [], - ForwardingParameterNode(244...247)(), - nil - ), - StatementsNode(249...257)( - [CallNode(249...257)( - nil, - nil, - (249...252), - (252...253), - ArgumentsNode(253...256)([ForwardingArgumentsNode(253...256)()]), - (256...257), - nil, - 0, - "bar" - )] - ), - [:b, :"..."], - (229...232), - nil, - nil, - nil, - nil, - (259...262) - ), - DefNode(264...292)( - :foo, - (268...271), - nil, - ParametersNode(272...278)( - [RequiredParameterNode(272...273)(:a)], - [], - [], - nil, - [], - ForwardingParameterNode(275...278)(), - nil - ), - StatementsNode(280...288)( - [CallNode(280...288)( - nil, - nil, - (280...283), - (283...284), - ArgumentsNode(284...287)([ForwardingArgumentsNode(284...287)()]), - (287...288), - nil, - 0, - "bar" - )] - ), - [:a, :"..."], - (264...267), - nil, - (271...272), - (278...279), - nil, - (289...292) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forward_args_legacy.txt b/test/yarp/snapshots/whitequark/forward_args_legacy.txt deleted file mode 100644 index 39b5cdbbaf87c4..00000000000000 --- a/test/yarp/snapshots/whitequark/forward_args_legacy.txt +++ /dev/null @@ -1,91 +0,0 @@ -ProgramNode(0...77)( - [], - StatementsNode(0...77)( - [DefNode(0...27)( - :foo, - (4...7), - nil, - ParametersNode(8...11)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(8...11)(), - nil - ), - StatementsNode(14...22)( - [CallNode(14...22)( - nil, - nil, - (14...17), - (17...18), - ArgumentsNode(18...21)([ForwardingArgumentsNode(18...21)()]), - (21...22), - nil, - 0, - "bar" - )] - ), - [:"..."], - (0...3), - nil, - (7...8), - (11...12), - nil, - (24...27) - ), - DefNode(29...46)( - :foo, - (33...36), - nil, - ParametersNode(37...40)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(37...40)(), - nil - ), - nil, - [:"..."], - (29...32), - nil, - (36...37), - (40...41), - nil, - (43...46) - ), - DefNode(48...77)( - :foo, - (52...55), - nil, - ParametersNode(56...59)( - [], - [], - [], - nil, - [], - ForwardingParameterNode(56...59)(), - nil - ), - StatementsNode(62...72)( - [SuperNode(62...72)( - (62...67), - (67...68), - ArgumentsNode(68...71)([ForwardingArgumentsNode(68...71)()]), - (71...72), - nil - )] - ), - [:"..."], - (48...51), - nil, - (55...56), - (59...60), - nil, - (74...77) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt deleted file mode 100644 index 9008112a49ff2f..00000000000000 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...45)( - [], - StatementsNode(0...45)( - [DefNode(0...45)( - :foo, - (4...7), - nil, - ParametersNode(8...20)( - [RequiredParameterNode(8...16)(:argument)], - [], - [], - nil, - [], - KeywordRestParameterNode(18...20)(nil, nil, (18...20)), - nil - ), - StatementsNode(23...40)( - [CallNode(23...40)( - nil, - nil, - (23...26), - (26...27), - ArgumentsNode(27...39)( - [LocalVariableReadNode(27...35)(:argument, 0), - KeywordHashNode(37...39)( - [AssocSplatNode(37...39)(nil, (37...39))] - )] - ), - (39...40), - nil, - 0, - "bar" - )] - ), - [:argument, :**], - (0...3), - nil, - (7...8), - (20...21), - nil, - (42...45) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt deleted file mode 100644 index 842def39c5cca8..00000000000000 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [DefNode(0...43)( - :foo, - (4...7), - nil, - ParametersNode(8...19)( - [RequiredParameterNode(8...16)(:argument)], - [], - [], - RestParameterNode(18...19)(nil, nil, (18...19)), - [], - nil, - nil - ), - StatementsNode(22...38)( - [CallNode(22...38)( - nil, - nil, - (22...25), - (25...26), - ArgumentsNode(26...37)( - [LocalVariableReadNode(26...34)(:argument, 0), - SplatNode(36...37)((36...37), nil)] - ), - (37...38), - nil, - 0, - "bar" - )] - ), - [:argument, :*], - (0...3), - nil, - (7...8), - (19...20), - nil, - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt deleted file mode 100644 index 264c73a6c32020..00000000000000 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [DefNode(0...25)( - :foo, - (4...7), - nil, - ParametersNode(8...10)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(8...10)(nil, nil, (8...10)), - nil - ), - StatementsNode(13...20)( - [CallNode(13...20)( - nil, - nil, - (13...16), - (16...17), - ArgumentsNode(17...19)( - [KeywordHashNode(17...19)( - [AssocSplatNode(17...19)(nil, (17...19))] - )] - ), - (19...20), - nil, - 0, - "bar" - )] - ), - [:**], - (0...3), - nil, - (7...8), - (10...11), - nil, - (22...25) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt deleted file mode 100644 index aa815fce8e35b0..00000000000000 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt +++ /dev/null @@ -1,48 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [DefNode(0...41)( - :foo, - (4...7), - nil, - ParametersNode(8...10)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(8...10)(nil, nil, (8...10)), - nil - ), - StatementsNode(13...36)( - [CallNode(13...36)( - nil, - nil, - (13...16), - (16...17), - ArgumentsNode(17...35)( - [KeywordHashNode(17...35)( - [AssocSplatNode(17...19)(nil, (17...19)), - AssocNode(21...35)( - SymbolNode(21...30)(nil, (21...29), (29...30), "from_foo"), - TrueNode(31...35)(), - nil - )] - )] - ), - (35...36), - nil, - 0, - "bar" - )] - ), - [:**], - (0...3), - nil, - (7...8), - (10...11), - nil, - (38...41) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/forwarded_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_restarg.txt deleted file mode 100644 index 40384fce94e885..00000000000000 --- a/test/yarp/snapshots/whitequark/forwarded_restarg.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [DefNode(0...23)( - :foo, - (4...7), - nil, - ParametersNode(8...9)( - [], - [], - [], - RestParameterNode(8...9)(nil, nil, (8...9)), - [], - nil, - nil - ), - StatementsNode(12...18)( - [CallNode(12...18)( - nil, - nil, - (12...15), - (15...16), - ArgumentsNode(16...17)([SplatNode(16...17)((16...17), nil)]), - (17...18), - nil, - 0, - "bar" - )] - ), - [:*], - (0...3), - nil, - (7...8), - (9...10), - nil, - (20...23) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/gvar.txt b/test/yarp/snapshots/whitequark/gvar.txt deleted file mode 100644 index dbc16e65d8409f..00000000000000 --- a/test/yarp/snapshots/whitequark/gvar.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([GlobalVariableReadNode(0...4)(:$foo)]) -) diff --git a/test/yarp/snapshots/whitequark/gvasgn.txt b/test/yarp/snapshots/whitequark/gvasgn.txt deleted file mode 100644 index b416ac55abb545..00000000000000 --- a/test/yarp/snapshots/whitequark/gvasgn.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [GlobalVariableWriteNode(0...9)( - :$var, - (0...4), - IntegerNode(7...9)(), - (5...6) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/hash_empty.txt b/test/yarp/snapshots/whitequark/hash_empty.txt deleted file mode 100644 index b06b9d299bdf09..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_empty.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)([HashNode(0...3)((0...1), [], (2...3))]) -) diff --git a/test/yarp/snapshots/whitequark/hash_hashrocket.txt b/test/yarp/snapshots/whitequark/hash_hashrocket.txt deleted file mode 100644 index 9b96268c015f94..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_hashrocket.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [HashNode(0...10)( - (0...1), - [AssocNode(2...8)(IntegerNode(2...3)(), IntegerNode(7...8)(), (4...6))], - (9...10) - ), - HashNode(12...37)( - (12...13), - [AssocNode(14...20)( - IntegerNode(14...15)(), - IntegerNode(19...20)(), - (16...18) - ), - AssocNode(22...35)( - SymbolNode(22...26)((22...23), (23...26), nil, "foo"), - StringNode(30...35)((30...31), (31...34), (34...35), "bar"), - (27...29) - )], - (36...37) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/hash_kwsplat.txt b/test/yarp/snapshots/whitequark/hash_kwsplat.txt deleted file mode 100644 index bb56b81800b047..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_kwsplat.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [HashNode(0...17)( - (0...1), - [AssocNode(2...8)( - SymbolNode(2...6)(nil, (2...5), (5...6), "foo"), - IntegerNode(7...8)(), - nil - ), - AssocSplatNode(10...15)( - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "bar"), - (10...12) - )], - (16...17) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/hash_label.txt b/test/yarp/snapshots/whitequark/hash_label.txt deleted file mode 100644 index cfebb4b70c04a9..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_label.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [HashNode(0...10)( - (0...1), - [AssocNode(2...8)( - SymbolNode(2...6)(nil, (2...5), (5...6), "foo"), - IntegerNode(7...8)(), - nil - )], - (9...10) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/hash_label_end.txt b/test/yarp/snapshots/whitequark/hash_label_end.txt deleted file mode 100644 index b5d4273d5ba625..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_label_end.txt +++ /dev/null @@ -1,53 +0,0 @@ -ProgramNode(0...50)( - [], - StatementsNode(0...50)( - [CallNode(0...12)( - nil, - nil, - (0...1), - (1...2), - ArgumentsNode(2...11)( - [IfNode(2...11)( - nil, - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a"), - StatementsNode(6...9)( - [StringNode(6...9)((6...7), (7...8), (8...9), "a")] - ), - ElseNode(9...11)( - (9...10), - StatementsNode(10...11)([IntegerNode(10...11)()]), - nil - ), - nil - )] - ), - (11...12), - nil, - 0, - "f" - ), - HashNode(14...26)( - (14...15), - [AssocNode(16...24)( - SymbolNode(16...22)((16...17), (17...20), (20...22), "foo"), - IntegerNode(23...24)(), - nil - )], - (25...26) - ), - HashNode(28...50)( - (28...29), - [AssocNode(30...38)( - SymbolNode(30...36)((30...31), (31...34), (34...36), "foo"), - IntegerNode(37...38)(), - nil - ), - AssocNode(40...49)( - SymbolNode(40...46)((40...41), (41...44), (44...46), "bar"), - HashNode(47...49)((47...48), [], (48...49)), - nil - )], - (49...50) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/hash_pair_value_omission.txt b/test/yarp/snapshots/whitequark/hash_pair_value_omission.txt deleted file mode 100644 index 825fe1beaabc61..00000000000000 --- a/test/yarp/snapshots/whitequark/hash_pair_value_omission.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [HashNode(0...6)( - (0...1), - [AssocNode(1...5)( - SymbolNode(1...5)(nil, (1...4), (4...5), "BAR"), - nil, - nil - )], - (5...6) - ), - HashNode(8...16)( - (8...9), - [AssocNode(9...11)( - SymbolNode(9...11)(nil, (9...10), (10...11), "a"), - nil, - nil - ), - AssocNode(13...15)( - SymbolNode(13...15)(nil, (13...14), (14...15), "b"), - nil, - nil - )], - (15...16) - ), - HashNode(18...25)( - (18...19), - [AssocNode(19...24)( - SymbolNode(19...24)(nil, (19...23), (23...24), "puts"), - nil, - nil - )], - (24...25) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/heredoc.txt b/test/yarp/snapshots/whitequark/heredoc.txt deleted file mode 100644 index c61829ebd4eca1..00000000000000 --- a/test/yarp/snapshots/whitequark/heredoc.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...52)( - [], - StatementsNode(0...52)( - [InterpolatedStringNode(0...8)( - (0...8), - [StringNode(9...17)(nil, (9...17), nil, "foo\n" + "bar\n")], - (17...22) - ), - InterpolatedStringNode(23...29)( - (23...29), - [StringNode(30...38)(nil, (30...38), nil, "foo\n" + "bar\n")], - (38...43) - ), - InterpolatedXStringNode(44...52)( - (44...52), - [StringNode(53...61)(nil, (53...61), nil, "foo\n" + "bar\n")], - (61...66) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if.txt b/test/yarp/snapshots/whitequark/if.txt deleted file mode 100644 index 069eb07f25344a..00000000000000 --- a/test/yarp/snapshots/whitequark/if.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [IfNode(0...20)( - (0...2), - CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "foo"), - StatementsNode(12...15)( - [CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (17...20) - ), - IfNode(22...38)( - (22...24), - CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 2, "foo"), - StatementsNode(30...33)( - [CallNode(30...33)(nil, nil, (30...33), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (35...38) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_else.txt b/test/yarp/snapshots/whitequark/if_else.txt deleted file mode 100644 index d8799a330c5284..00000000000000 --- a/test/yarp/snapshots/whitequark/if_else.txt +++ /dev/null @@ -1,55 +0,0 @@ -ProgramNode(0...58)( - [], - StatementsNode(0...58)( - [IfNode(0...30)( - (0...2), - CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "foo"), - StatementsNode(12...15)( - [CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "bar")] - ), - ElseNode(17...30)( - (17...21), - StatementsNode(22...25)( - [CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (27...30) - ), - (27...30) - ), - IfNode(32...58)( - (32...34), - CallNode(35...38)(nil, nil, (35...38), nil, nil, nil, nil, 2, "foo"), - StatementsNode(40...43)( - [CallNode(40...43)(nil, nil, (40...43), nil, nil, nil, nil, 2, "bar")] - ), - ElseNode(45...58)( - (45...49), - StatementsNode(50...53)( - [CallNode(50...53)( - nil, - nil, - (50...53), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (55...58) - ), - (55...58) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_elsif.txt b/test/yarp/snapshots/whitequark/if_elsif.txt deleted file mode 100644 index 953d565bf62898..00000000000000 --- a/test/yarp/snapshots/whitequark/if_elsif.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...38)( - [], - StatementsNode(0...38)( - [IfNode(0...38)( - (0...2), - CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "foo"), - StatementsNode(8...11)( - [CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 2, "bar")] - ), - IfNode(13...38)( - (13...18), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "baz"), - StatementsNode(24...25)([IntegerNode(24...25)()]), - ElseNode(27...38)( - (27...31), - StatementsNode(32...33)([IntegerNode(32...33)()]), - (35...38) - ), - (35...38) - ), - (35...38) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_masgn__24.txt b/test/yarp/snapshots/whitequark/if_masgn__24.txt deleted file mode 100644 index 1bdfd7bff69715..00000000000000 --- a/test/yarp/snapshots/whitequark/if_masgn__24.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...20)( - [:a, :b], - StatementsNode(0...20)( - [IfNode(0...20)( - (0...2), - ParenthesesNode(3...15)( - StatementsNode(4...14)( - [MultiWriteNode(4...14)( - [LocalVariableTargetNode(4...5)(:a, 0), - LocalVariableTargetNode(7...8)(:b, 0)], - nil, - nil, - (9...10), - CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )] - ), - (3...4), - (14...15) - ), - nil, - nil, - (17...20) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_mod.txt b/test/yarp/snapshots/whitequark/if_mod.txt deleted file mode 100644 index 9a6575b5d1d9b2..00000000000000 --- a/test/yarp/snapshots/whitequark/if_mod.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [IfNode(0...10)( - (4...6), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...3)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_nl_then.txt b/test/yarp/snapshots/whitequark/if_nl_then.txt deleted file mode 100644 index db1b5231ef21fc..00000000000000 --- a/test/yarp/snapshots/whitequark/if_nl_then.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [IfNode(0...19)( - (0...2), - CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "foo"), - StatementsNode(12...15)( - [CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (16...19) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt b/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt deleted file mode 100644 index f2ba2a124538bc..00000000000000 --- a/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt +++ /dev/null @@ -1,93 +0,0 @@ -ProgramNode(0...178)( - [], - StatementsNode(0...178)( - [ClassNode(0...38)( - [], - (0...5), - ConstantPathNode(6...33)( - IfNode(6...25)( - (6...8), - TrueNode(9...13)(), - StatementsNode(15...21)([ConstantReadNode(15...21)(:Object)]), - nil, - (22...25) - ), - ConstantReadNode(27...33)(:Kernel), - (25...27) - ), - nil, - nil, - nil, - (35...38), - :Kernel - ), - ClassNode(40...87)( - [], - (40...45), - ConstantPathNode(46...82)( - WhileNode(46...74)( - (46...51), - (71...74), - TrueNode(52...56)(), - StatementsNode(58...70)( - [BreakNode(58...70)( - ArgumentsNode(64...70)([ConstantReadNode(64...70)(:Object)]), - (58...63) - )] - ), - 0 - ), - ConstantReadNode(76...82)(:Kernel), - (74...76) - ), - nil, - nil, - nil, - (84...87), - :Kernel - ), - ModuleNode(89...128)( - [], - (89...95), - ConstantPathNode(96...123)( - IfNode(96...115)( - (96...98), - TrueNode(99...103)(), - StatementsNode(105...111)([ConstantReadNode(105...111)(:Object)]), - nil, - (112...115) - ), - ConstantReadNode(117...123)(:Kernel), - (115...117) - ), - nil, - (125...128), - :Kernel - ), - ModuleNode(130...178)( - [], - (130...136), - ConstantPathNode(137...173)( - WhileNode(137...165)( - (137...142), - (162...165), - TrueNode(143...147)(), - StatementsNode(149...161)( - [BreakNode(149...161)( - ArgumentsNode(155...161)( - [ConstantReadNode(155...161)(:Object)] - ), - (149...154) - )] - ), - 0 - ), - ConstantReadNode(167...173)(:Kernel), - (165...167) - ), - nil, - (175...178), - :Kernel - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/int.txt b/test/yarp/snapshots/whitequark/int.txt deleted file mode 100644 index a99820ad33b395..00000000000000 --- a/test/yarp/snapshots/whitequark/int.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [IntegerNode(0...3)(), IntegerNode(5...8)(), IntegerNode(10...12)()] - ) -) diff --git a/test/yarp/snapshots/whitequark/int___LINE__.txt b/test/yarp/snapshots/whitequark/int___LINE__.txt deleted file mode 100644 index 0f6e7aa884b629..00000000000000 --- a/test/yarp/snapshots/whitequark/int___LINE__.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...8)([], StatementsNode(0...8)([SourceLineNode(0...8)()])) diff --git a/test/yarp/snapshots/whitequark/interp_digit_var.txt b/test/yarp/snapshots/whitequark/interp_digit_var.txt deleted file mode 100644 index 48d7ac96716907..00000000000000 --- a/test/yarp/snapshots/whitequark/interp_digit_var.txt +++ /dev/null @@ -1,123 +0,0 @@ -ProgramNode(1...465)( - [], - StatementsNode(1...465)( - [StringNode(1...6)((1...2), (2...5), (5...6), "\#@1"), - StringNode(10...16)((10...11), (11...15), (15...16), "\#@@1"), - ArrayNode(20...27)( - [SymbolNode(23...26)(nil, (23...26), nil, "\#@1")], - (20...23), - (26...27) - ), - ArrayNode(31...39)( - [SymbolNode(34...38)(nil, (34...38), nil, "\#@@1")], - (31...34), - (38...39) - ), - StringNode(43...50)((43...46), (46...49), (49...50), "\#@1"), - StringNode(54...62)((54...57), (57...61), (61...62), "\#@@1"), - ArrayNode(66...73)( - [StringNode(69...72)(nil, (69...72), nil, "\#@1")], - (66...69), - (72...73) - ), - ArrayNode(77...85)( - [StringNode(80...84)(nil, (80...84), nil, "\#@@1")], - (77...80), - (84...85) - ), - ArrayNode(89...98)( - [SymbolNode(93...96)(nil, (93...96), nil, "\#@1")], - (89...92), - (97...98) - ), - ArrayNode(102...112)( - [SymbolNode(106...110)(nil, (106...110), nil, "\#@@1")], - (102...105), - (111...112) - ), - StringNode(116...123)((116...119), (119...122), (122...123), "\#@1"), - StringNode(127...135)((127...130), (130...134), (134...135), "\#@@1"), - RegularExpressionNode(139...146)( - (139...142), - (142...145), - (145...146), - "\#@1", - 0 - ), - RegularExpressionNode(150...158)( - (150...153), - (153...157), - (157...158), - "\#@@1", - 0 - ), - SymbolNode(162...169)((162...165), (165...168), (168...169), "\#@1"), - SymbolNode(173...181)((173...176), (176...180), (180...181), "\#@@1"), - ArrayNode(185...194)( - [StringNode(189...192)(nil, (189...192), nil, "\#@1")], - (185...188), - (193...194) - ), - ArrayNode(198...208)( - [StringNode(202...206)(nil, (202...206), nil, "\#@@1")], - (198...201), - (207...208) - ), - XStringNode(212...219)((212...215), (215...218), (218...219), "\#@1"), - XStringNode(223...231)((223...226), (226...230), (230...231), "\#@@1"), - StringNode(235...241)((235...237), (237...240), (240...241), "\#@1"), - StringNode(245...252)((245...247), (247...251), (251...252), "\#@@1"), - StringNode(256...261)((256...257), (257...260), (260...261), "\#@1"), - StringNode(265...271)((265...266), (266...270), (270...271), "\#@@1"), - RegularExpressionNode(275...280)( - (275...276), - (276...279), - (279...280), - "\#@1", - 0 - ), - RegularExpressionNode(284...290)( - (284...285), - (285...289), - (289...290), - "\#@@1", - 0 - ), - SymbolNode(294...300)((294...296), (296...299), (299...300), "\#@1"), - SymbolNode(304...311)((304...306), (306...310), (310...311), "\#@@1"), - SymbolNode(315...321)((315...317), (317...320), (320...321), "\#@1"), - SymbolNode(325...332)((325...327), (327...331), (331...332), "\#@@1"), - XStringNode(336...341)((336...337), (337...340), (340...341), "\#@1"), - XStringNode(345...351)((345...346), (346...350), (350...351), "\#@@1"), - InterpolatedStringNode(354...363)( - (354...363), - [StringNode(364...368)(nil, (364...368), nil, "\#@1\n")], - (368...373) - ), - InterpolatedStringNode(374...383)( - (374...383), - [StringNode(384...389)(nil, (384...389), nil, "\#@@1\n")], - (389...394) - ), - InterpolatedStringNode(395...404)( - (395...404), - [StringNode(405...409)(nil, (405...409), nil, "\#@1\n")], - (409...414) - ), - InterpolatedStringNode(415...424)( - (415...424), - [StringNode(425...430)(nil, (425...430), nil, "\#@@1\n")], - (430...435) - ), - InterpolatedXStringNode(436...445)( - (436...445), - [StringNode(446...450)(nil, (446...450), nil, "\#@1\n")], - (450...455) - ), - InterpolatedXStringNode(456...465)( - (456...465), - [StringNode(466...471)(nil, (466...471), nil, "\#@@1\n")], - (471...476) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ivar.txt b/test/yarp/snapshots/whitequark/ivar.txt deleted file mode 100644 index ae2c8c34b48306..00000000000000 --- a/test/yarp/snapshots/whitequark/ivar.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)([InstanceVariableReadNode(0...4)(:@foo)]) -) diff --git a/test/yarp/snapshots/whitequark/ivasgn.txt b/test/yarp/snapshots/whitequark/ivasgn.txt deleted file mode 100644 index 8e952de2465dd1..00000000000000 --- a/test/yarp/snapshots/whitequark/ivasgn.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [InstanceVariableWriteNode(0...9)( - :@var, - (0...4), - IntegerNode(7...9)(), - (5...6) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/keyword_argument_omission.txt b/test/yarp/snapshots/whitequark/keyword_argument_omission.txt deleted file mode 100644 index c1b3b8800dfac1..00000000000000 --- a/test/yarp/snapshots/whitequark/keyword_argument_omission.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - nil, - nil, - (0...3), - (3...4), - ArgumentsNode(4...10)( - [KeywordHashNode(4...10)( - [AssocNode(4...6)( - SymbolNode(4...6)(nil, (4...5), (5...6), "a"), - nil, - nil - ), - AssocNode(8...10)( - SymbolNode(8...10)(nil, (8...9), (9...10), "b"), - nil, - nil - )] - )] - ), - (10...11), - nil, - 0, - "foo" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwarg.txt b/test/yarp/snapshots/whitequark/kwarg.txt deleted file mode 100644 index b63c7ac9f53fba..00000000000000 --- a/test/yarp/snapshots/whitequark/kwarg.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [DefNode(0...16)( - :f, - (4...5), - nil, - ParametersNode(6...10)( - [], - [], - [], - nil, - [KeywordParameterNode(6...10)(:foo, (6...10), nil)], - nil, - nil - ), - nil, - [:foo], - (0...3), - nil, - (5...6), - (10...11), - nil, - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwbegin_compstmt.txt b/test/yarp/snapshots/whitequark/kwbegin_compstmt.txt deleted file mode 100644 index 0d05407aad98e4..00000000000000 --- a/test/yarp/snapshots/whitequark/kwbegin_compstmt.txt +++ /dev/null @@ -1,26 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [BeginNode(0...20)( - (0...5), - StatementsNode(6...16)( - [CallNode(6...10)(nil, nil, (6...10), nil, nil, nil, nil, 0, "foo!"), - CallNode(12...16)( - nil, - nil, - (12...16), - nil, - nil, - nil, - nil, - 0, - "bar!" - )] - ), - nil, - nil, - nil, - (17...20) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwnilarg.txt b/test/yarp/snapshots/whitequark/kwnilarg.txt deleted file mode 100644 index 402d0d3fb28028..00000000000000 --- a/test/yarp/snapshots/whitequark/kwnilarg.txt +++ /dev/null @@ -1,78 +0,0 @@ -ProgramNode(0...46)( - [], - StatementsNode(0...46)( - [LambdaNode(0...12)( - [], - (0...2), - (10...11), - (11...12), - BlockParametersNode(2...9)( - ParametersNode(3...8)( - [], - [], - [], - nil, - [], - NoKeywordsParameterNode(3...8)((3...5), (5...8)), - nil - ), - [], - (2...3), - (8...9) - ), - nil - ), - DefNode(14...31)( - :f, - (18...19), - nil, - ParametersNode(20...25)( - [], - [], - [], - nil, - [], - NoKeywordsParameterNode(20...25)((20...22), (22...25)), - nil - ), - nil, - [], - (14...17), - nil, - (19...20), - (25...26), - nil, - (28...31) - ), - CallNode(33...46)( - nil, - nil, - (33...34), - nil, - nil, - nil, - BlockNode(35...46)( - [], - BlockParametersNode(37...44)( - ParametersNode(38...43)( - [], - [], - [], - nil, - [], - NoKeywordsParameterNode(38...43)((38...40), (40...43)), - nil - ), - [], - (37...38), - (43...44) - ), - nil, - (35...36), - (45...46) - ), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwoptarg.txt b/test/yarp/snapshots/whitequark/kwoptarg.txt deleted file mode 100644 index 06ad7985233118..00000000000000 --- a/test/yarp/snapshots/whitequark/kwoptarg.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [DefNode(0...18)( - :f, - (4...5), - nil, - ParametersNode(6...12)( - [], - [], - [], - nil, - [KeywordParameterNode(6...12)( - :foo, - (6...10), - IntegerNode(11...12)() - )], - nil, - nil - ), - nil, - [:foo], - (0...3), - nil, - (5...6), - (12...13), - nil, - (15...18) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt deleted file mode 100644 index dfc20df0b4cf81..00000000000000 --- a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [DefNode(0...28)( - :f, - (4...5), - nil, - ParametersNode(6...16)( - [], - [], - [], - nil, - [KeywordParameterNode(6...12)(:a, (6...8), NilNode(9...12)())], - KeywordRestParameterNode(14...16)(nil, nil, (14...16)), - nil - ), - StatementsNode(19...24)( - [CallNode(19...24)( - nil, - nil, - (19...20), - (20...21), - ArgumentsNode(21...23)( - [KeywordHashNode(21...23)( - [AssocSplatNode(21...23)(nil, (21...23))] - )] - ), - (23...24), - nil, - 0, - "b" - )] - ), - [:a, :**], - (0...3), - nil, - (5...6), - (16...17), - nil, - (25...28) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwrestarg_named.txt b/test/yarp/snapshots/whitequark/kwrestarg_named.txt deleted file mode 100644 index cf0086619fe2bd..00000000000000 --- a/test/yarp/snapshots/whitequark/kwrestarg_named.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [DefNode(0...17)( - :f, - (4...5), - nil, - ParametersNode(6...11)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(6...11)(:foo, (8...11), (6...8)), - nil - ), - nil, - [:foo], - (0...3), - nil, - (5...6), - (11...12), - nil, - (14...17) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt b/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt deleted file mode 100644 index e59e72c3042ef1..00000000000000 --- a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [DefNode(0...14)( - :f, - (4...5), - nil, - ParametersNode(6...8)( - [], - [], - [], - nil, - [], - KeywordRestParameterNode(6...8)(nil, nil, (6...8)), - nil - ), - nil, - [:**], - (0...3), - nil, - (5...6), - (8...9), - nil, - (11...14) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/lbrace_arg_after_command_args.txt b/test/yarp/snapshots/whitequark/lbrace_arg_after_command_args.txt deleted file mode 100644 index 0b2c12417d8b9b..00000000000000 --- a/test/yarp/snapshots/whitequark/lbrace_arg_after_command_args.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [CallNode(0...22)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...8)( - [ParenthesesNode(4...8)( - StatementsNode(5...7)( - [SymbolNode(5...7)((5...6), (6...7), nil, "a")] - ), - (4...5), - (7...8) - )] - ), - nil, - BlockNode(9...22)( - [], - nil, - StatementsNode(11...20)( - [CallNode(11...20)( - nil, - nil, - (11...12), - nil, - nil, - nil, - BlockNode(13...20)([], nil, nil, (13...15), (17...20)), - 0, - "m" - )] - ), - (9...10), - (21...22) - ), - 0, - "let" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/lparenarg_after_lvar__since_25.txt b/test/yarp/snapshots/whitequark/lparenarg_after_lvar__since_25.txt deleted file mode 100644 index 027c04f09279cf..00000000000000 --- a/test/yarp/snapshots/whitequark/lparenarg_after_lvar__since_25.txt +++ /dev/null @@ -1,59 +0,0 @@ -ProgramNode(0...31)( - [], - StatementsNode(0...31)( - [CallNode(0...14)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...14)( - [CallNode(4...14)( - ParenthesesNode(4...10)( - StatementsNode(5...9)([FloatNode(5...9)()]), - (4...5), - (9...10) - ), - (10...11), - (11...14), - nil, - nil, - nil, - nil, - 0, - "abs" - )] - ), - nil, - nil, - 0, - "foo" - ), - CallNode(16...31)( - nil, - nil, - (16...20), - nil, - ArgumentsNode(21...31)( - [CallNode(21...31)( - ParenthesesNode(21...27)( - StatementsNode(22...26)([FloatNode(22...26)()]), - (21...22), - (26...27) - ), - (27...28), - (28...31), - nil, - nil, - nil, - nil, - 0, - "abs" - )] - ), - nil, - nil, - 0, - "meth" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/lvar.txt b/test/yarp/snapshots/whitequark/lvar.txt deleted file mode 100644 index 24f27ad073dbab..00000000000000 --- a/test/yarp/snapshots/whitequark/lvar.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo")] - ) -) diff --git a/test/yarp/snapshots/whitequark/lvar_injecting_match.txt b/test/yarp/snapshots/whitequark/lvar_injecting_match.txt deleted file mode 100644 index 924b997bc7ebdc..00000000000000 --- a/test/yarp/snapshots/whitequark/lvar_injecting_match.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...31)( - [:match], - StatementsNode(0...31)( - [CallNode(0...24)( - RegularExpressionNode(0...15)( - (0...1), - (1...14), - (14...15), - "(?bar)", - 0 - ), - nil, - (16...18), - nil, - ArgumentsNode(19...24)( - [StringNode(19...24)((19...20), (20...23), (23...24), "bar")] - ), - nil, - nil, - 0, - "=~" - ), - LocalVariableReadNode(26...31)(:match, 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/lvasgn.txt b/test/yarp/snapshots/whitequark/lvasgn.txt deleted file mode 100644 index bb762001ba0d17..00000000000000 --- a/test/yarp/snapshots/whitequark/lvasgn.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...13)( - [:var], - StatementsNode(0...13)( - [LocalVariableWriteNode(0...8)( - :var, - 0, - (0...3), - IntegerNode(6...8)(), - (4...5) - ), - LocalVariableReadNode(10...13)(:var, 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn.txt b/test/yarp/snapshots/whitequark/masgn.txt deleted file mode 100644 index 419d68ee7b4c69..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...56)( - [:foo, :bar, :baz], - StatementsNode(0...56)( - [MultiWriteNode(0...17)( - [LocalVariableTargetNode(1...4)(:foo, 0), - LocalVariableTargetNode(6...9)(:bar, 0)], - (0...1), - (9...10), - (11...12), - ArrayNode(13...17)( - [IntegerNode(13...14)(), IntegerNode(16...17)()], - nil, - nil - ) - ), - MultiWriteNode(19...34)( - [LocalVariableTargetNode(19...22)(:foo, 0), - LocalVariableTargetNode(24...27)(:bar, 0)], - nil, - nil, - (28...29), - ArrayNode(30...34)( - [IntegerNode(30...31)(), IntegerNode(33...34)()], - nil, - nil - ) - ), - MultiWriteNode(36...56)( - [LocalVariableTargetNode(36...39)(:foo, 0), - LocalVariableTargetNode(41...44)(:bar, 0), - LocalVariableTargetNode(46...49)(:baz, 0)], - nil, - nil, - (50...51), - ArrayNode(52...56)( - [IntegerNode(52...53)(), IntegerNode(55...56)()], - nil, - nil - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn_attr.txt b/test/yarp/snapshots/whitequark/masgn_attr.txt deleted file mode 100644 index 5ad893c96dd0cb..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn_attr.txt +++ /dev/null @@ -1,71 +0,0 @@ -ProgramNode(0...63)( - [:foo], - StatementsNode(0...63)( - [MultiWriteNode(0...17)( - [CallNode(0...6)( - SelfNode(0...4)(), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "A=" - ), - LocalVariableTargetNode(8...11)(:foo, 0)], - nil, - nil, - (12...13), - LocalVariableReadNode(14...17)(:foo, 0) - ), - MultiWriteNode(19...43)( - [CallNode(19...25)( - SelfNode(19...23)(), - (23...24), - (24...25), - nil, - nil, - nil, - nil, - 0, - "a=" - ), - CallNode(27...37)( - SelfNode(27...31)(), - nil, - (31...37), - (31...32), - ArgumentsNode(32...36)( - [IntegerNode(32...33)(), IntegerNode(35...36)()] - ), - (36...37), - nil, - 0, - "[]=" - )], - nil, - nil, - (38...39), - LocalVariableReadNode(40...43)(:foo, 0) - ), - MultiWriteNode(45...63)( - [CallNode(45...52)( - SelfNode(45...49)(), - (49...51), - (51...52), - nil, - nil, - nil, - nil, - 0, - "a=" - ), - LocalVariableTargetNode(54...57)(:foo, 0)], - nil, - nil, - (58...59), - LocalVariableReadNode(60...63)(:foo, 0) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn_cmd.txt b/test/yarp/snapshots/whitequark/masgn_cmd.txt deleted file mode 100644 index 5b9b9b03cec9d9..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn_cmd.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...16)( - [:foo, :bar], - StatementsNode(0...16)( - [MultiWriteNode(0...16)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], - nil, - nil, - (9...10), - CallNode(11...16)( - nil, - nil, - (11...12), - nil, - ArgumentsNode(13...16)([LocalVariableReadNode(13...16)(:foo, 0)]), - nil, - nil, - 0, - "m" - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn_const.txt b/test/yarp/snapshots/whitequark/masgn_const.txt deleted file mode 100644 index 85155526189cf6..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn_const.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...34)( - [:foo], - StatementsNode(0...34)( - [MultiWriteNode(0...14)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - LocalVariableTargetNode(5...8)(:foo, 0)], - nil, - nil, - (9...10), - LocalVariableReadNode(11...14)(:foo, 0) - ), - MultiWriteNode(16...34)( - [ConstantPathTargetNode(16...23)( - SelfNode(16...20)(), - ConstantReadNode(22...23)(:A), - (20...22) - ), - LocalVariableTargetNode(25...28)(:foo, 0)], - nil, - nil, - (29...30), - LocalVariableReadNode(31...34)(:foo, 0) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn_nested.txt b/test/yarp/snapshots/whitequark/masgn_nested.txt deleted file mode 100644 index 00f4eb1ef40745..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn_nested.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(1...30)( - [:b, :a, :c], - StatementsNode(1...30)( - [MultiWriteNode(1...13)( - [MultiTargetNode(1...6)( - [LocalVariableTargetNode(2...3)(:b, 0), - SplatNode(3...4)((3...4), nil)], - (1...2), - (5...6) - )], - nil, - nil, - (8...9), - CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo") - ), - MultiWriteNode(15...30)( - [LocalVariableTargetNode(15...16)(:a, 0), - MultiTargetNode(18...24)( - [LocalVariableTargetNode(19...20)(:b, 0), - LocalVariableTargetNode(22...23)(:c, 0)], - (18...19), - (23...24) - )], - nil, - nil, - (25...26), - CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo") - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/masgn_splat.txt b/test/yarp/snapshots/whitequark/masgn_splat.txt deleted file mode 100644 index c6cbe9ee70a3a0..00000000000000 --- a/test/yarp/snapshots/whitequark/masgn_splat.txt +++ /dev/null @@ -1,147 +0,0 @@ -ProgramNode(0...139)( - [:c, :d, :b, :a], - StatementsNode(0...139)( - [MultiWriteNode(0...7)( - [SplatNode(0...1)((0...1), nil)], - nil, - nil, - (2...3), - CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(9...22)( - [MultiTargetNode(9...10)([SplatNode(9...10)((9...10), nil)], nil, nil), - LocalVariableTargetNode(12...13)(:c, 0), - LocalVariableTargetNode(15...16)(:d, 0)], - nil, - nil, - (17...18), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(24...32)( - [SplatNode(24...26)( - (24...25), - LocalVariableTargetNode(25...26)(:b, 0) - )], - nil, - nil, - (27...28), - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(34...45)( - [MultiTargetNode(34...36)( - [SplatNode(34...36)( - (34...35), - LocalVariableTargetNode(35...36)(:b, 0) - )], - nil, - nil - ), - LocalVariableTargetNode(38...39)(:c, 0)], - nil, - nil, - (40...41), - CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(47...65)( - [InstanceVariableTargetNode(47...51)(:@foo), - ClassVariableTargetNode(53...58)(:@@bar)], - nil, - nil, - (59...60), - ArrayNode(61...65)( - [SplatNode(61...65)( - (61...62), - CallNode(62...65)( - nil, - nil, - (62...65), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )], - nil, - nil - ) - ), - MultiWriteNode(67...77)( - [LocalVariableTargetNode(67...68)(:a, 0), - SplatNode(70...71)((70...71), nil)], - nil, - nil, - (72...73), - CallNode(74...77)(nil, nil, (74...77), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(79...92)( - [LocalVariableTargetNode(79...80)(:a, 0), - SplatNode(82...83)((82...83), nil), - LocalVariableTargetNode(85...86)(:c, 0)], - nil, - nil, - (87...88), - CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(94...105)( - [LocalVariableTargetNode(94...95)(:a, 0), - SplatNode(97...99)( - (97...98), - LocalVariableTargetNode(98...99)(:b, 0) - )], - nil, - nil, - (100...101), - CallNode(102...105)(nil, nil, (102...105), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(107...121)( - [LocalVariableTargetNode(107...108)(:a, 0), - SplatNode(110...112)( - (110...111), - LocalVariableTargetNode(111...112)(:b, 0) - ), - LocalVariableTargetNode(114...115)(:c, 0)], - nil, - nil, - (116...117), - CallNode(118...121)(nil, nil, (118...121), nil, nil, nil, nil, 2, "bar") - ), - MultiWriteNode(123...139)( - [LocalVariableTargetNode(123...124)(:a, 0), - LocalVariableTargetNode(126...127)(:b, 0)], - nil, - nil, - (128...129), - ArrayNode(130...139)( - [SplatNode(130...134)( - (130...131), - CallNode(131...134)( - nil, - nil, - (131...134), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - ), - CallNode(136...139)( - nil, - nil, - (136...139), - nil, - nil, - nil, - nil, - 2, - "bar" - )], - nil, - nil - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt b/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt deleted file mode 100644 index 099ae9398640c2..00000000000000 --- a/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt +++ /dev/null @@ -1,155 +0,0 @@ -ProgramNode(0...190)( - [], - StatementsNode(0...190)( - [WhileNode(0...45)( - (0...5), - (42...45), - DefNode(6...33)( - :foo, - (10...13), - nil, - ParametersNode(14...28)( - [], - [OptionalParameterNode(14...28)( - :a, - (14...15), - (16...17), - CallNode(18...28)( - nil, - nil, - (18...21), - nil, - nil, - nil, - BlockNode(22...28)([], nil, nil, (22...24), (25...28)), - 0, - "tap" - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (6...9), - nil, - nil, - nil, - nil, - (30...33) - ), - StatementsNode(35...40)([BreakNode(35...40)(nil, (35...40))]), - 0 - ), - WhileNode(47...89)( - (47...52), - (86...89), - DefNode(53...77)( - :foo, - (57...60), - nil, - nil, - StatementsNode(62...72)( - [CallNode(62...72)( - nil, - nil, - (62...65), - nil, - nil, - nil, - BlockNode(66...72)([], nil, nil, (66...68), (69...72)), - 0, - "tap" - )] - ), - [], - (53...56), - nil, - nil, - nil, - nil, - (74...77) - ), - StatementsNode(79...84)([BreakNode(79...84)(nil, (79...84))]), - 0 - ), - WhileNode(91...141)( - (91...96), - (138...141), - DefNode(97...129)( - :foo, - (106...109), - SelfNode(101...105)(), - ParametersNode(110...124)( - [], - [OptionalParameterNode(110...124)( - :a, - (110...111), - (112...113), - CallNode(114...124)( - nil, - nil, - (114...117), - nil, - nil, - nil, - BlockNode(118...124)([], nil, nil, (118...120), (121...124)), - 0, - "tap" - ) - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:a], - (97...100), - (105...106), - nil, - nil, - nil, - (126...129) - ), - StatementsNode(131...136)([BreakNode(131...136)(nil, (131...136))]), - 0 - ), - WhileNode(143...190)( - (143...148), - (187...190), - DefNode(149...178)( - :foo, - (158...161), - SelfNode(153...157)(), - nil, - StatementsNode(163...173)( - [CallNode(163...173)( - nil, - nil, - (163...166), - nil, - nil, - nil, - BlockNode(167...173)([], nil, nil, (167...169), (170...173)), - 0, - "tap" - )] - ), - [], - (149...152), - (157...158), - nil, - nil, - nil, - (175...178) - ), - StatementsNode(180...185)([BreakNode(180...185)(nil, (180...185))]), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/module.txt b/test/yarp/snapshots/whitequark/module.txt deleted file mode 100644 index 18d3d2e9b55e00..00000000000000 --- a/test/yarp/snapshots/whitequark/module.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [ModuleNode(0...15)( - [], - (0...6), - ConstantReadNode(7...10)(:Foo), - nil, - (12...15), - :Foo - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/multiple_pattern_matches.txt b/test/yarp/snapshots/whitequark/multiple_pattern_matches.txt deleted file mode 100644 index 7f655240cddc57..00000000000000 --- a/test/yarp/snapshots/whitequark/multiple_pattern_matches.txt +++ /dev/null @@ -1,97 +0,0 @@ -ProgramNode(0...52)( - [:a], - StatementsNode(0...52)( - [MatchRequiredNode(0...12)( - HashNode(0...6)( - (0...1), - [AssocNode(1...5)( - SymbolNode(1...3)(nil, (1...2), (2...3), "a"), - IntegerNode(4...5)(), - nil - )], - (5...6) - ), - HashPatternNode(10...12)( - nil, - [AssocNode(10...12)( - SymbolNode(10...12)(nil, (10...11), (11...12), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (7...9) - ), - MatchRequiredNode(13...25)( - HashNode(13...19)( - (13...14), - [AssocNode(14...18)( - SymbolNode(14...16)(nil, (14...15), (15...16), "a"), - IntegerNode(17...18)(), - nil - )], - (18...19) - ), - HashPatternNode(23...25)( - nil, - [AssocNode(23...25)( - SymbolNode(23...25)(nil, (23...24), (24...25), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (20...22) - ), - MatchPredicateNode(27...39)( - HashNode(27...33)( - (27...28), - [AssocNode(28...32)( - SymbolNode(28...30)(nil, (28...29), (29...30), "a"), - IntegerNode(31...32)(), - nil - )], - (32...33) - ), - HashPatternNode(37...39)( - nil, - [AssocNode(37...39)( - SymbolNode(37...39)(nil, (37...38), (38...39), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (34...36) - ), - MatchPredicateNode(40...52)( - HashNode(40...46)( - (40...41), - [AssocNode(41...45)( - SymbolNode(41...43)(nil, (41...42), (42...43), "a"), - IntegerNode(44...45)(), - nil - )], - (45...46) - ), - HashPatternNode(50...52)( - nil, - [AssocNode(50...52)( - SymbolNode(50...52)(nil, (50...51), (51...52), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (47...49) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/newline_in_hash_argument.txt b/test/yarp/snapshots/whitequark/newline_in_hash_argument.txt deleted file mode 100644 index fad1c85494822b..00000000000000 --- a/test/yarp/snapshots/whitequark/newline_in_hash_argument.txt +++ /dev/null @@ -1,85 +0,0 @@ -ProgramNode(0...74)( - [:a, :b], - StatementsNode(0...74)( - [CaseNode(0...40)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [InNode(9...21)( - HashPatternNode(12...14)( - nil, - [AssocNode(12...14)( - SymbolNode(12...14)(nil, (12...13), (13...14), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - StatementsNode(15...21)( - [IntegerNode(15...16)(), TrueNode(17...21)()] - ), - (9...11), - nil - ), - InNode(22...36)( - HashPatternNode(25...29)( - nil, - [AssocNode(25...29)( - SymbolNode(25...29)((25...26), (26...27), (27...29), "b"), - nil, - nil - )], - nil, - nil, - nil - ), - StatementsNode(30...36)( - [IntegerNode(30...31)(), TrueNode(32...36)()] - ), - (22...24), - nil - )], - nil, - (0...4), - (37...40) - ), - CallNode(42...58)( - CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "obj"), - (45...46), - (46...49), - nil, - ArgumentsNode(50...58)( - [KeywordHashNode(50...58)( - [AssocNode(50...58)( - SymbolNode(50...56)((50...51), (51...54), (54...56), "foo"), - IntegerNode(57...58)(), - nil - )] - )] - ), - nil, - nil, - 0, - "set" - ), - CallNode(60...74)( - CallNode(60...63)(nil, nil, (60...63), nil, nil, nil, nil, 2, "obj"), - (63...64), - (64...67), - nil, - ArgumentsNode(68...74)( - [KeywordHashNode(68...74)( - [AssocNode(68...74)( - SymbolNode(68...72)(nil, (68...71), (71...72), "foo"), - IntegerNode(73...74)(), - nil - )] - )] - ), - nil, - nil, - 0, - "set" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/next.txt b/test/yarp/snapshots/whitequark/next.txt deleted file mode 100644 index 07dbb690dac91d..00000000000000 --- a/test/yarp/snapshots/whitequark/next.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [NextNode(0...4)(nil, (0...4)), - NextNode(6...14)( - ArgumentsNode(11...14)( - [CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo")] - ), - (6...10) - ), - NextNode(16...22)( - ArgumentsNode(20...22)( - [ParenthesesNode(20...22)(nil, (20...21), (21...22))] - ), - (16...20) - ), - NextNode(24...33)( - ArgumentsNode(28...33)( - [ParenthesesNode(28...33)( - StatementsNode(29...32)( - [CallNode(29...32)( - nil, - nil, - (29...32), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (28...29), - (32...33) - )] - ), - (24...28) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/next_block.txt b/test/yarp/snapshots/whitequark/next_block.txt deleted file mode 100644 index 20cbe0d837bafa..00000000000000 --- a/test/yarp/snapshots/whitequark/next_block.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [NextNode(0...19)( - ArgumentsNode(5...19)( - [CallNode(5...19)( - nil, - nil, - (5...8), - nil, - ArgumentsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - BlockNode(13...19)([], nil, nil, (13...15), (16...19)), - 0, - "fun" - )] - ), - (0...4) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/nil.txt b/test/yarp/snapshots/whitequark/nil.txt deleted file mode 100644 index 4af940de662d5a..00000000000000 --- a/test/yarp/snapshots/whitequark/nil.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...3)([], StatementsNode(0...3)([NilNode(0...3)()])) diff --git a/test/yarp/snapshots/whitequark/nil_expression.txt b/test/yarp/snapshots/whitequark/nil_expression.txt deleted file mode 100644 index b9e8d19adbfcbf..00000000000000 --- a/test/yarp/snapshots/whitequark/nil_expression.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [ParenthesesNode(0...2)(nil, (0...1), (1...2)), - BeginNode(4...13)((4...9), nil, nil, nil, nil, (10...13))] - ) -) diff --git a/test/yarp/snapshots/whitequark/non_lvar_injecting_match.txt b/test/yarp/snapshots/whitequark/non_lvar_injecting_match.txt deleted file mode 100644 index e44f5db294d8f5..00000000000000 --- a/test/yarp/snapshots/whitequark/non_lvar_injecting_match.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...28)( - InterpolatedRegularExpressionNode(0...19)( - (0...1), - [EmbeddedStatementsNode(1...5)( - (1...3), - StatementsNode(3...4)([IntegerNode(3...4)()]), - (4...5) - ), - StringNode(5...18)(nil, (5...18), nil, "(?bar)")], - (18...19), - 0 - ), - nil, - (20...22), - nil, - ArgumentsNode(23...28)( - [StringNode(23...28)((23...24), (24...27), (27...28), "bar")] - ), - nil, - nil, - 0, - "=~" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/not.txt b/test/yarp/snapshots/whitequark/not.txt deleted file mode 100644 index 1dc7b381cd397e..00000000000000 --- a/test/yarp/snapshots/whitequark/not.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [CallNode(0...7)( - CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "foo"), - nil, - (0...3), - nil, - nil, - nil, - nil, - 0, - "!" - ), - CallNode(9...14)( - nil, - nil, - (9...12), - (12...13), - nil, - (13...14), - nil, - 0, - "!" - ), - CallNode(16...24)( - CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "foo"), - nil, - (16...19), - (19...20), - nil, - (23...24), - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/not_cmd.txt b/test/yarp/snapshots/whitequark/not_cmd.txt deleted file mode 100644 index ff2acd00f5fe49..00000000000000 --- a/test/yarp/snapshots/whitequark/not_cmd.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(4...9)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo")] - ), - nil, - nil, - 0, - "m" - ), - nil, - (0...3), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/not_masgn__24.txt b/test/yarp/snapshots/whitequark/not_masgn__24.txt deleted file mode 100644 index c20896826318b2..00000000000000 --- a/test/yarp/snapshots/whitequark/not_masgn__24.txt +++ /dev/null @@ -1,39 +0,0 @@ -ProgramNode(0...13)( - [:a, :b], - StatementsNode(0...13)( - [CallNode(0...13)( - ParenthesesNode(1...13)( - StatementsNode(2...12)( - [MultiWriteNode(2...12)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(5...6)(:b, 0)], - nil, - nil, - (7...8), - CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )] - ), - (1...2), - (12...13) - ), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "!" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/nth_ref.txt b/test/yarp/snapshots/whitequark/nth_ref.txt deleted file mode 100644 index ca131a208ce53f..00000000000000 --- a/test/yarp/snapshots/whitequark/nth_ref.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...3)( - [], - StatementsNode(0...3)([NumberedReferenceReadNode(0...3)(10)]) -) diff --git a/test/yarp/snapshots/whitequark/numbered_args_after_27.txt b/test/yarp/snapshots/whitequark/numbered_args_after_27.txt deleted file mode 100644 index c2a67b4cc32dc0..00000000000000 --- a/test/yarp/snapshots/whitequark/numbered_args_after_27.txt +++ /dev/null @@ -1,181 +0,0 @@ -ProgramNode(0...65)( - [], - StatementsNode(0...65)( - [LambdaNode(0...17)( - [], - (0...2), - (3...5), - (14...17), - nil, - StatementsNode(6...13)( - [CallNode(6...13)( - CallNode(6...8)(nil, nil, (6...8), nil, nil, nil, nil, 2, "_1"), - nil, - (9...10), - nil, - ArgumentsNode(11...13)( - [CallNode(11...13)( - nil, - nil, - (11...13), - nil, - nil, - nil, - nil, - 2, - "_9" - )] - ), - nil, - nil, - 0, - "+" - )] - ) - ), - LambdaNode(19...32)( - [], - (19...21), - (22...23), - (31...32), - nil, - StatementsNode(24...31)( - [CallNode(24...31)( - CallNode(24...26)( - nil, - nil, - (24...26), - nil, - nil, - nil, - nil, - 2, - "_1" - ), - nil, - (27...28), - nil, - ArgumentsNode(29...31)( - [CallNode(29...31)( - nil, - nil, - (29...31), - nil, - nil, - nil, - nil, - 2, - "_9" - )] - ), - nil, - nil, - 0, - "+" - )] - ) - ), - CallNode(34...50)( - nil, - nil, - (34...35), - nil, - nil, - nil, - BlockNode(36...50)( - [], - nil, - StatementsNode(39...46)( - [CallNode(39...46)( - CallNode(39...41)( - nil, - nil, - (39...41), - nil, - nil, - nil, - nil, - 2, - "_1" - ), - nil, - (42...43), - nil, - ArgumentsNode(44...46)( - [CallNode(44...46)( - nil, - nil, - (44...46), - nil, - nil, - nil, - nil, - 2, - "_9" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (36...38), - (47...50) - ), - 0, - "m" - ), - CallNode(52...65)( - nil, - nil, - (52...53), - nil, - nil, - nil, - BlockNode(54...65)( - [], - nil, - StatementsNode(56...63)( - [CallNode(56...63)( - CallNode(56...58)( - nil, - nil, - (56...58), - nil, - nil, - nil, - nil, - 2, - "_1" - ), - nil, - (59...60), - nil, - ArgumentsNode(61...63)( - [CallNode(61...63)( - nil, - nil, - (61...63), - nil, - nil, - nil, - nil, - 2, - "_9" - )] - ), - nil, - nil, - 0, - "+" - )] - ), - (54...55), - (64...65) - ), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/numparam_outside_block.txt b/test/yarp/snapshots/whitequark/numparam_outside_block.txt deleted file mode 100644 index 0dff33b0a99b56..00000000000000 --- a/test/yarp/snapshots/whitequark/numparam_outside_block.txt +++ /dev/null @@ -1,54 +0,0 @@ -ProgramNode(0...83)( - [], - StatementsNode(0...83)( - [CallNode(0...2)(nil, nil, (0...2), nil, nil, nil, nil, 2, "_1"), - SingletonClassNode(4...25)( - [], - (4...9), - (10...12), - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo"), - StatementsNode(18...20)( - [CallNode(18...20)(nil, nil, (18...20), nil, nil, nil, nil, 2, "_1")] - ), - (22...25) - ), - ClassNode(27...43)( - [], - (27...32), - ConstantReadNode(33...34)(:A), - nil, - nil, - StatementsNode(36...38)( - [CallNode(36...38)(nil, nil, (36...38), nil, nil, nil, nil, 2, "_1")] - ), - (40...43), - :A - ), - DefNode(45...64)( - :m, - (54...55), - SelfNode(49...53)(), - nil, - StatementsNode(57...59)( - [CallNode(57...59)(nil, nil, (57...59), nil, nil, nil, nil, 2, "_1")] - ), - [], - (45...48), - (53...54), - nil, - nil, - nil, - (61...64) - ), - ModuleNode(66...83)( - [], - (66...72), - ConstantReadNode(73...74)(:A), - StatementsNode(76...78)( - [CallNode(76...78)(nil, nil, (76...78), nil, nil, nil, nil, 2, "_1")] - ), - (80...83), - :A - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/op_asgn.txt b/test/yarp/snapshots/whitequark/op_asgn.txt deleted file mode 100644 index 44e3694392afb3..00000000000000 --- a/test/yarp/snapshots/whitequark/op_asgn.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [CallOperatorWriteNode(0...10)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...5), - nil, - nil, - nil, - 0, - "A", - "A=", - :+, - (6...8), - IntegerNode(9...10)() - ), - CallOperatorWriteNode(12...22)( - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "foo"), - (15...16), - (16...17), - nil, - nil, - nil, - 0, - "a", - "a=", - :+, - (18...20), - IntegerNode(21...22)() - ), - CallOperatorWriteNode(24...35)( - CallNode(24...27)(nil, nil, (24...27), nil, nil, nil, nil, 2, "foo"), - (27...29), - (29...30), - nil, - nil, - nil, - 0, - "a", - "a=", - :+, - (31...33), - IntegerNode(34...35)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/op_asgn_cmd.txt b/test/yarp/snapshots/whitequark/op_asgn_cmd.txt deleted file mode 100644 index 9c15e15cde7ab7..00000000000000 --- a/test/yarp/snapshots/whitequark/op_asgn_cmd.txt +++ /dev/null @@ -1,145 +0,0 @@ -ProgramNode(0...64)( - [], - StatementsNode(0...64)( - [CallOperatorWriteNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...5), - nil, - nil, - nil, - 0, - "A", - "A=", - :+, - (6...8), - CallNode(9...14)( - nil, - nil, - (9...10), - nil, - ArgumentsNode(11...14)( - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "m" - ) - ), - CallOperatorWriteNode(16...30)( - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "foo"), - (19...20), - (20...21), - nil, - nil, - nil, - 0, - "a", - "a=", - :+, - (22...24), - CallNode(25...30)( - nil, - nil, - (25...26), - nil, - ArgumentsNode(27...30)( - [CallNode(27...30)( - nil, - nil, - (27...30), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "m" - ) - ), - ConstantPathOperatorWriteNode(32...47)( - ConstantPathNode(32...38)( - CallNode(32...35)(nil, nil, (32...35), nil, nil, nil, nil, 2, "foo"), - ConstantReadNode(37...38)(:A), - (35...37) - ), - (39...41), - CallNode(42...47)( - nil, - nil, - (42...43), - nil, - ArgumentsNode(44...47)( - [CallNode(44...47)( - nil, - nil, - (44...47), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "m" - ), - :+ - ), - CallOperatorWriteNode(49...64)( - CallNode(49...52)(nil, nil, (49...52), nil, nil, nil, nil, 2, "foo"), - (52...54), - (54...55), - nil, - nil, - nil, - 0, - "a", - "a=", - :+, - (56...58), - CallNode(59...64)( - nil, - nil, - (59...60), - nil, - ArgumentsNode(61...64)( - [CallNode(61...64)( - nil, - nil, - (61...64), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "m" - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/op_asgn_index.txt b/test/yarp/snapshots/whitequark/op_asgn_index.txt deleted file mode 100644 index 153077be967da1..00000000000000 --- a/test/yarp/snapshots/whitequark/op_asgn_index.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallOperatorWriteNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...8)([IntegerNode(4...5)(), IntegerNode(7...8)()]), - (8...9), - 0, - "[]", - "[]=", - :+, - (10...12), - IntegerNode(13...14)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/op_asgn_index_cmd.txt b/test/yarp/snapshots/whitequark/op_asgn_index_cmd.txt deleted file mode 100644 index 9dda56d651d9bd..00000000000000 --- a/test/yarp/snapshots/whitequark/op_asgn_index_cmd.txt +++ /dev/null @@ -1,41 +0,0 @@ -ProgramNode(0...18)( - [], - StatementsNode(0...18)( - [CallOperatorWriteNode(0...18)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...8)([IntegerNode(4...5)(), IntegerNode(7...8)()]), - (8...9), - 0, - "[]", - "[]=", - :+, - (10...12), - CallNode(13...18)( - nil, - nil, - (13...14), - nil, - ArgumentsNode(15...18)( - [CallNode(15...18)( - nil, - nil, - (15...18), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - nil, - 0, - "m" - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/optarg.txt b/test/yarp/snapshots/whitequark/optarg.txt deleted file mode 100644 index f2a0dd24371dd7..00000000000000 --- a/test/yarp/snapshots/whitequark/optarg.txt +++ /dev/null @@ -1,65 +0,0 @@ -ProgramNode(0...44)( - [], - StatementsNode(0...44)( - [DefNode(0...18)( - :f, - (4...5), - nil, - ParametersNode(6...13)( - [], - [OptionalParameterNode(6...13)( - :foo, - (6...9), - (10...11), - IntegerNode(12...13)() - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:foo], - (0...3), - nil, - nil, - nil, - nil, - (15...18) - ), - DefNode(20...44)( - :f, - (24...25), - nil, - ParametersNode(26...38)( - [], - [OptionalParameterNode(26...31)( - :foo, - (26...29), - (29...30), - IntegerNode(30...31)() - ), - OptionalParameterNode(33...38)( - :bar, - (33...36), - (36...37), - IntegerNode(37...38)() - )], - [], - nil, - [], - nil, - nil - ), - nil, - [:foo, :bar], - (20...23), - nil, - (25...26), - (38...39), - nil, - (41...44) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/or.txt b/test/yarp/snapshots/whitequark/or.txt deleted file mode 100644 index fb1599df1da051..00000000000000 --- a/test/yarp/snapshots/whitequark/or.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [OrNode(0...10)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "bar"), - (4...6) - ), - OrNode(12...22)( - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "foo"), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar"), - (16...18) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/or_asgn.txt b/test/yarp/snapshots/whitequark/or_asgn.txt deleted file mode 100644 index f681a319824893..00000000000000 --- a/test/yarp/snapshots/whitequark/or_asgn.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallOrWriteNode(0...11)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...5), - nil, - nil, - nil, - 0, - "a", - "a=", - (6...9), - IntegerNode(10...11)() - ), - CallOrWriteNode(13...28)( - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo"), - nil, - (16...22), - (16...17), - ArgumentsNode(17...21)( - [IntegerNode(17...18)(), IntegerNode(20...21)()] - ), - (21...22), - 0, - "[]", - "[]=", - (23...26), - IntegerNode(27...28)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_272.txt b/test/yarp/snapshots/whitequark/parser_bug_272.txt deleted file mode 100644 index 0cb194d1ae4126..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_272.txt +++ /dev/null @@ -1,35 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [CallNode(0...15)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...4)([InstanceVariableReadNode(2...4)(:@b)]), - nil, - BlockNode(5...15)( - [:c], - BlockParametersNode(8...11)( - ParametersNode(9...10)( - [RequiredParameterNode(9...10)(:c)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (8...9), - (10...11) - ), - nil, - (5...7), - (12...15) - ), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_490.txt b/test/yarp/snapshots/whitequark/parser_bug_490.txt deleted file mode 100644 index 5c087b60f659e7..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_490.txt +++ /dev/null @@ -1,101 +0,0 @@ -ProgramNode(0...132)( - [], - StatementsNode(0...132)( - [DefNode(0...39)( - :m, - (4...5), - nil, - nil, - StatementsNode(7...34)( - [SingletonClassNode(7...34)( - [], - (7...12), - (13...15), - SelfNode(16...20)(), - StatementsNode(22...29)( - [ConstantWriteNode(22...29)( - :A, - (22...23), - NilNode(26...29)(), - (24...25) - )] - ), - (31...34) - )] - ), - [], - (0...3), - nil, - nil, - nil, - nil, - (36...39) - ), - DefNode(41...85)( - :m, - (45...46), - nil, - nil, - StatementsNode(48...80)( - [SingletonClassNode(48...80)( - [], - (48...53), - (54...56), - SelfNode(57...61)(), - StatementsNode(63...75)( - [ClassNode(63...75)( - [], - (63...68), - ConstantReadNode(69...70)(:C), - nil, - nil, - nil, - (72...75), - :C - )] - ), - (77...80) - )] - ), - [], - (41...44), - nil, - nil, - nil, - nil, - (82...85) - ), - DefNode(87...132)( - :m, - (91...92), - nil, - nil, - StatementsNode(94...127)( - [SingletonClassNode(94...127)( - [], - (94...99), - (100...102), - SelfNode(103...107)(), - StatementsNode(109...122)( - [ModuleNode(109...122)( - [], - (109...115), - ConstantReadNode(116...117)(:M), - nil, - (119...122), - :M - )] - ), - (124...127) - )] - ), - [], - (87...90), - nil, - nil, - nil, - nil, - (129...132) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_507.txt b/test/yarp/snapshots/whitequark/parser_bug_507.txt deleted file mode 100644 index 07e5d8ed602b2a..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_507.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...19)( - [:m], - StatementsNode(0...19)( - [LocalVariableWriteNode(0...19)( - :m, - 0, - (0...1), - LambdaNode(4...19)( - [:args], - (4...6), - (13...15), - (16...19), - BlockParametersNode(7...12)( - ParametersNode(7...12)( - [], - [], - [], - RestParameterNode(7...12)(:args, (8...12), (7...8)), - [], - nil, - nil - ), - [], - nil, - nil - ), - nil - ), - (2...3) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_518.txt b/test/yarp/snapshots/whitequark/parser_bug_518.txt deleted file mode 100644 index 1f2cca8d1ddff2..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_518.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [ClassNode(0...15)( - [], - (0...5), - ConstantReadNode(6...7)(:A), - (8...9), - ConstantReadNode(10...11)(:B), - nil, - (12...15), - :A - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_525.txt b/test/yarp/snapshots/whitequark/parser_bug_525.txt deleted file mode 100644 index 0b5c2a5a44f77f..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_525.txt +++ /dev/null @@ -1,52 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [CallNode(0...32)( - nil, - nil, - (0...2), - nil, - ArgumentsNode(3...11)( - [KeywordHashNode(3...11)( - [AssocNode(3...11)( - SymbolNode(3...5)((3...4), (4...5), nil, "k"), - CallNode(9...11)( - nil, - nil, - (9...11), - nil, - nil, - nil, - nil, - 2, - "m2" - ), - (6...8) - )] - )] - ), - nil, - BlockNode(12...32)( - [], - nil, - StatementsNode(16...27)( - [CallNode(16...27)( - nil, - nil, - (16...18), - (18...19), - nil, - (19...20), - BlockNode(21...27)([], nil, nil, (21...23), (24...27)), - 0, - "m3" - )] - ), - (12...14), - (29...32) - ), - 0, - "m1" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_604.txt b/test/yarp/snapshots/whitequark/parser_bug_604.txt deleted file mode 100644 index ff732e34c57b67..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_604.txt +++ /dev/null @@ -1,30 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [CallNode(0...14)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...7)( - [CallNode(2...7)( - CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a"), - nil, - (4...5), - nil, - ArgumentsNode(6...7)( - [CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b")] - ), - nil, - nil, - 0, - "+" - )] - ), - nil, - BlockNode(8...14)([], nil, nil, (8...10), (11...14)), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_640.txt b/test/yarp/snapshots/whitequark/parser_bug_640.txt deleted file mode 100644 index 5ca73c08a5739a..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_640.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...6)( - [], - StatementsNode(0...6)( - [InterpolatedStringNode(0...6)( - (0...6), - [StringNode(7...20)(nil, (7...20), nil, "bazqux\n")], - (20...24) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_645.txt b/test/yarp/snapshots/whitequark/parser_bug_645.txt deleted file mode 100644 index 27680b00aecf85..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_645.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [LambdaNode(0...14)( - [:arg], - (0...2), - (12...13), - (13...14), - BlockParametersNode(3...11)( - ParametersNode(4...10)( - [], - [OptionalParameterNode(4...10)( - :arg, - (4...7), - (7...8), - HashNode(8...10)((8...9), [], (9...10)) - )], - [], - nil, - [], - nil, - nil - ), - [], - (3...4), - (10...11) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_bug_830.txt b/test/yarp/snapshots/whitequark/parser_bug_830.txt deleted file mode 100644 index c8f0c34e7dafc1..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_bug_830.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [RegularExpressionNode(0...4)((0...1), (1...3), (3...4), "(", 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt b/test/yarp/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt deleted file mode 100644 index d2fe26f163da54..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_drops_truncated_parts_of_squiggly_heredoc.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [InterpolatedStringNode(0...7)( - (0...7), - [EmbeddedStatementsNode(10...13)((10...12), nil, (12...13)), - StringNode(13...14)(nil, (13...14), nil, "\n")], - (14...19) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt b/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt deleted file mode 100644 index 3a3377f96d6aa2..00000000000000 --- a/test/yarp/snapshots/whitequark/parser_slash_slash_n_escaping_in_literals.txt +++ /dev/null @@ -1,63 +0,0 @@ -ProgramNode(0...210)( - [], - StatementsNode(0...210)( - [StringNode(0...6)((0...1), (1...5), (5...6), "ab"), - ArrayNode(8...16)( - [SymbolNode(11...15)(nil, (11...15), nil, "ab")], - (8...11), - (15...16) - ), - StringNode(18...26)((18...21), (21...25), (25...26), "ab"), - ArrayNode(28...36)( - [StringNode(31...35)(nil, (31...35), nil, "ab")], - (28...31), - (35...36) - ), - ArrayNode(38...46)( - [SymbolNode(41...45)(nil, (41...45), nil, "a\\\n" + "b")], - (38...41), - (45...46) - ), - StringNode(48...56)((48...51), (51...55), (55...56), "a\\\n" + "b"), - RegularExpressionNode(58...66)((58...61), (61...65), (65...66), "ab", 0), - SymbolNode(68...76)((68...71), (71...75), (75...76), "ab"), - ArrayNode(78...86)( - [StringNode(81...85)(nil, (81...85), nil, "a\\\n" + "b")], - (78...81), - (85...86) - ), - XStringNode(88...96)((88...91), (91...95), (95...96), "ab"), - StringNode(98...105)((98...100), (100...104), (104...105), "ab"), - StringNode(107...113)( - (107...108), - (108...112), - (112...113), - "a\\\n" + "b" - ), - RegularExpressionNode(115...121)( - (115...116), - (116...120), - (120...121), - "ab", - 0 - ), - SymbolNode(123...130)((123...125), (125...129), (129...130), "ab"), - SymbolNode(132...139)((132...134), (134...138), (138...139), "ab"), - InterpolatedStringNode(141...150)( - (141...150), - [StringNode(151...156)(nil, (151...156), nil, "ab\n")], - (156...161) - ), - InterpolatedStringNode(162...171)( - (162...171), - [StringNode(172...177)(nil, (172...177), nil, "a\\\n" + "b\n")], - (177...182) - ), - InterpolatedXStringNode(183...192)( - (183...192), - [StringNode(193...198)(nil, (193...198), nil, "ab\n")], - (198...203) - ), - XStringNode(204...210)((204...205), (205...209), (209...210), "ab")] - ) -) diff --git a/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt deleted file mode 100644 index 55938adfd8c113..00000000000000 --- a/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(8...111)( - [], - StatementsNode(8...111)( - [CaseNode(8...111)( - ArrayNode(13...51)( - [SourceFileNode(14...22)( - "whitequark/pattern_matching__FILE__LINE_literals.txt" - ), - CallNode(24...36)( - SourceLineNode(24...32)(), - nil, - (33...34), - nil, - ArgumentsNode(35...36)([IntegerNode(35...36)()]), - nil, - nil, - 0, - "+" - ), - SourceEncodingNode(38...50)()], - (13...14), - (50...51) - ), - [InNode(62...99)( - ArrayPatternNode(65...99)( - nil, - [SourceFileNode(66...74)( - "whitequark/pattern_matching__FILE__LINE_literals.txt" - ), - SourceLineNode(76...84)(), - SourceEncodingNode(86...98)()], - nil, - [], - (65...66), - (98...99) - ), - nil, - (62...64), - nil - )], - nil, - (8...12), - (108...111) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/pattern_matching_blank_else.txt b/test/yarp/snapshots/whitequark/pattern_matching_blank_else.txt deleted file mode 100644 index df949e90b0db1e..00000000000000 --- a/test/yarp/snapshots/whitequark/pattern_matching_blank_else.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [CaseNode(0...26)( - IntegerNode(5...6)(), - [InNode(8...15)( - IntegerNode(11...12)(), - StatementsNode(14...15)([IntegerNode(14...15)()]), - (8...10), - nil - )], - ElseNode(17...26)((17...21), nil, (23...26)), - (0...4), - (23...26) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/pattern_matching_else.txt b/test/yarp/snapshots/whitequark/pattern_matching_else.txt deleted file mode 100644 index d776a0ba1eb096..00000000000000 --- a/test/yarp/snapshots/whitequark/pattern_matching_else.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [CaseNode(0...29)( - IntegerNode(5...6)(), - [InNode(8...15)( - IntegerNode(11...12)(), - StatementsNode(14...15)([IntegerNode(14...15)()]), - (8...10), - nil - )], - ElseNode(17...29)( - (17...21), - StatementsNode(23...24)([IntegerNode(23...24)()]), - (26...29) - ), - (0...4), - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/pattern_matching_single_line.txt b/test/yarp/snapshots/whitequark/pattern_matching_single_line.txt deleted file mode 100644 index c428d83cda5e3d..00000000000000 --- a/test/yarp/snapshots/whitequark/pattern_matching_single_line.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...24)( - [:a], - StatementsNode(0...24)( - [MatchRequiredNode(0...8)( - IntegerNode(0...1)(), - ArrayPatternNode(5...8)( - nil, - [LocalVariableTargetNode(6...7)(:a, 0)], - nil, - [], - (5...6), - (7...8) - ), - (2...4) - ), - LocalVariableReadNode(10...11)(:a, 0), - MatchPredicateNode(13...21)( - IntegerNode(13...14)(), - ArrayPatternNode(18...21)( - nil, - [LocalVariableTargetNode(19...20)(:a, 0)], - nil, - [], - (18...19), - (20...21) - ), - (15...17) - ), - LocalVariableReadNode(23...24)(:a, 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt b/test/yarp/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt deleted file mode 100644 index 1e009aa3db8a71..00000000000000 --- a/test/yarp/snapshots/whitequark/pattern_matching_single_line_allowed_omission_of_parentheses.txt +++ /dev/null @@ -1,137 +0,0 @@ -ProgramNode(0...142)( - [:a, :b, :value], - StatementsNode(0...142)( - [MatchRequiredNode(0...14)( - ArrayNode(0...6)( - [IntegerNode(1...2)(), IntegerNode(4...5)()], - (0...1), - (5...6) - ), - ArrayPatternNode(10...14)( - nil, - [LocalVariableTargetNode(10...11)(:a, 0), - LocalVariableTargetNode(13...14)(:b, 0)], - nil, - [], - nil, - nil - ), - (7...9) - ), - LocalVariableReadNode(16...17)(:a, 0), - MatchPredicateNode(19...33)( - ArrayNode(19...25)( - [IntegerNode(20...21)(), IntegerNode(23...24)()], - (19...20), - (24...25) - ), - ArrayPatternNode(29...33)( - nil, - [LocalVariableTargetNode(29...30)(:a, 0), - LocalVariableTargetNode(32...33)(:b, 0)], - nil, - [], - nil, - nil - ), - (26...28) - ), - LocalVariableReadNode(35...36)(:a, 0), - MatchRequiredNode(38...50)( - HashNode(38...44)( - (38...39), - [AssocNode(39...43)( - SymbolNode(39...41)(nil, (39...40), (40...41), "a"), - IntegerNode(42...43)(), - nil - )], - (43...44) - ), - HashPatternNode(48...50)( - nil, - [AssocNode(48...50)( - SymbolNode(48...50)(nil, (48...49), (49...50), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (45...47) - ), - LocalVariableReadNode(52...53)(:a, 0), - MatchPredicateNode(55...67)( - HashNode(55...61)( - (55...56), - [AssocNode(56...60)( - SymbolNode(56...58)(nil, (56...57), (57...58), "a"), - IntegerNode(59...60)(), - nil - )], - (60...61) - ), - HashPatternNode(65...67)( - nil, - [AssocNode(65...67)( - SymbolNode(65...67)(nil, (65...66), (66...67), "a"), - nil, - nil - )], - nil, - nil, - nil - ), - (62...64) - ), - LocalVariableReadNode(69...70)(:a, 0), - MatchRequiredNode(72...99)( - HashNode(72...85)( - (72...73), - [AssocNode(73...84)( - SymbolNode(73...77)(nil, (73...76), (76...77), "key"), - SymbolNode(78...84)((78...79), (79...84), nil, "value"), - nil - )], - (84...85) - ), - HashPatternNode(89...99)( - nil, - [AssocNode(89...99)( - SymbolNode(89...93)(nil, (89...92), (92...93), "key"), - LocalVariableTargetNode(94...99)(:value, 0), - nil - )], - nil, - nil, - nil - ), - (86...88) - ), - LocalVariableReadNode(101...106)(:value, 0), - MatchPredicateNode(108...135)( - HashNode(108...121)( - (108...109), - [AssocNode(109...120)( - SymbolNode(109...113)(nil, (109...112), (112...113), "key"), - SymbolNode(114...120)((114...115), (115...120), nil, "value"), - nil - )], - (120...121) - ), - HashPatternNode(125...135)( - nil, - [AssocNode(125...135)( - SymbolNode(125...129)(nil, (125...128), (128...129), "key"), - LocalVariableTargetNode(130...135)(:value, 0), - nil - )], - nil, - nil, - nil - ), - (122...124) - ), - LocalVariableReadNode(137...142)(:value, 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/postexe.txt b/test/yarp/snapshots/whitequark/postexe.txt deleted file mode 100644 index d6af82bf15c949..00000000000000 --- a/test/yarp/snapshots/whitequark/postexe.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [PostExecutionNode(0...9)( - StatementsNode(6...7)([IntegerNode(6...7)()]), - (0...3), - (4...5), - (8...9) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/preexe.txt b/test/yarp/snapshots/whitequark/preexe.txt deleted file mode 100644 index bfa071f72c87c1..00000000000000 --- a/test/yarp/snapshots/whitequark/preexe.txt +++ /dev/null @@ -1,11 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [PreExecutionNode(0...11)( - StatementsNode(8...9)([IntegerNode(8...9)()]), - (0...5), - (6...7), - (10...11) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/procarg0.txt b/test/yarp/snapshots/whitequark/procarg0.txt deleted file mode 100644 index fb43e8721080b1..00000000000000 --- a/test/yarp/snapshots/whitequark/procarg0.txt +++ /dev/null @@ -1,70 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - nil, - nil, - BlockNode(2...18)( - [:foo, :bar], - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [RequiredDestructuredParameterNode(5...15)( - [RequiredParameterNode(6...9)(:foo), - RequiredParameterNode(11...14)(:bar)], - (5...6), - (14...15) - )], - [], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - nil, - (2...3), - (17...18) - ), - 0, - "m" - ), - CallNode(21...32)( - nil, - nil, - (21...22), - nil, - nil, - nil, - BlockNode(23...32)( - [:foo], - BlockParametersNode(25...30)( - ParametersNode(26...29)( - [RequiredParameterNode(26...29)(:foo)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (25...26), - (29...30) - ), - nil, - (23...24), - (31...32) - ), - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/range_exclusive.txt b/test/yarp/snapshots/whitequark/range_exclusive.txt deleted file mode 100644 index 4571ea317a8eb5..00000000000000 --- a/test/yarp/snapshots/whitequark/range_exclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [RangeNode(0...5)(IntegerNode(0...1)(), IntegerNode(4...5)(), (1...4), 1)] - ) -) diff --git a/test/yarp/snapshots/whitequark/range_inclusive.txt b/test/yarp/snapshots/whitequark/range_inclusive.txt deleted file mode 100644 index 021f010a66920f..00000000000000 --- a/test/yarp/snapshots/whitequark/range_inclusive.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [RangeNode(0...4)(IntegerNode(0...1)(), IntegerNode(3...4)(), (1...3), 0)] - ) -) diff --git a/test/yarp/snapshots/whitequark/rational.txt b/test/yarp/snapshots/whitequark/rational.txt deleted file mode 100644 index dfa7d0c29f562d..00000000000000 --- a/test/yarp/snapshots/whitequark/rational.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [RationalNode(0...5)(FloatNode(0...4)()), - RationalNode(7...10)(IntegerNode(7...9)())] - ) -) diff --git a/test/yarp/snapshots/whitequark/redo.txt b/test/yarp/snapshots/whitequark/redo.txt deleted file mode 100644 index 99ab66873b8c13..00000000000000 --- a/test/yarp/snapshots/whitequark/redo.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...4)([], StatementsNode(0...4)([RedoNode(0...4)()])) diff --git a/test/yarp/snapshots/whitequark/regex_interp.txt b/test/yarp/snapshots/whitequark/regex_interp.txt deleted file mode 100644 index d314875cc4c25f..00000000000000 --- a/test/yarp/snapshots/whitequark/regex_interp.txt +++ /dev/null @@ -1,19 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedRegularExpressionNode(0...14)( - (0...1), - [StringNode(1...4)(nil, (1...4), nil, "foo"), - EmbeddedStatementsNode(4...10)( - (4...6), - StatementsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "bar")] - ), - (9...10) - ), - StringNode(10...13)(nil, (10...13), nil, "baz")], - (13...14), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/regex_plain.txt b/test/yarp/snapshots/whitequark/regex_plain.txt deleted file mode 100644 index cf2728065e71f8..00000000000000 --- a/test/yarp/snapshots/whitequark/regex_plain.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [RegularExpressionNode(0...10)((0...1), (1...7), (7...10), "source", 3)] - ) -) diff --git a/test/yarp/snapshots/whitequark/resbody_list.txt b/test/yarp/snapshots/whitequark/resbody_list.txt deleted file mode 100644 index 8456996663daa9..00000000000000 --- a/test/yarp/snapshots/whitequark/resbody_list.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [BeginNode(0...39)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...34)( - (13...19), - [ConstantReadNode(20...29)(:Exception)], - nil, - nil, - StatementsNode(31...34)( - [CallNode(31...34)( - nil, - nil, - (31...34), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (36...39) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/resbody_list_mrhs.txt b/test/yarp/snapshots/whitequark/resbody_list_mrhs.txt deleted file mode 100644 index f4160d82daf037..00000000000000 --- a/test/yarp/snapshots/whitequark/resbody_list_mrhs.txt +++ /dev/null @@ -1,45 +0,0 @@ -ProgramNode(0...44)( - [], - StatementsNode(0...44)( - [BeginNode(0...44)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...39)( - (13...19), - [ConstantReadNode(20...29)(:Exception), - CallNode(31...34)( - nil, - nil, - (31...34), - nil, - nil, - nil, - nil, - 2, - "foo" - )], - nil, - nil, - StatementsNode(36...39)( - [CallNode(36...39)( - nil, - nil, - (36...39), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (41...44) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/resbody_list_var.txt b/test/yarp/snapshots/whitequark/resbody_list_var.txt deleted file mode 100644 index 660abcc181dfff..00000000000000 --- a/test/yarp/snapshots/whitequark/resbody_list_var.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...39)( - [:ex], - StatementsNode(0...39)( - [BeginNode(0...39)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...34)( - (13...19), - [CallNode(20...23)( - nil, - nil, - (20...23), - nil, - nil, - nil, - nil, - 2, - "foo" - )], - (24...26), - LocalVariableTargetNode(27...29)(:ex, 0), - StatementsNode(31...34)( - [CallNode(31...34)( - nil, - nil, - (31...34), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (36...39) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/resbody_var.txt b/test/yarp/snapshots/whitequark/resbody_var.txt deleted file mode 100644 index e88a7612dc1b2a..00000000000000 --- a/test/yarp/snapshots/whitequark/resbody_var.txt +++ /dev/null @@ -1,73 +0,0 @@ -ProgramNode(0...73)( - [:ex], - StatementsNode(0...73)( - [BeginNode(0...36)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...31)( - (13...19), - [], - (20...22), - InstanceVariableTargetNode(23...26)(:@ex), - StatementsNode(28...31)( - [CallNode(28...31)( - nil, - nil, - (28...31), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (33...36) - ), - BeginNode(38...73)( - (38...43), - StatementsNode(45...49)( - [CallNode(45...49)( - nil, - nil, - (45...49), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - RescueNode(51...68)( - (51...57), - [], - (58...60), - LocalVariableTargetNode(61...63)(:ex, 0), - StatementsNode(65...68)( - [CallNode(65...68)( - nil, - nil, - (65...68), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (70...73) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue.txt b/test/yarp/snapshots/whitequark/rescue.txt deleted file mode 100644 index 6a14aa0803248c..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [BeginNode(0...29)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...24)( - (13...19), - [], - nil, - nil, - StatementsNode(21...24)( - [CallNode(21...24)( - nil, - nil, - (21...24), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil - ), - nil, - nil, - (26...29) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_else.txt b/test/yarp/snapshots/whitequark/rescue_else.txt deleted file mode 100644 index 5359bb2a626b4d..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_else.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [BeginNode(0...40)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...24)( - (13...19), - [], - nil, - nil, - StatementsNode(21...24)( - [CallNode(21...24)( - nil, - nil, - (21...24), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil - ), - ElseNode(26...40)( - (26...30), - StatementsNode(32...35)( - [CallNode(32...35)( - nil, - nil, - (32...35), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (37...40) - ), - nil, - (37...40) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_else_ensure.txt b/test/yarp/snapshots/whitequark/rescue_else_ensure.txt deleted file mode 100644 index 89fc12478464a1..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_else_ensure.txt +++ /dev/null @@ -1,66 +0,0 @@ -ProgramNode(0...51)( - [], - StatementsNode(0...51)( - [BeginNode(0...51)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...24)( - (13...19), - [], - nil, - nil, - StatementsNode(21...24)( - [CallNode(21...24)( - nil, - nil, - (21...24), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - ElseNode(26...42)( - (26...30), - StatementsNode(31...34)( - [CallNode(31...34)( - nil, - nil, - (31...34), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (36...42) - ), - EnsureNode(36...51)( - (36...42), - StatementsNode(44...47)( - [CallNode(44...47)( - nil, - nil, - (44...47), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (48...51) - ), - (48...51) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_ensure.txt b/test/yarp/snapshots/whitequark/rescue_ensure.txt deleted file mode 100644 index 719ed167fec916..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_ensure.txt +++ /dev/null @@ -1,50 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [BeginNode(0...42)( - (0...5), - StatementsNode(7...11)( - [CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth")] - ), - RescueNode(13...24)( - (13...19), - [], - nil, - nil, - StatementsNode(21...24)( - [CallNode(21...24)( - nil, - nil, - (21...24), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - nil - ), - nil, - EnsureNode(26...42)( - (26...32), - StatementsNode(34...37)( - [CallNode(34...37)( - nil, - nil, - (34...37), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (39...42) - ), - (39...42) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_in_lambda_block.txt b/test/yarp/snapshots/whitequark/rescue_in_lambda_block.txt deleted file mode 100644 index 89825a7ac412ac..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_in_lambda_block.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [LambdaNode(0...17)( - [], - (0...2), - (3...5), - (14...17), - nil, - BeginNode(6...17)( - nil, - nil, - RescueNode(6...12)((6...12), [], nil, nil, nil, nil), - nil, - nil, - (14...17) - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_mod.txt b/test/yarp/snapshots/whitequark/rescue_mod.txt deleted file mode 100644 index e755977e7decfa..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_mod.txt +++ /dev/null @@ -1,10 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [RescueModifierNode(0...15)( - CallNode(0...4)(nil, nil, (0...4), nil, nil, nil, nil, 2, "meth"), - (5...11), - CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "bar") - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt deleted file mode 100644 index b0ca3f6c951009..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_mod_asgn.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...21)( - [:foo], - StatementsNode(0...21)( - [LocalVariableWriteNode(0...21)( - :foo, - 0, - (0...3), - RescueModifierNode(6...21)( - CallNode(6...10)(nil, nil, (6...10), nil, nil, nil, nil, 2, "meth"), - (11...17), - CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "bar") - ), - (4...5) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt deleted file mode 100644 index 82b1220cd7a4d8..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt +++ /dev/null @@ -1,21 +0,0 @@ -ProgramNode(0...29)( - [:foo, :bar], - StatementsNode(0...29)( - [MultiWriteNode(0...29)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], - nil, - nil, - (9...10), - RescueModifierNode(11...29)( - CallNode(11...15)(nil, nil, (11...15), nil, nil, nil, nil, 2, "meth"), - (16...22), - ArrayNode(23...29)( - [IntegerNode(24...25)(), IntegerNode(27...28)()], - (23...24), - (28...29) - ) - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_mod_op_assign.txt b/test/yarp/snapshots/whitequark/rescue_mod_op_assign.txt deleted file mode 100644 index f9bfc7bfeb3649..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_mod_op_assign.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...22)( - [:foo], - StatementsNode(0...22)( - [LocalVariableOperatorWriteNode(0...22)( - (0...3), - (4...6), - RescueModifierNode(7...22)( - CallNode(7...11)(nil, nil, (7...11), nil, nil, nil, nil, 2, "meth"), - (12...18), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar") - ), - :foo, - :+, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/rescue_without_begin_end.txt b/test/yarp/snapshots/whitequark/rescue_without_begin_end.txt deleted file mode 100644 index 038219dc1fc636..00000000000000 --- a/test/yarp/snapshots/whitequark/rescue_without_begin_end.txt +++ /dev/null @@ -1,60 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [CallNode(0...30)( - nil, - nil, - (0...4), - nil, - nil, - nil, - BlockNode(5...30)( - [], - nil, - BeginNode(9...30)( - nil, - StatementsNode(9...12)( - [CallNode(9...12)( - nil, - nil, - (9...12), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - RescueNode(14...25)( - (14...20), - [], - nil, - nil, - StatementsNode(22...25)( - [CallNode(22...25)( - nil, - nil, - (22...25), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil - ), - nil, - nil, - (27...30) - ), - (5...7), - (27...30) - ), - 0, - "meth" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/restarg_named.txt b/test/yarp/snapshots/whitequark/restarg_named.txt deleted file mode 100644 index d3eed889c6f03e..00000000000000 --- a/test/yarp/snapshots/whitequark/restarg_named.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [DefNode(0...16)( - :f, - (4...5), - nil, - ParametersNode(6...10)( - [], - [], - [], - RestParameterNode(6...10)(:foo, (7...10), (6...7)), - [], - nil, - nil - ), - nil, - [:foo], - (0...3), - nil, - (5...6), - (10...11), - nil, - (13...16) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/restarg_unnamed.txt b/test/yarp/snapshots/whitequark/restarg_unnamed.txt deleted file mode 100644 index a15f667603c2ea..00000000000000 --- a/test/yarp/snapshots/whitequark/restarg_unnamed.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [DefNode(0...13)( - :f, - (4...5), - nil, - ParametersNode(6...7)( - [], - [], - [], - RestParameterNode(6...7)(nil, nil, (6...7)), - [], - nil, - nil - ), - nil, - [:*], - (0...3), - nil, - (5...6), - (7...8), - nil, - (10...13) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/retry.txt b/test/yarp/snapshots/whitequark/retry.txt deleted file mode 100644 index 8963228e67bfc0..00000000000000 --- a/test/yarp/snapshots/whitequark/retry.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...5)([], StatementsNode(0...5)([RetryNode(0...5)()])) diff --git a/test/yarp/snapshots/whitequark/return.txt b/test/yarp/snapshots/whitequark/return.txt deleted file mode 100644 index 0afc3de823e8ca..00000000000000 --- a/test/yarp/snapshots/whitequark/return.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [ReturnNode(0...6)((0...6), nil), - ReturnNode(8...18)( - (8...14), - ArgumentsNode(15...18)( - [CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "foo")] - ) - ), - ReturnNode(20...28)( - (20...26), - ArgumentsNode(26...28)( - [ParenthesesNode(26...28)(nil, (26...27), (27...28))] - ) - ), - ReturnNode(30...41)( - (30...36), - ArgumentsNode(36...41)( - [ParenthesesNode(36...41)( - StatementsNode(37...40)( - [CallNode(37...40)( - nil, - nil, - (37...40), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - (36...37), - (40...41) - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/return_block.txt b/test/yarp/snapshots/whitequark/return_block.txt deleted file mode 100644 index 60f24062954bc0..00000000000000 --- a/test/yarp/snapshots/whitequark/return_block.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [ReturnNode(0...21)( - (0...6), - ArgumentsNode(7...21)( - [CallNode(7...21)( - nil, - nil, - (7...10), - nil, - ArgumentsNode(11...14)( - [CallNode(11...14)( - nil, - nil, - (11...14), - nil, - nil, - nil, - nil, - 2, - "foo" - )] - ), - nil, - BlockNode(15...21)([], nil, nil, (15...17), (18...21)), - 0, - "fun" - )] - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_10279.txt b/test/yarp/snapshots/whitequark/ruby_bug_10279.txt deleted file mode 100644 index 74c9d70fa39f9f..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_10279.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [HashNode(0...24)( - (0...1), - [AssocNode(1...23)( - SymbolNode(1...3)(nil, (1...2), (2...3), "a"), - IfNode(4...23)( - (4...6), - TrueNode(7...11)(), - StatementsNode(17...19)([IntegerNode(17...19)()]), - nil, - (20...23) - ), - nil - )], - (23...24) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_10653.txt b/test/yarp/snapshots/whitequark/ruby_bug_10653.txt deleted file mode 100644 index 9223db088bd1ec..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_10653.txt +++ /dev/null @@ -1,131 +0,0 @@ -ProgramNode(0...93)( - [], - StatementsNode(0...93)( - [IfNode(0...33)( - nil, - FalseNode(0...5)(), - StatementsNode(8...20)( - [CallNode(8...20)( - nil, - nil, - (8...13), - nil, - nil, - nil, - BlockNode(14...20)([], nil, nil, (14...16), (17...20)), - 0, - "raise" - )] - ), - ElseNode(21...33)( - (21...22), - StatementsNode(23...33)( - [CallNode(23...33)( - nil, - nil, - (23...26), - nil, - nil, - nil, - BlockNode(27...33)([], nil, nil, (27...29), (30...33)), - 0, - "tap" - )] - ), - nil - ), - nil - ), - IfNode(35...60)( - nil, - FalseNode(35...40)(), - StatementsNode(43...51)( - [CallNode(43...51)( - nil, - nil, - (43...48), - nil, - nil, - nil, - BlockNode(49...51)([], nil, nil, (49...50), (50...51)), - 0, - "raise" - )] - ), - ElseNode(52...60)( - (52...53), - StatementsNode(54...60)( - [CallNode(54...60)( - nil, - nil, - (54...57), - nil, - nil, - nil, - BlockNode(58...60)([], nil, nil, (58...59), (59...60)), - 0, - "tap" - )] - ), - nil - ), - nil - ), - IfNode(62...93)( - nil, - TrueNode(62...66)(), - StatementsNode(69...89)( - [CallNode(69...89)( - IntegerNode(69...70)(), - (70...71), - (71...74), - nil, - nil, - nil, - BlockNode(75...89)( - [:n], - BlockParametersNode(78...81)( - ParametersNode(79...80)( - [RequiredParameterNode(79...80)(:n)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (78...79), - (80...81) - ), - StatementsNode(82...85)( - [CallNode(82...85)( - nil, - nil, - (82...83), - nil, - ArgumentsNode(84...85)( - [LocalVariableReadNode(84...85)(:n, 0)] - ), - nil, - nil, - 0, - "p" - )] - ), - (75...77), - (86...89) - ), - 0, - "tap" - )] - ), - ElseNode(90...93)( - (90...91), - StatementsNode(92...93)([IntegerNode(92...93)()]), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11107.txt b/test/yarp/snapshots/whitequark/ruby_bug_11107.txt deleted file mode 100644 index c61ee9ef80d316..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11107.txt +++ /dev/null @@ -1,37 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [CallNode(0...24)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...24)( - [LambdaNode(2...24)( - [], - (2...4), - (7...9), - (21...24), - BlockParametersNode(4...6)(nil, [], (4...5), (5...6)), - StatementsNode(10...20)( - [CallNode(10...20)( - nil, - nil, - (10...11), - (11...12), - nil, - (12...13), - BlockNode(14...20)([], nil, nil, (14...16), (17...20)), - 0, - "a" - )] - ) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11380.txt b/test/yarp/snapshots/whitequark/ruby_bug_11380.txt deleted file mode 100644 index 9e89161e7817e9..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11380.txt +++ /dev/null @@ -1,34 +0,0 @@ -ProgramNode(0...28)( - [], - StatementsNode(0...28)( - [CallNode(0...28)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...21)( - [LambdaNode(2...15)( - [], - (2...4), - (5...6), - (14...15), - nil, - StatementsNode(7...13)( - [SymbolNode(7...13)((7...8), (8...13), nil, "hello")] - ) - ), - KeywordHashNode(17...21)( - [AssocNode(17...21)( - SymbolNode(17...19)(nil, (17...18), (18...19), "a"), - IntegerNode(20...21)(), - nil - )] - )] - ), - nil, - BlockNode(22...28)([], nil, nil, (22...24), (25...28)), - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11873.txt b/test/yarp/snapshots/whitequark/ruby_bug_11873.txt deleted file mode 100644 index 5c63deed0850b3..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11873.txt +++ /dev/null @@ -1,665 +0,0 @@ -ProgramNode(0...272)( - [], - StatementsNode(0...272)( - [CallNode(0...20)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...13)( - [CallNode(2...8)( - nil, - nil, - (2...3), - (3...4), - ArgumentsNode(4...7)( - [CallNode(4...7)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...7)( - [CallNode(6...7)( - nil, - nil, - (6...7), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (7...8), - nil, - 0, - "b" - ), - StringNode(10...13)((10...11), (11...12), (12...13), "x")] - ), - nil, - BlockNode(14...20)([], nil, nil, (14...16), (17...20)), - 0, - "a" - ), - CallNode(22...42)( - nil, - nil, - (22...23), - nil, - ArgumentsNode(24...35)( - [CallNode(24...30)( - nil, - nil, - (24...25), - (25...26), - ArgumentsNode(26...29)( - [CallNode(26...29)( - nil, - nil, - (26...27), - nil, - ArgumentsNode(28...29)( - [CallNode(28...29)( - nil, - nil, - (28...29), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (29...30), - nil, - 0, - "b" - ), - RegularExpressionNode(32...35)( - (32...33), - (33...34), - (34...35), - "x", - 0 - )] - ), - nil, - BlockNode(36...42)([], nil, nil, (36...38), (39...42)), - 0, - "a" - ), - CallNode(44...65)( - nil, - nil, - (44...45), - nil, - ArgumentsNode(46...58)( - [CallNode(46...52)( - nil, - nil, - (46...47), - (47...48), - ArgumentsNode(48...51)( - [CallNode(48...51)( - nil, - nil, - (48...49), - nil, - ArgumentsNode(50...51)( - [CallNode(50...51)( - nil, - nil, - (50...51), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (51...52), - nil, - 0, - "b" - ), - RegularExpressionNode(54...58)( - (54...55), - (55...56), - (56...58), - "x", - 2 - )] - ), - nil, - BlockNode(59...65)([], nil, nil, (59...61), (62...65)), - 0, - "a" - ), - CallNode(67...88)( - nil, - nil, - (67...68), - nil, - ArgumentsNode(69...81)( - [CallNode(69...76)( - nil, - nil, - (69...70), - (70...71), - ArgumentsNode(71...75)( - [CallNode(71...75)( - nil, - nil, - (71...72), - (72...73), - ArgumentsNode(73...74)( - [CallNode(73...74)( - nil, - nil, - (73...74), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (74...75), - nil, - 0, - "c" - )] - ), - (75...76), - nil, - 0, - "b" - ), - StringNode(78...81)((78...79), (79...80), (80...81), "x")] - ), - nil, - BlockNode(82...88)([], nil, nil, (82...84), (85...88)), - 0, - "a" - ), - CallNode(90...111)( - nil, - nil, - (90...91), - nil, - ArgumentsNode(92...104)( - [CallNode(92...99)( - nil, - nil, - (92...93), - (93...94), - ArgumentsNode(94...98)( - [CallNode(94...98)( - nil, - nil, - (94...95), - (95...96), - ArgumentsNode(96...97)( - [CallNode(96...97)( - nil, - nil, - (96...97), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (97...98), - nil, - 0, - "c" - )] - ), - (98...99), - nil, - 0, - "b" - ), - RegularExpressionNode(101...104)( - (101...102), - (102...103), - (103...104), - "x", - 0 - )] - ), - nil, - BlockNode(105...111)([], nil, nil, (105...107), (108...111)), - 0, - "a" - ), - CallNode(113...135)( - nil, - nil, - (113...114), - nil, - ArgumentsNode(115...128)( - [CallNode(115...122)( - nil, - nil, - (115...116), - (116...117), - ArgumentsNode(117...121)( - [CallNode(117...121)( - nil, - nil, - (117...118), - (118...119), - ArgumentsNode(119...120)( - [CallNode(119...120)( - nil, - nil, - (119...120), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (120...121), - nil, - 0, - "c" - )] - ), - (121...122), - nil, - 0, - "b" - ), - RegularExpressionNode(124...128)( - (124...125), - (125...126), - (126...128), - "x", - 2 - )] - ), - nil, - BlockNode(129...135)([], nil, nil, (129...131), (132...135)), - 0, - "a" - ), - CallNode(137...157)( - nil, - nil, - (137...138), - nil, - ArgumentsNode(139...150)( - [CallNode(139...145)( - nil, - nil, - (139...140), - nil, - nil, - nil, - BlockNode(140...145)( - [], - nil, - StatementsNode(141...144)( - [CallNode(141...144)( - nil, - nil, - (141...142), - nil, - ArgumentsNode(143...144)( - [CallNode(143...144)( - nil, - nil, - (143...144), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (140...141), - (144...145) - ), - 0, - "b" - ), - StringNode(147...150)((147...148), (148...149), (149...150), "x")] - ), - nil, - BlockNode(151...157)([], nil, nil, (151...153), (154...157)), - 0, - "a" - ), - CallNode(159...179)( - nil, - nil, - (159...160), - nil, - ArgumentsNode(161...172)( - [CallNode(161...167)( - nil, - nil, - (161...162), - nil, - nil, - nil, - BlockNode(162...167)( - [], - nil, - StatementsNode(163...166)( - [CallNode(163...166)( - nil, - nil, - (163...164), - nil, - ArgumentsNode(165...166)( - [CallNode(165...166)( - nil, - nil, - (165...166), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (162...163), - (166...167) - ), - 0, - "b" - ), - RegularExpressionNode(169...172)( - (169...170), - (170...171), - (171...172), - "x", - 0 - )] - ), - nil, - BlockNode(173...179)([], nil, nil, (173...175), (176...179)), - 0, - "a" - ), - CallNode(181...202)( - nil, - nil, - (181...182), - nil, - ArgumentsNode(183...195)( - [CallNode(183...189)( - nil, - nil, - (183...184), - nil, - nil, - nil, - BlockNode(184...189)( - [], - nil, - StatementsNode(185...188)( - [CallNode(185...188)( - nil, - nil, - (185...186), - nil, - ArgumentsNode(187...188)( - [CallNode(187...188)( - nil, - nil, - (187...188), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (184...185), - (188...189) - ), - 0, - "b" - ), - RegularExpressionNode(191...195)( - (191...192), - (192...193), - (193...195), - "x", - 2 - )] - ), - nil, - BlockNode(196...202)([], nil, nil, (196...198), (199...202)), - 0, - "a" - ), - CallNode(204...225)( - nil, - nil, - (204...205), - nil, - ArgumentsNode(206...218)( - [CallNode(206...213)( - nil, - nil, - (206...207), - nil, - nil, - nil, - BlockNode(207...213)( - [], - nil, - StatementsNode(208...212)( - [CallNode(208...212)( - nil, - nil, - (208...209), - (209...210), - ArgumentsNode(210...211)( - [CallNode(210...211)( - nil, - nil, - (210...211), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (211...212), - nil, - 0, - "c" - )] - ), - (207...208), - (212...213) - ), - 0, - "b" - ), - StringNode(215...218)((215...216), (216...217), (217...218), "x")] - ), - nil, - BlockNode(219...225)([], nil, nil, (219...221), (222...225)), - 0, - "a" - ), - CallNode(227...248)( - nil, - nil, - (227...228), - nil, - ArgumentsNode(229...241)( - [CallNode(229...236)( - nil, - nil, - (229...230), - nil, - nil, - nil, - BlockNode(230...236)( - [], - nil, - StatementsNode(231...235)( - [CallNode(231...235)( - nil, - nil, - (231...232), - (232...233), - ArgumentsNode(233...234)( - [CallNode(233...234)( - nil, - nil, - (233...234), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (234...235), - nil, - 0, - "c" - )] - ), - (230...231), - (235...236) - ), - 0, - "b" - ), - RegularExpressionNode(238...241)( - (238...239), - (239...240), - (240...241), - "x", - 0 - )] - ), - nil, - BlockNode(242...248)([], nil, nil, (242...244), (245...248)), - 0, - "a" - ), - CallNode(250...272)( - nil, - nil, - (250...251), - nil, - ArgumentsNode(252...265)( - [CallNode(252...259)( - nil, - nil, - (252...253), - nil, - nil, - nil, - BlockNode(253...259)( - [], - nil, - StatementsNode(254...258)( - [CallNode(254...258)( - nil, - nil, - (254...255), - (255...256), - ArgumentsNode(256...257)( - [CallNode(256...257)( - nil, - nil, - (256...257), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (257...258), - nil, - 0, - "c" - )] - ), - (253...254), - (258...259) - ), - 0, - "b" - ), - RegularExpressionNode(261...265)( - (261...262), - (262...263), - (263...265), - "x", - 2 - )] - ), - nil, - BlockNode(266...272)([], nil, nil, (266...268), (269...272)), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11873_a.txt b/test/yarp/snapshots/whitequark/ruby_bug_11873_a.txt deleted file mode 100644 index 5cdffe39b18bcb..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11873_a.txt +++ /dev/null @@ -1,1025 +0,0 @@ -ProgramNode(0...444)( - [], - StatementsNode(0...444)( - [CallNode(0...18)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...11)( - [CallNode(2...8)( - nil, - nil, - (2...3), - (3...4), - ArgumentsNode(4...7)( - [CallNode(4...7)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...7)( - [CallNode(6...7)( - nil, - nil, - (6...7), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (7...8), - nil, - 0, - "b" - ), - IntegerNode(10...11)()] - ), - nil, - BlockNode(12...18)([], nil, nil, (12...14), (15...18)), - 0, - "a" - ), - CallNode(20...40)( - nil, - nil, - (20...21), - nil, - ArgumentsNode(22...33)( - [CallNode(22...28)( - nil, - nil, - (22...23), - (23...24), - ArgumentsNode(24...27)( - [CallNode(24...27)( - nil, - nil, - (24...25), - nil, - ArgumentsNode(26...27)( - [CallNode(26...27)( - nil, - nil, - (26...27), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (27...28), - nil, - 0, - "b" - ), - FloatNode(30...33)()] - ), - nil, - BlockNode(34...40)([], nil, nil, (34...36), (37...40)), - 0, - "a" - ), - CallNode(42...63)( - nil, - nil, - (42...43), - nil, - ArgumentsNode(44...56)( - [CallNode(44...50)( - nil, - nil, - (44...45), - (45...46), - ArgumentsNode(46...49)( - [CallNode(46...49)( - nil, - nil, - (46...47), - nil, - ArgumentsNode(48...49)( - [CallNode(48...49)( - nil, - nil, - (48...49), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (49...50), - nil, - 0, - "b" - ), - ImaginaryNode(52...56)(FloatNode(52...55)())] - ), - nil, - BlockNode(57...63)([], nil, nil, (57...59), (60...63)), - 0, - "a" - ), - CallNode(65...86)( - nil, - nil, - (65...66), - nil, - ArgumentsNode(67...79)( - [CallNode(67...73)( - nil, - nil, - (67...68), - (68...69), - ArgumentsNode(69...72)( - [CallNode(69...72)( - nil, - nil, - (69...70), - nil, - ArgumentsNode(71...72)( - [CallNode(71...72)( - nil, - nil, - (71...72), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (72...73), - nil, - 0, - "b" - ), - RationalNode(75...79)(FloatNode(75...78)())] - ), - nil, - BlockNode(80...86)([], nil, nil, (80...82), (83...86)), - 0, - "a" - ), - CallNode(88...107)( - nil, - nil, - (88...89), - nil, - ArgumentsNode(90...100)( - [CallNode(90...96)( - nil, - nil, - (90...91), - (91...92), - ArgumentsNode(92...95)( - [CallNode(92...95)( - nil, - nil, - (92...93), - nil, - ArgumentsNode(94...95)( - [CallNode(94...95)( - nil, - nil, - (94...95), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (95...96), - nil, - 0, - "b" - ), - SymbolNode(98...100)((98...99), (99...100), nil, "e")] - ), - nil, - BlockNode(101...107)([], nil, nil, (101...103), (104...107)), - 0, - "a" - ), - CallNode(109...128)( - nil, - nil, - (109...110), - nil, - ArgumentsNode(111...121)( - [CallNode(111...118)( - nil, - nil, - (111...112), - (112...113), - ArgumentsNode(113...117)( - [CallNode(113...117)( - nil, - nil, - (113...114), - (114...115), - ArgumentsNode(115...116)( - [CallNode(115...116)( - nil, - nil, - (115...116), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (116...117), - nil, - 0, - "c" - )] - ), - (117...118), - nil, - 0, - "b" - ), - IntegerNode(120...121)()] - ), - nil, - BlockNode(122...128)([], nil, nil, (122...124), (125...128)), - 0, - "a" - ), - CallNode(130...151)( - nil, - nil, - (130...131), - nil, - ArgumentsNode(132...144)( - [CallNode(132...139)( - nil, - nil, - (132...133), - (133...134), - ArgumentsNode(134...138)( - [CallNode(134...138)( - nil, - nil, - (134...135), - (135...136), - ArgumentsNode(136...137)( - [CallNode(136...137)( - nil, - nil, - (136...137), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (137...138), - nil, - 0, - "c" - )] - ), - (138...139), - nil, - 0, - "b" - ), - FloatNode(141...144)()] - ), - nil, - BlockNode(145...151)([], nil, nil, (145...147), (148...151)), - 0, - "a" - ), - CallNode(153...175)( - nil, - nil, - (153...154), - nil, - ArgumentsNode(155...168)( - [CallNode(155...162)( - nil, - nil, - (155...156), - (156...157), - ArgumentsNode(157...161)( - [CallNode(157...161)( - nil, - nil, - (157...158), - (158...159), - ArgumentsNode(159...160)( - [CallNode(159...160)( - nil, - nil, - (159...160), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (160...161), - nil, - 0, - "c" - )] - ), - (161...162), - nil, - 0, - "b" - ), - ImaginaryNode(164...168)(FloatNode(164...167)())] - ), - nil, - BlockNode(169...175)([], nil, nil, (169...171), (172...175)), - 0, - "a" - ), - CallNode(177...199)( - nil, - nil, - (177...178), - nil, - ArgumentsNode(179...192)( - [CallNode(179...186)( - nil, - nil, - (179...180), - (180...181), - ArgumentsNode(181...185)( - [CallNode(181...185)( - nil, - nil, - (181...182), - (182...183), - ArgumentsNode(183...184)( - [CallNode(183...184)( - nil, - nil, - (183...184), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (184...185), - nil, - 0, - "c" - )] - ), - (185...186), - nil, - 0, - "b" - ), - RationalNode(188...192)(FloatNode(188...191)())] - ), - nil, - BlockNode(193...199)([], nil, nil, (193...195), (196...199)), - 0, - "a" - ), - CallNode(201...221)( - nil, - nil, - (201...202), - nil, - ArgumentsNode(203...214)( - [CallNode(203...210)( - nil, - nil, - (203...204), - (204...205), - ArgumentsNode(205...209)( - [CallNode(205...209)( - nil, - nil, - (205...206), - (206...207), - ArgumentsNode(207...208)( - [CallNode(207...208)( - nil, - nil, - (207...208), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (208...209), - nil, - 0, - "c" - )] - ), - (209...210), - nil, - 0, - "b" - ), - SymbolNode(212...214)((212...213), (213...214), nil, "e")] - ), - nil, - BlockNode(215...221)([], nil, nil, (215...217), (218...221)), - 0, - "a" - ), - CallNode(223...241)( - nil, - nil, - (223...224), - nil, - ArgumentsNode(225...234)( - [CallNode(225...231)( - nil, - nil, - (225...226), - nil, - nil, - nil, - BlockNode(226...231)( - [], - nil, - StatementsNode(227...230)( - [CallNode(227...230)( - nil, - nil, - (227...228), - nil, - ArgumentsNode(229...230)( - [CallNode(229...230)( - nil, - nil, - (229...230), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (226...227), - (230...231) - ), - 0, - "b" - ), - IntegerNode(233...234)()] - ), - nil, - BlockNode(235...241)([], nil, nil, (235...237), (238...241)), - 0, - "a" - ), - CallNode(243...263)( - nil, - nil, - (243...244), - nil, - ArgumentsNode(245...256)( - [CallNode(245...251)( - nil, - nil, - (245...246), - nil, - nil, - nil, - BlockNode(246...251)( - [], - nil, - StatementsNode(247...250)( - [CallNode(247...250)( - nil, - nil, - (247...248), - nil, - ArgumentsNode(249...250)( - [CallNode(249...250)( - nil, - nil, - (249...250), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (246...247), - (250...251) - ), - 0, - "b" - ), - FloatNode(253...256)()] - ), - nil, - BlockNode(257...263)([], nil, nil, (257...259), (260...263)), - 0, - "a" - ), - CallNode(265...286)( - nil, - nil, - (265...266), - nil, - ArgumentsNode(267...279)( - [CallNode(267...273)( - nil, - nil, - (267...268), - nil, - nil, - nil, - BlockNode(268...273)( - [], - nil, - StatementsNode(269...272)( - [CallNode(269...272)( - nil, - nil, - (269...270), - nil, - ArgumentsNode(271...272)( - [CallNode(271...272)( - nil, - nil, - (271...272), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (268...269), - (272...273) - ), - 0, - "b" - ), - ImaginaryNode(275...279)(FloatNode(275...278)())] - ), - nil, - BlockNode(280...286)([], nil, nil, (280...282), (283...286)), - 0, - "a" - ), - CallNode(288...309)( - nil, - nil, - (288...289), - nil, - ArgumentsNode(290...302)( - [CallNode(290...296)( - nil, - nil, - (290...291), - nil, - nil, - nil, - BlockNode(291...296)( - [], - nil, - StatementsNode(292...295)( - [CallNode(292...295)( - nil, - nil, - (292...293), - nil, - ArgumentsNode(294...295)( - [CallNode(294...295)( - nil, - nil, - (294...295), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (291...292), - (295...296) - ), - 0, - "b" - ), - RationalNode(298...302)(FloatNode(298...301)())] - ), - nil, - BlockNode(303...309)([], nil, nil, (303...305), (306...309)), - 0, - "a" - ), - CallNode(311...330)( - nil, - nil, - (311...312), - nil, - ArgumentsNode(313...323)( - [CallNode(313...319)( - nil, - nil, - (313...314), - nil, - nil, - nil, - BlockNode(314...319)( - [], - nil, - StatementsNode(315...318)( - [CallNode(315...318)( - nil, - nil, - (315...316), - nil, - ArgumentsNode(317...318)( - [CallNode(317...318)( - nil, - nil, - (317...318), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - nil, - nil, - 0, - "c" - )] - ), - (314...315), - (318...319) - ), - 0, - "b" - ), - SymbolNode(321...323)((321...322), (322...323), nil, "e")] - ), - nil, - BlockNode(324...330)([], nil, nil, (324...326), (327...330)), - 0, - "a" - ), - CallNode(332...351)( - nil, - nil, - (332...333), - nil, - ArgumentsNode(334...344)( - [CallNode(334...341)( - nil, - nil, - (334...335), - nil, - nil, - nil, - BlockNode(335...341)( - [], - nil, - StatementsNode(336...340)( - [CallNode(336...340)( - nil, - nil, - (336...337), - (337...338), - ArgumentsNode(338...339)( - [CallNode(338...339)( - nil, - nil, - (338...339), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (339...340), - nil, - 0, - "c" - )] - ), - (335...336), - (340...341) - ), - 0, - "b" - ), - IntegerNode(343...344)()] - ), - nil, - BlockNode(345...351)([], nil, nil, (345...347), (348...351)), - 0, - "a" - ), - CallNode(353...374)( - nil, - nil, - (353...354), - nil, - ArgumentsNode(355...367)( - [CallNode(355...362)( - nil, - nil, - (355...356), - nil, - nil, - nil, - BlockNode(356...362)( - [], - nil, - StatementsNode(357...361)( - [CallNode(357...361)( - nil, - nil, - (357...358), - (358...359), - ArgumentsNode(359...360)( - [CallNode(359...360)( - nil, - nil, - (359...360), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (360...361), - nil, - 0, - "c" - )] - ), - (356...357), - (361...362) - ), - 0, - "b" - ), - FloatNode(364...367)()] - ), - nil, - BlockNode(368...374)([], nil, nil, (368...370), (371...374)), - 0, - "a" - ), - CallNode(376...398)( - nil, - nil, - (376...377), - nil, - ArgumentsNode(378...391)( - [CallNode(378...385)( - nil, - nil, - (378...379), - nil, - nil, - nil, - BlockNode(379...385)( - [], - nil, - StatementsNode(380...384)( - [CallNode(380...384)( - nil, - nil, - (380...381), - (381...382), - ArgumentsNode(382...383)( - [CallNode(382...383)( - nil, - nil, - (382...383), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (383...384), - nil, - 0, - "c" - )] - ), - (379...380), - (384...385) - ), - 0, - "b" - ), - ImaginaryNode(387...391)(FloatNode(387...390)())] - ), - nil, - BlockNode(392...398)([], nil, nil, (392...394), (395...398)), - 0, - "a" - ), - CallNode(400...422)( - nil, - nil, - (400...401), - nil, - ArgumentsNode(402...415)( - [CallNode(402...409)( - nil, - nil, - (402...403), - nil, - nil, - nil, - BlockNode(403...409)( - [], - nil, - StatementsNode(404...408)( - [CallNode(404...408)( - nil, - nil, - (404...405), - (405...406), - ArgumentsNode(406...407)( - [CallNode(406...407)( - nil, - nil, - (406...407), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (407...408), - nil, - 0, - "c" - )] - ), - (403...404), - (408...409) - ), - 0, - "b" - ), - RationalNode(411...415)(FloatNode(411...414)())] - ), - nil, - BlockNode(416...422)([], nil, nil, (416...418), (419...422)), - 0, - "a" - ), - CallNode(424...444)( - nil, - nil, - (424...425), - nil, - ArgumentsNode(426...437)( - [CallNode(426...433)( - nil, - nil, - (426...427), - nil, - nil, - nil, - BlockNode(427...433)( - [], - nil, - StatementsNode(428...432)( - [CallNode(428...432)( - nil, - nil, - (428...429), - (429...430), - ArgumentsNode(430...431)( - [CallNode(430...431)( - nil, - nil, - (430...431), - nil, - nil, - nil, - nil, - 2, - "d" - )] - ), - (431...432), - nil, - 0, - "c" - )] - ), - (427...428), - (432...433) - ), - 0, - "b" - ), - SymbolNode(435...437)((435...436), (436...437), nil, "e")] - ), - nil, - BlockNode(438...444)([], nil, nil, (438...440), (441...444)), - 0, - "a" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11873_b.txt b/test/yarp/snapshots/whitequark/ruby_bug_11873_b.txt deleted file mode 100644 index f1a840a8923abb..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11873_b.txt +++ /dev/null @@ -1,82 +0,0 @@ -ProgramNode(0...25)( - [], - StatementsNode(0...25)( - [CallNode(0...25)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...18)( - [CallNode(2...13)( - nil, - nil, - (2...3), - nil, - nil, - nil, - BlockNode(3...13)( - [], - nil, - StatementsNode(4...12)( - [CallNode(4...8)( - nil, - nil, - (4...5), - (5...6), - ArgumentsNode(6...7)( - [CallNode(6...7)( - nil, - nil, - (6...7), - nil, - nil, - nil, - nil, - 2, - "p" - )] - ), - (7...8), - nil, - 0, - "p" - ), - CallNode(9...12)( - nil, - nil, - (9...10), - nil, - ArgumentsNode(11...12)( - [CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "p" - )] - ), - nil, - nil, - 0, - "p" - )] - ), - (3...4), - (12...13) - ), - 0, - "p" - ), - CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "tap")] - ), - nil, - BlockNode(19...25)([], nil, nil, (19...21), (22...25)), - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11989.txt b/test/yarp/snapshots/whitequark/ruby_bug_11989.txt deleted file mode 100644 index 847bc83fac538c..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11989.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...8)( - [InterpolatedStringNode(2...8)( - (2...8), - [StringNode(9...19)(nil, (9...19), nil, "x\n" + " y\n")], - (19...21) - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_11990.txt b/test/yarp/snapshots/whitequark/ruby_bug_11990.txt deleted file mode 100644 index 379407bffb1c32..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_11990.txt +++ /dev/null @@ -1,25 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...12)( - [StringConcatNode(2...12)( - InterpolatedStringNode(2...6)( - (2...6), - [StringNode(13...17)(nil, (13...17), nil, "x\n")], - (17...19) - ), - StringNode(7...12)((7...8), (8...11), (11...12), " y") - )] - ), - nil, - nil, - 0, - "p" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt b/test/yarp/snapshots/whitequark/ruby_bug_12073.txt deleted file mode 100644 index 29ac50831d05a7..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt +++ /dev/null @@ -1,72 +0,0 @@ -ProgramNode(0...49)( - [:a], - StatementsNode(0...49)( - [LocalVariableWriteNode(0...5)( - :a, - 0, - (0...1), - IntegerNode(4...5)(), - (2...3) - ), - CallNode(7...13)( - nil, - nil, - (7...8), - nil, - ArgumentsNode(9...13)( - [KeywordHashNode(9...13)( - [AssocNode(9...13)( - SymbolNode(9...11)(nil, (9...10), (10...11), "b"), - IntegerNode(12...13)(), - nil - )] - )] - ), - nil, - nil, - 0, - "a" - ), - DefNode(15...49)( - :foo, - (19...22), - nil, - ParametersNode(23...28)( - [RequiredParameterNode(23...28)(:raise)], - [], - [], - nil, - [], - nil, - nil - ), - StatementsNode(30...44)( - [CallNode(30...44)( - nil, - nil, - (30...35), - nil, - ArgumentsNode(36...44)( - [ConstantPathNode(36...40)( - ConstantReadNode(36...37)(:A), - ConstantReadNode(39...40)(:B), - (37...39) - ), - StringNode(42...44)((42...43), (43...43), (43...44), "")] - ), - nil, - nil, - 0, - "raise" - )] - ), - [:raise], - (15...18), - nil, - nil, - nil, - nil, - (46...49) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12402.txt b/test/yarp/snapshots/whitequark/ruby_bug_12402.txt deleted file mode 100644 index 2f7562fd20b22d..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_12402.txt +++ /dev/null @@ -1,529 +0,0 @@ -ProgramNode(0...437)( - [:foo], - StatementsNode(0...437)( - [LocalVariableOperatorWriteNode(0...27)( - (0...3), - (4...6), - CallNode(7...27)( - nil, - nil, - (7...12), - nil, - ArgumentsNode(13...27)( - [RescueModifierNode(13...27)( - CallNode(13...16)( - nil, - nil, - (13...16), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (17...23), - NilNode(24...27)() - )] - ), - nil, - nil, - 0, - "raise" - ), - :foo, - :+, - 0 - ), - LocalVariableOperatorWriteNode(29...57)( - (29...32), - (33...35), - RescueModifierNode(36...57)( - CallNode(36...46)( - nil, - nil, - (36...41), - (41...42), - ArgumentsNode(42...45)( - [CallNode(42...45)( - nil, - nil, - (42...45), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (45...46), - nil, - 0, - "raise" - ), - (47...53), - NilNode(54...57)() - ), - :foo, - :+, - 0 - ), - LocalVariableWriteNode(59...85)( - :foo, - 0, - (59...62), - CallNode(65...85)( - nil, - nil, - (65...70), - nil, - ArgumentsNode(71...85)( - [RescueModifierNode(71...85)( - CallNode(71...74)( - nil, - nil, - (71...74), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (75...81), - NilNode(82...85)() - )] - ), - nil, - nil, - 0, - "raise" - ), - (63...64) - ), - LocalVariableWriteNode(87...114)( - :foo, - 0, - (87...90), - RescueModifierNode(93...114)( - CallNode(93...103)( - nil, - nil, - (93...98), - (98...99), - ArgumentsNode(99...102)( - [CallNode(99...102)( - nil, - nil, - (99...102), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (102...103), - nil, - 0, - "raise" - ), - (104...110), - NilNode(111...114)() - ), - (91...92) - ), - CallOperatorWriteNode(116...145)( - LocalVariableReadNode(116...119)(:foo, 0), - (119...120), - (120...121), - nil, - nil, - nil, - 0, - "C", - "C=", - :+, - (122...124), - CallNode(125...145)( - nil, - nil, - (125...130), - nil, - ArgumentsNode(131...145)( - [RescueModifierNode(131...145)( - CallNode(131...134)( - nil, - nil, - (131...134), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (135...141), - NilNode(142...145)() - )] - ), - nil, - nil, - 0, - "raise" - ) - ), - CallOperatorWriteNode(147...177)( - LocalVariableReadNode(147...150)(:foo, 0), - (150...151), - (151...152), - nil, - nil, - nil, - 0, - "C", - "C=", - :+, - (153...155), - RescueModifierNode(156...177)( - CallNode(156...166)( - nil, - nil, - (156...161), - (161...162), - ArgumentsNode(162...165)( - [CallNode(162...165)( - nil, - nil, - (162...165), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (165...166), - nil, - 0, - "raise" - ), - (167...173), - NilNode(174...177)() - ) - ), - CallOperatorWriteNode(179...208)( - LocalVariableReadNode(179...182)(:foo, 0), - (182...183), - (183...184), - nil, - nil, - nil, - 0, - "m", - "m=", - :+, - (185...187), - CallNode(188...208)( - nil, - nil, - (188...193), - nil, - ArgumentsNode(194...208)( - [RescueModifierNode(194...208)( - CallNode(194...197)( - nil, - nil, - (194...197), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (198...204), - NilNode(205...208)() - )] - ), - nil, - nil, - 0, - "raise" - ) - ), - CallOperatorWriteNode(210...240)( - LocalVariableReadNode(210...213)(:foo, 0), - (213...214), - (214...215), - nil, - nil, - nil, - 0, - "m", - "m=", - :+, - (216...218), - RescueModifierNode(219...240)( - CallNode(219...229)( - nil, - nil, - (219...224), - (224...225), - ArgumentsNode(225...228)( - [CallNode(225...228)( - nil, - nil, - (225...228), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (228...229), - nil, - 0, - "raise" - ), - (230...236), - NilNode(237...240)() - ) - ), - ConstantPathOrWriteNode(242...273)( - ConstantPathNode(242...248)( - LocalVariableReadNode(242...245)(:foo, 0), - ConstantReadNode(247...248)(:C), - (245...247) - ), - (249...252), - CallNode(253...273)( - nil, - nil, - (253...258), - nil, - ArgumentsNode(259...273)( - [RescueModifierNode(259...273)( - CallNode(259...262)( - nil, - nil, - (259...262), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (263...269), - NilNode(270...273)() - )] - ), - nil, - nil, - 0, - "raise" - ) - ), - ConstantPathOrWriteNode(275...307)( - ConstantPathNode(275...281)( - LocalVariableReadNode(275...278)(:foo, 0), - ConstantReadNode(280...281)(:C), - (278...280) - ), - (282...285), - RescueModifierNode(286...307)( - CallNode(286...296)( - nil, - nil, - (286...291), - (291...292), - ArgumentsNode(292...295)( - [CallNode(292...295)( - nil, - nil, - (292...295), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (295...296), - nil, - 0, - "raise" - ), - (297...303), - NilNode(304...307)() - ) - ), - CallOperatorWriteNode(309...339)( - LocalVariableReadNode(309...312)(:foo, 0), - (312...314), - (314...315), - nil, - nil, - nil, - 0, - "m", - "m=", - :+, - (316...318), - CallNode(319...339)( - nil, - nil, - (319...324), - nil, - ArgumentsNode(325...339)( - [RescueModifierNode(325...339)( - CallNode(325...328)( - nil, - nil, - (325...328), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (329...335), - NilNode(336...339)() - )] - ), - nil, - nil, - 0, - "raise" - ) - ), - CallOperatorWriteNode(341...372)( - LocalVariableReadNode(341...344)(:foo, 0), - (344...346), - (346...347), - nil, - nil, - nil, - 0, - "m", - "m=", - :+, - (348...350), - RescueModifierNode(351...372)( - CallNode(351...361)( - nil, - nil, - (351...356), - (356...357), - ArgumentsNode(357...360)( - [CallNode(357...360)( - nil, - nil, - (357...360), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (360...361), - nil, - 0, - "raise" - ), - (362...368), - NilNode(369...372)() - ) - ), - CallOperatorWriteNode(374...404)( - LocalVariableReadNode(374...377)(:foo, 0), - nil, - (377...380), - (377...378), - ArgumentsNode(378...379)([IntegerNode(378...379)()]), - (379...380), - 0, - "[]", - "[]=", - :+, - (381...383), - CallNode(384...404)( - nil, - nil, - (384...389), - nil, - ArgumentsNode(390...404)( - [RescueModifierNode(390...404)( - CallNode(390...393)( - nil, - nil, - (390...393), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (394...400), - NilNode(401...404)() - )] - ), - nil, - nil, - 0, - "raise" - ) - ), - CallOperatorWriteNode(406...437)( - LocalVariableReadNode(406...409)(:foo, 0), - nil, - (409...412), - (409...410), - ArgumentsNode(410...411)([IntegerNode(410...411)()]), - (411...412), - 0, - "[]", - "[]=", - :+, - (413...415), - RescueModifierNode(416...437)( - CallNode(416...426)( - nil, - nil, - (416...421), - (421...422), - ArgumentsNode(422...425)( - [CallNode(422...425)( - nil, - nil, - (422...425), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (425...426), - nil, - 0, - "raise" - ), - (427...433), - NilNode(434...437)() - ) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12669.txt b/test/yarp/snapshots/whitequark/ruby_bug_12669.txt deleted file mode 100644 index 689a3d9a77a245..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_12669.txt +++ /dev/null @@ -1,109 +0,0 @@ -ProgramNode(0...74)( - [:a, :b], - StatementsNode(0...74)( - [LocalVariableOperatorWriteNode(0...18)( - (0...1), - (2...4), - LocalVariableOperatorWriteNode(5...18)( - (5...6), - (7...9), - CallNode(10...18)( - nil, - nil, - (10...15), - nil, - ArgumentsNode(16...18)( - [SymbolNode(16...18)((16...17), (17...18), nil, "x")] - ), - nil, - nil, - 0, - "raise" - ), - :b, - :+, - 0 - ), - :a, - :+, - 0 - ), - LocalVariableOperatorWriteNode(20...37)( - (20...21), - (22...24), - LocalVariableWriteNode(25...37)( - :b, - 0, - (25...26), - CallNode(29...37)( - nil, - nil, - (29...34), - nil, - ArgumentsNode(35...37)( - [SymbolNode(35...37)((35...36), (36...37), nil, "x")] - ), - nil, - nil, - 0, - "raise" - ), - (27...28) - ), - :a, - :+, - 0 - ), - LocalVariableWriteNode(39...56)( - :a, - 0, - (39...40), - LocalVariableOperatorWriteNode(43...56)( - (43...44), - (45...47), - CallNode(48...56)( - nil, - nil, - (48...53), - nil, - ArgumentsNode(54...56)( - [SymbolNode(54...56)((54...55), (55...56), nil, "x")] - ), - nil, - nil, - 0, - "raise" - ), - :b, - :+, - 0 - ), - (41...42) - ), - LocalVariableWriteNode(58...74)( - :a, - 0, - (58...59), - LocalVariableWriteNode(62...74)( - :b, - 0, - (62...63), - CallNode(66...74)( - nil, - nil, - (66...71), - nil, - ArgumentsNode(72...74)( - [SymbolNode(72...74)((72...73), (73...74), nil, "x")] - ), - nil, - nil, - 0, - "raise" - ), - (64...65) - ), - (60...61) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12686.txt b/test/yarp/snapshots/whitequark/ruby_bug_12686.txt deleted file mode 100644 index f0ae6d107494fd..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_12686.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...16)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...16)( - [ParenthesesNode(2...16)( - StatementsNode(3...15)( - [RescueModifierNode(3...15)( - CallNode(3...4)( - nil, - nil, - (3...4), - nil, - nil, - nil, - nil, - 2, - "g" - ), - (5...11), - NilNode(12...15)() - )] - ), - (2...3), - (15...16) - )] - ), - nil, - nil, - 0, - "f" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_13547.txt b/test/yarp/snapshots/whitequark/ruby_bug_13547.txt deleted file mode 100644 index c0e5ccd927151e..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_13547.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(0...4)(nil, nil, (0...4), nil, nil, nil, nil, 2, "meth"), - nil, - (4...6), - (4...5), - nil, - (5...6), - BlockNode(7...9)([], nil, nil, (7...8), (8...9)), - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_14690.txt b/test/yarp/snapshots/whitequark/ruby_bug_14690.txt deleted file mode 100644 index 743cf8b7b6e1b7..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_14690.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...23)( - [], - StatementsNode(0...23)( - [CallNode(0...23)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...6)([ParenthesesNode(4...6)(nil, (4...5), (5...6))]), - nil, - BlockNode(7...23)( - [], - nil, - StatementsNode(9...21)( - [CallNode(9...21)( - nil, - nil, - (9...10), - (10...11), - ArgumentsNode(11...12)( - [CallNode(11...12)( - nil, - nil, - (11...12), - nil, - nil, - nil, - nil, - 2, - "a" - )] - ), - (12...13), - BlockNode(14...21)([], nil, nil, (14...16), (18...21)), - 0, - "m" - )] - ), - (7...8), - (22...23) - ), - 0, - "let" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_15789.txt b/test/yarp/snapshots/whitequark/ruby_bug_15789.txt deleted file mode 100644 index 9066a4032bbdec..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_15789.txt +++ /dev/null @@ -1,118 +0,0 @@ -ProgramNode(0...41)( - [], - StatementsNode(0...41)( - [CallNode(0...20)( - nil, - nil, - (0...1), - nil, - ArgumentsNode(2...20)( - [LambdaNode(2...20)( - [:a], - (2...4), - (17...18), - (19...20), - BlockParametersNode(4...16)( - ParametersNode(5...15)( - [], - [OptionalParameterNode(5...15)( - :a, - (5...6), - (7...8), - LambdaNode(9...15)( - [], - (9...11), - (11...12), - (14...15), - nil, - StatementsNode(12...14)( - [CallNode(12...14)( - nil, - nil, - (12...14), - nil, - nil, - nil, - nil, - 2, - "_1" - )] - ) - ) - )], - [], - nil, - [], - nil, - nil - ), - [], - (4...5), - (15...16) - ), - StatementsNode(18...19)([LocalVariableReadNode(18...19)(:a, 0)]) - )] - ), - nil, - nil, - 0, - "m" - ), - CallNode(22...41)( - nil, - nil, - (22...23), - nil, - ArgumentsNode(24...41)( - [LambdaNode(24...41)( - [:a], - (24...26), - (38...39), - (40...41), - BlockParametersNode(26...37)( - ParametersNode(27...36)( - [], - [], - [], - nil, - [KeywordParameterNode(27...36)( - :a, - (27...29), - LambdaNode(30...36)( - [], - (30...32), - (32...33), - (35...36), - nil, - StatementsNode(33...35)( - [CallNode(33...35)( - nil, - nil, - (33...35), - nil, - nil, - nil, - nil, - 2, - "_1" - )] - ) - ) - )], - nil, - nil - ), - [], - (26...27), - (36...37) - ), - StatementsNode(39...40)([LocalVariableReadNode(39...40)(:a, 0)]) - )] - ), - nil, - nil, - 0, - "m" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt deleted file mode 100644 index c79fad99415a43..00000000000000 --- a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt +++ /dev/null @@ -1,42 +0,0 @@ -ProgramNode(0...33)( - [:o], - StatementsNode(0...33)( - [DefNode(0...19)( - :a, - (4...5), - nil, - ParametersNode(6...8)( - [], - [], - [], - nil, - [KeywordParameterNode(6...8)(:b, (6...8), nil)], - nil, - nil - ), - StatementsNode(9...15)([ReturnNode(9...15)((9...15), nil)]), - [:b], - (0...3), - nil, - nil, - nil, - nil, - (16...19) - ), - LocalVariableWriteNode(21...33)( - :o, - 0, - (21...22), - HashNode(25...33)( - (25...26), - [AssocNode(27...31)( - SymbolNode(27...29)(nil, (27...28), (28...29), "a"), - IntegerNode(30...31)(), - nil - )], - (32...33) - ), - (23...24) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/sclass.txt b/test/yarp/snapshots/whitequark/sclass.txt deleted file mode 100644 index a8beb303ebf774..00000000000000 --- a/test/yarp/snapshots/whitequark/sclass.txt +++ /dev/null @@ -1,13 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [SingletonClassNode(0...22)( - [], - (0...5), - (6...8), - CallNode(9...12)(nil, nil, (9...12), nil, nil, nil, nil, 2, "foo"), - StatementsNode(14...17)([NilNode(14...17)()]), - (19...22) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/self.txt b/test/yarp/snapshots/whitequark/self.txt deleted file mode 100644 index 0002d6ee6d48dc..00000000000000 --- a/test/yarp/snapshots/whitequark/self.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...4)([], StatementsNode(0...4)([SelfNode(0...4)()])) diff --git a/test/yarp/snapshots/whitequark/send_attr_asgn.txt b/test/yarp/snapshots/whitequark/send_attr_asgn.txt deleted file mode 100644 index b4b3d5706433c5..00000000000000 --- a/test/yarp/snapshots/whitequark/send_attr_asgn.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...44)( - [], - StatementsNode(0...44)( - [CallNode(0...9)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...5), - nil, - ArgumentsNode(8...9)([IntegerNode(8...9)()]), - nil, - nil, - 0, - "A=" - ), - CallNode(11...20)( - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - (14...15), - (15...16), - nil, - ArgumentsNode(19...20)([IntegerNode(19...20)()]), - nil, - nil, - 0, - "a=" - ), - ConstantPathWriteNode(22...32)( - ConstantPathNode(22...28)( - CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "foo"), - ConstantReadNode(27...28)(:A), - (25...27) - ), - (29...30), - IntegerNode(31...32)() - ), - CallNode(34...44)( - CallNode(34...37)(nil, nil, (34...37), nil, nil, nil, nil, 2, "foo"), - (37...39), - (39...40), - nil, - ArgumentsNode(43...44)([IntegerNode(43...44)()]), - nil, - nil, - 0, - "a=" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_attr_asgn_conditional.txt b/test/yarp/snapshots/whitequark/send_attr_asgn_conditional.txt deleted file mode 100644 index a48f189f41a122..00000000000000 --- a/test/yarp/snapshots/whitequark/send_attr_asgn_conditional.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - ArgumentsNode(7...8)([IntegerNode(7...8)()]), - nil, - nil, - 1, - "b=" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_binary_op.txt b/test/yarp/snapshots/whitequark/send_binary_op.txt deleted file mode 100644 index aadcb1fcb9dea3..00000000000000 --- a/test/yarp/snapshots/whitequark/send_binary_op.txt +++ /dev/null @@ -1,336 +0,0 @@ -ProgramNode(0...200)( - [], - StatementsNode(0...200)( - [CallNode(0...8)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (4...6), - nil, - ArgumentsNode(7...8)([IntegerNode(7...8)()]), - nil, - nil, - 0, - "!=" - ), - CallNode(10...18)( - CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo"), - nil, - (14...16), - nil, - ArgumentsNode(17...18)([IntegerNode(17...18)()]), - nil, - nil, - 0, - "!~" - ), - CallNode(20...27)( - CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "foo"), - nil, - (24...25), - nil, - ArgumentsNode(26...27)([IntegerNode(26...27)()]), - nil, - nil, - 0, - "%" - ), - CallNode(29...36)( - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "foo"), - nil, - (33...34), - nil, - ArgumentsNode(35...36)([IntegerNode(35...36)()]), - nil, - nil, - 0, - "&" - ), - CallNode(38...45)( - CallNode(38...41)(nil, nil, (38...41), nil, nil, nil, nil, 2, "foo"), - nil, - (42...43), - nil, - ArgumentsNode(44...45)([IntegerNode(44...45)()]), - nil, - nil, - 0, - "*" - ), - CallNode(47...55)( - CallNode(47...50)(nil, nil, (47...50), nil, nil, nil, nil, 2, "foo"), - nil, - (51...53), - nil, - ArgumentsNode(54...55)([IntegerNode(54...55)()]), - nil, - nil, - 0, - "**" - ), - CallNode(57...64)( - CallNode(57...60)(nil, nil, (57...60), nil, nil, nil, nil, 2, "foo"), - nil, - (61...62), - nil, - ArgumentsNode(63...64)([IntegerNode(63...64)()]), - nil, - nil, - 0, - "+" - ), - CallNode(66...73)( - CallNode(66...69)(nil, nil, (66...69), nil, nil, nil, nil, 2, "foo"), - nil, - (70...71), - nil, - ArgumentsNode(72...73)([IntegerNode(72...73)()]), - nil, - nil, - 0, - "-" - ), - CallNode(75...82)( - CallNode(75...78)(nil, nil, (75...78), nil, nil, nil, nil, 2, "foo"), - nil, - (79...80), - nil, - ArgumentsNode(81...82)([IntegerNode(81...82)()]), - nil, - nil, - 0, - "/" - ), - CallNode(84...91)( - CallNode(84...87)(nil, nil, (84...87), nil, nil, nil, nil, 2, "foo"), - nil, - (88...89), - nil, - ArgumentsNode(90...91)([IntegerNode(90...91)()]), - nil, - nil, - 0, - "<" - ), - CallNode(93...101)( - CallNode(93...96)(nil, nil, (93...96), nil, nil, nil, nil, 2, "foo"), - nil, - (97...99), - nil, - ArgumentsNode(100...101)([IntegerNode(100...101)()]), - nil, - nil, - 0, - "<<" - ), - CallNode(103...111)( - CallNode(103...106)( - nil, - nil, - (103...106), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (107...109), - nil, - ArgumentsNode(110...111)([IntegerNode(110...111)()]), - nil, - nil, - 0, - "<=" - ), - CallNode(113...122)( - CallNode(113...116)( - nil, - nil, - (113...116), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (117...120), - nil, - ArgumentsNode(121...122)([IntegerNode(121...122)()]), - nil, - nil, - 0, - "<=>" - ), - CallNode(124...132)( - CallNode(124...127)( - nil, - nil, - (124...127), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (128...130), - nil, - ArgumentsNode(131...132)([IntegerNode(131...132)()]), - nil, - nil, - 0, - "==" - ), - CallNode(134...143)( - CallNode(134...137)( - nil, - nil, - (134...137), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (138...141), - nil, - ArgumentsNode(142...143)([IntegerNode(142...143)()]), - nil, - nil, - 0, - "===" - ), - CallNode(145...153)( - CallNode(145...148)( - nil, - nil, - (145...148), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (149...151), - nil, - ArgumentsNode(152...153)([IntegerNode(152...153)()]), - nil, - nil, - 0, - "=~" - ), - CallNode(155...162)( - CallNode(155...158)( - nil, - nil, - (155...158), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (159...160), - nil, - ArgumentsNode(161...162)([IntegerNode(161...162)()]), - nil, - nil, - 0, - ">" - ), - CallNode(164...172)( - CallNode(164...167)( - nil, - nil, - (164...167), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (168...170), - nil, - ArgumentsNode(171...172)([IntegerNode(171...172)()]), - nil, - nil, - 0, - ">=" - ), - CallNode(174...182)( - CallNode(174...177)( - nil, - nil, - (174...177), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (178...180), - nil, - ArgumentsNode(181...182)([IntegerNode(181...182)()]), - nil, - nil, - 0, - ">>" - ), - CallNode(184...191)( - CallNode(184...187)( - nil, - nil, - (184...187), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (188...189), - nil, - ArgumentsNode(190...191)([IntegerNode(190...191)()]), - nil, - nil, - 0, - "^" - ), - CallNode(193...200)( - CallNode(193...196)( - nil, - nil, - (193...196), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - nil, - (197...198), - nil, - ArgumentsNode(199...200)([IntegerNode(199...200)()]), - nil, - nil, - 0, - "|" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_block_chain_cmd.txt b/test/yarp/snapshots/whitequark/send_block_chain_cmd.txt deleted file mode 100644 index c9d9a3662887eb..00000000000000 --- a/test/yarp/snapshots/whitequark/send_block_chain_cmd.txt +++ /dev/null @@ -1,194 +0,0 @@ -ProgramNode(0...173)( - [], - StatementsNode(0...173)( - [CallNode(0...21)( - CallNode(0...13)( - nil, - nil, - (0...4), - nil, - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - nil, - BlockNode(7...13)([], nil, nil, (7...9), (10...13)), - 0, - "meth" - ), - (13...14), - (14...17), - nil, - ArgumentsNode(18...21)( - [CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "fun" - ), - CallNode(23...51)( - CallNode(23...36)( - nil, - nil, - (23...27), - nil, - ArgumentsNode(28...29)([IntegerNode(28...29)()]), - nil, - BlockNode(30...36)([], nil, nil, (30...32), (33...36)), - 0, - "meth" - ), - (36...37), - (37...40), - nil, - ArgumentsNode(41...44)( - [CallNode(41...44)(nil, nil, (41...44), nil, nil, nil, nil, 2, "bar")] - ), - nil, - BlockNode(45...51)([], nil, nil, (45...47), (48...51)), - 0, - "fun" - ), - CallNode(53...73)( - CallNode(53...66)( - nil, - nil, - (53...57), - nil, - ArgumentsNode(58...59)([IntegerNode(58...59)()]), - nil, - BlockNode(60...66)([], nil, nil, (60...62), (63...66)), - 0, - "meth" - ), - (66...67), - (67...70), - nil, - nil, - nil, - BlockNode(71...73)([], nil, nil, (71...72), (72...73)), - 0, - "fun" - ), - CallNode(75...97)( - CallNode(75...88)( - nil, - nil, - (75...79), - nil, - ArgumentsNode(80...81)([IntegerNode(80...81)()]), - nil, - BlockNode(82...88)([], nil, nil, (82...84), (85...88)), - 0, - "meth" - ), - (88...89), - (89...92), - (92...93), - ArgumentsNode(93...96)( - [CallNode(93...96)(nil, nil, (93...96), nil, nil, nil, nil, 2, "bar")] - ), - (96...97), - nil, - 0, - "fun" - ), - CallNode(99...124)( - CallNode(99...112)( - nil, - nil, - (99...103), - nil, - ArgumentsNode(104...105)([IntegerNode(104...105)()]), - nil, - BlockNode(106...112)([], nil, nil, (106...108), (109...112)), - 0, - "meth" - ), - (112...113), - (113...116), - (116...117), - ArgumentsNode(117...120)( - [CallNode(117...120)( - nil, - nil, - (117...120), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (120...121), - BlockNode(122...124)([], nil, nil, (122...123), (123...124)), - 0, - "fun" - ), - CallNode(126...148)( - CallNode(126...139)( - nil, - nil, - (126...130), - nil, - ArgumentsNode(131...132)([IntegerNode(131...132)()]), - nil, - BlockNode(133...139)([], nil, nil, (133...135), (136...139)), - 0, - "meth" - ), - (139...141), - (141...144), - nil, - ArgumentsNode(145...148)( - [CallNode(145...148)( - nil, - nil, - (145...148), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "fun" - ), - CallNode(150...173)( - CallNode(150...163)( - nil, - nil, - (150...154), - nil, - ArgumentsNode(155...156)([IntegerNode(155...156)()]), - nil, - BlockNode(157...163)([], nil, nil, (157...159), (160...163)), - 0, - "meth" - ), - (163...165), - (165...168), - (168...169), - ArgumentsNode(169...172)( - [CallNode(169...172)( - nil, - nil, - (169...172), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (172...173), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_block_conditional.txt b/test/yarp/snapshots/whitequark/send_block_conditional.txt deleted file mode 100644 index 3ac7347f7ab21b..00000000000000 --- a/test/yarp/snapshots/whitequark/send_block_conditional.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...5), - (5...8), - nil, - nil, - nil, - BlockNode(9...11)([], nil, nil, (9...10), (10...11)), - 1, - "bar" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_call.txt b/test/yarp/snapshots/whitequark/send_call.txt deleted file mode 100644 index f96195145baf54..00000000000000 --- a/test/yarp/snapshots/whitequark/send_call.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...7)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - nil, - (4...5), - ArgumentsNode(5...6)([IntegerNode(5...6)()]), - (6...7), - nil, - 0, - "call" - ), - CallNode(9...17)( - CallNode(9...12)(nil, nil, (9...12), nil, nil, nil, nil, 2, "foo"), - (12...14), - nil, - (14...15), - ArgumentsNode(15...16)([IntegerNode(15...16)()]), - (16...17), - nil, - 0, - "call" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_conditional.txt b/test/yarp/snapshots/whitequark/send_conditional.txt deleted file mode 100644 index d170db0f559f59..00000000000000 --- a/test/yarp/snapshots/whitequark/send_conditional.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...4)( - [], - StatementsNode(0...4)( - [CallNode(0...4)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - nil, - 1, - "b" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_index.txt b/test/yarp/snapshots/whitequark/send_index.txt deleted file mode 100644 index 75f8c0ff876ec5..00000000000000 --- a/test/yarp/snapshots/whitequark/send_index.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...8)([IntegerNode(4...5)(), IntegerNode(7...8)()]), - (8...9), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_index_asgn.txt b/test/yarp/snapshots/whitequark/send_index_asgn.txt deleted file mode 100644 index d38af8fb52cadd..00000000000000 --- a/test/yarp/snapshots/whitequark/send_index_asgn.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...13)( - [IntegerNode(4...5)(), IntegerNode(7...8)(), IntegerNode(12...13)()] - ), - (8...9), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_index_asgn_legacy.txt b/test/yarp/snapshots/whitequark/send_index_asgn_legacy.txt deleted file mode 100644 index d38af8fb52cadd..00000000000000 --- a/test/yarp/snapshots/whitequark/send_index_asgn_legacy.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...13)( - [], - StatementsNode(0...13)( - [CallNode(0...13)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...13)( - [IntegerNode(4...5)(), IntegerNode(7...8)(), IntegerNode(12...13)()] - ), - (8...9), - nil, - 0, - "[]=" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_index_cmd.txt b/test/yarp/snapshots/whitequark/send_index_cmd.txt deleted file mode 100644 index 38c69392b3d943..00000000000000 --- a/test/yarp/snapshots/whitequark/send_index_cmd.txt +++ /dev/null @@ -1,40 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallNode(0...10)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...10), - (3...4), - ArgumentsNode(4...9)( - [CallNode(4...9)( - nil, - nil, - (4...5), - nil, - ArgumentsNode(6...9)( - [CallNode(6...9)( - nil, - nil, - (6...9), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "m" - )] - ), - (9...10), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_index_legacy.txt b/test/yarp/snapshots/whitequark/send_index_legacy.txt deleted file mode 100644 index 75f8c0ff876ec5..00000000000000 --- a/test/yarp/snapshots/whitequark/send_index_legacy.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - nil, - (3...9), - (3...4), - ArgumentsNode(4...8)([IntegerNode(4...5)(), IntegerNode(7...8)()]), - (8...9), - nil, - 0, - "[]" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_lambda.txt b/test/yarp/snapshots/whitequark/send_lambda.txt deleted file mode 100644 index 52d1fb26a5454a..00000000000000 --- a/test/yarp/snapshots/whitequark/send_lambda.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...26)( - [], - StatementsNode(0...26)( - [LambdaNode(0...8)( - [:*], - (0...2), - (5...6), - (7...8), - BlockParametersNode(3...4)( - ParametersNode(3...4)( - [], - [], - [], - RestParameterNode(3...4)(nil, nil, (3...4)), - [], - nil, - nil - ), - [], - nil, - nil - ), - nil - ), - LambdaNode(10...19)([], (10...12), (13...15), (16...19), nil, nil), - LambdaNode(21...26)([], (21...23), (23...24), (25...26), nil, nil)] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_lambda_args.txt b/test/yarp/snapshots/whitequark/send_lambda_args.txt deleted file mode 100644 index ae41cfa463fa6f..00000000000000 --- a/test/yarp/snapshots/whitequark/send_lambda_args.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...21)( - [], - StatementsNode(0...21)( - [LambdaNode(0...10)( - [:a], - (0...2), - (7...8), - (9...10), - BlockParametersNode(3...6)( - ParametersNode(4...5)( - [RequiredParameterNode(4...5)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (3...4), - (5...6) - ), - nil - ), - LambdaNode(12...21)( - [:a], - (12...14), - (18...19), - (20...21), - BlockParametersNode(14...17)( - ParametersNode(15...16)( - [RequiredParameterNode(15...16)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [], - (14...15), - (16...17) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt b/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt deleted file mode 100644 index 57f5c2ead21096..00000000000000 --- a/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt +++ /dev/null @@ -1,47 +0,0 @@ -ProgramNode(0...22)( - [], - StatementsNode(0...22)( - [LambdaNode(0...11)( - [:a], - (0...2), - (8...9), - (10...11), - BlockParametersNode(3...7)( - ParametersNode(3...7)( - [], - [], - [], - nil, - [KeywordParameterNode(3...7)(:a, (3...5), IntegerNode(6...7)())], - nil, - nil - ), - [], - nil, - nil - ), - nil - ), - LambdaNode(13...22)( - [:a], - (13...15), - (19...20), - (21...22), - BlockParametersNode(16...18)( - ParametersNode(16...18)( - [], - [], - [], - nil, - [KeywordParameterNode(16...18)(:a, (16...18), nil)], - nil, - nil - ), - [], - nil, - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_lambda_args_shadow.txt b/test/yarp/snapshots/whitequark/send_lambda_args_shadow.txt deleted file mode 100644 index cee0016fa79d2c..00000000000000 --- a/test/yarp/snapshots/whitequark/send_lambda_args_shadow.txt +++ /dev/null @@ -1,27 +0,0 @@ -ProgramNode(0...19)( - [], - StatementsNode(0...19)( - [LambdaNode(0...19)( - [:a, :foo, :bar], - (0...2), - (16...17), - (18...19), - BlockParametersNode(2...15)( - ParametersNode(3...4)( - [RequiredParameterNode(3...4)(:a)], - [], - [], - nil, - [], - nil, - nil - ), - [BlockLocalVariableNode(6...9)(:foo), - BlockLocalVariableNode(11...14)(:bar)], - (2...3), - (14...15) - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_lambda_legacy.txt b/test/yarp/snapshots/whitequark/send_lambda_legacy.txt deleted file mode 100644 index 57b827cb7edd27..00000000000000 --- a/test/yarp/snapshots/whitequark/send_lambda_legacy.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)( - [LambdaNode(0...5)([], (0...2), (2...3), (4...5), nil, nil)] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_op_asgn_conditional.txt b/test/yarp/snapshots/whitequark/send_op_asgn_conditional.txt deleted file mode 100644 index 767a6e7b2252cc..00000000000000 --- a/test/yarp/snapshots/whitequark/send_op_asgn_conditional.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...10)( - [], - StatementsNode(0...10)( - [CallAndWriteNode(0...10)( - CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"), - (1...3), - (3...4), - nil, - nil, - nil, - 1, - "b", - "b=", - (5...8), - IntegerNode(9...10)() - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_plain.txt b/test/yarp/snapshots/whitequark/send_plain.txt deleted file mode 100644 index 2272355126da7c..00000000000000 --- a/test/yarp/snapshots/whitequark/send_plain.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...29)( - [], - StatementsNode(0...29)( - [CallNode(0...7)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...7), - nil, - nil, - nil, - nil, - 0, - "fun" - ), - CallNode(9...19)( - CallNode(9...12)(nil, nil, (9...12), nil, nil, nil, nil, 2, "foo"), - (12...14), - (14...17), - (17...18), - nil, - (18...19), - nil, - 0, - "Fun" - ), - CallNode(21...29)( - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"), - (24...26), - (26...29), - nil, - nil, - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_plain_cmd.txt b/test/yarp/snapshots/whitequark/send_plain_cmd.txt deleted file mode 100644 index 4fc9fcb730700a..00000000000000 --- a/test/yarp/snapshots/whitequark/send_plain_cmd.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...39)( - [], - StatementsNode(0...39)( - [CallNode(0...11)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...7), - nil, - ArgumentsNode(8...11)( - [CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "fun" - ), - CallNode(13...25)( - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo"), - (16...18), - (18...21), - nil, - ArgumentsNode(22...25)( - [CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "Fun" - ), - CallNode(27...39)( - CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo"), - (30...32), - (32...35), - nil, - ArgumentsNode(36...39)( - [CallNode(36...39)(nil, nil, (36...39), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_self.txt b/test/yarp/snapshots/whitequark/send_self.txt deleted file mode 100644 index 6f24c1ba8963ba..00000000000000 --- a/test/yarp/snapshots/whitequark/send_self.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...17)( - [], - StatementsNode(0...17)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "fun"), - CallNode(5...9)(nil, nil, (5...9), nil, nil, nil, nil, 0, "fun!"), - CallNode(11...17)( - nil, - nil, - (11...14), - (14...15), - ArgumentsNode(15...16)([IntegerNode(15...16)()]), - (16...17), - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_self_block.txt b/test/yarp/snapshots/whitequark/send_self_block.txt deleted file mode 100644 index 1ae9968e74aefe..00000000000000 --- a/test/yarp/snapshots/whitequark/send_self_block.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [CallNode(0...10)( - nil, - nil, - (0...3), - nil, - nil, - nil, - BlockNode(4...10)([], nil, nil, (4...6), (7...10)), - 0, - "fun" - ), - CallNode(12...19)( - nil, - nil, - (12...15), - nil, - nil, - nil, - BlockNode(16...19)([], nil, nil, (16...17), (18...19)), - 0, - "fun" - ), - CallNode(21...30)( - nil, - nil, - (21...24), - (24...25), - nil, - (25...26), - BlockNode(27...30)([], nil, nil, (27...28), (29...30)), - 0, - "fun" - ), - CallNode(32...42)( - nil, - nil, - (32...35), - (35...36), - ArgumentsNode(36...37)([IntegerNode(36...37)()]), - (37...38), - BlockNode(39...42)([], nil, nil, (39...40), (41...42)), - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/send_unary_op.txt b/test/yarp/snapshots/whitequark/send_unary_op.txt deleted file mode 100644 index 6906d49ae0acad..00000000000000 --- a/test/yarp/snapshots/whitequark/send_unary_op.txt +++ /dev/null @@ -1,38 +0,0 @@ -ProgramNode(0...16)( - [], - StatementsNode(0...16)( - [CallNode(0...4)( - CallNode(1...4)(nil, nil, (1...4), nil, nil, nil, nil, 2, "foo"), - nil, - (0...1), - nil, - nil, - nil, - nil, - 0, - "+@" - ), - CallNode(6...10)( - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "foo"), - nil, - (6...7), - nil, - nil, - nil, - nil, - 0, - "-@" - ), - CallNode(12...16)( - CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo"), - nil, - (12...13), - nil, - nil, - nil, - nil, - 0, - "~" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/slash_newline_in_heredocs.txt b/test/yarp/snapshots/whitequark/slash_newline_in_heredocs.txt deleted file mode 100644 index 7485f4c8bdba39..00000000000000 --- a/test/yarp/snapshots/whitequark/slash_newline_in_heredocs.txt +++ /dev/null @@ -1,15 +0,0 @@ -ProgramNode(0...33)( - [], - StatementsNode(0...33)( - [InterpolatedStringNode(0...4)( - (0...4), - [StringNode(5...25)(nil, (5...25), nil, " 1 2\n" + " 3\n")], - (25...27) - ), - InterpolatedStringNode(29...33)( - (29...33), - [StringNode(34...54)(nil, (34...54), nil, "1 2\n" + "3\n")], - (54...56) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_arg.txt b/test/yarp/snapshots/whitequark/space_args_arg.txt deleted file mode 100644 index d1dfcc4f6559de..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_arg.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...7)( - [], - StatementsNode(0...7)( - [CallNode(0...7)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...7)( - [ParenthesesNode(4...7)( - StatementsNode(5...6)([IntegerNode(5...6)()]), - (4...5), - (6...7) - )] - ), - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_arg_block.txt b/test/yarp/snapshots/whitequark/space_args_arg_block.txt deleted file mode 100644 index d17aae90cd237b..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_arg_block.txt +++ /dev/null @@ -1,56 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CallNode(0...14)( - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - (3...4), - (4...7), - nil, - ArgumentsNode(8...11)( - [ParenthesesNode(8...11)( - StatementsNode(9...10)([IntegerNode(9...10)()]), - (8...9), - (10...11) - )] - ), - nil, - BlockNode(12...14)([], nil, nil, (12...13), (13...14)), - 0, - "fun" - ), - CallNode(16...31)( - CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "foo"), - (19...21), - (21...24), - nil, - ArgumentsNode(25...28)( - [ParenthesesNode(25...28)( - StatementsNode(26...27)([IntegerNode(26...27)()]), - (25...26), - (27...28) - )] - ), - nil, - BlockNode(29...31)([], nil, nil, (29...30), (30...31)), - 0, - "fun" - ), - CallNode(33...43)( - nil, - nil, - (33...36), - nil, - ArgumentsNode(37...40)( - [ParenthesesNode(37...40)( - StatementsNode(38...39)([IntegerNode(38...39)()]), - (37...38), - (39...40) - )] - ), - nil, - BlockNode(41...43)([], nil, nil, (41...42), (42...43)), - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_arg_call.txt b/test/yarp/snapshots/whitequark/space_args_arg_call.txt deleted file mode 100644 index 01bc1dbde372a5..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_arg_call.txt +++ /dev/null @@ -1,32 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [CallNode(0...12)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...12)( - [CallNode(4...12)( - ParenthesesNode(4...7)( - StatementsNode(5...6)([IntegerNode(5...6)()]), - (4...5), - (6...7) - ), - (7...8), - (8...12), - nil, - nil, - nil, - nil, - 0, - "to_i" - )] - ), - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_arg_newline.txt b/test/yarp/snapshots/whitequark/space_args_arg_newline.txt deleted file mode 100644 index 36e321ad7c5605..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_arg_newline.txt +++ /dev/null @@ -1,22 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [CallNode(0...8)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...8)( - [ParenthesesNode(4...8)( - StatementsNode(5...6)([IntegerNode(5...6)()]), - (4...5), - (7...8) - )] - ), - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_block.txt b/test/yarp/snapshots/whitequark/space_args_block.txt deleted file mode 100644 index 7895ad26064060..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_block.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...9)( - [], - StatementsNode(0...9)( - [CallNode(0...9)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...6)([ParenthesesNode(4...6)(nil, (4...5), (5...6))]), - nil, - BlockNode(7...9)([], nil, nil, (7...8), (8...9)), - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/space_args_cmd.txt b/test/yarp/snapshots/whitequark/space_args_cmd.txt deleted file mode 100644 index 84493c09a946dd..00000000000000 --- a/test/yarp/snapshots/whitequark/space_args_cmd.txt +++ /dev/null @@ -1,46 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [CallNode(0...11)( - nil, - nil, - (0...3), - nil, - ArgumentsNode(4...11)( - [ParenthesesNode(4...11)( - StatementsNode(5...10)( - [CallNode(5...10)( - nil, - nil, - (5...6), - nil, - ArgumentsNode(7...10)( - [CallNode(7...10)( - nil, - nil, - (7...10), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - nil, - nil, - 0, - "f" - )] - ), - (4...5), - (10...11) - )] - ), - nil, - nil, - 0, - "fun" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/string___FILE__.txt b/test/yarp/snapshots/whitequark/string___FILE__.txt deleted file mode 100644 index 83e601222d7658..00000000000000 --- a/test/yarp/snapshots/whitequark/string___FILE__.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [SourceFileNode(0...8)("whitequark/string___FILE__.txt")] - ) -) diff --git a/test/yarp/snapshots/whitequark/string_concat.txt b/test/yarp/snapshots/whitequark/string_concat.txt deleted file mode 100644 index a51362805e4997..00000000000000 --- a/test/yarp/snapshots/whitequark/string_concat.txt +++ /dev/null @@ -1,17 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [StringConcatNode(0...14)( - InterpolatedStringNode(0...8)( - (0...1), - [StringNode(1...4)(nil, (1...4), nil, "foo"), - EmbeddedVariableNode(4...7)( - (4...5), - InstanceVariableReadNode(5...7)(:@a) - )], - (7...8) - ), - StringNode(9...14)((9...10), (10...13), (13...14), "bar") - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/string_dvar.txt b/test/yarp/snapshots/whitequark/string_dvar.txt deleted file mode 100644 index 66cd00b5cb34e7..00000000000000 --- a/test/yarp/snapshots/whitequark/string_dvar.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedStringNode(0...14)( - (0...1), - [EmbeddedVariableNode(1...4)( - (1...2), - InstanceVariableReadNode(2...4)(:@a) - ), - StringNode(4...5)(nil, (4...5), nil, " "), - EmbeddedVariableNode(5...9)( - (5...6), - ClassVariableReadNode(6...9)(:@@a) - ), - StringNode(9...10)(nil, (9...10), nil, " "), - EmbeddedVariableNode(10...13)( - (10...11), - GlobalVariableReadNode(11...13)(:$a) - )], - (13...14) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/string_interp.txt b/test/yarp/snapshots/whitequark/string_interp.txt deleted file mode 100644 index cd41265c99b133..00000000000000 --- a/test/yarp/snapshots/whitequark/string_interp.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedStringNode(0...14)( - (0...1), - [StringNode(1...4)(nil, (1...4), nil, "foo"), - EmbeddedStatementsNode(4...10)( - (4...6), - StatementsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "bar")] - ), - (9...10) - ), - StringNode(10...13)(nil, (10...13), nil, "baz")], - (13...14) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/string_plain.txt b/test/yarp/snapshots/whitequark/string_plain.txt deleted file mode 100644 index fe0822a5687d19..00000000000000 --- a/test/yarp/snapshots/whitequark/string_plain.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...20)( - [], - StatementsNode(0...20)( - [StringNode(0...10)((0...3), (3...9), (9...10), "foobar"), - StringNode(12...20)((12...13), (13...19), (19...20), "foobar")] - ) -) diff --git a/test/yarp/snapshots/whitequark/super.txt b/test/yarp/snapshots/whitequark/super.txt deleted file mode 100644 index 65eb72d5f5ba1e..00000000000000 --- a/test/yarp/snapshots/whitequark/super.txt +++ /dev/null @@ -1,24 +0,0 @@ -ProgramNode(0...30)( - [], - StatementsNode(0...30)( - [SuperNode(0...9)( - (0...5), - nil, - ArgumentsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo")] - ), - nil, - nil - ), - SuperNode(11...18)((11...16), (16...17), nil, (17...18), nil), - SuperNode(20...30)( - (20...25), - (25...26), - ArgumentsNode(26...29)( - [CallNode(26...29)(nil, nil, (26...29), nil, nil, nil, nil, 2, "foo")] - ), - (29...30), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/super_block.txt b/test/yarp/snapshots/whitequark/super_block.txt deleted file mode 100644 index a26dad1b37b4f7..00000000000000 --- a/test/yarp/snapshots/whitequark/super_block.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...35)( - [], - StatementsNode(0...35)( - [ForwardingSuperNode(0...12)( - BlockNode(6...12)([], nil, nil, (6...8), (9...12)) - ), - SuperNode(14...35)( - (14...19), - nil, - ArgumentsNode(20...28)( - [CallNode(20...23)(nil, nil, (20...23), nil, nil, nil, nil, 2, "foo"), - CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 2, "bar")] - ), - nil, - BlockNode(29...35)([], nil, nil, (29...31), (32...35)) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/symbol_interp.txt b/test/yarp/snapshots/whitequark/symbol_interp.txt deleted file mode 100644 index 5fd0375ae6a122..00000000000000 --- a/test/yarp/snapshots/whitequark/symbol_interp.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...15)( - [], - StatementsNode(0...15)( - [InterpolatedSymbolNode(0...15)( - (0...2), - [StringNode(2...5)(nil, (2...5), nil, "foo"), - EmbeddedStatementsNode(5...11)( - (5...7), - StatementsNode(7...10)( - [CallNode(7...10)( - nil, - nil, - (7...10), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (10...11) - ), - StringNode(11...14)(nil, (11...14), nil, "baz")], - (14...15) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/symbol_plain.txt b/test/yarp/snapshots/whitequark/symbol_plain.txt deleted file mode 100644 index 7cbac4e19de545..00000000000000 --- a/test/yarp/snapshots/whitequark/symbol_plain.txt +++ /dev/null @@ -1,7 +0,0 @@ -ProgramNode(0...12)( - [], - StatementsNode(0...12)( - [SymbolNode(0...6)((0...2), (2...5), (5...6), "foo"), - SymbolNode(8...12)((8...9), (9...12), nil, "foo")] - ) -) diff --git a/test/yarp/snapshots/whitequark/ternary.txt b/test/yarp/snapshots/whitequark/ternary.txt deleted file mode 100644 index c975e93c7eff00..00000000000000 --- a/test/yarp/snapshots/whitequark/ternary.txt +++ /dev/null @@ -1,16 +0,0 @@ -ProgramNode(0...11)( - [], - StatementsNode(0...11)( - [IfNode(0...11)( - nil, - CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"), - StatementsNode(6...7)([IntegerNode(6...7)()]), - ElseNode(8...11)( - (8...9), - StatementsNode(10...11)([IntegerNode(10...11)()]), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt b/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt deleted file mode 100644 index e7e814c053ac41..00000000000000 --- a/test/yarp/snapshots/whitequark/ternary_ambiguous_symbol.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...13)( - [:t], - StatementsNode(0...13)( - [LocalVariableWriteNode(0...3)( - :t, - 0, - (0...1), - IntegerNode(2...3)(), - (1...2) - ), - IfNode(4...13)( - nil, - ParenthesesNode(4...9)( - StatementsNode(5...8)( - [CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo")] - ), - (4...5), - (8...9) - ), - StatementsNode(10...11)([LocalVariableReadNode(10...11)(:t, 0)]), - ElseNode(11...13)( - (11...12), - StatementsNode(12...13)([ConstantReadNode(12...13)(:T)]), - nil - ), - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/trailing_forward_arg.txt b/test/yarp/snapshots/whitequark/trailing_forward_arg.txt deleted file mode 100644 index f250529610a3bf..00000000000000 --- a/test/yarp/snapshots/whitequark/trailing_forward_arg.txt +++ /dev/null @@ -1,44 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [DefNode(0...40)( - :foo, - (4...7), - nil, - ParametersNode(8...17)( - [RequiredParameterNode(8...9)(:a), - RequiredParameterNode(11...12)(:b)], - [], - [], - nil, - [], - ForwardingParameterNode(14...17)(), - nil - ), - StatementsNode(20...35)( - [CallNode(20...35)( - nil, - nil, - (20...23), - (23...24), - ArgumentsNode(24...34)( - [LocalVariableReadNode(24...25)(:a, 0), - IntegerNode(27...29)(), - ForwardingArgumentsNode(31...34)()] - ), - (34...35), - nil, - 0, - "bar" - )] - ), - [:a, :b, :"..."], - (0...3), - nil, - (7...8), - (17...18), - nil, - (37...40) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/true.txt b/test/yarp/snapshots/whitequark/true.txt deleted file mode 100644 index 14b0c8cecccd16..00000000000000 --- a/test/yarp/snapshots/whitequark/true.txt +++ /dev/null @@ -1 +0,0 @@ -ProgramNode(0...4)([], StatementsNode(0...4)([TrueNode(0...4)()])) diff --git a/test/yarp/snapshots/whitequark/unary_num_pow_precedence.txt b/test/yarp/snapshots/whitequark/unary_num_pow_precedence.txt deleted file mode 100644 index 319b29b170f38f..00000000000000 --- a/test/yarp/snapshots/whitequark/unary_num_pow_precedence.txt +++ /dev/null @@ -1,58 +0,0 @@ -ProgramNode(0...32)( - [], - StatementsNode(0...32)( - [CallNode(0...10)( - FloatNode(0...4)(), - nil, - (5...7), - nil, - ArgumentsNode(8...10)([IntegerNode(8...10)()]), - nil, - nil, - 0, - "**" - ), - CallNode(12...20)( - CallNode(13...20)( - IntegerNode(13...14)(), - nil, - (15...17), - nil, - ArgumentsNode(18...20)([IntegerNode(18...20)()]), - nil, - nil, - 0, - "**" - ), - nil, - (12...13), - nil, - nil, - nil, - nil, - 0, - "-@" - ), - CallNode(22...32)( - CallNode(23...32)( - FloatNode(23...26)(), - nil, - (27...29), - nil, - ArgumentsNode(30...32)([IntegerNode(30...32)()]), - nil, - nil, - 0, - "**" - ), - nil, - (22...23), - nil, - nil, - nil, - nil, - 0, - "-@" - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/undef.txt b/test/yarp/snapshots/whitequark/undef.txt deleted file mode 100644 index eb253762b36a10..00000000000000 --- a/test/yarp/snapshots/whitequark/undef.txt +++ /dev/null @@ -1,20 +0,0 @@ -ProgramNode(0...27)( - [], - StatementsNode(0...27)( - [UndefNode(0...27)( - [SymbolNode(6...9)(nil, (6...9), nil, "foo"), - SymbolNode(11...15)((11...12), (12...15), nil, "bar"), - InterpolatedSymbolNode(17...27)( - (17...19), - [StringNode(19...22)(nil, (19...22), nil, "foo"), - EmbeddedStatementsNode(22...26)( - (22...24), - StatementsNode(24...25)([IntegerNode(24...25)()]), - (25...26) - )], - (26...27) - )], - (0...5) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/unless.txt b/test/yarp/snapshots/whitequark/unless.txt deleted file mode 100644 index 2c0a7aa062545f..00000000000000 --- a/test/yarp/snapshots/whitequark/unless.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...46)( - [], - StatementsNode(0...46)( - [UnlessNode(0...24)( - (0...6), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "foo"), - StatementsNode(16...19)( - [CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (21...24) - ), - UnlessNode(26...46)( - (26...32), - CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 2, "foo"), - StatementsNode(38...41)( - [CallNode(38...41)(nil, nil, (38...41), nil, nil, nil, nil, 2, "bar")] - ), - nil, - (43...46) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/unless_else.txt b/test/yarp/snapshots/whitequark/unless_else.txt deleted file mode 100644 index d08e1294e1f60a..00000000000000 --- a/test/yarp/snapshots/whitequark/unless_else.txt +++ /dev/null @@ -1,55 +0,0 @@ -ProgramNode(0...66)( - [], - StatementsNode(0...66)( - [UnlessNode(0...34)( - (0...6), - CallNode(7...10)(nil, nil, (7...10), nil, nil, nil, nil, 2, "foo"), - StatementsNode(16...19)( - [CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "bar")] - ), - ElseNode(21...34)( - (21...25), - StatementsNode(26...29)( - [CallNode(26...29)( - nil, - nil, - (26...29), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (31...34) - ), - (31...34) - ), - UnlessNode(36...66)( - (36...42), - CallNode(43...46)(nil, nil, (43...46), nil, nil, nil, nil, 2, "foo"), - StatementsNode(48...51)( - [CallNode(48...51)(nil, nil, (48...51), nil, nil, nil, nil, 2, "bar")] - ), - ElseNode(53...66)( - (53...57), - StatementsNode(58...61)( - [CallNode(58...61)( - nil, - nil, - (58...61), - nil, - nil, - nil, - nil, - 2, - "baz" - )] - ), - (63...66) - ), - (63...66) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/unless_mod.txt b/test/yarp/snapshots/whitequark/unless_mod.txt deleted file mode 100644 index 8f2306aa6cd9ba..00000000000000 --- a/test/yarp/snapshots/whitequark/unless_mod.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [UnlessNode(0...14)( - (4...10), - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...3)( - [CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "bar")] - ), - nil, - nil - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/until.txt b/test/yarp/snapshots/whitequark/until.txt deleted file mode 100644 index 5a40a615bd68ef..00000000000000 --- a/test/yarp/snapshots/whitequark/until.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [UntilNode(0...21)( - (0...5), - (18...21), - CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo"), - StatementsNode(13...17)( - [CallNode(13...17)( - nil, - nil, - (13...17), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - 0 - ), - UntilNode(23...42)( - (23...28), - (39...42), - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "foo"), - StatementsNode(34...38)( - [CallNode(34...38)( - nil, - nil, - (34...38), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/until_mod.txt b/test/yarp/snapshots/whitequark/until_mod.txt deleted file mode 100644 index ab5acaf4b37eb4..00000000000000 --- a/test/yarp/snapshots/whitequark/until_mod.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [UntilNode(0...14)( - (5...10), - nil, - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...4)( - [CallNode(0...4)(nil, nil, (0...4), nil, nil, nil, nil, 2, "meth")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/until_post.txt b/test/yarp/snapshots/whitequark/until_post.txt deleted file mode 100644 index 87a0fa3a12e0f0..00000000000000 --- a/test/yarp/snapshots/whitequark/until_post.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [UntilNode(0...24)( - (15...20), - nil, - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...14)( - [BeginNode(0...14)( - (0...5), - StatementsNode(6...10)( - [CallNode(6...10)( - nil, - nil, - (6...10), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - nil, - nil, - nil, - (11...14) - )] - ), - 1 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/var_and_asgn.txt b/test/yarp/snapshots/whitequark/var_and_asgn.txt deleted file mode 100644 index a613761d87e163..00000000000000 --- a/test/yarp/snapshots/whitequark/var_and_asgn.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...7)( - [:a], - StatementsNode(0...7)( - [LocalVariableAndWriteNode(0...7)( - (0...1), - (2...5), - IntegerNode(6...7)(), - :a, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/var_op_asgn.txt b/test/yarp/snapshots/whitequark/var_op_asgn.txt deleted file mode 100644 index 48abb4ebf67ba5..00000000000000 --- a/test/yarp/snapshots/whitequark/var_op_asgn.txt +++ /dev/null @@ -1,49 +0,0 @@ -ProgramNode(0...53)( - [:a], - StatementsNode(0...53)( - [ClassVariableOperatorWriteNode(0...11)( - :@@var, - (0...5), - (6...8), - IntegerNode(9...11)(), - :| - ), - InstanceVariableOperatorWriteNode(13...20)( - :@a, - (13...15), - (16...18), - IntegerNode(19...20)(), - :| - ), - LocalVariableOperatorWriteNode(22...28)( - (22...23), - (24...26), - IntegerNode(27...28)(), - :a, - :+, - 0 - ), - DefNode(30...53)( - :a, - (34...35), - nil, - nil, - StatementsNode(37...48)( - [ClassVariableOperatorWriteNode(37...48)( - :@@var, - (37...42), - (43...45), - IntegerNode(46...48)(), - :| - )] - ), - [], - (30...33), - nil, - nil, - nil, - nil, - (50...53) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/var_op_asgn_cmd.txt b/test/yarp/snapshots/whitequark/var_op_asgn_cmd.txt deleted file mode 100644 index 21c1fb6e1056a6..00000000000000 --- a/test/yarp/snapshots/whitequark/var_op_asgn_cmd.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...12)( - [:foo], - StatementsNode(0...12)( - [LocalVariableOperatorWriteNode(0...12)( - (0...3), - (4...6), - CallNode(7...12)( - nil, - nil, - (7...8), - nil, - ArgumentsNode(9...12)([LocalVariableReadNode(9...12)(:foo, 0)]), - nil, - nil, - 0, - "m" - ), - :foo, - :+, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/var_or_asgn.txt b/test/yarp/snapshots/whitequark/var_or_asgn.txt deleted file mode 100644 index 3fb56b7f4a88d8..00000000000000 --- a/test/yarp/snapshots/whitequark/var_or_asgn.txt +++ /dev/null @@ -1,12 +0,0 @@ -ProgramNode(0...7)( - [:a], - StatementsNode(0...7)( - [LocalVariableOrWriteNode(0...7)( - (0...1), - (2...5), - IntegerNode(6...7)(), - :a, - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/when_multi.txt b/test/yarp/snapshots/whitequark/when_multi.txt deleted file mode 100644 index 7a5c41f7479863..00000000000000 --- a/test/yarp/snapshots/whitequark/when_multi.txt +++ /dev/null @@ -1,29 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [CaseNode(0...37)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [WhenNode(10...32)( - (10...14), - [StringNode(15...20)((15...16), (16...19), (19...20), "bar"), - StringNode(22...27)((22...23), (23...26), (26...27), "baz")], - StatementsNode(29...32)( - [CallNode(29...32)( - nil, - nil, - (29...32), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (0...4), - (34...37) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/when_splat.txt b/test/yarp/snapshots/whitequark/when_splat.txt deleted file mode 100644 index 88d2115eb44de4..00000000000000 --- a/test/yarp/snapshots/whitequark/when_splat.txt +++ /dev/null @@ -1,60 +0,0 @@ -ProgramNode(0...43)( - [], - StatementsNode(0...43)( - [CaseNode(0...43)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [WhenNode(10...27)( - (10...14), - [IntegerNode(15...16)(), - SplatNode(18...22)( - (18...19), - CallNode(19...22)( - nil, - nil, - (19...22), - nil, - nil, - nil, - nil, - 2, - "baz" - ) - )], - StatementsNode(24...27)( - [CallNode(24...27)( - nil, - nil, - (24...27), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - ), - WhenNode(29...38)( - (29...33), - [SplatNode(34...38)( - (34...35), - CallNode(35...38)( - nil, - nil, - (35...38), - nil, - nil, - nil, - nil, - 2, - "foo" - ) - )], - nil - )], - nil, - (0...4), - (40...43) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/when_then.txt b/test/yarp/snapshots/whitequark/when_then.txt deleted file mode 100644 index 8c08e6d8e50e38..00000000000000 --- a/test/yarp/snapshots/whitequark/when_then.txt +++ /dev/null @@ -1,28 +0,0 @@ -ProgramNode(0...34)( - [], - StatementsNode(0...34)( - [CaseNode(0...34)( - CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), - [WhenNode(10...29)( - (10...14), - [StringNode(15...20)((15...16), (16...19), (19...20), "bar")], - StatementsNode(26...29)( - [CallNode(26...29)( - nil, - nil, - (26...29), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ) - )], - nil, - (0...4), - (31...34) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/while.txt b/test/yarp/snapshots/whitequark/while.txt deleted file mode 100644 index 7529b6e1bc1ec6..00000000000000 --- a/test/yarp/snapshots/whitequark/while.txt +++ /dev/null @@ -1,43 +0,0 @@ -ProgramNode(0...42)( - [], - StatementsNode(0...42)( - [WhileNode(0...21)( - (0...5), - (18...21), - CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo"), - StatementsNode(13...17)( - [CallNode(13...17)( - nil, - nil, - (13...17), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - 0 - ), - WhileNode(23...42)( - (23...28), - (39...42), - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "foo"), - StatementsNode(34...38)( - [CallNode(34...38)( - nil, - nil, - (34...38), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/while_mod.txt b/test/yarp/snapshots/whitequark/while_mod.txt deleted file mode 100644 index 2f0ade7006b5fc..00000000000000 --- a/test/yarp/snapshots/whitequark/while_mod.txt +++ /dev/null @@ -1,14 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [WhileNode(0...14)( - (5...10), - nil, - CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...4)( - [CallNode(0...4)(nil, nil, (0...4), nil, nil, nil, nil, 2, "meth")] - ), - 0 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/while_post.txt b/test/yarp/snapshots/whitequark/while_post.txt deleted file mode 100644 index 1b2169107a160f..00000000000000 --- a/test/yarp/snapshots/whitequark/while_post.txt +++ /dev/null @@ -1,33 +0,0 @@ -ProgramNode(0...24)( - [], - StatementsNode(0...24)( - [WhileNode(0...24)( - (15...20), - nil, - CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"), - StatementsNode(0...14)( - [BeginNode(0...14)( - (0...5), - StatementsNode(6...10)( - [CallNode(6...10)( - nil, - nil, - (6...10), - nil, - nil, - nil, - nil, - 2, - "meth" - )] - ), - nil, - nil, - nil, - (11...14) - )] - ), - 1 - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/xstring_interp.txt b/test/yarp/snapshots/whitequark/xstring_interp.txt deleted file mode 100644 index 39d4a12c9830d0..00000000000000 --- a/test/yarp/snapshots/whitequark/xstring_interp.txt +++ /dev/null @@ -1,18 +0,0 @@ -ProgramNode(0...14)( - [], - StatementsNode(0...14)( - [InterpolatedXStringNode(0...14)( - (0...1), - [StringNode(1...4)(nil, (1...4), nil, "foo"), - EmbeddedStatementsNode(4...10)( - (4...6), - StatementsNode(6...9)( - [CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "bar")] - ), - (9...10) - ), - StringNode(10...13)(nil, (10...13), nil, "baz")], - (13...14) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/xstring_plain.txt b/test/yarp/snapshots/whitequark/xstring_plain.txt deleted file mode 100644 index 61515d89d97165..00000000000000 --- a/test/yarp/snapshots/whitequark/xstring_plain.txt +++ /dev/null @@ -1,6 +0,0 @@ -ProgramNode(0...8)( - [], - StatementsNode(0...8)( - [XStringNode(0...8)((0...1), (1...7), (7...8), "foobar")] - ) -) diff --git a/test/yarp/snapshots/whitequark/yield.txt b/test/yarp/snapshots/whitequark/yield.txt deleted file mode 100644 index ae0c2140a3d6c1..00000000000000 --- a/test/yarp/snapshots/whitequark/yield.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...37)( - [], - StatementsNode(0...37)( - [YieldNode(0...5)((0...5), nil, nil, nil), - YieldNode(7...16)( - (7...12), - nil, - ArgumentsNode(13...16)( - [CallNode(13...16)(nil, nil, (13...16), nil, nil, nil, nil, 2, "foo")] - ), - nil - ), - YieldNode(18...25)((18...23), (23...24), nil, (24...25)), - YieldNode(27...37)( - (27...32), - (32...33), - ArgumentsNode(33...36)( - [CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 2, "foo")] - ), - (36...37) - )] - ) -) diff --git a/test/yarp/snapshots/whitequark/zsuper.txt b/test/yarp/snapshots/whitequark/zsuper.txt deleted file mode 100644 index b9f92d0055857f..00000000000000 --- a/test/yarp/snapshots/whitequark/zsuper.txt +++ /dev/null @@ -1,4 +0,0 @@ -ProgramNode(0...5)( - [], - StatementsNode(0...5)([ForwardingSuperNode(0...5)(nil)]) -) diff --git a/test/yarp/snapshots/xstring.txt b/test/yarp/snapshots/xstring.txt deleted file mode 100644 index fe7d5de5a0a987..00000000000000 --- a/test/yarp/snapshots/xstring.txt +++ /dev/null @@ -1,31 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [XStringNode(0...7)((0...3), (3...6), (6...7), "foo"), - InterpolatedXStringNode(9...25)( - (9...10), - [StringNode(10...14)(nil, (10...14), nil, "foo "), - EmbeddedStatementsNode(14...20)( - (14...16), - StatementsNode(16...19)( - [CallNode(16...19)( - nil, - nil, - (16...19), - nil, - nil, - nil, - nil, - 2, - "bar" - )] - ), - (19...20) - ), - StringNode(20...24)(nil, (20...24), nil, " baz")], - (24...25) - ), - XStringNode(27...33)((27...28), (28...32), (32...33), "foo"), - XStringNode(35...40)((35...36), (36...39), (39...40), "foo")] - ) -) diff --git a/test/yarp/snapshots/yield.txt b/test/yarp/snapshots/yield.txt deleted file mode 100644 index 9dba03e7b74eec..00000000000000 --- a/test/yarp/snapshots/yield.txt +++ /dev/null @@ -1,23 +0,0 @@ -ProgramNode(0...40)( - [], - StatementsNode(0...40)( - [YieldNode(0...5)((0...5), nil, nil, nil), - YieldNode(7...14)((7...12), (12...13), nil, (13...14)), - YieldNode(16...24)( - (16...21), - (21...22), - ArgumentsNode(22...23)([IntegerNode(22...23)()]), - (23...24) - ), - YieldNode(26...40)( - (26...31), - (31...32), - ArgumentsNode(32...39)( - [IntegerNode(32...33)(), - IntegerNode(35...36)(), - IntegerNode(38...39)()] - ), - (39...40) - )] - ) -) diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 464141f7d49f55..779c5834248471 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -506,6 +506,7 @@ def test_set_dictionary end def test_multithread_deflate + pend 'hangs' if RUBY_ENGINE == 'truffleruby' zd = Zlib::Deflate.new s = "x" * 10000 @@ -522,6 +523,7 @@ def test_multithread_deflate end def test_multithread_inflate + pend 'hangs' if RUBY_ENGINE == 'truffleruby' zi = Zlib::Inflate.new s = Zlib.deflate("x" * 10000) @@ -792,7 +794,7 @@ def test_path } end - if defined? File::TMPFILE + if defined?(File::TMPFILE) and RUBY_ENGINE != 'truffleruby' def test_path_tmpfile sio = StringIO.new("".dup, 'w') gz = Zlib::GzipWriter.new(sio) diff --git a/test_code.rb b/test_code.rb deleted file mode 100644 index f599e28b8ab0d8..00000000000000 --- a/test_code.rb +++ /dev/null @@ -1 +0,0 @@ -10 diff --git a/thread_pthread.c b/thread_pthread.c index 057c50c1248a50..7c53325240cb64 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -637,6 +637,18 @@ rb_thread_sched_destroy(struct rb_thread_sched *sched) clear_thread_cache_altstack(); } +#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 + #if defined(HAVE_WORKING_FORK) static void thread_cache_reset(void); static void @@ -646,6 +658,9 @@ thread_sched_atfork(struct rb_thread_sched *sched) thread_cache_reset(); rb_thread_sched_init(sched); thread_sched_to_running(sched, GET_THREAD()); +#ifdef RB_THREAD_T_HAS_NATIVE_ID + GET_THREAD()->nt->tid = get_native_thread_id(); +#endif } #endif @@ -693,18 +708,6 @@ ruby_thread_set_native(rb_thread_t *th) #endif } -#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) { diff --git a/thread_sync.c b/thread_sync.c index 85ebec4d8cfc3d..ca463c35f1a8b1 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -1138,6 +1138,21 @@ rb_queue_length(VALUE self) return LONG2NUM(queue_length(self, queue_ptr(self))); } +NORETURN(static VALUE rb_queue_freeze(VALUE self)); +/* + * call-seq: + * freeze + * + * Raises an exception: + * Queue.new.freeze # Raises TypeError (cannot freeze #) + */ +static VALUE +rb_queue_freeze(VALUE self) +{ + rb_raise(rb_eTypeError, "cannot freeze " "%+"PRIsVALUE, self); + UNREACHABLE_RETURN(self); +} + /* * Document-method: Thread::Queue#num_waiting * @@ -1599,6 +1614,7 @@ 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"); @@ -1615,6 +1631,7 @@ 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/tool/leaked-globals b/tool/leaked-globals index 99de52dd6c1861..4f4a35cc30057c 100755 --- a/tool/leaked-globals +++ b/tool/leaked-globals @@ -68,7 +68,7 @@ IO.foreach("|#{NM} #{ARGV.join(' ')}") do |line| next if n.include?(".") next if !so and n.start_with?("___asan_") case n - when /\A(?:Init_|InitVM_|yp_|[Oo]nig|dln_|coroutine_)/ + when /\A(?:Init_|InitVM_|pm_|[Oo]nig|dln_|coroutine_)/ next when /\Aruby_static_id_/ next unless so diff --git a/tool/lib/core_assertions.rb b/tool/lib/core_assertions.rb index 23de1f7e50ea67..4eb56b04be05de 100644 --- a/tool/lib/core_assertions.rb +++ b/tool/lib/core_assertions.rb @@ -778,9 +778,9 @@ def assert_all_assertions_foreach(msg = nil, *keys, &block) %w[ CLOCK_THREAD_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID CLOCK_MONOTONIC - ].find do |clk| - if Process.const_defined?(clk) - [clk.to_sym, Process.const_get(clk)].find do |clk| + ].find do |c| + if Process.const_defined?(c) + [c.to_sym, Process.const_get(c)].find do |clk| Process.clock_gettime(clk) rescue # Constants may be defined but not implemented, e.g., mingw. diff --git a/tool/lib/vcs.rb b/tool/lib/vcs.rb index 8566d723497554..13e74ac017d883 100644 --- a/tool/lib/vcs.rb +++ b/tool/lib/vcs.rb @@ -698,15 +698,22 @@ def format_changelog(path, arg, base_url = nil) 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[^ +(\d+)s([#{LOG_FIX_REGEXP_SEPARATORS}])(.+)\2(.*)\2]o - n = $1.to_i - wrong = $3 - correct = $4 - begin + when %r[^s([#{LOG_FIX_REGEXP_SEPARATORS}])(.+)\1(.*)\1]o + wrong = $2 + correct = $3 + range.each do |n| s[n][wrong] = correct rescue IndexError - message = ["format_changelog failed to replace #{wrong.dump} with #{correct.dump} at #$1\n"] + message = ["format_changelog failed to replace #{wrong.dump} with #{correct.dump} at #{n}\n"] from = [1, n-2].max to = [s.size-1, n+2].min s.each_with_index do |e, i| @@ -716,12 +723,13 @@ def format_changelog(path, arg, base_url = nil) end raise message.join('') end - 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)] = [] + 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] = [] end end s = s.join('') diff --git a/tool/lrama/exe/lrama b/tool/lrama/exe/lrama index 5e1ee582cf5681..ba5fb06c82c7dd 100755 --- a/tool/lrama/exe/lrama +++ b/tool/lrama/exe/lrama @@ -3,4 +3,4 @@ $LOAD_PATH << File.join(__dir__, "../lib") require "lrama" -Lrama::Command.new(ARGV.dup).run +Lrama::Command.new.run(ARGV.dup) diff --git a/tool/lrama/lib/lrama.rb b/tool/lrama/lib/lrama.rb index 12e635d8b6ae73..880e64df5fa090 100644 --- a/tool/lrama/lib/lrama.rb +++ b/tool/lrama/lib/lrama.rb @@ -5,6 +5,8 @@ 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" diff --git a/tool/lrama/lib/lrama/command.rb b/tool/lrama/lib/lrama/command.rb index 45670ae405c0c6..39e3c3665bbf8e 100644 --- a/tool/lrama/lib/lrama/command.rb +++ b/tool/lrama/lib/lrama/command.rb @@ -1,53 +1,34 @@ -require 'optparse' - module Lrama class Command - def initialize(argv) - @argv = argv - - @skeleton = "bison/yacc.c" - @header = false - @header_file = nil - @report = [] - @report_file = nil - @outfile = "y.tab.c" - @trace = [] - @error_recovery = false - @grammar_file = nil - @report_file = nil - @trace_opts = nil - @report_opts = nil - end + def run(argv) + options = OptionParser.new.parse(argv) - def run - parse_option - - Report::Duration.enable if @trace_opts[:time] + Report::Duration.enable if options.trace_opts[:time] warning = Lrama::Warning.new - grammar = Lrama::Parser.new(@y.read).parse - @y.close if @y != STDIN - states = Lrama::States.new(grammar, warning, trace_state: (@trace_opts[:automaton] || @trace_opts[:closure])) + grammar = Lrama::Parser.new(options.y.read).parse + options.y.close if options.y != STDIN + states = Lrama::States.new(grammar, warning, trace_state: (options.trace_opts[:automaton] || options.trace_opts[:closure])) states.compute context = Lrama::Context.new(states) - if @report_file + if options.report_file reporter = Lrama::StatesReporter.new(states) - File.open(@report_file, "w+") do |f| - reporter.report(f, **@report_opts) + File.open(options.report_file, "w+") do |f| + reporter.report(f, **options.report_opts) end end - File.open(@outfile, "w+") do |f| + File.open(options.outfile, "w+") do |f| Lrama::Output.new( out: f, - output_file_path: @outfile, - template_name: @skeleton, - grammar_file_path: @grammar_file, - header_file_path: @header_file, + 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: @error_recovery, + error_recovery: options.error_recovery, ).render end @@ -55,108 +36,5 @@ def run exit 1 end end - - private - - 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 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 - - def parse_option - opt = OptionParser.new - - # opt.on('-h') {|v| p v } - opt.on('-V', '--version') {|v| puts "lrama #{Lrama::VERSION}"; exit 0 } - - # Tuning the Parser - opt.on('-S', '--skeleton=FILE') {|v| @skeleton = v } - opt.on('-t') { } # Do nothing - - # Output Files: - opt.on('-h', '--header=[FILE]') {|v| @header = true; @header_file = v } - opt.on('-d') { @header = true } - opt.on('-r', '--report=THINGS', Array) {|v| @report = v } - opt.on('--report-file=FILE') {|v| @report_file = v } - opt.on('-v') { } # Do nothing - opt.on('-o', '--output=FILE') {|v| @outfile = v } - - # Hidden - opt.on('--trace=THINGS', Array) {|v| @trace = v } - - # Error Recovery - opt.on('-e') {|v| @error_recovery = true } - - opt.parse!(@argv) - - @trace_opts = validate_trace(@trace) - @report_opts = validate_report(@report) - - @grammar_file = @argv.shift - - if !@grammar_file - abort "File should be specified\n" - end - - if @grammar_file == '-' - @grammar_file = @argv.shift or abort "File name for STDIN should be specified\n" - @y = STDIN - else - @y = File.open(@grammar_file, 'r') - end - - if !@report.empty? && @report_file.nil? && @grammar_file - @report_file = File.dirname(@grammar_file) + "/" + File.basename(@grammar_file, ".*") + ".output" - end - - if !@header_file && @header - case - when @outfile - @header_file = File.dirname(@outfile) + "/" + File.basename(@outfile, ".*") + ".h" - when @grammar_file - @header_file = File.dirname(@grammar_file) + "/" + File.basename(@grammar_file, ".*") + ".h" - end - end - end end end diff --git a/tool/lrama/lib/lrama/lexer.rb b/tool/lrama/lib/lrama/lexer.rb index c591684a05e621..72ce90195f0d9e 100644 --- a/tool/lrama/lib/lrama/lexer.rb +++ b/tool/lrama/lib/lrama/lexer.rb @@ -213,19 +213,33 @@ def lex_user_code(ss, line, column, lines) string, line = lex_string(ss, "'", line, lines) str << string next + + # $ references + # It need to wrap an identifier with brackets to use ".-" for identifiers when ss.scan(/\$(<[a-zA-Z0-9_]+>)?\$/) # $$, $$ tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil references << [:dollar, "$", tag, str.length, str.length + ss[0].length - 1] when ss.scan(/\$(<[a-zA-Z0-9_]+>)?(\d+)/) # $1, $2, $1 tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil references << [:dollar, Integer(ss[2]), tag, str.length, str.length + ss[0].length - 1] - when ss.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_.][-a-zA-Z0-9_.]*)/) # $foo, $expr, $program + when ss.scan(/\$(<[a-zA-Z0-9_]+>)?([a-zA-Z_][a-zA-Z0-9_]*)/) # $foo, $expr, $program (named reference without brackets) + tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil + references << [:dollar, ss[2], tag, str.length, str.length + ss[0].length - 1] + when ss.scan(/\$(<[a-zA-Z0-9_]+>)?\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # $expr.right, $expr-right, $program (named reference with brackets) tag = ss[1] ? create_token(Token::Tag, ss[1], line, str.length) : nil references << [:dollar, ss[2], tag, str.length, str.length + ss[0].length - 1] + + # @ references + # It need to wrap an identifier with brackets to use ".-" for identifiers when ss.scan(/@\$/) # @$ references << [:at, "$", nil, str.length, str.length + ss[0].length - 1] when ss.scan(/@(\d+)/) # @1 references << [:at, Integer(ss[1]), nil, str.length, str.length + ss[0].length - 1] + when ss.scan(/@([a-zA-Z][a-zA-Z0-9_]*)/) # @foo, @expr (named reference without brackets) + references << [:at, ss[1], nil, str.length, str.length + ss[0].length - 1] + when ss.scan(/@\[([a-zA-Z_.][-a-zA-Z0-9_.]*)\]/) # @expr.right, @expr-right (named reference with brackets) + references << [:at, ss[1], nil, str.length, str.length + ss[0].length - 1] + when ss.scan(/{/) brace_count += 1 when ss.scan(/}/) diff --git a/tool/lrama/lib/lrama/lexer/token.rb b/tool/lrama/lib/lrama/lexer/token.rb index 4eca6f60077bbb..a6180746cc3f77 100644 --- a/tool/lrama/lib/lrama/lexer/token.rb +++ b/tool/lrama/lib/lrama/lexer/token.rb @@ -28,7 +28,13 @@ def numberize_references(lhs, rhs) if lhs.referred_by?(ref_name) '$' else - rhs.find_index {|token| token.referred_by?(ref_name) } + 1 + index = rhs.find_index {|token| token.referred_by?(ref_name) } + + if index + index + 1 + else + raise "'#{ref_name}' is invalid name." + end end [ref[0], value, ref[2], ref[3], ref[4]] else diff --git a/tool/lrama/lib/lrama/option_parser.rb b/tool/lrama/lib/lrama/option_parser.rb new file mode 100644 index 00000000000000..d8ed62ee07e398 --- /dev/null +++ b/tool/lrama/lib/lrama/option_parser.rb @@ -0,0 +1,124 @@ +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 'Tuning the Parser:' + o.on('-S', '--skeleton=FILE', 'specify the skeleton to use') {|v| @options.skeleton = v } + o.on('-t', 'reserved, do nothing') { } + 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('--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 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 new file mode 100644 index 00000000000000..01b3e701d97f14 --- /dev/null +++ b/tool/lrama/lib/lrama/options.rb @@ -0,0 +1,23 @@ +module Lrama + # Command line options. + class Options + attr_accessor :skeleton, :header, :header_file, + :report_file, :outfile, + :error_recovery, :grammar_file, + :report_file, :trace_opts, :report_opts, :y + + def initialize + @skeleton = "bison/yacc.c" + @header = false + @header_file = nil + @report_file = nil + @outfile = "y.tab.c" + @error_recovery = false + @grammar_file = nil + @report_file = nil + @trace_opts = nil + @report_opts = nil + @y = STDIN + end + end +end diff --git a/tool/lrama/lib/lrama/version.rb b/tool/lrama/lib/lrama/version.rb index 41215c1aee8b18..fe695873e5f972 100644 --- a/tool/lrama/lib/lrama/version.rb +++ b/tool/lrama/lib/lrama/version.rb @@ -1,3 +1,3 @@ module Lrama - VERSION = "0.5.5".freeze + VERSION = "0.5.6".freeze end diff --git a/tool/make-snapshot b/tool/make-snapshot index 3e5689e873b057..154ee89b4c4441 100755 --- a/tool/make-snapshot +++ b/tool/make-snapshot @@ -384,8 +384,21 @@ def package(vcs, rev, destdir, tmp = nil) puts $colorize.fail("patching failed") return end - def (clean = []).add(n) push(n); n end - def clean.create(file, content = "") File.binwrite(add(file), content) 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 + Dir.chdir(v) do unless File.exist?("ChangeLog") vcs.export_changelog(url, nil, revision, "ChangeLog") @@ -406,7 +419,7 @@ def package(vcs, rev, destdir, tmp = nil) puts end - File.open(clean.add("cross.rb"), "w") do |f| + clean.create("cross.rb") 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)" @@ -505,8 +518,7 @@ touch-unicode-files: end vcs.after_export(".") if exported clean.concat(Dir.glob("ext/**/autom4te.cache")) - FileUtils.rm_rf(clean) unless $keep_temp - FileUtils.rm_rf(".downloaded-cache") + clean.add(".downloaded-cache") if File.exist?("gems/bundled_gems") gems = Dir.glob("gems/*.gem") gems -= File.readlines("gems/bundled_gems").map {|line| @@ -514,10 +526,11 @@ touch-unicode-files: name, version, _ = line.split(' ') "gems/#{name}-#{version}.gem" } - FileUtils.rm_f(gems) + clean.concat(gems) else - FileUtils.rm_rf("gems") + clean.add("gems") end + FileUtils.rm_rf(clean) if modified touch_all(modified, "**/*/", 0) do |name, stat| stat.mtime > modified diff --git a/tool/sync_default_gems.rb b/tool/sync_default_gems.rb index fcfb06047e7b60..44f11e22d21bef 100755 --- a/tool/sync_default_gems.rb +++ b/tool/sync_default_gems.rb @@ -53,6 +53,7 @@ module SyncDefaultGems pathname: "ruby/pathname", pp: "ruby/pp", prettyprint: "ruby/prettyprint", + prism: ["ruby/prism", "main"], pstore: "ruby/pstore", psych: 'ruby/psych', rdoc: 'ruby/rdoc', @@ -79,7 +80,6 @@ module SyncDefaultGems weakref: "ruby/weakref", win32ole: "ruby/win32ole", yaml: "ruby/yaml", - yarp: ["ruby/yarp", "main"], zlib: 'ruby/zlib', }.transform_keys(&:to_s) @@ -397,32 +397,23 @@ def sync_default_gems(gem) rm_rf(%w[spec/syntax_suggest libexec/syntax_suggest]) cp_r("#{upstream}/spec", "spec/syntax_suggest") cp_r("#{upstream}/exe/syntax_suggest", "libexec/syntax_suggest") - when "yarp" - # We don't want to remove yarp_init.c, so we temporarily move it - # out of the yarp dir, wipe the yarp dir, and then put it back - mv("yarp/yarp_init.c", ".") - mv("yarp/yarp_compiler.c", ".") - mv("test/yarp/compiler_test.rb", ".") - rm_rf(%w[test/yarp yarp]) - - # Run the YARP templating scripts - cp_r("#{upstream}/ext/yarp", "yarp") + when "prism" + rm_rf(%w[test/prism prism]) + + cp_r("#{upstream}/ext/prism", "prism") cp_r("#{upstream}/lib/.", "lib") - cp_r("#{upstream}/test/yarp", "test") - cp_r("#{upstream}/src/.", "yarp") + cp_r("#{upstream}/test/prism", "test") + cp_r("#{upstream}/src/.", "prism") - cp_r("#{upstream}/yarp.gemspec", "lib/yarp") - cp_r("#{upstream}/include/yarp/.", "yarp") - cp_r("#{upstream}/include/yarp.h", "yarp") + cp_r("#{upstream}/prism.gemspec", "lib/prism") + cp_r("#{upstream}/include/prism/.", "prism") + cp_r("#{upstream}/include/prism.h", "prism") - cp_r("#{upstream}/config.yml", "yarp/") - cp_r("#{upstream}/templates", "yarp/") - rm_rf("yarp/templates/java") + cp_r("#{upstream}/config.yml", "prism/") + cp_r("#{upstream}/templates", "prism/") + rm_rf("prism/templates/java") - rm("yarp/extconf.rb") - mv("yarp_init.c", "yarp/") - mv("yarp_compiler.c", "yarp/") - mv("compiler_test.rb", "test/yarp/") + rm("prism/extconf.rb") else sync_lib gem, upstream end @@ -434,15 +425,13 @@ def ignore_file_pattern_for(gem) # Common patterns patterns << %r[\A(?: - [A-Z]\w*\.(?:md|txt) - |[^/]+\.yml + [^/]+ # top-level entries |\.git.* - |[A-Z]\w+file - |COPYING - |Gemfile.lock |bin/.* + |ext/.*\.java |rakelib/.* - |test/lib/.* + |test/(?:lib|fixtures)/.* + |tool/.* )\z]mx # Gem-specific patterns @@ -565,16 +554,11 @@ def filter_pickup_files(changed, ignore_file_pattern, base) changed = changed.reject do |f| case when toplevels.fetch(top = f[%r[\A[^/]+(?=/|\z)]m]) { - remove << top unless - toplevels[top] = system(*%w"git cat-file -e", "#{base}:#{top}", err: File::NULL) + remove << top if toplevels[top] = + !system(*%w"git cat-file -e", "#{base}:#{top}", err: File::NULL) } # Remove any new top-level directories. true - when !f.include?("/"), - f.start_with?("test/fixtures/", "test/lib/", "tool/") - # Forcibly reset any top-level entries, and any changes under - # /test/fixtures, /test/lib, or /tool. - ignore << f when ignore_file_pattern.match?(f) # Forcibly reset any changes matching ignore_file_pattern. ignore << f @@ -603,7 +587,7 @@ def pickup_files(gem, changed, picked) unless ignore.empty? puts "Reset ignored files: #{ignore.join(', ')}" system(*%W"git rm -r --", *ignore) - system(*%W"git checkout -f", base, "--", *ignore) + ignore.each {|f| system(*%W"git checkout -f", base, "--", f)} end if changed.empty? diff --git a/tool/test/test_sync_default_gems.rb b/tool/test/test_sync_default_gems.rb index a73fc65d6e6b48..489feb2894566f 100755 --- a/tool/test/test_sync_default_gems.rb +++ b/tool/test/test_sync_default_gems.rb @@ -1,6 +1,7 @@ #!/usr/bin/ruby require 'test/unit' require 'stringio' +require 'tmpdir' require_relative '../sync_default_gems' module Test_SyncDefaultGems @@ -83,31 +84,38 @@ def setup @git_config = %W"HOME GIT_CONFIG_GLOBAL".each_with_object({}) {|k, c| c[k] = ENV[k]} ENV["HOME"] = @testdir ENV["GIT_CONFIG_GLOBAL"] = @testdir + "/gitconfig" - system(*%W"git config --global user.email test@ruby-lang.org") - system(*%W"git config --global user.name", "Ruby") - system(*%W"git config --global init.defaultBranch default") + git(*%W"config --global user.email test@ruby-lang.org") + git(*%W"config --global user.name", "Ruby") + git(*%W"config --global init.defaultBranch default") @target = "sync-test" SyncDefaultGems::REPOSITORIES[@target] = ["ruby/#{@target}", "default"] @sha = {} @origdir = Dir.pwd Dir.chdir(@testdir) ["src", @target].each do |dir| - system(*%W"git init -q #{dir}", exception: true) + git(*%W"init -q #{dir}") + File.write("#{dir}/.gitignore", "*~\n") + Dir.mkdir("#{dir}/lib") + File.write("#{dir}/lib/common.rb", ":ok\n") + Dir.mkdir("#{dir}/.github") + Dir.mkdir("#{dir}/.github/workflows") + File.write("#{dir}/.github/workflows/default.yml", "default:\n") + git(*%W"add .gitignore lib/common.rb .github", chdir: dir) + git(*%W"commit -q -m", "Initialize", chdir: dir) if dir == "src" - Dir.mkdir("#{dir}/lib") File.write("#{dir}/lib/fine.rb", "return\n") Dir.mkdir("#{dir}/test") File.write("#{dir}/test/test_fine.rb", "return\n") - system(*%W"git add lib/fine.rb test/test_fine.rb", exception: true, chdir: dir) - system(*%W"git commit -q -m", "Looks fine", exception: true, chdir: dir) + git(*%W"add lib/fine.rb test/test_fine.rb", chdir: dir) + git(*%W"commit -q -m", "Looks fine", chdir: dir) end Dir.mkdir("#{dir}/tool") File.write("#{dir}/tool/ok", "#!/bin/sh\n""echo ok\n") - system(*%W"git add tool/ok", exception: true, chdir: dir) - system(*%W"git commit -q -m", "Add tool #{dir}", exception: true, chdir: dir) - @sha[dir] = IO.popen(%W[git log --format=%H -1], chdir: dir, &:read).chomp + git(*%W"add tool/ok", chdir: dir) + git(*%W"commit -q -m", "Add tool #{dir}", chdir: dir) + @sha[dir] = top_commit(dir) end - system(*%W"git remote add #{@target} ../#{@target}", exception: true, chdir: "src") + git(*%W"remote add #{@target} ../#{@target}", chdir: "src") end def teardown @@ -121,6 +129,7 @@ def teardown end def capture_process_output_to(outputs) + return yield unless outputs&.empty? == false IO.pipe do |r, w| orig = outputs.map {|out| out.dup} outputs.each {|out| out.reopen(w)} @@ -145,60 +154,90 @@ def capture_process_outputs return out, err end - def test_skip_tool - system(*%W"git rm -q tool/ok", exception: true, chdir: @target) - system(*%W"git commit -q -m", "Remove tool", exception: true, chdir: @target) + def git(*commands, **opts) + system("git", *commands, exception: true, **opts) + end + + def top_commit(dir, format: "%H") + IO.popen(%W[git log --format=#{format} -1], chdir: dir, &:read)&.chomp + end + + def assert_sync(commits = true, success: true) + result = nil out = capture_process_output_to([STDOUT, STDERR]) do Dir.chdir("src") do - SyncDefaultGems.sync_default_gems_with_commits(@target, true) + result = SyncDefaultGems.sync_default_gems_with_commits(@target, commits) end end - assert_equal(@sha["src"], IO.popen(%W[git log --format=%H -1], chdir: "src", &:read).chomp, out) + assert_equal(success, result, out) + out + end + + def test_sync + File.write("#@target/lib/common.rb", "# OK!\n") + git(*%W"commit -q -m", "OK", "lib/common.rb", chdir: @target) + out = assert_sync() + assert_not_equal(@sha["src"], top_commit("src"), out) + assert_equal("# OK!\n", File.read("src/lib/common.rb")) + log = top_commit("src", format: "%B").lines + assert_equal("[ruby/#@target] OK\n", log.first, out) + assert_match(%r[/ruby/#{@target}/commit/\h+$], log.last, out) + assert_operator(top_commit(@target), :start_with?, log.last[/\h+$/], out) + end + + def test_skip_tool + git(*%W"rm -q tool/ok", chdir: @target) + git(*%W"commit -q -m", "Remove tool", chdir: @target) + out = assert_sync() + assert_equal(@sha["src"], top_commit("src"), out) end def test_skip_test_fixtures Dir.mkdir("#@target/test") Dir.mkdir("#@target/test/fixtures") File.write("#@target/test/fixtures/fixme.rb", "") - system(*%W"git add test/fixtures/fixme.rb", exception: true, chdir: @target) - system(*%W"git commit -q -m", "Add fitures", exception: true, chdir: @target) - out = capture_process_output_to([STDOUT, STDERR]) do - Dir.chdir("src") do - SyncDefaultGems.sync_default_gems_with_commits(@target, ["#{@sha[@target]}..#{@target}/default"]) - end - end - assert_equal(@sha["src"], IO.popen(%W[git log --format=%H -1], chdir: "src", &:read).chomp, out) + git(*%W"add test/fixtures/fixme.rb", chdir: @target) + git(*%W"commit -q -m", "Add fixtures", chdir: @target) + out = assert_sync(["#{@sha[@target]}..#{@target}/default"]) + assert_equal(@sha["src"], top_commit("src"), out) end def test_skip_toplevel Dir.mkdir("#@target/docs") File.write("#@target/docs/NEWS.md", "= NEWS!!!\n") - system(*%W"git add --", "docs/NEWS.md", exception: true, chdir: @target) - system(*%W"git commit -q -m", "It's a news", exception: true, chdir: @target) - out = capture_process_output_to([STDOUT, STDERR]) do - Dir.chdir("src") do - SyncDefaultGems.sync_default_gems_with_commits(@target, true) - end - end - assert_equal(@sha["src"], IO.popen(%W[git log --format=%H -1], chdir: "src", &:read).chomp, out) + git(*%W"add --", "docs/NEWS.md", chdir: @target) + File.write("#@target/docs/hello.md", "Hello\n") + git(*%W"add --", "docs/hello.md", chdir: @target) + git(*%W"commit -q -m", "It's a news", chdir: @target) + out = assert_sync() + assert_equal(@sha["src"], top_commit("src"), out) end def test_adding_toplevel Dir.mkdir("#@target/docs") File.write("#@target/docs/NEWS.md", "= New library\n") - Dir.mkdir("#@target/lib") File.write("#@target/lib/news.rb", "return\n") - system(*%W"git add --", "docs/NEWS.md", "lib/news.rb", exception: true, chdir: @target) - system(*%W"git commit -q -m", "New lib", exception: true, chdir: @target) - out = capture_process_output_to([STDOUT, STDERR]) do - Dir.chdir("src") do - SyncDefaultGems.sync_default_gems_with_commits(@target, true) - end - end - assert_not_equal(@sha["src"], IO.popen(%W[git log --format=%H -1], chdir: "src", &:read).chomp, out) + git(*%W"add --", "docs/NEWS.md", "lib/news.rb", chdir: @target) + git(*%W"commit -q -m", "New lib", chdir: @target) + out = assert_sync() + assert_not_equal(@sha["src"], top_commit("src"), out) assert_equal "return\n", File.read("src/lib/news.rb") - assert_include IO.popen(%W[git log -1 --oneline], chdir: "src", &:read), "[ruby/#{@target}] New lib" + assert_include top_commit("src", format: "oneline"), "[ruby/#{@target}] New lib" assert_not_operator File, :exist?, "src/docs" end + + def test_gitignore + File.write("#@target/.gitignore", "*.bak\n", mode: "a") + File.write("#@target/lib/common.rb", "Should.be_merged\n", mode: "a") + File.write("#@target/.github/workflows/main.yml", "# Should not merge\n", mode: "a") + git(*%W"add .github", chdir: @target) + git(*%W"commit -q -m", "Should be common.rb only", + *%W".gitignore lib/common.rb .github", chdir: @target) + out = assert_sync() + assert_not_equal(@sha["src"], top_commit("src"), out) + assert_equal("*~\n", File.read("src/.gitignore"), out) + assert_equal("#!/bin/sh\n""echo ok\n", File.read("src/tool/ok"), out) + assert_not_operator(File, :exist?, "src/.github/workflows/.yml", out) + end end end diff --git a/tool/update-deps b/tool/update-deps index 90107e50c83758..2a07d55e37dbea 100755 --- a/tool/update-deps +++ b/tool/update-deps @@ -150,13 +150,13 @@ FILES_NEED_VPATH = %w[ enc/trans/utf8_mac.c enc/trans/utf_16_32.c - yarp/api_node.c - yarp/ast.h - yarp/node.c - yarp/prettyprint.c - yarp/serialize.c - yarp/token_type.c - yarp/version.h + prism/api_node.c + prism/ast.h + prism/node.c + prism/prettyprint.c + prism/serialize.c + prism/token_type.c + prism/version.h ] # Multiple files with same filename. @@ -184,7 +184,7 @@ def in_makefile(target, source) target = target.to_s source = source.to_s case target - when %r{\A[^/]*\z}, %r{\Acoroutine/}, %r{\Ayarp/} + when %r{\A[^/]*\z}, %r{\Acoroutine/}, %r{\Aprism/} target2 = "#{target.sub(/\.o\z/, '.$(OBJEXT)')}" case source when *FILES_IN_SOURCE_DIRECTORY then source2 = "$(top_srcdir)/#{source}" diff --git a/universal_parser.c b/universal_parser.c index 0f1395322e263b..9678597639ab98 100644 --- a/universal_parser.c +++ b/universal_parser.c @@ -113,8 +113,6 @@ struct rb_imemo_tmpbuf_struct { #define new_strterm p->config->new_strterm #define strterm_is_heredoc p->config->strterm_is_heredoc -#define rb_imemo_tmpbuf_auto_free_pointer p->config->tmpbuf_auto_free_pointer -#define rb_imemo_tmpbuf_set_ptr p->config->tmpbuf_set_ptr #define rb_imemo_tmpbuf_parser_heap p->config->tmpbuf_parser_heap #define compile_callback p->config->compile_callback diff --git a/vm.c b/vm.c index 5e2c1c19d5e8ee..5d7ae19708f83d 100644 --- a/vm.c +++ b/vm.c @@ -1386,7 +1386,7 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I rb_execution_context_t *ec = GET_EC(); const rb_iseq_t *base_iseq, *iseq; rb_ast_body_t ast; - NODE tmp_node; + rb_node_scope_t tmp_node; if (dyncount < 0) return 0; @@ -1398,8 +1398,12 @@ rb_binding_add_dynavars(VALUE bindval, rb_binding_t *bind, int dyncount, const I dyns->size = dyncount; MEMCPY(dyns->ids, dynvars, ID, dyncount); - rb_node_init(&tmp_node, NODE_SCOPE, (VALUE)dyns, 0, 0); - ast.root = &tmp_node; + rb_node_init(RNODE(&tmp_node), NODE_SCOPE); + tmp_node.nd_tbl = dyns; + tmp_node.nd_body = 0; + tmp_node.nd_args = 0; + + ast.root = RNODE(&tmp_node); ast.frozen_string_literal = -1; ast.coverage_enabled = -1; ast.script_lines = INT2FIX(-1); @@ -1748,6 +1752,17 @@ rb_lastline_set(VALUE val) vm_svar_set(GET_EC(), VM_SVAR_LASTLINE, val); } +void +rb_lastline_set_up(VALUE val, unsigned int up) +{ + rb_control_frame_t * cfp = GET_EC()->cfp; + + for(unsigned int i = 0; i < up; i++) { + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + } + vm_cfp_svar_set(GET_EC(), cfp, VM_SVAR_LASTLINE, val); +} + /* misc */ const char * @@ -3565,7 +3580,7 @@ extern size_t rb_gc_stack_maxsize; static VALUE sdr(VALUE self) { - rb_vm_bugreport(NULL); + rb_vm_bugreport(NULL, stderr); return Qnil; } @@ -3687,6 +3702,7 @@ Init_VM(void) { VALUE opts; VALUE klass; + VALUE fcore; /* * Document-class: RubyVM @@ -3712,8 +3728,9 @@ Init_VM(void) #endif /* FrozenCore (hidden) */ - VALUE fcore = rb_mRubyVMFrozenCore = rb_iclass_alloc(rb_cBasicObject); + fcore = rb_class_new(rb_cBasicObject); rb_set_class_path(fcore, rb_cRubyVM, "FrozenCore"); + RBASIC(fcore)->flags = T_ICLASS; klass = rb_singleton_class(fcore); rb_define_method_id(klass, id_core_set_method_alias, m_core_set_method_alias, 3); rb_define_method_id(klass, id_core_set_variable_alias, m_core_set_variable_alias, 2); @@ -3732,6 +3749,8 @@ Init_VM(void) RBASIC_CLEAR_CLASS(klass); rb_obj_freeze(klass); rb_gc_register_mark_object(fcore); + rb_gc_register_mark_object(rb_class_path_cached(fcore)); + rb_mRubyVMFrozenCore = fcore; /* * Document-class: Thread diff --git a/vm_args.c b/vm_args.c index a02e08d7fc2433..882966e4328361 100644 --- a/vm_args.c +++ b/vm_args.c @@ -885,10 +885,7 @@ vm_caller_setup_arg_block(const rb_execution_context_t *ec, rb_control_frame_t * return VM_BLOCK_HANDLER_NONE; } else if (block_code == rb_block_param_proxy) { - VM_ASSERT(!VM_CFP_IN_HEAP_P(GET_EC(), reg_cfp)); - VALUE handler = VM_CF_BLOCK_HANDLER(reg_cfp); - reg_cfp->block_code = (const void *) handler; - return handler; + return VM_CF_BLOCK_HANDLER(reg_cfp); } else if (SYMBOL_P(block_code) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) { const rb_cref_t *cref = vm_env_cref(reg_cfp->ep); diff --git a/vm_backtrace.c b/vm_backtrace.c index e46eaa5b813bca..34ebde0f0b66ef 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -71,7 +71,7 @@ calc_pos(const rb_iseq_t *iseq, const VALUE *pc, int *lineno, int *node_id) #if VMDEBUG && defined(HAVE_BUILTIN___BUILTIN_TRAP) else { /* SDR() is not possible; that causes infinite loop. */ - rb_print_backtrace(); + rb_print_backtrace(stderr); __builtin_trap(); } #endif @@ -1003,31 +1003,38 @@ vm_backtrace_print(FILE *fp) &arg); } +struct oldbt_bugreport_arg { + FILE *fp; + int count; +}; + static void oldbt_bugreport(void *arg, VALUE file, int line, VALUE method) { + struct oldbt_bugreport_arg *p = arg; + FILE *fp = p->fp; const char *filename = NIL_P(file) ? "ruby" : RSTRING_PTR(file); - if (!*(int *)arg) { - fprintf(stderr, "-- Ruby level backtrace information " + if (!p->count) { + fprintf(fp, "-- Ruby level backtrace information " "----------------------------------------\n"); - *(int *)arg = 1; + p->count = 1; } if (NIL_P(method)) { - fprintf(stderr, "%s:%d:in unknown method\n", filename, line); + fprintf(fp, "%s:%d:in unknown method\n", filename, line); } else { - fprintf(stderr, "%s:%d:in `%s'\n", filename, line, RSTRING_PTR(method)); + fprintf(fp, "%s:%d:in `%s'\n", filename, line, RSTRING_PTR(method)); } } void -rb_backtrace_print_as_bugreport(void) +rb_backtrace_print_as_bugreport(FILE *fp) { struct oldbt_arg arg; - int i = 0; + struct oldbt_bugreport_arg barg = {fp, 0}; arg.func = oldbt_bugreport; - arg.data = (int *)&i; + arg.data = &barg; backtrace_each(GET_EC(), oldbt_init, @@ -1583,6 +1590,7 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines) int i; const rb_execution_context_t *ec = GET_EC(); const rb_control_frame_t *cfp = ec->cfp, *end_cfp = RUBY_VM_END_CONTROL_FRAME(ec); + const rb_control_frame_t *top = cfp; const rb_callable_method_entry_t *cme; // If this function is called inside a thread after thread creation, but @@ -1613,7 +1621,18 @@ rb_profile_frames(int start, int limit, VALUE *buff, int *lines) buff[i] = (VALUE)cfp->iseq; } - if (lines) lines[i] = calc_lineno(cfp->iseq, cfp->pc); + if (lines) { + // The topmost frame may not have an updated PC because the JIT + // may not have set one. The JIT compiler will update the PC + // before entering a new function (so that `caller` will work), + // so only the topmost frame could possibly have an out of date PC + if (cfp == top && cfp->jit_return) { + lines[i] = 0; + } + else { + lines[i] = calc_lineno(cfp->iseq, cfp->pc); + } + } i++; } diff --git a/vm_core.h b/vm_core.h index 55e86a611d65f8..f92787191fd2f8 100644 --- a/vm_core.h +++ b/vm_core.h @@ -1566,12 +1566,6 @@ vm_block_handler_verify(MAYBE_UNUSED(VALUE block_handler)) (vm_block_handler_type(block_handler), 1)); } -static inline int -vm_cfp_forwarded_bh_p(const rb_control_frame_t *cfp, VALUE block_handler) -{ - return ((VALUE) cfp->block_code) == block_handler; -} - static inline enum rb_block_type vm_block_type(const struct rb_block *block) { @@ -1705,13 +1699,13 @@ bool rb_redirecting_allocation(void); rb_ractor_t *rb_current_allocating_ractor(void); /* for debug */ -extern void rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp); -extern void rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc); -extern void rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp); +extern bool rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *); +extern bool rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc, FILE *); +extern bool rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *); -#define SDR() rb_vmdebug_stack_dump_raw(GET_EC(), GET_EC()->cfp) -#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_EC(), (cfp)) -void rb_vm_bugreport(const void *); +#define SDR() rb_vmdebug_stack_dump_raw(GET_EC(), GET_EC()->cfp, stderr) +#define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_EC(), (cfp), stderr) +bool rb_vm_bugreport(const void *, FILE *); typedef void (*ruby_sighandler_t)(int); RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 4, 5) NORETURN(void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int sig, const void *, const char *fmt, ...)); diff --git a/vm_dump.c b/vm_dump.c index b9f4e098a00cc1..d635af2c8911b6 100644 --- a/vm_dump.c +++ b/vm_dump.c @@ -46,8 +46,11 @@ const char *rb_method_type_name(rb_method_type_t type); int ruby_on_ci; -static void -control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *cfp) +#define kprintf(...) if (fprintf(errout, __VA_ARGS__) < 0) goto error +#define kputs(s) if (fputs(s, errout) < 0) goto error + +static bool +control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { ptrdiff_t pc = -1; ptrdiff_t ep = cfp->ep - ec->vm_stack; @@ -140,30 +143,30 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c line = -1; } - fprintf(stderr, "c:%04"PRIdPTRDIFF" ", + kprintf("c:%04"PRIdPTRDIFF" ", ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size) - cfp)); if (pc == -1) { - fprintf(stderr, "p:---- "); + kprintf("p:---- "); } else { - fprintf(stderr, "p:%04"PRIdPTRDIFF" ", pc); + kprintf("p:%04"PRIdPTRDIFF" ", pc); } - fprintf(stderr, "s:%04"PRIdPTRDIFF" ", cfp->sp - ec->vm_stack); - fprintf(stderr, ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000); - fprintf(stderr, "%-6s", magic); + kprintf("s:%04"PRIdPTRDIFF" ", cfp->sp - ec->vm_stack); + kprintf(ep_in_heap == ' ' ? "e:%06"PRIdPTRDIFF" " : "E:%06"PRIxPTRDIFF" ", ep % 10000); + kprintf("%-6s", magic); if (line) { - fprintf(stderr, " %s", posbuf); + kprintf(" %s", posbuf); } if (VM_FRAME_FINISHED_P(cfp)) { - fprintf(stderr, " [FINISH]"); + kprintf(" [FINISH]"); } if (0) { - fprintf(stderr, " \t"); - fprintf(stderr, "iseq: %-24s ", iseq_name); - fprintf(stderr, "self: %-24s ", selfstr); - fprintf(stderr, "%-1s ", biseq_name); + kprintf(" \t"); + kprintf("iseq: %-24s ", iseq_name); + kprintf("self: %-24s ", selfstr); + kprintf("%-1s ", biseq_name); } - fprintf(stderr, "\n"); + kprintf("\n"); // additional information for CI machines if (ruby_on_ci) { @@ -171,112 +174,127 @@ control_frame_dump(const rb_execution_context_t *ec, const rb_control_frame_t *c if (me) { if (IMEMO_TYPE_P(me, imemo_ment)) { - fprintf(stderr, " me:\n"); - fprintf(stderr, " called_id: %s, type: %s\n", rb_id2name(me->called_id), rb_method_type_name(me->def->type)); - fprintf(stderr, " owner class: %s\n", rb_raw_obj_info(buff, 0x100, me->owner)); + kprintf(" me:\n"); + kprintf(" called_id: %s, type: %s\n", rb_id2name(me->called_id), rb_method_type_name(me->def->type)); + kprintf(" owner class: %s\n", rb_raw_obj_info(buff, 0x100, me->owner)); if (me->owner != me->defined_class) { - fprintf(stderr, " defined_class: %s\n", rb_raw_obj_info(buff, 0x100, me->defined_class)); + kprintf(" defined_class: %s\n", rb_raw_obj_info(buff, 0x100, me->defined_class)); } } else { - fprintf(stderr, " me is corrupted (%s)\n", rb_raw_obj_info(buff, 0x100, (VALUE)me)); + kprintf(" me is corrupted (%s)\n", rb_raw_obj_info(buff, 0x100, (VALUE)me)); } } - fprintf(stderr, " self: %s\n", rb_raw_obj_info(buff, 0x100, cfp->self)); + kprintf(" self: %s\n", rb_raw_obj_info(buff, 0x100, cfp->self)); if (iseq) { if (ISEQ_BODY(iseq)->local_table_size > 0) { - fprintf(stderr, " lvars:\n"); + kprintf(" lvars:\n"); for (unsigned int i=0; ilocal_table_size; i++) { const VALUE *argv = cfp->ep - ISEQ_BODY(cfp->iseq)->local_table_size - VM_ENV_DATA_SIZE + 1; - fprintf(stderr, " %s: %s\n", + kprintf(" %s: %s\n", rb_id2name(ISEQ_BODY(iseq)->local_table[i]), rb_raw_obj_info(buff, 0x100, argv[i])); } } } } + return true; + error: + return false; } -void -rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp) +bool +rb_vmdebug_stack_dump_raw(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { #if 0 VALUE *sp = cfp->sp; const VALUE *ep = cfp->ep; VALUE *p, *st, *t; - fprintf(stderr, "-- stack frame ------------\n"); + kprintf("-- stack frame ------------\n"); for (p = st = ec->vm_stack; p < sp; p++) { - fprintf(stderr, "%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p); + kprintf("%04ld (%p): %08"PRIxVALUE, (long)(p - st), p, *p); t = (VALUE *)*p; if (ec->vm_stack <= t && t < sp) { - fprintf(stderr, " (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF((VALUE)t) - ec->vm_stack)); + kprintf(" (= %ld)", (long)((VALUE *)GC_GUARDED_PTR_REF((VALUE)t) - ec->vm_stack)); } if (p == ep) - fprintf(stderr, " <- ep"); + kprintf(" <- ep"); - fprintf(stderr, "\n"); + kprintf("\n"); } #endif - fprintf(stderr, "-- Control frame information " + kprintf("-- Control frame information " "-----------------------------------------------\n"); while ((void *)cfp < (void *)(ec->vm_stack + ec->vm_stack_size)) { - control_frame_dump(ec, cfp); + control_frame_dump(ec, cfp, errout); cfp++; } - fprintf(stderr, "\n"); + kprintf("\n"); + return true; + + error: + return false; } -void +bool rb_vmdebug_stack_dump_raw_current(void) { const rb_execution_context_t *ec = GET_EC(); - rb_vmdebug_stack_dump_raw(ec, ec->cfp); + return rb_vmdebug_stack_dump_raw(ec, ec->cfp, stderr); } -void -rb_vmdebug_env_dump_raw(const rb_env_t *env, const VALUE *ep) +bool +rb_vmdebug_env_dump_raw(const rb_env_t *env, const VALUE *ep, FILE *errout) { unsigned int i; - fprintf(stderr, "-- env --------------------\n"); + kprintf("-- env --------------------\n"); while (env) { - fprintf(stderr, "--\n"); + kprintf("--\n"); for (i = 0; i < env->env_size; i++) { - fprintf(stderr, "%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]); - if (&env->env[i] == ep) fprintf(stderr, " <- ep"); - fprintf(stderr, "\n"); + kprintf("%04d: %08"PRIxVALUE" (%p)", i, env->env[i], (void *)&env->env[i]); + if (&env->env[i] == ep) kprintf(" <- ep"); + kprintf("\n"); } env = rb_vm_env_prev_env(env); } - fprintf(stderr, "---------------------------\n"); + kprintf("---------------------------\n"); + return true; + + error: + return false; } -void -rb_vmdebug_proc_dump_raw(rb_proc_t *proc) +bool +rb_vmdebug_proc_dump_raw(rb_proc_t *proc, FILE *errout) { const rb_env_t *env; char *selfstr; VALUE val = rb_inspect(vm_block_self(&proc->block)); selfstr = StringValueCStr(val); - fprintf(stderr, "-- proc -------------------\n"); - fprintf(stderr, "self: %s\n", selfstr); + kprintf("-- proc -------------------\n"); + kprintf("self: %s\n", selfstr); env = VM_ENV_ENVVAL_PTR(vm_block_ep(&proc->block)); - rb_vmdebug_env_dump_raw(env, vm_block_ep(&proc->block)); + rb_vmdebug_env_dump_raw(env, vm_block_ep(&proc->block), errout); + return true; + + error: + return false; } -void -rb_vmdebug_stack_dump_th(VALUE thval) +bool +rb_vmdebug_stack_dump_th(VALUE thval, FILE *errout) { rb_thread_t *target_th = rb_thread_ptr(thval); - rb_vmdebug_stack_dump_raw(target_th->ec, target_th->ec->cfp); + return rb_vmdebug_stack_dump_raw(target_th->ec, target_th->ec->cfp, errout); } #if VMDEBUG > 2 @@ -295,7 +313,7 @@ vm_base_ptr(const rb_control_frame_t *cfp) } static void -vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *cfp) +vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { int i, argc = 0, local_table_size = 0; VALUE rstr; @@ -321,17 +339,17 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c { const VALUE *ptr = ep - local_table_size; - control_frame_dump(ec, cfp); + control_frame_dump(ec, cfp, errout); for (i = 0; i < argc; i++) { rstr = rb_inspect(*ptr); - fprintf(stderr, " arg %2d: %8s (%p)\n", i, StringValueCStr(rstr), - (void *)ptr++); + kprintf(" arg %2d: %8s (%p)\n", i, StringValueCStr(rstr), + (void *)ptr++); } for (; i < local_table_size - 1; i++) { rstr = rb_inspect(*ptr); - fprintf(stderr, " local %2d: %8s (%p)\n", i, StringValueCStr(rstr), - (void *)ptr++); + kprintf(" local %2d: %8s (%p)\n", i, StringValueCStr(rstr), + (void *)ptr++); } ptr = vm_base_ptr(cfp); @@ -347,13 +365,13 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c rstr = rb_inspect(*ptr); break; } - fprintf(stderr, " stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr), + kprintf(" stack %2d: %8s (%"PRIdPTRDIFF")\n", i, StringValueCStr(rstr), (ptr - ec->vm_stack)); } } else if (VM_FRAME_FINISHED_P(cfp)) { if (ec->vm_stack + ec->vm_stack_size > (VALUE *)(cfp + 1)) { - vm_stack_dump_each(ec, cfp + 1); + vm_stack_dump_each(ec, cfp + 1, errout); } else { /* SDR(); */ @@ -365,8 +383,8 @@ vm_stack_dump_each(const rb_execution_context_t *ec, const rb_control_frame_t *c } #endif -void -rb_vmdebug_debug_print_register(const rb_execution_context_t *ec) +bool +rb_vmdebug_debug_print_register(const rb_execution_context_t *ec, FILE *errout) { rb_control_frame_t *cfp = ec->cfp; ptrdiff_t pc = -1; @@ -382,18 +400,22 @@ rb_vmdebug_debug_print_register(const rb_execution_context_t *ec) } cfpi = ((rb_control_frame_t *)(ec->vm_stack + ec->vm_stack_size)) - cfp; - fprintf(stderr, " [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n", + kprintf(" [PC] %04"PRIdPTRDIFF", [SP] %04"PRIdPTRDIFF", [EP] %04"PRIdPTRDIFF", [CFP] %04"PRIdPTRDIFF"\n", pc, (cfp->sp - ec->vm_stack), ep, cfpi); + return true; + + error: + return false; } -void -rb_vmdebug_thread_dump_regs(VALUE thval) +bool +rb_vmdebug_thread_dump_regs(VALUE thval, FILE *errout) { - rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec); + return rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec, errout); } -void -rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc) +bool +rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc, FILE *errout) { const rb_iseq_t *iseq = cfp->iseq; @@ -402,10 +424,10 @@ rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_fr int i; for (i=0; i<(int)VM_CFP_CNT(ec, cfp); i++) { - printf(" "); + kprintf(" "); } - printf("| "); - if(0)printf("[%03ld] ", (long)(cfp->sp - ec->vm_stack)); + kprintf("| "); + if(0) kprintf("[%03ld] ", (long)(cfp->sp - ec->vm_stack)); /* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(ec, cfp)); */ if (pc >= 0) { @@ -416,43 +438,54 @@ rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_fr } #if VMDEBUG > 3 - fprintf(stderr, " (1)"); - rb_vmdebug_debug_print_register(ec); + kprintf(" (1)"); + rb_vmdebug_debug_print_register(errout, ec); #endif + return true; + + error: + return false; } -void -rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp) +bool +rb_vmdebug_debug_print_post(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, FILE *errout) { #if VMDEBUG > 9 - SDR2(cfp); + if (!rb_vmdebug_stack_dump_raw(ec, cfp, errout)) goto errout; #endif #if VMDEBUG > 3 - fprintf(stderr, " (2)"); - rb_vmdebug_debug_print_register(ec); + kprintf(" (2)"); + rb_vmdebug_debug_print_register(errout, ec); #endif /* stack_dump_raw(ec, cfp); */ #if VMDEBUG > 2 /* stack_dump_thobj(ec); */ - vm_stack_dump_each(ec, ec->cfp); + vm_stack_dump_each(ec, ec->cfp, errout); - printf + kprintf ("--------------------------------------------------------------\n"); +#endif + return true; + +#if VMDEBUG > 2 + error: + return false; #endif } VALUE -rb_vmdebug_thread_dump_state(VALUE self) +rb_vmdebug_thread_dump_state(FILE *errout, VALUE self) { rb_thread_t *th = rb_thread_ptr(self); rb_control_frame_t *cfp = th->ec->cfp; - fprintf(stderr, "Thread state dump:\n"); - fprintf(stderr, "pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp); - fprintf(stderr, "cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep); + kprintf("Thread state dump:\n"); + kprintf("pc : %p, sp : %p\n", (void *)cfp->pc, (void *)cfp->sp); + kprintf("cfp: %p, ep : %p\n", (void *)cfp, (void *)cfp->ep); + error: return Qnil; } @@ -664,6 +697,11 @@ typedef void *PGET_MODULE_BASE_ROUTINE64; typedef void *PTRANSLATE_ADDRESS_ROUTINE64; # endif +struct dump_thead_arg { + DWORD tid; + FILE *errout; +}; + static void dump_thread(void *arg) { @@ -675,7 +713,8 @@ dump_thread(void *arg) BOOL (WINAPI *pSymFromAddr)(HANDLE, DWORD64, DWORD64 *, SYMBOL_INFO *); BOOL (WINAPI *pSymGetLineFromAddr64)(HANDLE, DWORD64, DWORD *, IMAGEHLP_LINE64 *); HANDLE (WINAPI *pOpenThread)(DWORD, BOOL, DWORD); - DWORD tid = *(DWORD *)arg; + DWORD tid = ((struct dump_thead_arg *)arg)->tid; + FILE *errout = ((struct dump_thead_arg *)arg)->errout; HANDLE ph; HANDLE th; @@ -740,19 +779,20 @@ dump_thread(void *arg) info->MaxNameLen = MAX_SYM_NAME; if (pSymFromAddr(ph, addr, &displacement, info)) { if (GetModuleFileName((HANDLE)(uintptr_t)pSymGetModuleBase64(ph, addr), libpath, sizeof(libpath))) - fprintf(stderr, "%s", libpath); - fprintf(stderr, "(%s+0x%"PRI_64_PREFIX"x)", + kprintf("%s", libpath); + kprintf("(%s+0x%"PRI_64_PREFIX"x)", info->Name, displacement); } - fprintf(stderr, " [0x%p]", (void *)(VALUE)addr); + kprintf(" [0x%p]", (void *)(VALUE)addr); memset(&line, 0, sizeof(line)); line.SizeOfStruct = sizeof(line); if (pSymGetLineFromAddr64(ph, addr, &tmp, &line)) - fprintf(stderr, " %s:%lu", line.FileName, line.LineNumber); - fprintf(stderr, "\n"); + kprintf(" %s:%lu", line.FileName, line.LineNumber); + kprintf("\n"); } } + error: ResumeThread(th); } CloseHandle(th); @@ -764,27 +804,32 @@ dump_thread(void *arg) #endif void -rb_print_backtrace(void) +rb_print_backtrace(FILE *errout) { #if USE_BACKTRACE #define MAX_NATIVE_TRACE 1024 static void *trace[MAX_NATIVE_TRACE]; int n = (int)backtrace(trace, MAX_NATIVE_TRACE); #if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)) && defined(HAVE_DLADDR) && !defined(__sparc) - rb_dump_backtrace_with_lines(n, trace); + rb_dump_backtrace_with_lines(n, trace, errout); #else char **syms = backtrace_symbols(trace, n); if (syms) { int i; for (i=0; igregs[REG_##reg], #reg, col_count, 80)) +# define dump_machine_register(reg) (col_count = print_machine_register(errout, mctx->gregs[REG_##reg], #reg, col_count, 80)) # elif defined(__aarch64__) || defined(__arm__) || defined(__riscv) || defined(__loongarch64) -# define dump_machine_register(reg, regstr) (col_count = print_machine_register(reg, regstr, col_count, 80)) +# define dump_machine_register(reg, regstr) (col_count = print_machine_register(errout, reg, regstr, col_count, 80)) # endif #elif defined __APPLE__ # if defined(__aarch64__) -# define dump_machine_register(reg, regstr) (col_count = print_machine_register(mctx->MCTX_SS_REG(reg), regstr, col_count, 80)) +# define dump_machine_register(reg, regstr) (col_count = print_machine_register(errout, mctx->MCTX_SS_REG(reg), regstr, col_count, 80)) # else -# define dump_machine_register(reg) (col_count = print_machine_register(mctx->MCTX_SS_REG(reg), #reg, col_count, 80)) +# define dump_machine_register(reg) (col_count = print_machine_register(errout, mctx->MCTX_SS_REG(reg), #reg, col_count, 80)) # endif #endif #ifdef dump_machine_register static int -print_machine_register(size_t reg, const char *reg_name, int col_count, int max_col) +print_machine_register(FILE *errout, size_t reg, const char *reg_name, int col_count, int max_col) { int ret; char buf[64]; @@ -818,21 +863,24 @@ print_machine_register(size_t reg, const char *reg_name, int col_count, int max_ ret = snprintf(buf, sizeof(buf), " %3.3s: 0x%.*" PRIxSIZE, reg_name, size_width, reg); if (col_count + ret > max_col) { - fputs("\n", stderr); + kputs("\n"); col_count = 0; } col_count += ret; - fputs(buf, stderr); + kputs(buf); return col_count; + + error: + return -1; } -static void -rb_dump_machine_register(const ucontext_t *ctx) +static bool +rb_dump_machine_register(FILE *errout, const ucontext_t *ctx) { int col_count = 0; - if (!ctx) return; + if (!ctx) return true; - fprintf(stderr, "-- Machine register context " + kprintf("-- Machine register context " "------------------------------------------------\n"); # if defined __linux__ @@ -1025,14 +1073,18 @@ rb_dump_machine_register(const ucontext_t *ctx) # endif } # endif - fprintf(stderr, "\n\n"); + kprintf("\n\n"); + return true; + + error: + return false; } #else -# define rb_dump_machine_register(ctx) ((void)0) +# define rb_dump_machine_register(errout, ctx) ((void)0) #endif /* dump_machine_register */ -void -rb_vm_bugreport(const void *ctx) +bool +rb_vm_bugreport(const void *ctx, FILE *errout) { const char *cmd = getenv("RUBY_ON_BUG"); if (cmd) { @@ -1049,8 +1101,8 @@ rb_vm_bugreport(const void *ctx) { static bool crashing = false; if (crashing) { - fprintf(stderr, "Crashed while printing bug report\n"); - return; + kprintf("Crashed while printing bug report\n"); + return true; } crashing = true; } @@ -1067,32 +1119,32 @@ rb_vm_bugreport(const void *ctx) const rb_execution_context_t *ec = rb_current_execution_context(false); if (vm && ec) { - SDR(); - rb_backtrace_print_as_bugreport(); - fputs("\n", stderr); + rb_vmdebug_stack_dump_raw(ec, ec->cfp, errout); + rb_backtrace_print_as_bugreport(errout); + kputs("\n"); // If we get here, hopefully things are intact enough that // we can read these two numbers. It is an estimate because // we are reading without synchronization. - fprintf(stderr, "-- Threading information " + kprintf("-- Threading information " "---------------------------------------------------\n"); - fprintf(stderr, "Total ractor count: %u\n", vm->ractor.cnt); - fprintf(stderr, "Ruby thread count for this ractor: %u\n", rb_ec_ractor_ptr(ec)->threads.cnt); - fputs("\n", stderr); + kprintf("Total ractor count: %u\n", vm->ractor.cnt); + kprintf("Ruby thread count for this ractor: %u\n", rb_ec_ractor_ptr(ec)->threads.cnt); + kputs("\n"); } - rb_dump_machine_register(ctx); + rb_dump_machine_register(errout, ctx); #if USE_BACKTRACE || defined(_WIN32) - fprintf(stderr, "-- C level backtrace information " + kprintf("-- C level backtrace information " "-------------------------------------------\n"); - rb_print_backtrace(); + rb_print_backtrace(errout); - fprintf(stderr, "\n"); + kprintf("\n"); #endif /* USE_BACKTRACE */ if (other_runtime_info || vm) { - fprintf(stderr, "-- Other runtime information " + kprintf("-- Other runtime information " "-----------------------------------------------\n\n"); } if (vm && !rb_during_gc()) { @@ -1105,16 +1157,16 @@ rb_vm_bugreport(const void *ctx) name = vm->progname; if (name) { - fprintf(stderr, "* Loaded script: %.*s\n", + kprintf("* Loaded script: %.*s\n", LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); - fprintf(stderr, "\n"); + kprintf("\n"); } if (vm->loaded_features) { - fprintf(stderr, "* Loaded features:\n\n"); + kprintf("* Loaded features:\n\n"); for (i=0; iloaded_features); i++) { name = RARRAY_AREF(vm->loaded_features, i); if (RB_TYPE_P(name, T_STRING)) { - fprintf(stderr, " %4d %.*s\n", i, + kprintf(" %4d %.*s\n", i, LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); } else if (RB_TYPE_P(name, T_CLASS) || RB_TYPE_P(name, T_MODULE)) { @@ -1122,26 +1174,26 @@ rb_vm_bugreport(const void *ctx) "class" : "module"; name = rb_search_class_path(rb_class_real(name)); if (!RB_TYPE_P(name, T_STRING)) { - fprintf(stderr, " %4d %s:\n", i, type); + kprintf(" %4d %s:\n", i, type); continue; } - fprintf(stderr, " %4d %s:%.*s\n", i, type, + kprintf(" %4d %s:%.*s\n", i, type, LIMITED_NAME_LENGTH(name), RSTRING_PTR(name)); } else { VALUE klass = rb_search_class_path(rb_obj_class(name)); if (!RB_TYPE_P(klass, T_STRING)) { - fprintf(stderr, " %4d #<%p:%p>\n", i, + kprintf(" %4d #<%p:%p>\n", i, (void *)CLASS_OF(name), (void *)name); continue; } - fprintf(stderr, " %4d #<%.*s:%p>\n", i, + kprintf(" %4d #<%.*s:%p>\n", i, LIMITED_NAME_LENGTH(klass), RSTRING_PTR(klass), (void *)name); } } } - fprintf(stderr, "\n"); + kprintf("\n"); } { @@ -1149,17 +1201,17 @@ rb_vm_bugreport(const void *ctx) { FILE *fp = fopen(PROC_MAPS_NAME, "r"); if (fp) { - fprintf(stderr, "* Process memory map:\n\n"); + kprintf("* Process memory map:\n\n"); while (!feof(fp)) { char buff[0x100]; size_t rn = fread(buff, 1, 0x100, fp); - if (fwrite(buff, 1, rn, stderr) != rn) + if (fwrite(buff, 1, rn, errout) != rn) break; } fclose(fp); - fprintf(stderr, "\n\n"); + kprintf("\n\n"); } } #endif /* __linux__ */ @@ -1173,14 +1225,14 @@ rb_vm_bugreport(const void *ctx) mib[2] = KERN_PROC_PID; mib[3] = getpid(); if (sysctl(mib, MIB_KERN_PROC_PID_LEN, &kp, &len, NULL, 0) == -1) { - perror("sysctl"); + kprintf("sysctl: %s\n", strerror(errno)); } else { struct procstat *prstat = procstat_open_sysctl(); - fprintf(stderr, "* Process memory map:\n\n"); - procstat_vm(prstat, &kp); + kprintf("* Process memory map:\n\n"); + procstat_vm(prstat, &kp, errout); procstat_close(prstat); - fprintf(stderr, "\n"); + kprintf("\n"); } #endif /* __FreeBSD__ */ #ifdef __APPLE__ @@ -1190,7 +1242,7 @@ rb_vm_bugreport(const void *ctx) mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT; natural_t depth = 0; - fprintf(stderr, "* Process memory map:\n\n"); + kprintf("* Process memory map:\n\n"); while (1) { if (vm_region_recurse(mach_task_self(), &addr, &size, &depth, (vm_region_recurse_info_t)&map, &count) != KERN_SUCCESS) { @@ -1202,17 +1254,17 @@ rb_vm_bugreport(const void *ctx) depth++; } else { - fprintf(stderr, "%lx-%lx %s%s%s", addr, (addr+size), + kprintf("%lx-%lx %s%s%s", addr, (addr+size), ((map.protection & VM_PROT_READ) != 0 ? "r" : "-"), ((map.protection & VM_PROT_WRITE) != 0 ? "w" : "-"), ((map.protection & VM_PROT_EXECUTE) != 0 ? "x" : "-")); #ifdef HAVE_LIBPROC_H char buff[PATH_MAX]; if (proc_regionfilename(getpid(), addr, buff, sizeof(buff)) > 0) { - fprintf(stderr, " %s", buff); + kprintf(" %s", buff); } #endif - fprintf(stderr, "\n"); + kprintf("\n"); } addr += size; @@ -1220,21 +1272,30 @@ rb_vm_bugreport(const void *ctx) } #endif } + return true; + + error: + return false; } -void +bool rb_vmdebug_stack_dump_all_threads(void) { rb_thread_t *th = NULL; rb_ractor_t *r = GET_RACTOR(); + FILE *errout = stderr; // TODO: now it only shows current ractor ccan_list_for_each(&r->threads.set, th, lt_node) { #ifdef NON_SCALAR_THREAD_ID - fprintf(stderr, "th: %p, native_id: N/A\n", th); + kprintf("th: %p, native_id: N/A\n", th); #else - fprintf(stderr, "th: %p, native_id: %p\n", (void *)th, (void *)(uintptr_t)th->nt->thread_id); + kprintf("th: %p, native_id: %p\n", (void *)th, (void *)(uintptr_t)th->nt->thread_id); #endif - rb_vmdebug_stack_dump_raw(th->ec, th->ec->cfp); + if (!rb_vmdebug_stack_dump_raw(th->ec, th->ec->cfp, errout)) goto error; } + return true; + + error: + return false; } diff --git a/vm_eval.c b/vm_eval.c index 676c2211cd30dc..115662de57c02d 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -546,7 +546,7 @@ rb_call0(rb_execution_context_t *ec, RB_DEBUG_COUNTER_INC(call0_public); const rb_callable_method_entry_t *cc_cme = cc ? vm_cc_cme(cc) : NULL; - const rb_callable_method_entry_t *cme = callable_method_entry_refeinements0(CLASS_OF(recv), mid, NULL, true, cc_cme); + const rb_callable_method_entry_t *cme = callable_method_entry_refinements0(CLASS_OF(recv), mid, NULL, true, cc_cme); call_status = rb_method_call_status(ec, cme, scope, self); if (UNLIKELY(call_status != MISSING_NONE)) { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index a325d070a252db..9d3842ac7576ce 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -93,6 +93,7 @@ rb_ec_stack_overflow(rb_execution_context_t *ec, int crit) #endif } +static inline void stack_check(rb_execution_context_t *ec); #if VM_CHECK_MODE > 0 static int @@ -3810,7 +3811,7 @@ aliased_callable_method_entry(const rb_callable_method_entry_t *me) VM_ASSERT(RB_TYPE_P(orig_me->owner, T_MODULE)); cme = rb_method_entry_complement_defined_class(orig_me, me->called_id, defined_class); - if (me->def->alias_count + me->def->complemented_count == 0) { + if (me->def->reference_count == 1) { RB_OBJ_WRITE(me, &me->def->body.alias.original_me, cme); } else { @@ -5565,6 +5566,7 @@ vm_sendish( VALUE rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq) { + stack_check(ec); VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, false); VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); VM_EXEC(ec, val); @@ -5574,6 +5576,7 @@ rb_vm_send(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd VALUE rb_vm_opt_send_without_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd) { + stack_check(ec); VALUE bh = VM_BLOCK_HANDLER_NONE; VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_method); VM_EXEC(ec, val); @@ -5583,6 +5586,7 @@ rb_vm_opt_send_without_block(rb_execution_context_t *ec, rb_control_frame_t *reg VALUE rb_vm_invokesuper(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd, ISEQ blockiseq) { + stack_check(ec); VALUE bh = vm_caller_setup_arg_block(ec, GET_CFP(), cd->ci, blockiseq, true); VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_super); VM_EXEC(ec, val); @@ -5592,6 +5596,7 @@ rb_vm_invokesuper(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_ VALUE rb_vm_invokeblock(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, CALL_DATA cd) { + stack_check(ec); VALUE bh = VM_BLOCK_HANDLER_NONE; VALUE val = vm_sendish(ec, GET_CFP(), cd, bh, mexp_search_invokeblock); VM_EXEC(ec, val); diff --git a/vm_method.c b/vm_method.c index a65c676cfcee79..e2a3907c33bca7 100644 --- a/vm_method.c +++ b/vm_method.c @@ -166,7 +166,6 @@ invalidate_negative_cache(ID mid) } } -static rb_method_entry_t *rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def); const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me); static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id); static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme); @@ -403,33 +402,25 @@ rb_add_method_optimized(VALUE klass, ID mid, enum method_optimized_type opt_type } static void -rb_method_definition_release(rb_method_definition_t *def, int complemented) +rb_method_definition_release(rb_method_definition_t *def) { if (def != NULL) { - const int alias_count = def->alias_count; - const int complemented_count = def->complemented_count; - VM_ASSERT(alias_count >= 0); - VM_ASSERT(complemented_count >= 0); - - if (alias_count + complemented_count == 0) { - if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d,%d (remove)\n", (void *)def, - rb_id2name(def->original_id), alias_count, complemented_count); + const int reference_count = def->reference_count; + def->reference_count--; + + VM_ASSERT(reference_count >= 0); + + if (def->reference_count == 0) { + if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d (remove)\n", (void *)def, + rb_id2name(def->original_id), def->reference_count); if (def->type == VM_METHOD_TYPE_BMETHOD && def->body.bmethod.hooks) { xfree(def->body.bmethod.hooks); } xfree(def); } else { - if (complemented) { - VM_ASSERT(def->complemented_count > 0); - def->complemented_count--; - } - else if (def->alias_count > 0) { - def->alias_count--; - } - - if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d,%d->%d (dec)\n", (void *)def, rb_id2name(def->original_id), - alias_count, def->alias_count, complemented_count, def->complemented_count); + if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d (dec)\n", (void *)def, rb_id2name(def->original_id), + reference_count, def->reference_count); } } } @@ -442,7 +433,7 @@ rb_free_method_entry(const rb_method_entry_t *me) if (me->def && me->def->iseq_overload) { delete_overloaded_cme((const rb_callable_method_entry_t *)me); } - rb_method_definition_release(me->def, METHOD_ENTRY_COMPLEMENTED(me)); + rb_method_definition_release(me->def); } static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr); @@ -509,10 +500,20 @@ setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE (*func)(ANYARGS), int cfunc->invoker = call_cfunc_invoker_func(argc); } +static rb_method_definition_t * +method_definition_addref(rb_method_definition_t *def, bool complemented) +{ + if (!complemented && def->reference_count > 0) def->aliased = true; + def->reference_count++; + if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->reference_count); + return def; +} + void rb_method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts) { - *(rb_method_definition_t **)&me->def = def; + rb_method_definition_release(me->def); + *(rb_method_definition_t **)&me->def = method_definition_addref(def, METHOD_ENTRY_COMPLEMENTED(me)); if (opts != NULL) { switch (def->type) { @@ -642,25 +643,10 @@ rb_method_definition_create(rb_method_type_t type, ID mid) return def; } -static rb_method_definition_t * -method_definition_addref(rb_method_definition_t *def) -{ - def->alias_count++; - if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->alias_count); - return def; -} - -static rb_method_definition_t * -method_definition_addref_complement(rb_method_definition_t *def) -{ - def->complemented_count++; - if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", (void *)def, rb_id2name(def->original_id), def->complemented_count); - return def; -} - static rb_method_entry_t * -rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def) +rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, rb_method_definition_t *def, bool complement) { + if (def) method_definition_addref(def, complement); rb_method_entry_t *me = (rb_method_entry_t *)rb_imemo_new(imemo_ment, (VALUE)def, (VALUE)called_id, owner, defined_class); return me; } @@ -682,9 +668,9 @@ filter_defined_class(VALUE klass) } rb_method_entry_t * -rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def) +rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, rb_method_definition_t *def) { - rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def); + rb_method_entry_t *me = rb_method_entry_alloc(called_id, klass, filter_defined_class(klass), def, false); METHOD_ENTRY_FLAGS_SET(me, visi, ruby_running ? FALSE : TRUE); if (def != NULL) method_definition_reset(me); return me; @@ -693,11 +679,7 @@ rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, c const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me) { - rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class, - method_definition_addref(src_me->def)); - if (METHOD_ENTRY_COMPLEMENTED(src_me)) { - method_definition_addref_complement(src_me->def); - } + rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, src_me->defined_class, src_me->def, METHOD_ENTRY_COMPLEMENTED(src_me)); METHOD_ENTRY_FLAGS_COPY(me, src_me); return me; @@ -723,10 +705,8 @@ rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID cal refined.owner = orig_me->owner; def = NULL; } - else { - def = method_definition_addref_complement(def); - } - me = rb_method_entry_alloc(called_id, src_me->owner, defined_class, def); + + me = rb_method_entry_alloc(called_id, src_me->owner, defined_class, def, true); METHOD_ENTRY_FLAGS_COPY(me, src_me); METHOD_ENTRY_COMPLEMENTED_SET(me); if (!def) { @@ -742,7 +722,8 @@ rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID cal void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src) { - *(rb_method_definition_t **)&dst->def = method_definition_addref(src->def); + rb_method_definition_release(dst->def); + *(rb_method_definition_t **)&dst->def = method_definition_addref(src->def, METHOD_ENTRY_COMPLEMENTED(src)); method_definition_reset(dst); dst->called_id = src->called_id; RB_OBJ_WRITE((VALUE)dst, &dst->owner, src->owner); @@ -769,7 +750,8 @@ make_method_entry_refined(VALUE owner, rb_method_entry_t *me) rb_method_entry_alloc(me->called_id, me->owner, me->defined_class ? me->defined_class : owner, - method_definition_addref(me->def)); + me->def, + true); METHOD_ENTRY_FLAGS_COPY(refined.orig_me, me); refined.owner = owner; @@ -897,7 +879,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil if (RTEST(ruby_verbose) && type != VM_METHOD_TYPE_UNDEF && - (old_def->alias_count == 0) && + (old_def->aliased == false) && (!old_def->no_redef_warning) && !make_refined && old_def->type != VM_METHOD_TYPE_UNDEF && @@ -927,7 +909,9 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil /* create method entry */ me = rb_method_entry_create(mid, defined_class, visi, NULL); - if (def == NULL) def = rb_method_definition_create(type, original_id); + if (def == NULL) { + def = rb_method_definition_create(type, original_id); + } rb_method_definition_set(me, def, opts); rb_clear_method_cache(klass, mid); @@ -965,7 +949,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil return me; } -static rb_method_entry_t *rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def); +static rb_method_entry_t *rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, rb_method_definition_t *def, bool refined); static st_table * overloaded_cme_table(void) @@ -1055,7 +1039,8 @@ get_overloaded_cme(const rb_callable_method_entry_t *cme) rb_method_entry_t *me = rb_method_entry_alloc(cme->called_id, cme->owner, cme->defined_class, - def); + def, + false); ASSERT_vm_locking(); st_insert(overloaded_cme_table(), (st_data_t)cme, (st_data_t)me); @@ -1134,9 +1119,7 @@ method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, if (newme == me) { me->def->no_redef_warning = TRUE; } - else { - method_definition_addref(me->def); - } + method_added(klass, mid); return newme; } @@ -1350,7 +1333,7 @@ negative_cme(ID mid) cme = (rb_callable_method_entry_t *)cme_data; } else { - cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL); + cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL, false); rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme); } @@ -1445,7 +1428,7 @@ rb_method_entry_with_refinements(VALUE klass, ID id, VALUE *defined_class_ptr) } static const rb_callable_method_entry_t * -callable_method_entry_refeinements0(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements, +callable_method_entry_refinements0(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements, const rb_callable_method_entry_t *cme) { if (cme == NULL || LIKELY(cme->def->type != VM_METHOD_TYPE_REFINED)) { @@ -1462,7 +1445,7 @@ static const rb_callable_method_entry_t * callable_method_entry_refinements(VALUE klass, ID id, VALUE *defined_class_ptr, bool with_refinements) { const rb_callable_method_entry_t *cme = callable_method_entry(klass, id, defined_class_ptr); - return callable_method_entry_refeinements0(klass, id, defined_class_ptr, with_refinements, cme); + return callable_method_entry_refinements0(klass, id, defined_class_ptr, with_refinements, cme); } const rb_callable_method_entry_t * @@ -2887,12 +2870,6 @@ obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv) return Qfalse; } -void -Init_Method(void) -{ - // -} - void Init_eval_method(void) { diff --git a/win32/Makefile.sub b/win32/Makefile.sub index feb7bfd2b514e3..ab1e46a4b0eee9 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -514,8 +514,6 @@ VCSUP = rem !endif ruby_pc = $(RUBY_BASE_NAME)-$(MAJOR).$(MINOR).pc -YARP_BUILD_DIR = $(MAKEDIR)/yarp - MESSAGE_BEGIN = @(for %I in ( MESSAGE_END = ) do @echo.%~I) ECHO_BEGIN = @echo. @@ -1281,13 +1279,13 @@ $(ruby_pc): $(RBCONFIG) $(ECHO) assembling $(<:\=/) $(Q) $(AS) $(ASFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(<:\=/) -{$(srcdir)/yarp}.c.obj: +{$(srcdir)/prism}.c.obj: $(ECHO) compiling $(<:\=/) $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/) -{$(srcdir)/yarp/enc}.c.obj: +{$(srcdir)/prism/enc}.c.obj: $(ECHO) compiling $(<:\=/) $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/) -{$(srcdir)/yarp/util}.c.obj: +{$(srcdir)/prism/util}.c.obj: $(ECHO) compiling $(<:\=/) $(Q) $(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$(<:\=/) {$(srcdir)/enc/trans}.c.obj: diff --git a/win32/file.h b/win32/file.h index 4f1f36a75cd72a..7bf9868e7daa39 100644 --- a/win32/file.h +++ b/win32/file.h @@ -47,4 +47,7 @@ int fchmod(int fd, int mode); UINT rb_w32_filecp(void); WCHAR *rb_w32_home_dir(void); +rb_pid_t rb_w32_uspawn_process(int mode, const char *prog, char *const *argv, + int in_fd, int out_fd, int err_fd, DWORD flags); + #endif /* RUBY_WIN32_FILE_H */ diff --git a/win32/win32.c b/win32/win32.c index 61b13777bd8589..bf96439c47f375 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -1537,7 +1537,8 @@ rb_w32_uspawn(int mode, const char *cmd, const char *prog) /* License: Artistic or GPL */ static rb_pid_t -w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UINT cp) +w32_spawn_process(int mode, const char *prog, char *const *argv, + int in_fd, int out_fd, int err_fd, DWORD flags, UINT cp) { int c_switch = 0; size_t len; @@ -1548,9 +1549,20 @@ w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UIN int e = 0; rb_pid_t ret = -1; VALUE v = 0; + HANDLE in_handle = NULL, out_handle = NULL, err_handle = NULL; if (check_spawn_mode(mode)) return -1; + if (in_fd >= 0) { + in_handle = (HANDLE)rb_w32_get_osfhandle(in_fd); + } + if (out_fd >= 0) { + out_handle = (HANDLE)rb_w32_get_osfhandle(out_fd); + } + if (err_fd >= 0) { + err_handle = (HANDLE)rb_w32_get_osfhandle(err_fd); + } + if (!prog) prog = argv[0]; if ((shell = w32_getenv("COMSPEC", cp)) && internal_cmd_match(prog, tmpnt = !is_command_com(shell))) { @@ -1598,7 +1610,7 @@ w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags, UIN if (!e) { struct ChildRecord *child = FindFreeChildSlot(); - if (CreateChild(child, wcmd, wprog, NULL, NULL, NULL, flags)) { + if (CreateChild(child, wcmd, wprog, in_handle, out_handle, err_handle, flags)) { ret = child_result(child, mode); } } @@ -1613,21 +1625,21 @@ rb_pid_t rb_w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags) { /* assume ACP */ - return w32_aspawn_flags(mode, prog, argv, flags, filecp()); + return w32_spawn_process(mode, prog, argv, -1, -1, -1, flags, filecp()); } /* License: Ruby's */ rb_pid_t rb_w32_uaspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags) { - return w32_aspawn_flags(mode, prog, argv, flags, CP_UTF8); + return w32_spawn_process(mode, prog, argv, -1, -1, -1, flags, CP_UTF8); } /* License: Ruby's */ rb_pid_t rb_w32_aspawn(int mode, const char *prog, char *const *argv) { - return w32_aspawn_flags(mode, prog, argv, 0, filecp()); + return w32_spawn_process(mode, prog, argv, -1, -1, -1, 0, filecp()); } /* License: Ruby's */ @@ -1637,6 +1649,15 @@ rb_w32_uaspawn(int mode, const char *prog, char *const *argv) return rb_w32_uaspawn_flags(mode, prog, argv, 0); } +/* License: Ruby's */ +rb_pid_t +rb_w32_uspawn_process(int mode, const char *prog, char *const *argv, + int in_fd, int out_fd, int err_fd, DWORD flags) +{ + return w32_spawn_process(mode, prog, argv, in_fd, out_fd, err_fd, + flags, CP_UTF8); +} + /* License: Artistic or GPL */ typedef struct _NtCmdLineElement { struct _NtCmdLineElement *next; diff --git a/yarp/api_pack.c b/yarp/api_pack.c deleted file mode 100644 index 7f0440970e3514..00000000000000 --- a/yarp/api_pack.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "yarp/extension.h" - -static VALUE rb_cYARP; -static VALUE rb_cYARPPack; -static VALUE rb_cYARPPackDirective; -static VALUE rb_cYARPPackFormat; - -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(yp_pack_type type) { - switch (type) { - case YP_PACK_SPACE: - return ID2SYM(rb_intern("SPACE")); - case YP_PACK_COMMENT: - return ID2SYM(rb_intern("COMMENT")); - case YP_PACK_INTEGER: - return ID2SYM(rb_intern("INTEGER")); - case YP_PACK_UTF8: - return ID2SYM(rb_intern("UTF8")); - case YP_PACK_BER: - return ID2SYM(rb_intern("BER")); - case YP_PACK_FLOAT: - return ID2SYM(rb_intern("FLOAT")); - case YP_PACK_STRING_SPACE_PADDED: - return ID2SYM(rb_intern("STRING_SPACE_PADDED")); - case YP_PACK_STRING_NULL_PADDED: - return ID2SYM(rb_intern("STRING_NULL_PADDED")); - case YP_PACK_STRING_NULL_TERMINATED: - return ID2SYM(rb_intern("STRING_NULL_TERMINATED")); - case YP_PACK_STRING_MSB: - return ID2SYM(rb_intern("STRING_MSB")); - case YP_PACK_STRING_LSB: - return ID2SYM(rb_intern("STRING_LSB")); - case YP_PACK_STRING_HEX_HIGH: - return ID2SYM(rb_intern("STRING_HEX_HIGH")); - case YP_PACK_STRING_HEX_LOW: - return ID2SYM(rb_intern("STRING_HEX_LOW")); - case YP_PACK_STRING_UU: - return ID2SYM(rb_intern("STRING_UU")); - case YP_PACK_STRING_MIME: - return ID2SYM(rb_intern("STRING_MIME")); - case YP_PACK_STRING_BASE64: - return ID2SYM(rb_intern("STRING_BASE64")); - case YP_PACK_STRING_FIXED: - return ID2SYM(rb_intern("STRING_FIXED")); - case YP_PACK_STRING_POINTER: - return ID2SYM(rb_intern("STRING_POINTER")); - case YP_PACK_MOVE: - return ID2SYM(rb_intern("MOVE")); - case YP_PACK_BACK: - return ID2SYM(rb_intern("BACK")); - case YP_PACK_NULL: - return ID2SYM(rb_intern("NULL")); - default: - return Qnil; - } -} - -static VALUE -pack_signed_to_symbol(yp_pack_signed signed_type) { - switch (signed_type) { - case YP_PACK_UNSIGNED: - return ID2SYM(rb_intern("UNSIGNED")); - case YP_PACK_SIGNED: - return ID2SYM(rb_intern("SIGNED")); - case YP_PACK_SIGNED_NA: - return ID2SYM(rb_intern("SIGNED_NA")); - default: - return Qnil; - } -} - -static VALUE -pack_endian_to_symbol(yp_pack_endian endian) { - switch (endian) { - case YP_PACK_AGNOSTIC_ENDIAN: - return ID2SYM(rb_intern("AGNOSTIC_ENDIAN")); - case YP_PACK_LITTLE_ENDIAN: - return ID2SYM(rb_intern("LITTLE_ENDIAN")); - case YP_PACK_BIG_ENDIAN: - return ID2SYM(rb_intern("BIG_ENDIAN")); - case YP_PACK_NATIVE_ENDIAN: - return ID2SYM(rb_intern("NATIVE_ENDIAN")); - case YP_PACK_ENDIAN_NA: - return ID2SYM(rb_intern("ENDIAN_NA")); - default: - return Qnil; - } -} - -static VALUE -pack_size_to_symbol(yp_pack_size size) { - switch (size) { - case YP_PACK_SIZE_SHORT: - return ID2SYM(rb_intern("SIZE_SHORT")); - case YP_PACK_SIZE_INT: - return ID2SYM(rb_intern("SIZE_INT")); - case YP_PACK_SIZE_LONG: - return ID2SYM(rb_intern("SIZE_LONG")); - case YP_PACK_SIZE_LONG_LONG: - return ID2SYM(rb_intern("SIZE_LONG_LONG")); - case YP_PACK_SIZE_8: - return ID2SYM(rb_intern("SIZE_8")); - case YP_PACK_SIZE_16: - return ID2SYM(rb_intern("SIZE_16")); - case YP_PACK_SIZE_32: - return ID2SYM(rb_intern("SIZE_32")); - case YP_PACK_SIZE_64: - return ID2SYM(rb_intern("SIZE_64")); - case YP_PACK_SIZE_P: - return ID2SYM(rb_intern("SIZE_P")); - case YP_PACK_SIZE_NA: - return ID2SYM(rb_intern("SIZE_NA")); - default: - return Qnil; - } -} - -static VALUE -pack_length_type_to_symbol(yp_pack_length_type length_type) { - switch (length_type) { - case YP_PACK_LENGTH_FIXED: - return ID2SYM(rb_intern("LENGTH_FIXED")); - case YP_PACK_LENGTH_MAX: - return ID2SYM(rb_intern("LENGTH_MAX")); - case YP_PACK_LENGTH_RELATIVE: - return ID2SYM(rb_intern("LENGTH_RELATIVE")); - case YP_PACK_LENGTH_NA: - return ID2SYM(rb_intern("LENGTH_NA")); - default: - return Qnil; - } -} - -static VALUE -pack_encoding_to_ruby(yp_pack_encoding encoding) { - int index; - switch (encoding) { - case YP_PACK_ENCODING_ASCII_8BIT: - index = rb_ascii8bit_encindex(); - break; - case YP_PACK_ENCODING_US_ASCII: - index = rb_usascii_encindex(); - break; - case YP_PACK_ENCODING_UTF_8: - index = rb_utf8_encindex(); - break; - default: - return Qnil; - } - return rb_enc_from_encoding(rb_enc_from_index(index)); -} - -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"); - } - - yp_pack_variant variant; - if (variant_symbol == pack_symbol) { - variant = YP_PACK_VARIANT_PACK; - } else if (variant_symbol == unpack_symbol) { - variant = YP_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); - yp_pack_encoding encoding = YP_PACK_ENCODING_START; - - VALUE directives_array = rb_ary_new(); - - while (format < format_end) { - yp_pack_type type; - yp_pack_signed signed_type; - yp_pack_endian endian; - yp_pack_size size; - yp_pack_length_type length_type; - uint64_t length; - - const char *directive_start = format; - - yp_pack_result parse_result = yp_pack_parse(variant, &format, format_end, &type, &signed_type, &endian, - &size, &length_type, &length, &encoding); - - const char *directive_end = format; - - switch (parse_result) { - case YP_PACK_OK: - break; - case YP_PACK_ERROR_UNSUPPORTED_DIRECTIVE: - rb_raise(rb_eArgError, "unsupported directive"); - case YP_PACK_ERROR_UNKNOWN_DIRECTIVE: - rb_raise(rb_eArgError, "unsupported directive"); - case YP_PACK_ERROR_LENGTH_TOO_BIG: - rb_raise(rb_eRangeError, "pack length too big"); - case YP_PACK_ERROR_BANG_NOT_ALLOWED: - rb_raise(rb_eRangeError, "bang not allowed"); - case YP_PACK_ERROR_DOUBLE_ENDIAN: - rb_raise(rb_eRangeError, "double endian"); - default: - rb_bug("parse result"); - } - - if (type == YP_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_cYARPPackDirective)); - } - - 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_cYARPPackFormat); -} - -void -Init_yarp_pack(void) { - rb_cYARP = rb_define_module("YARP"); - rb_cYARPPack = rb_define_module_under(rb_cYARP, "Pack"); - rb_cYARPPackDirective = rb_define_class_under(rb_cYARPPack, "Directive", rb_cObject); - rb_cYARPPackFormat = rb_define_class_under(rb_cYARPPack, "Format", rb_cObject); - rb_define_singleton_method(rb_cYARPPack, "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/yarp/defines.h b/yarp/defines.h deleted file mode 100644 index 24d33b5e091d84..00000000000000 --- a/yarp/defines.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef YARP_DEFINES_H -#define YARP_DEFINES_H - -// This file should be included first by any *.h or *.c in YARP - -#include -#include -#include -#include -#include -#include - -// YP_EXPORTED_FUNCTION -#ifndef YP_EXPORTED_FUNCTION -# ifdef YP_EXPORT_SYMBOLS -# ifdef _WIN32 -# define YP_EXPORTED_FUNCTION __declspec(dllexport) extern -# else -# define YP_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern -# endif -# else -# define YP_EXPORTED_FUNCTION -# endif -#endif - -// YP_ATTRIBUTE_UNUSED -#if defined(__GNUC__) -# define YP_ATTRIBUTE_UNUSED __attribute__((unused)) -#else -# define YP_ATTRIBUTE_UNUSED -#endif - -// inline -#if defined(_MSC_VER) && !defined(inline) -# define inline __inline -#endif - -// Windows versions before 2015 use _snprintf -#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900) -# define snprintf _snprintf -#endif - -int yp_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length); - -#endif diff --git a/yarp/diagnostic.c b/yarp/diagnostic.c deleted file mode 100644 index e92a1ee49109fd..00000000000000 --- a/yarp/diagnostic.c +++ /dev/null @@ -1,277 +0,0 @@ -#include "yarp/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" - - 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 (YP_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 YP_ERR_ARGUMENT_NO_FORWARDING_* for an example. -*/ - -static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = { - [YP_ERR_ALIAS_ARGUMENT] = "Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", - [YP_ERR_AMPAMPEQ_MULTI_ASSIGN] = "Unexpected `&&=` in a multiple assignment", - [YP_ERR_ARGUMENT_AFTER_BLOCK] = "Unexpected argument after a block argument", - [YP_ERR_ARGUMENT_BARE_HASH] = "Unexpected bare hash argument", - [YP_ERR_ARGUMENT_BLOCK_MULTI] = "Multiple block arguments; only one block is allowed", - [YP_ERR_ARGUMENT_FORMAL_CLASS] = "Invalid formal argument; formal argument cannot be a class variable", - [YP_ERR_ARGUMENT_FORMAL_CONSTANT] = "Invalid formal argument; formal argument cannot be a constant", - [YP_ERR_ARGUMENT_FORMAL_GLOBAL] = "Invalid formal argument; formal argument cannot be a global variable", - [YP_ERR_ARGUMENT_FORMAL_IVAR] = "Invalid formal argument; formal argument cannot be an instance variable", - [YP_ERR_ARGUMENT_NO_FORWARDING_AMP] = "Unexpected `&` when the parent method is not forwarding", - [YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "Unexpected `...` when the parent method is not forwarding", - [YP_ERR_ARGUMENT_NO_FORWARDING_STAR] = "Unexpected `*` when the parent method is not forwarding", - [YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = "Unexpected `*` splat argument after a `**` keyword splat argument", - [YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = "Unexpected `*` splat argument after a `*` splat argument", - [YP_ERR_ARGUMENT_TERM_PAREN] = "Expected a `)` to close the arguments", - [YP_ERR_ARRAY_ELEMENT] = "Expected an element for the array", - [YP_ERR_ARRAY_EXPRESSION] = "Expected an expression for the array element", - [YP_ERR_ARRAY_EXPRESSION_AFTER_STAR] = "Expected an expression after `*` in the array", - [YP_ERR_ARRAY_SEPARATOR] = "Expected a `,` separator for the array elements", - [YP_ERR_ARRAY_TERM] = "Expected a `]` to close the array", - [YP_ERR_BEGIN_LONELY_ELSE] = "Unexpected `else` in `begin` block; a `rescue` clause must precede `else`", - [YP_ERR_BEGIN_TERM] = "Expected an `end` to close the `begin` statement", - [YP_ERR_BEGIN_UPCASE_BRACE] = "Expected a `{` after `BEGIN`", - [YP_ERR_BEGIN_UPCASE_TERM] = "Expected a `}` to close the `BEGIN` statement", - [YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE] = "Expected a local variable name in the block parameters", - [YP_ERR_BLOCK_PARAM_PIPE_TERM] = "Expected the block parameters to end with `|`", - [YP_ERR_BLOCK_TERM_BRACE] = "Expected a block beginning with `{` to end with `}`", - [YP_ERR_BLOCK_TERM_END] = "Expected a block beginning with `do` to end with `end`", - [YP_ERR_CANNOT_PARSE_EXPRESSION] = "Cannot parse the expression", - [YP_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part", - [YP_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`", - [YP_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`", - [YP_ERR_CASE_LONELY_ELSE] = "Unexpected `else` in `case` statement; a `when` clause must precede `else`", - [YP_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement", - [YP_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body", - [YP_ERR_CLASS_NAME] = "Expected a constant name after `class`", - [YP_ERR_CLASS_SUPERCLASS] = "Expected a superclass after `<`", - [YP_ERR_CLASS_TERM] = "Expected an `end` to close the `class` statement", - [YP_ERR_CONDITIONAL_ELSIF_PREDICATE] = "Expected a predicate expression for the `elsif` statement", - [YP_ERR_CONDITIONAL_IF_PREDICATE] = "Expected a predicate expression for the `if` statement", - [YP_ERR_CONDITIONAL_TERM] = "Expected an `end` to close the conditional clause", - [YP_ERR_CONDITIONAL_TERM_ELSE] = "Expected an `end` to close the `else` clause", - [YP_ERR_CONDITIONAL_UNLESS_PREDICATE] = "Expected a predicate expression for the `unless` statement", - [YP_ERR_CONDITIONAL_UNTIL_PREDICATE] = "Expected a predicate expression for the `until` statement", - [YP_ERR_CONDITIONAL_WHILE_PREDICATE] = "Expected a predicate expression for the `while` statement", - [YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = "Expected a constant after the `::` operator", - [YP_ERR_DEF_ENDLESS] = "Could not parse the endless method body", - [YP_ERR_DEF_ENDLESS_SETTER] = "Invalid method name; a setter method cannot be defined in an endless method definition", - [YP_ERR_DEF_NAME] = "Expected a method name", - [YP_ERR_DEF_NAME_AFTER_RECEIVER] = "Expected a method name after the receiver", - [YP_ERR_DEF_PARAMS_TERM] = "Expected a delimiter to close the parameters", - [YP_ERR_DEF_PARAMS_TERM_PAREN] = "Expected a `)` to close the parameters", - [YP_ERR_DEF_RECEIVER] = "Expected a receiver for the method definition", - [YP_ERR_DEF_RECEIVER_TERM] = "Expected a `.` or `::` after the receiver in a method definition", - [YP_ERR_DEF_TERM] = "Expected an `end` to close the `def` statement", - [YP_ERR_DEFINED_EXPRESSION] = "Expected an expression after `defined?`", - [YP_ERR_EMBDOC_TERM] = "Could not find a terminator for the embedded document", - [YP_ERR_EMBEXPR_END] = "Expected a `}` to close the embedded expression", - [YP_ERR_EMBVAR_INVALID] = "Invalid embedded variable", - [YP_ERR_END_UPCASE_BRACE] = "Expected a `{` after `END`", - [YP_ERR_END_UPCASE_TERM] = "Expected a `}` to close the `END` statement", - [YP_ERR_ESCAPE_INVALID_CONTROL] = "Invalid control escape sequence", - [YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = "Invalid control escape sequence; control cannot be repeated", - [YP_ERR_ESCAPE_INVALID_HEXADECIMAL] = "Invalid hexadecimal escape sequence", - [YP_ERR_ESCAPE_INVALID_META] = "Invalid meta escape sequence", - [YP_ERR_ESCAPE_INVALID_META_REPEAT] = "Invalid meta escape sequence; meta cannot be repeated", - [YP_ERR_ESCAPE_INVALID_UNICODE] = "Invalid Unicode escape sequence", - [YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = "Invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags", - [YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = "Invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", - [YP_ERR_ESCAPE_INVALID_UNICODE_LONG] = "Invalid Unicode escape sequence; maximum length is 6 digits", - [YP_ERR_ESCAPE_INVALID_UNICODE_TERM] = "Invalid Unicode escape sequence; needs closing `}`", - [YP_ERR_EXPECT_ARGUMENT] = "Expected an argument", - [YP_ERR_EXPECT_EOL_AFTER_STATEMENT] = "Expected a newline or semicolon after the statement", - [YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = "Expected an expression after `&&=`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = "Expected an expression after `||=`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA] = "Expected an expression after `,`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL] = "Expected an expression after `=`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS] = "Expected an expression after `<<`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN] = "Expected an expression after `(`", - [YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR] = "Expected an expression after the operator", - [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = "Expected an expression after `*` splat in an argument", - [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = "Expected an expression after `**` in a hash", - [YP_ERR_EXPECT_EXPRESSION_AFTER_STAR] = "Expected an expression after `*`", - [YP_ERR_EXPECT_IDENT_REQ_PARAMETER] = "Expected an identifier for the required parameter", - [YP_ERR_EXPECT_LPAREN_REQ_PARAMETER] = "Expected a `(` to start a required parameter", - [YP_ERR_EXPECT_RBRACKET] = "Expected a matching `]`", - [YP_ERR_EXPECT_RPAREN] = "Expected a matching `)`", - [YP_ERR_EXPECT_RPAREN_AFTER_MULTI] = "Expected a `)` after multiple assignment", - [YP_ERR_EXPECT_RPAREN_REQ_PARAMETER] = "Expected a `)` to end a required parameter", - [YP_ERR_EXPECT_STRING_CONTENT] = "Expected string content after opening string delimiter", - [YP_ERR_EXPECT_WHEN_DELIMITER] = "Expected a delimiter after the predicates of a `when` clause", - [YP_ERR_EXPRESSION_BARE_HASH] = "Unexpected bare hash in expression", - [YP_ERR_FOR_COLLECTION] = "Expected a collection after the `in` in a `for` statement", - [YP_ERR_FOR_INDEX] = "Expected an index after `for`", - [YP_ERR_FOR_IN] = "Expected an `in` after the index in a `for` statement", - [YP_ERR_FOR_TERM] = "Expected an `end` to close the `for` loop", - [YP_ERR_HASH_EXPRESSION_AFTER_LABEL] = "Expected an expression after the label in a hash", - [YP_ERR_HASH_KEY] = "Expected a key in the hash literal", - [YP_ERR_HASH_ROCKET] = "Expected a `=>` between the hash key and value", - [YP_ERR_HASH_TERM] = "Expected a `}` to close the hash literal", - [YP_ERR_HASH_VALUE] = "Expected a value in the hash literal", - [YP_ERR_HEREDOC_TERM] = "Could not find a terminator for the heredoc", - [YP_ERR_INCOMPLETE_QUESTION_MARK] = "Incomplete expression at `?`", - [YP_ERR_INCOMPLETE_VARIABLE_CLASS] = "Incomplete class variable", - [YP_ERR_INCOMPLETE_VARIABLE_INSTANCE] = "Incomplete instance variable", - [YP_ERR_INVALID_ENCODING_MAGIC_COMMENT] = "Unknown or invalid encoding in the magic comment", - [YP_ERR_INVALID_FLOAT_EXPONENT] = "Invalid exponent", - [YP_ERR_INVALID_NUMBER_BINARY] = "Invalid binary number", - [YP_ERR_INVALID_NUMBER_DECIMAL] = "Invalid decimal number", - [YP_ERR_INVALID_NUMBER_HEXADECIMAL] = "Invalid hexadecimal number", - [YP_ERR_INVALID_NUMBER_OCTAL] = "Invalid octal number", - [YP_ERR_INVALID_PERCENT] = "Invalid `%` token", // TODO WHAT? - [YP_ERR_INVALID_TOKEN] = "Invalid token", // TODO WHAT? - [YP_ERR_INVALID_VARIABLE_GLOBAL] = "Invalid global variable", - [YP_ERR_LAMBDA_OPEN] = "Expected a `do` keyword or a `{` to open the lambda block", - [YP_ERR_LAMBDA_TERM_BRACE] = "Expected a lambda block beginning with `{` to end with `}`", - [YP_ERR_LAMBDA_TERM_END] = "Expected a lambda block beginning with `do` to end with `end`", - [YP_ERR_LIST_I_LOWER_ELEMENT] = "Expected a symbol in a `%i` list", - [YP_ERR_LIST_I_LOWER_TERM] = "Expected a closing delimiter for the `%i` list", - [YP_ERR_LIST_I_UPPER_ELEMENT] = "Expected a symbol in a `%I` list", - [YP_ERR_LIST_I_UPPER_TERM] = "Expected a closing delimiter for the `%I` list", - [YP_ERR_LIST_W_LOWER_ELEMENT] = "Expected a string in a `%w` list", - [YP_ERR_LIST_W_LOWER_TERM] = "Expected a closing delimiter for the `%w` list", - [YP_ERR_LIST_W_UPPER_ELEMENT] = "Expected a string in a `%W` list", - [YP_ERR_LIST_W_UPPER_TERM] = "Expected a closing delimiter for the `%W` list", - [YP_ERR_MALLOC_FAILED] = "Failed to allocate memory", - [YP_ERR_MODULE_IN_METHOD] = "Unexpected module definition in a method body", - [YP_ERR_MODULE_NAME] = "Expected a constant name after `module`", - [YP_ERR_MODULE_TERM] = "Expected an `end` to close the `module` statement", - [YP_ERR_MULTI_ASSIGN_MULTI_SPLATS] = "Multiple splats in multiple assignment", - [YP_ERR_NOT_EXPRESSION] = "Expected an expression after `not`", - [YP_ERR_NUMBER_LITERAL_UNDERSCORE] = "Number literal ending with a `_`", - [YP_ERR_OPERATOR_MULTI_ASSIGN] = "Unexpected operator for a multiple assignment", - [YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters", - [YP_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed", - [YP_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name", - [YP_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter", - [YP_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter", - [YP_ERR_PARAMETER_NUMBERED_RESERVED] = "Token reserved for a numbered parameter", - [YP_ERR_PARAMETER_ORDER] = "Unexpected parameter order", - [YP_ERR_PARAMETER_SPLAT_MULTI] = "Unexpected multiple `*` splat parameters", - [YP_ERR_PARAMETER_STAR] = "Unexpected parameter `*`", - [YP_ERR_PARAMETER_WILD_LOOSE_COMMA] = "Unexpected `,` in parameters", - [YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = "Expected a pattern expression after the `[` operator", - [YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = "Expected a pattern expression after `,`", - [YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = "Expected a pattern expression after `=>`", - [YP_ERR_PATTERN_EXPRESSION_AFTER_IN] = "Expected a pattern expression after the `in` keyword", - [YP_ERR_PATTERN_EXPRESSION_AFTER_KEY] = "Expected a pattern expression after the key", - [YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN] = "Expected a pattern expression after the `(` operator", - [YP_ERR_PATTERN_EXPRESSION_AFTER_PIN] = "Expected a pattern expression after the `^` pin operator", - [YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = "Expected a pattern expression after the `|` operator", - [YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = "Expected a pattern expression after the range operator", - [YP_ERR_PATTERN_HASH_KEY] = "Expected a key in the hash pattern", - [YP_ERR_PATTERN_HASH_KEY_LABEL] = "Expected a label as the key in the hash pattern", // TODO // THIS // AND // ABOVE // IS WEIRD - [YP_ERR_PATTERN_IDENT_AFTER_HROCKET] = "Expected an identifier after the `=>` operator", - [YP_ERR_PATTERN_LABEL_AFTER_COMMA] = "Expected a label after the `,` in the hash pattern", - [YP_ERR_PATTERN_REST] = "Unexpected rest pattern", - [YP_ERR_PATTERN_TERM_BRACE] = "Expected a `}` to close the pattern expression", - [YP_ERR_PATTERN_TERM_BRACKET] = "Expected a `]` to close the pattern expression", - [YP_ERR_PATTERN_TERM_PAREN] = "Expected a `)` to close the pattern expression", - [YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN] = "Unexpected `||=` in a multiple assignment", - [YP_ERR_REGEXP_TERM] = "Expected a closing delimiter for the regular expression", - [YP_ERR_RESCUE_EXPRESSION] = "Expected a rescued expression", - [YP_ERR_RESCUE_MODIFIER_VALUE] = "Expected a value after the `rescue` modifier", - [YP_ERR_RESCUE_TERM] = "Expected a closing delimiter for the `rescue` clause", - [YP_ERR_RESCUE_VARIABLE] = "Expected an exception variable after `=>` in a rescue statement", - [YP_ERR_RETURN_INVALID] = "Invalid `return` in a class or module body", - [YP_ERR_STRING_CONCATENATION] = "Expected a string for concatenation", - [YP_ERR_STRING_INTERPOLATED_TERM] = "Expected a closing delimiter for the interpolated string", - [YP_ERR_STRING_LITERAL_TERM] = "Expected a closing delimiter for the string literal", - [YP_ERR_SYMBOL_INVALID] = "Invalid symbol", // TODO expected symbol? yarp.c ~9719 - [YP_ERR_SYMBOL_TERM_DYNAMIC] = "Expected a closing delimiter for the dynamic symbol", - [YP_ERR_SYMBOL_TERM_INTERPOLATED] = "Expected a closing delimiter for the interpolated symbol", - [YP_ERR_TERNARY_COLON] = "Expected a `:` after the true expression of a ternary operator", - [YP_ERR_TERNARY_EXPRESSION_FALSE] = "Expected an expression after `:` in the ternary operator", - [YP_ERR_TERNARY_EXPRESSION_TRUE] = "Expected an expression after `?` in the ternary operator", - [YP_ERR_UNDEF_ARGUMENT] = "Invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", - [YP_ERR_UNARY_RECEIVER_BANG] = "Expected a receiver for unary `!`", - [YP_ERR_UNARY_RECEIVER_MINUS] = "Expected a receiver for unary `-`", - [YP_ERR_UNARY_RECEIVER_PLUS] = "Expected a receiver for unary `+`", - [YP_ERR_UNARY_RECEIVER_TILDE] = "Expected a receiver for unary `~`", - [YP_ERR_UNTIL_TERM] = "Expected an `end` to close the `until` statement", - [YP_ERR_WHILE_TERM] = "Expected an `end` to close the `while` statement", - [YP_ERR_WRITE_TARGET_READONLY] = "Immutable variable as a write target", - [YP_ERR_WRITE_TARGET_UNEXPECTED] = "Unexpected write target", - [YP_ERR_XSTRING_TERM] = "Expected a closing delimiter for the `%x` or backtick string", - [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = "Ambiguous first argument; put parentheses or a space even after `-` operator", - [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = "Ambiguous first argument; put parentheses or a space even after `+` operator", - [YP_WARN_AMBIGUOUS_PREFIX_STAR] = "Ambiguous `*` has been interpreted as an argument prefix", - [YP_WARN_AMBIGUOUS_SLASH] = "Ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator", -}; - -static const char* -yp_diagnostic_message(yp_diagnostic_id_t diag_id) { - assert(diag_id < YP_DIAGNOSTIC_ID_LEN); - const char *message = diagnostic_messages[diag_id]; - assert(message); - return message; -} - -// Append an error to the given list of diagnostic. -bool -yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id) { - yp_diagnostic_t *diagnostic = (yp_diagnostic_t *) malloc(sizeof(yp_diagnostic_t)); - if (diagnostic == NULL) return false; - - *diagnostic = (yp_diagnostic_t) { .start = start, .end = end, .message = yp_diagnostic_message(diag_id) }; - yp_list_append(list, (yp_list_node_t *) diagnostic); - return true; -} - -// Deallocate the internal state of the given diagnostic list. -void -yp_diagnostic_list_free(yp_list_t *list) { - yp_list_node_t *node, *next; - - for (node = list->head; node != NULL; node = next) { - next = node->next; - - yp_diagnostic_t *diagnostic = (yp_diagnostic_t *) node; - free(diagnostic); - } -} diff --git a/yarp/diagnostic.h b/yarp/diagnostic.h deleted file mode 100644 index fd17945e0d9e24..00000000000000 --- a/yarp/diagnostic.h +++ /dev/null @@ -1,221 +0,0 @@ -#ifndef YARP_DIAGNOSTIC_H -#define YARP_DIAGNOSTIC_H - -#include "yarp/defines.h" -#include "yarp/util/yp_list.h" - -#include -#include -#include - -// This struct represents a diagnostic found during parsing. -typedef struct { - yp_list_node_t node; - const uint8_t *start; - const uint8_t *end; - const char *message; -} yp_diagnostic_t; - -typedef enum { - YP_ERR_ALIAS_ARGUMENT, - YP_ERR_AMPAMPEQ_MULTI_ASSIGN, - YP_ERR_ARGUMENT_AFTER_BLOCK, - YP_ERR_ARGUMENT_BARE_HASH, - YP_ERR_ARGUMENT_BLOCK_MULTI, - YP_ERR_ARGUMENT_FORMAL_CLASS, - YP_ERR_ARGUMENT_FORMAL_CONSTANT, - YP_ERR_ARGUMENT_FORMAL_GLOBAL, - YP_ERR_ARGUMENT_FORMAL_IVAR, - YP_ERR_ARGUMENT_NO_FORWARDING_AMP, - YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES, - YP_ERR_ARGUMENT_NO_FORWARDING_STAR, - YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT, - YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT, - YP_ERR_ARGUMENT_TERM_PAREN, - YP_ERR_ARRAY_ELEMENT, - YP_ERR_ARRAY_EXPRESSION, - YP_ERR_ARRAY_EXPRESSION_AFTER_STAR, - YP_ERR_ARRAY_SEPARATOR, - YP_ERR_ARRAY_TERM, - YP_ERR_BEGIN_LONELY_ELSE, - YP_ERR_BEGIN_TERM, - YP_ERR_BEGIN_UPCASE_BRACE, - YP_ERR_BEGIN_UPCASE_TERM, - YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE, - YP_ERR_BLOCK_PARAM_PIPE_TERM, - YP_ERR_BLOCK_TERM_BRACE, - YP_ERR_BLOCK_TERM_END, - YP_ERR_CANNOT_PARSE_EXPRESSION, - YP_ERR_CANNOT_PARSE_STRING_PART, - YP_ERR_CASE_EXPRESSION_AFTER_CASE, - YP_ERR_CASE_EXPRESSION_AFTER_WHEN, - YP_ERR_CASE_LONELY_ELSE, - YP_ERR_CASE_TERM, - YP_ERR_CLASS_IN_METHOD, - YP_ERR_CLASS_NAME, - YP_ERR_CLASS_SUPERCLASS, - YP_ERR_CLASS_TERM, - YP_ERR_CONDITIONAL_ELSIF_PREDICATE, - YP_ERR_CONDITIONAL_IF_PREDICATE, - YP_ERR_CONDITIONAL_TERM, - YP_ERR_CONDITIONAL_TERM_ELSE, - YP_ERR_CONDITIONAL_UNLESS_PREDICATE, - YP_ERR_CONDITIONAL_UNTIL_PREDICATE, - YP_ERR_CONDITIONAL_WHILE_PREDICATE, - YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT, - YP_ERR_DEF_ENDLESS, - YP_ERR_DEF_ENDLESS_SETTER, - YP_ERR_DEF_NAME, - YP_ERR_DEF_NAME_AFTER_RECEIVER, - YP_ERR_DEF_PARAMS_TERM, - YP_ERR_DEF_PARAMS_TERM_PAREN, - YP_ERR_DEF_RECEIVER, - YP_ERR_DEF_RECEIVER_TERM, - YP_ERR_DEF_TERM, - YP_ERR_DEFINED_EXPRESSION, - YP_ERR_EMBDOC_TERM, - YP_ERR_EMBEXPR_END, - YP_ERR_EMBVAR_INVALID, - YP_ERR_END_UPCASE_BRACE, - YP_ERR_END_UPCASE_TERM, - YP_ERR_ESCAPE_INVALID_CONTROL, - YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT, - YP_ERR_ESCAPE_INVALID_HEXADECIMAL, - YP_ERR_ESCAPE_INVALID_META, - YP_ERR_ESCAPE_INVALID_META_REPEAT, - YP_ERR_ESCAPE_INVALID_UNICODE, - YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS, - YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL, - YP_ERR_ESCAPE_INVALID_UNICODE_LONG, - YP_ERR_ESCAPE_INVALID_UNICODE_TERM, - YP_ERR_EXPECT_ARGUMENT, - YP_ERR_EXPECT_EOL_AFTER_STATEMENT, - YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, - YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, - YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA, - YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, - YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS, - YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN, - YP_ERR_EXPECT_EXPRESSION_AFTER_QUESTION, - YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, - YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT, - YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, - YP_ERR_EXPECT_EXPRESSION_AFTER_STAR, - YP_ERR_EXPECT_IDENT_REQ_PARAMETER, - YP_ERR_EXPECT_LPAREN_REQ_PARAMETER, - YP_ERR_EXPECT_RBRACKET, - YP_ERR_EXPECT_RPAREN, - YP_ERR_EXPECT_RPAREN_AFTER_MULTI, - YP_ERR_EXPECT_RPAREN_REQ_PARAMETER, - YP_ERR_EXPECT_STRING_CONTENT, - YP_ERR_EXPECT_WHEN_DELIMITER, - YP_ERR_EXPRESSION_BARE_HASH, - YP_ERR_FOR_COLLECTION, - YP_ERR_FOR_IN, - YP_ERR_FOR_INDEX, - YP_ERR_FOR_TERM, - YP_ERR_HASH_EXPRESSION_AFTER_LABEL, - YP_ERR_HASH_KEY, - YP_ERR_HASH_ROCKET, - YP_ERR_HASH_TERM, - YP_ERR_HASH_VALUE, - YP_ERR_HEREDOC_TERM, - YP_ERR_INCOMPLETE_QUESTION_MARK, - YP_ERR_INCOMPLETE_VARIABLE_CLASS, - YP_ERR_INCOMPLETE_VARIABLE_INSTANCE, - YP_ERR_INVALID_ENCODING_MAGIC_COMMENT, - YP_ERR_INVALID_FLOAT_EXPONENT, - YP_ERR_INVALID_NUMBER_BINARY, - YP_ERR_INVALID_NUMBER_DECIMAL, - YP_ERR_INVALID_NUMBER_HEXADECIMAL, - YP_ERR_INVALID_NUMBER_OCTAL, - YP_ERR_INVALID_PERCENT, - YP_ERR_INVALID_TOKEN, - YP_ERR_INVALID_VARIABLE_GLOBAL, - YP_ERR_LAMBDA_OPEN, - YP_ERR_LAMBDA_TERM_BRACE, - YP_ERR_LAMBDA_TERM_END, - YP_ERR_LIST_I_LOWER_ELEMENT, - YP_ERR_LIST_I_LOWER_TERM, - YP_ERR_LIST_I_UPPER_ELEMENT, - YP_ERR_LIST_I_UPPER_TERM, - YP_ERR_LIST_W_LOWER_ELEMENT, - YP_ERR_LIST_W_LOWER_TERM, - YP_ERR_LIST_W_UPPER_ELEMENT, - YP_ERR_LIST_W_UPPER_TERM, - YP_ERR_MALLOC_FAILED, - YP_ERR_MODULE_IN_METHOD, - YP_ERR_MODULE_NAME, - YP_ERR_MODULE_TERM, - YP_ERR_MULTI_ASSIGN_MULTI_SPLATS, - YP_ERR_NOT_EXPRESSION, - YP_ERR_NUMBER_LITERAL_UNDERSCORE, - YP_ERR_OPERATOR_MULTI_ASSIGN, - YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI, - YP_ERR_PARAMETER_BLOCK_MULTI, - YP_ERR_PARAMETER_NAME_REPEAT, - YP_ERR_PARAMETER_NO_DEFAULT, - YP_ERR_PARAMETER_NO_DEFAULT_KW, - YP_ERR_PARAMETER_NUMBERED_RESERVED, - YP_ERR_PARAMETER_ORDER, - YP_ERR_PARAMETER_SPLAT_MULTI, - YP_ERR_PARAMETER_STAR, - YP_ERR_PARAMETER_WILD_LOOSE_COMMA, - YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, - YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, - YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA, - YP_ERR_PATTERN_EXPRESSION_AFTER_IN, - YP_ERR_PATTERN_EXPRESSION_AFTER_KEY, - YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN, - YP_ERR_PATTERN_EXPRESSION_AFTER_PIN, - YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE, - YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE, - YP_ERR_PATTERN_HASH_KEY, - YP_ERR_PATTERN_HASH_KEY_LABEL, - YP_ERR_PATTERN_IDENT_AFTER_HROCKET, - YP_ERR_PATTERN_LABEL_AFTER_COMMA, - YP_ERR_PATTERN_REST, - YP_ERR_PATTERN_TERM_BRACE, - YP_ERR_PATTERN_TERM_BRACKET, - YP_ERR_PATTERN_TERM_PAREN, - YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN, - YP_ERR_REGEXP_TERM, - YP_ERR_RESCUE_EXPRESSION, - YP_ERR_RESCUE_MODIFIER_VALUE, - YP_ERR_RESCUE_TERM, - YP_ERR_RESCUE_VARIABLE, - YP_ERR_RETURN_INVALID, - YP_ERR_STRING_CONCATENATION, - YP_ERR_STRING_INTERPOLATED_TERM, - YP_ERR_STRING_LITERAL_TERM, - YP_ERR_SYMBOL_INVALID, - YP_ERR_SYMBOL_TERM_DYNAMIC, - YP_ERR_SYMBOL_TERM_INTERPOLATED, - YP_ERR_TERNARY_COLON, - YP_ERR_TERNARY_EXPRESSION_FALSE, - YP_ERR_TERNARY_EXPRESSION_TRUE, - YP_ERR_UNDEF_ARGUMENT, - YP_ERR_UNARY_RECEIVER_BANG, - YP_ERR_UNARY_RECEIVER_MINUS, - YP_ERR_UNARY_RECEIVER_PLUS, - YP_ERR_UNARY_RECEIVER_TILDE, - YP_ERR_UNTIL_TERM, - YP_ERR_WHILE_TERM, - YP_ERR_WRITE_TARGET_READONLY, - YP_ERR_WRITE_TARGET_UNEXPECTED, - YP_ERR_XSTRING_TERM, - YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS, - YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS, - YP_WARN_AMBIGUOUS_PREFIX_STAR, - YP_WARN_AMBIGUOUS_SLASH, - /* This must be the last member. */ - YP_DIAGNOSTIC_ID_LEN, -} yp_diagnostic_id_t; - -// Append a diagnostic to the given list of diagnostics. -bool yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id); - -// Deallocate the internal state of the given diagnostic list. -void yp_diagnostic_list_free(yp_list_t *list); - -#endif diff --git a/yarp/enc/yp_big5.c b/yarp/enc/yp_big5.c deleted file mode 100644 index a7c879cd0abb16..00000000000000 --- a/yarp/enc/yp_big5.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -static size_t -yp_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] <= 0xFE)) { - return 2; - } - - return 0; -} - -static size_t -yp_encoding_big5_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_big5_char_width(b, n) == 1) { - return yp_encoding_ascii_alpha_char(b, n); - } else { - return 0; - } -} - -static size_t -yp_encoding_big5_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_big5_char_width(b, n) == 1) { - return yp_encoding_ascii_alnum_char(b, n); - } else { - return 0; - } -} - -static bool -yp_encoding_big5_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_big5_char_width(b, n) == 1) { - return yp_encoding_ascii_isupper_char(b, n); - } else { - return false; - } -} - -yp_encoding_t yp_encoding_big5 = { - .name = "big5", - .char_width = yp_encoding_big5_char_width, - .alnum_char = yp_encoding_big5_alnum_char, - .alpha_char = yp_encoding_big5_alpha_char, - .isupper_char = yp_encoding_big5_isupper_char, - .multibyte = true -}; diff --git a/yarp/enc/yp_encoding.h b/yarp/enc/yp_encoding.h deleted file mode 100644 index 9e8e7e01f60dba..00000000000000 --- a/yarp/enc/yp_encoding.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef YARP_ENCODING_H -#define YARP_ENCODING_H - -#include "yarp/defines.h" - -#include -#include -#include -#include - -// 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; -} yp_encoding_t; - -// These bits define the location of each bit of metadata within the various -// lookup tables that are used to determine the properties of a character. -#define YP_ENCODING_ALPHABETIC_BIT 1 << 0 -#define YP_ENCODING_ALPHANUMERIC_BIT 1 << 1 -#define YP_ENCODING_UPPERCASE_BIT 1 << 2 - -// These functions are reused by some other encodings, so they are defined here -// so they can be shared. -size_t yp_encoding_ascii_alpha_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n); -size_t yp_encoding_ascii_alnum_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n); -bool yp_encoding_ascii_isupper_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n); - -// These functions are shared between the actual encoding and the fast path in -// the parser so they need to be internally visible. -size_t yp_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n); -size_t yp_encoding_utf_8_alnum_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. -extern uint8_t yp_encoding_unicode_table[256]; - -// These are the encodings that are supported by the parser. They are defined in -// their own files in the src/enc directory. -extern yp_encoding_t yp_encoding_ascii; -extern yp_encoding_t yp_encoding_ascii_8bit; -extern yp_encoding_t yp_encoding_big5; -extern yp_encoding_t yp_encoding_euc_jp; -extern yp_encoding_t yp_encoding_gbk; -extern yp_encoding_t yp_encoding_iso_8859_1; -extern yp_encoding_t yp_encoding_iso_8859_2; -extern yp_encoding_t yp_encoding_iso_8859_3; -extern yp_encoding_t yp_encoding_iso_8859_4; -extern yp_encoding_t yp_encoding_iso_8859_5; -extern yp_encoding_t yp_encoding_iso_8859_6; -extern yp_encoding_t yp_encoding_iso_8859_7; -extern yp_encoding_t yp_encoding_iso_8859_8; -extern yp_encoding_t yp_encoding_iso_8859_9; -extern yp_encoding_t yp_encoding_iso_8859_10; -extern yp_encoding_t yp_encoding_iso_8859_11; -extern yp_encoding_t yp_encoding_iso_8859_13; -extern yp_encoding_t yp_encoding_iso_8859_14; -extern yp_encoding_t yp_encoding_iso_8859_15; -extern yp_encoding_t yp_encoding_iso_8859_16; -extern yp_encoding_t yp_encoding_koi8_r; -extern yp_encoding_t yp_encoding_shift_jis; -extern yp_encoding_t yp_encoding_utf_8; -extern yp_encoding_t yp_encoding_utf8_mac; -extern yp_encoding_t yp_encoding_windows_31j; -extern yp_encoding_t yp_encoding_windows_1251; -extern yp_encoding_t yp_encoding_windows_1252; - -#endif diff --git a/yarp/enc/yp_euc_jp.c b/yarp/enc/yp_euc_jp.c deleted file mode 100644 index f6f80d528bcde0..00000000000000 --- a/yarp/enc/yp_euc_jp.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -static size_t -yp_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[1] >= 0xA1 && b[1] <= 0xFE)) || - ((b[0] >= 0xA1 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) - ) - ) { - return 2; - } - - return 0; -} - -static size_t -yp_encoding_euc_jp_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_euc_jp_char_width(b, n) == 1) { - return yp_encoding_ascii_alpha_char(b, n); - } else { - return 0; - } -} - -static size_t -yp_encoding_euc_jp_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_euc_jp_char_width(b, n) == 1) { - return yp_encoding_ascii_alnum_char(b, n); - } else { - return 0; - } -} - -static bool -yp_encoding_euc_jp_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_euc_jp_char_width(b, n) == 1) { - return yp_encoding_ascii_isupper_char(b, n); - } else { - return 0; - } -} - -yp_encoding_t yp_encoding_euc_jp = { - .name = "euc-jp", - .char_width = yp_encoding_euc_jp_char_width, - .alnum_char = yp_encoding_euc_jp_alnum_char, - .alpha_char = yp_encoding_euc_jp_alpha_char, - .isupper_char = yp_encoding_euc_jp_isupper_char, - .multibyte = true -}; diff --git a/yarp/enc/yp_gbk.c b/yarp/enc/yp_gbk.c deleted file mode 100644 index 71de318612d45d..00000000000000 --- a/yarp/enc/yp_gbk.c +++ /dev/null @@ -1,61 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -static size_t -yp_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 - ) - ) { - return 2; - } - - return 0; -} - -static size_t -yp_encoding_gbk_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_gbk_char_width(b, n) == 1) { - return yp_encoding_ascii_alpha_char(b, n); - } else { - return 0; - } -} - -static size_t -yp_encoding_gbk_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_gbk_char_width(b, n) == 1) { - return yp_encoding_ascii_alnum_char(b, n); - } else { - return 0; - } -} - -static bool -yp_encoding_gbk_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_gbk_char_width(b, n) == 1) { - return yp_encoding_ascii_isupper_char(b, n); - } else { - return false; - } -} - -yp_encoding_t yp_encoding_gbk = { - .name = "gbk", - .char_width = yp_encoding_gbk_char_width, - .alnum_char = yp_encoding_gbk_alnum_char, - .alpha_char = yp_encoding_gbk_alpha_char, - .isupper_char = yp_encoding_gbk_isupper_char, - .multibyte = true -}; diff --git a/yarp/enc/yp_shift_jis.c b/yarp/enc/yp_shift_jis.c deleted file mode 100644 index e6ca10d1fdc5b1..00000000000000 --- a/yarp/enc/yp_shift_jis.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -static size_t -yp_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; -} - -static size_t -yp_encoding_shift_jis_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_shift_jis_char_width(b, n) == 1) { - return yp_encoding_ascii_alpha_char(b, n); - } else { - return 0; - } -} - -static size_t -yp_encoding_shift_jis_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_shift_jis_char_width(b, n) == 1) { - return yp_encoding_ascii_alnum_char(b, n); - } else { - return 0; - } -} - -static bool -yp_encoding_shift_jis_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_shift_jis_char_width(b, n) == 1) { - return yp_encoding_ascii_isupper_char(b, n); - } else { - return 0; - } -} - -yp_encoding_t yp_encoding_shift_jis = { - .name = "shift_jis", - .char_width = yp_encoding_shift_jis_char_width, - .alnum_char = yp_encoding_shift_jis_alnum_char, - .alpha_char = yp_encoding_shift_jis_alpha_char, - .isupper_char = yp_encoding_shift_jis_isupper_char, - .multibyte = true -}; diff --git a/yarp/enc/yp_tables.c b/yarp/enc/yp_tables.c deleted file mode 100644 index 5504cd5419ac93..00000000000000 --- a/yarp/enc/yp_tables.c +++ /dev/null @@ -1,507 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -// Each element of the following table contains a bitfield that indicates a -// piece of information about the corresponding ASCII character. -static uint8_t yp_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 ISO-8859-1 character. -static uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 uint8_t yp_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 windows-1251 character. -static uint8_t yp_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 uint8_t yp_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 -}; - -static size_t -yp_encoding_ascii_char_width(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return *b < 0x80 ? 1 : 0; -} - -size_t -yp_encoding_ascii_alpha_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (yp_encoding_ascii_table[*b] & YP_ENCODING_ALPHABETIC_BIT); -} - -size_t -yp_encoding_ascii_alnum_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (yp_encoding_ascii_table[*b] & YP_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; -} - -bool -yp_encoding_ascii_isupper_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return (yp_encoding_ascii_table[*b] & YP_ENCODING_UPPERCASE_BIT); -} - -static size_t -yp_encoding_koi8_r_char_width(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return ((*b >= 0x20 && *b <= 0x7E) || (*b >= 0x80)) ? 1 : 0; -} - -static size_t -yp_encoding_single_char_width(YP_ATTRIBUTE_UNUSED const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { - return 1; -} - -yp_encoding_t yp_encoding_ascii = { - .name = "ascii", - .char_width = yp_encoding_ascii_char_width, - .alnum_char = yp_encoding_ascii_alnum_char, - .alpha_char = yp_encoding_ascii_alpha_char, - .isupper_char = yp_encoding_ascii_isupper_char, - .multibyte = false -}; - -yp_encoding_t yp_encoding_ascii_8bit = { - .name = "ascii-8bit", - .char_width = yp_encoding_single_char_width, - .alnum_char = yp_encoding_ascii_alnum_char, - .alpha_char = yp_encoding_ascii_alpha_char, - .isupper_char = yp_encoding_ascii_isupper_char, - .multibyte = false -}; - -#define YP_ENCODING_TABLE(s, i, w) \ - static size_t yp_encoding_ ##i ## _alpha_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (yp_encoding_ ##i ## _table[*b] & YP_ENCODING_ALPHABETIC_BIT); \ - } \ - static size_t yp_encoding_ ##i ## _alnum_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (yp_encoding_ ##i ## _table[*b] & YP_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; \ - } \ - static bool yp_encoding_ ##i ## _isupper_char(const uint8_t *b, YP_ATTRIBUTE_UNUSED ptrdiff_t n) { \ - return (yp_encoding_ ##i ## _table[*b] & YP_ENCODING_UPPERCASE_BIT); \ - } \ - yp_encoding_t yp_encoding_ ##i = { \ - .name = s, \ - .char_width = w, \ - .alnum_char = yp_encoding_ ##i ## _alnum_char, \ - .alpha_char = yp_encoding_ ##i ## _alpha_char, \ - .isupper_char = yp_encoding_ ##i ## _isupper_char, \ - .multibyte = false, \ - }; - -YP_ENCODING_TABLE("iso-8859-1", iso_8859_1, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-2", iso_8859_2, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-3", iso_8859_3, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-4", iso_8859_4, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-5", iso_8859_5, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-6", iso_8859_6, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-7", iso_8859_7, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-8", iso_8859_8, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-9", iso_8859_9, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-10", iso_8859_10, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-11", iso_8859_11, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-13", iso_8859_13, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-14", iso_8859_14, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-15", iso_8859_15, yp_encoding_single_char_width) -YP_ENCODING_TABLE("iso-8859-16", iso_8859_16, yp_encoding_single_char_width) -YP_ENCODING_TABLE("koi8-r", koi8_r, yp_encoding_koi8_r_char_width) -YP_ENCODING_TABLE("windows-1251", windows_1251, yp_encoding_single_char_width) -YP_ENCODING_TABLE("windows-1252", windows_1252, yp_encoding_single_char_width) - -#undef YP_ENCODING_TABLE diff --git a/yarp/enc/yp_unicode.c b/yarp/enc/yp_unicode.c deleted file mode 100644 index bb4e041309baa7..00000000000000 --- a/yarp/enc/yp_unicode.c +++ /dev/null @@ -1,2324 +0,0 @@ -// Note that the UTF-8 decoding code is based on Bjoern Hoehrmann's UTF-8 DFA -// decoder. See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. - -#include "yarp/enc/yp_encoding.h" - -typedef uint32_t yp_unicode_codepoint_t; - -// 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. -uint8_t yp_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 -}; - -#define UNICODE_ALPHA_CODEPOINTS_LENGTH 1450 -static yp_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 yp_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 yp_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, -}; - -static bool -yp_unicode_codepoint_match(yp_unicode_codepoint_t codepoint, yp_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; -} - -static const uint8_t yp_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 -}; - -static yp_unicode_codepoint_t -yp_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 = yp_utf_8_dfa[byte]; - - codepoint = (state != 0) ? - (byte & 0x3fu) | (codepoint << 6) : - (0xffu >> type) & (byte); - - state = yp_utf_8_dfa[256 + (state * 16) + type]; - if (!state) { - *width = index + 1; - return (yp_unicode_codepoint_t) codepoint; - } - } - - *width = 0; - return 0; -} - -static size_t -yp_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) { - size_t width; - yp_utf_8_codepoint(b, n, &width); - return width; -} - -size_t -yp_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (*b < 0x80) { - return (yp_encoding_unicode_table[*b] & YP_ENCODING_ALPHABETIC_BIT) ? 1 : 0; - } - - size_t width; - yp_unicode_codepoint_t codepoint = yp_utf_8_codepoint(b, n, &width); - - if (codepoint <= 0xFF) { - return (yp_encoding_unicode_table[(uint8_t) codepoint] & YP_ENCODING_ALPHABETIC_BIT) ? width : 0; - } else { - return yp_unicode_codepoint_match(codepoint, unicode_alpha_codepoints, UNICODE_ALPHA_CODEPOINTS_LENGTH) ? width : 0; - } -} - -size_t -yp_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (*b < 0x80) { - return (yp_encoding_unicode_table[*b] & (YP_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; - } - - size_t width; - yp_unicode_codepoint_t codepoint = yp_utf_8_codepoint(b, n, &width); - - if (codepoint <= 0xFF) { - return (yp_encoding_unicode_table[(uint8_t) codepoint] & (YP_ENCODING_ALPHANUMERIC_BIT)) ? width : 0; - } else { - return yp_unicode_codepoint_match(codepoint, unicode_alnum_codepoints, UNICODE_ALNUM_CODEPOINTS_LENGTH) ? width : 0; - } -} - -static bool -yp_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (*b < 0x80) { - return (yp_encoding_unicode_table[*b] & YP_ENCODING_UPPERCASE_BIT) ? true : false; - } - - size_t width; - yp_unicode_codepoint_t codepoint = yp_utf_8_codepoint(b, n, &width); - - if (codepoint <= 0xFF) { - return (yp_encoding_unicode_table[(uint8_t) codepoint] & YP_ENCODING_UPPERCASE_BIT) ? true : false; - } else { - return yp_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 - -yp_encoding_t yp_encoding_utf_8 = { - .name = "utf-8", - .char_width = yp_encoding_utf_8_char_width, - .alnum_char = yp_encoding_utf_8_alnum_char, - .alpha_char = yp_encoding_utf_8_alpha_char, - .isupper_char = yp_encoding_utf_8_isupper_char, - .multibyte = true -}; - -yp_encoding_t yp_encoding_utf8_mac = { - .name = "utf8-mac", - .char_width = yp_encoding_utf_8_char_width, - .alnum_char = yp_encoding_utf_8_alnum_char, - .alpha_char = yp_encoding_utf_8_alpha_char, - .isupper_char = yp_encoding_utf_8_isupper_char, - .multibyte = true -}; diff --git a/yarp/enc/yp_windows_31j.c b/yarp/enc/yp_windows_31j.c deleted file mode 100644 index 0d346395353e1e..00000000000000 --- a/yarp/enc/yp_windows_31j.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "yarp/enc/yp_encoding.h" - -static size_t -yp_encoding_windows_31j_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; -} - -static size_t -yp_encoding_windows_31j_alpha_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_windows_31j_char_width(b, n) == 1) { - return yp_encoding_ascii_alpha_char(b, n); - } else { - return 0; - } -} - -static size_t -yp_encoding_windows_31j_alnum_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_windows_31j_char_width(b, n) == 1) { - return yp_encoding_ascii_alnum_char(b, n); - } else { - return 0; - } -} - -static bool -yp_encoding_windows_31j_isupper_char(const uint8_t *b, ptrdiff_t n) { - if (yp_encoding_windows_31j_char_width(b, n) == 1) { - return yp_encoding_ascii_isupper_char(b, n); - } else { - return false; - } -} - -yp_encoding_t yp_encoding_windows_31j = { - .name = "windows-31j", - .char_width = yp_encoding_windows_31j_char_width, - .alnum_char = yp_encoding_windows_31j_alnum_char, - .alpha_char = yp_encoding_windows_31j_alpha_char, - .isupper_char = yp_encoding_windows_31j_isupper_char, - .multibyte = true -}; diff --git a/yarp/extension.c b/yarp/extension.c deleted file mode 100644 index 8d36cd44272f02..00000000000000 --- a/yarp/extension.c +++ /dev/null @@ -1,612 +0,0 @@ -#include "yarp/extension.h" - -// NOTE: this file should contain only bindings. -// All non-trivial logic should be in librubyparser so it can be shared its the various callers. - -VALUE rb_cYARP; -VALUE rb_cYARPNode; -VALUE rb_cYARPSource; -VALUE rb_cYARPToken; -VALUE rb_cYARPLocation; - -VALUE rb_cYARPComment; -VALUE rb_cYARPParseError; -VALUE rb_cYARPParseWarning; -VALUE rb_cYARPParseResult; - -/******************************************************************************/ -/* 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 yp_string_t. -static void -input_load_string(yp_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)); - } - - yp_string_constant_init(input, RSTRING_PTR(string), RSTRING_LEN(string)); -} - -/******************************************************************************/ -/* Serializing the AST */ -/******************************************************************************/ - -// Dump the AST corresponding to the given input to a string. -static VALUE -dump_input(yp_string_t *input, const char *filepath) { - yp_buffer_t buffer; - if (!yp_buffer_init(&buffer)) { - rb_raise(rb_eNoMemError, "failed to allocate memory"); - } - - yp_parser_t parser; - yp_parser_init(&parser, yp_string_source(input), yp_string_length(input), filepath); - - yp_node_t *node = yp_parse(&parser); - yp_serialize(&parser, node, &buffer); - - VALUE result = rb_str_new(yp_buffer_value(&buffer), yp_buffer_length(&buffer)); - yp_node_destroy(&parser, node); - yp_buffer_free(&buffer); - yp_parser_free(&parser); - - return result; -} - -// Dump the AST corresponding to the given string to a string. -static VALUE -dump(int argc, VALUE *argv, VALUE self) { - VALUE string; - VALUE filepath; - rb_scan_args(argc, argv, "11", &string, &filepath); - - yp_string_t input; - input_load_string(&input, string); - -#ifdef YARP_DEBUG_MODE_BUILD - size_t length = yp_string_length(&input); - char* dup = malloc(length); - memcpy(dup, yp_string_source(&input), length); - yp_string_constant_init(&input, dup, length); -#endif - - VALUE value = dump_input(&input, check_string(filepath)); - -#ifdef YARP_DEBUG_MODE_BUILD - free(dup); -#endif - - return value; -} - -// Dump the AST corresponding to the given file to a string. -static VALUE -dump_file(VALUE self, VALUE filepath) { - yp_string_t input; - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - VALUE value = dump_input(&input, checked); - yp_string_free(&input); - - return value; -} - -/******************************************************************************/ -/* Extracting values for the parse result */ -/******************************************************************************/ - -// Extract the comments out of the parser into an array. -static VALUE -parser_comments(yp_parser_t *parser, VALUE source) { - VALUE comments = rb_ary_new(); - - for (yp_comment_t *comment = (yp_comment_t *) parser->comment_list.head; comment != NULL; comment = (yp_comment_t *) comment->node.next) { - VALUE location_argv[] = { - source, - LONG2FIX(comment->start - parser->start), - LONG2FIX(comment->end - comment->start) - }; - - VALUE type; - switch (comment->type) { - case YP_COMMENT_INLINE: - type = ID2SYM(rb_intern("inline")); - break; - case YP_COMMENT_EMBDOC: - type = ID2SYM(rb_intern("embdoc")); - break; - case YP_COMMENT___END__: - type = ID2SYM(rb_intern("__END__")); - break; - default: - type = ID2SYM(rb_intern("inline")); - break; - } - - VALUE comment_argv[] = { type, rb_class_new_instance(3, location_argv, rb_cYARPLocation) }; - rb_ary_push(comments, rb_class_new_instance(2, comment_argv, rb_cYARPComment)); - } - - return comments; -} - -// Extract the errors out of the parser into an array. -static VALUE -parser_errors(yp_parser_t *parser, rb_encoding *encoding, VALUE source) { - VALUE errors = rb_ary_new(); - yp_diagnostic_t *error; - - for (error = (yp_diagnostic_t *) parser->error_list.head; error != NULL; error = (yp_diagnostic_t *) error->node.next) { - VALUE location_argv[] = { - source, - LONG2FIX(error->start - parser->start), - LONG2FIX(error->end - error->start) - }; - - VALUE error_argv[] = { - rb_enc_str_new_cstr(error->message, encoding), - rb_class_new_instance(3, location_argv, rb_cYARPLocation) - }; - - rb_ary_push(errors, rb_class_new_instance(2, error_argv, rb_cYARPParseError)); - } - - return errors; -} - -// Extract the warnings out of the parser into an array. -static VALUE -parser_warnings(yp_parser_t *parser, rb_encoding *encoding, VALUE source) { - VALUE warnings = rb_ary_new(); - yp_diagnostic_t *warning; - - for (warning = (yp_diagnostic_t *) parser->warning_list.head; warning != NULL; warning = (yp_diagnostic_t *) warning->node.next) { - VALUE location_argv[] = { - source, - LONG2FIX(warning->start - parser->start), - LONG2FIX(warning->end - warning->start) - }; - - VALUE warning_argv[] = { - rb_enc_str_new_cstr(warning->message, encoding), - rb_class_new_instance(3, location_argv, rb_cYARPLocation) - }; - - rb_ary_push(warnings, rb_class_new_instance(2, warning_argv, rb_cYARPParseWarning)); - } - - 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, yp_parser_t *parser, yp_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, yp_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(yp_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(yp_string_t *input, const char *filepath, bool return_nodes) { - yp_parser_t parser; - yp_parser_init(&parser, yp_string_source(input), yp_string_length(input), filepath); - yp_parser_register_encoding_changed_callback(&parser, parse_lex_encoding_changed_callback); - - VALUE offsets = rb_ary_new(); - VALUE source_argv[] = { rb_str_new((const char *) yp_string_source(input), yp_string_length(input)), offsets }; - VALUE source = rb_class_new_instance(2, source_argv, rb_cYARPSource); - - 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; - yp_lex_callback_t lex_callback = (yp_lex_callback_t) { - .data = (void *) data, - .callback = parse_lex_token, - }; - - parser.lex_callback = &lex_callback; - yp_node_t *node = yp_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, yp_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_errors(&parser, parse_lex_data.encoding, source), - parser_warnings(&parser, parse_lex_data.encoding, source), - source - }; - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); - return rb_class_new_instance(5, result_argv, rb_cYARPParseResult); -} - -// Return an array of tokens corresponding to the given string. -static VALUE -lex(int argc, VALUE *argv, VALUE self) { - VALUE string; - VALUE filepath; - rb_scan_args(argc, argv, "11", &string, &filepath); - - yp_string_t input; - input_load_string(&input, string); - - return parse_lex_input(&input, check_string(filepath), false); -} - -// Return an array of tokens corresponding to the given file. -static VALUE -lex_file(VALUE self, VALUE filepath) { - yp_string_t input; - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - VALUE value = parse_lex_input(&input, checked, false); - yp_string_free(&input); - - return value; -} - -/******************************************************************************/ -/* Parsing Ruby code */ -/******************************************************************************/ - -// Parse the given input and return a ParseResult instance. -static VALUE -parse_input(yp_string_t *input, const char *filepath) { - yp_parser_t parser; - yp_parser_init(&parser, yp_string_source(input), yp_string_length(input), filepath); - - yp_node_t *node = yp_parse(&parser); - rb_encoding *encoding = rb_enc_find(parser.encoding.name); - - VALUE source = yp_source_new(&parser, encoding); - VALUE result_argv[] = { - yp_ast_new(&parser, node, encoding), - parser_comments(&parser, source), - parser_errors(&parser, encoding, source), - parser_warnings(&parser, encoding, source), - source - }; - - VALUE result = rb_class_new_instance(5, result_argv, rb_cYARPParseResult); - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); - - return result; -} - -// Parse the given string and return a ParseResult instance. -static VALUE -parse(int argc, VALUE *argv, VALUE self) { - VALUE string; - VALUE filepath; - rb_scan_args(argc, argv, "11", &string, &filepath); - - yp_string_t input; - input_load_string(&input, string); - -#ifdef YARP_DEBUG_MODE_BUILD - size_t length = yp_string_length(&input); - char* dup = malloc(length); - memcpy(dup, yp_string_source(&input), length); - yp_string_constant_init(&input, dup, length); -#endif - - VALUE value = parse_input(&input, check_string(filepath)); - -#ifdef YARP_DEBUG_MODE_BUILD - free(dup); -#endif - - return value; -} - -// Parse the given file and return a ParseResult instance. -static VALUE -parse_file(VALUE self, VALUE filepath) { - yp_string_t input; - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - VALUE value = parse_input(&input, checked); - yp_string_free(&input); - - return value; -} - -// Parse the given string and return a ParseResult instance. -static VALUE -parse_lex(int argc, VALUE *argv, VALUE self) { - VALUE string; - VALUE filepath; - rb_scan_args(argc, argv, "11", &string, &filepath); - - yp_string_t input; - input_load_string(&input, string); - return parse_lex_input(&input, check_string(filepath), true); -} - -// Parse and lex the given file and return a ParseResult instance. -static VALUE -parse_lex_file(VALUE self, VALUE filepath) { - yp_string_t input; - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - VALUE value = parse_lex_input(&input, checked, true); - yp_string_free(&input); - - return value; -} - -/******************************************************************************/ -/* Utility functions exposed to make testing easier */ -/******************************************************************************/ - -// Returns an array of strings corresponding to the named capture groups in the -// given source string. If YARP was unable to parse the regular expression, this -// function returns nil. -static VALUE -named_captures(VALUE self, VALUE source) { - yp_string_list_t string_list; - yp_string_list_init(&string_list); - - if (!yp_regexp_named_capture_group_names((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), &string_list, false, &yp_encoding_utf_8)) { - yp_string_list_free(&string_list); - return Qnil; - } - - VALUE names = rb_ary_new(); - for (size_t index = 0; index < string_list.length; index++) { - const yp_string_t *string = &string_list.strings[index]; - rb_ary_push(names, rb_str_new((const char *) yp_string_source(string), yp_string_length(string))); - } - - yp_string_list_free(&string_list); - return names; -} - -// Accepts a source string and a type of unescaping and returns the unescaped -// version. -static VALUE -unescape(VALUE source, yp_unescape_type_t unescape_type) { - yp_string_t result; - - if (yp_unescape_string((const uint8_t *) RSTRING_PTR(source), RSTRING_LEN(source), unescape_type, &result)) { - VALUE str = rb_str_new((const char *) yp_string_source(&result), yp_string_length(&result)); - yp_string_free(&result); - return str; - } else { - yp_string_free(&result); - return Qnil; - } -} - -// Do not unescape anything in the given string. This is here to provide a -// consistent API. -static VALUE -unescape_none(VALUE self, VALUE source) { - return unescape(source, YP_UNESCAPE_NONE); -} - -// Minimally unescape the given string. This means effectively unescaping just -// the quotes of a string. Returns the unescaped string. -static VALUE -unescape_minimal(VALUE self, VALUE source) { - return unescape(source, YP_UNESCAPE_MINIMAL); -} - -// Unescape everything in the given string. Return the unescaped string. -static VALUE -unescape_all(VALUE self, VALUE source) { - return unescape(source, YP_UNESCAPE_ALL); -} - -// Return a hash of information about the given source string's memory usage. -static VALUE -memsize(VALUE self, VALUE string) { - yp_parser_t parser; - size_t length = RSTRING_LEN(string); - yp_parser_init(&parser, (const uint8_t *) RSTRING_PTR(string), length, NULL); - - yp_node_t *node = yp_parse(&parser); - yp_memsize_t memsize; - yp_node_memsize(node, &memsize); - - yp_node_destroy(&parser, node); - yp_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; -} - -// 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) { - yp_string_t input; - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - yp_parser_t parser; - yp_parser_init(&parser, yp_string_source(&input), yp_string_length(&input), checked); - - yp_node_t *node = yp_parse(&parser); - yp_node_destroy(&parser, node); - yp_parser_free(&parser); - - return Qnil; -} - -// Parse the file and serialize the result. This is mostly used to test this -// path since it is used by client libraries. -static VALUE -parse_serialize_file_metadata(VALUE self, VALUE filepath, VALUE metadata) { - yp_string_t input; - yp_buffer_t buffer; - yp_buffer_init(&buffer); - - const char *checked = check_string(filepath); - if (!yp_string_mapped_init(&input, checked)) return Qnil; - - yp_parse_serialize(yp_string_source(&input), yp_string_length(&input), &buffer, check_string(metadata)); - VALUE result = rb_str_new(yp_buffer_value(&buffer), yp_buffer_length(&buffer)); - - yp_buffer_free(&buffer); - return result; -} - -/******************************************************************************/ -/* Initialization of the extension */ -/******************************************************************************/ - -RUBY_FUNC_EXPORTED void -Init_yarp(void) { - // Make sure that the YARP library version matches the expected version. - // Otherwise something was compiled incorrectly. - if (strcmp(yp_version(), EXPECTED_YARP_VERSION) != 0) { - rb_raise( - rb_eRuntimeError, - "The YARP library version (%s) does not match the expected version (%s)", - yp_version(), - EXPECTED_YARP_VERSION - ); - } - - // Grab up references to all of the constants that we're going to need to - // reference throughout this extension. - rb_cYARP = rb_define_module("YARP"); - rb_cYARPNode = rb_define_class_under(rb_cYARP, "Node", rb_cObject); - rb_cYARPSource = rb_define_class_under(rb_cYARP, "Source", rb_cObject); - rb_cYARPToken = rb_define_class_under(rb_cYARP, "Token", rb_cObject); - rb_cYARPLocation = rb_define_class_under(rb_cYARP, "Location", rb_cObject); - rb_cYARPComment = rb_define_class_under(rb_cYARP, "Comment", rb_cObject); - rb_cYARPParseError = rb_define_class_under(rb_cYARP, "ParseError", rb_cObject); - rb_cYARPParseWarning = rb_define_class_under(rb_cYARP, "ParseWarning", rb_cObject); - rb_cYARPParseResult = rb_define_class_under(rb_cYARP, "ParseResult", rb_cObject); - - // Define the version string here so that we can use the constants defined - // in yarp.h. - rb_define_const(rb_cYARP, "VERSION", rb_str_new2(EXPECTED_YARP_VERSION)); - rb_define_const(rb_cYARP, "BACKEND", ID2SYM(rb_intern("CExtension"))); - - // First, the functions that have to do with lexing and parsing. - rb_define_singleton_method(rb_cYARP, "dump", dump, -1); - rb_define_singleton_method(rb_cYARP, "dump_file", dump_file, 1); - rb_define_singleton_method(rb_cYARP, "lex", lex, -1); - rb_define_singleton_method(rb_cYARP, "lex_file", lex_file, 1); - rb_define_singleton_method(rb_cYARP, "parse", parse, -1); - rb_define_singleton_method(rb_cYARP, "parse_file", parse_file, 1); - rb_define_singleton_method(rb_cYARP, "parse_lex", parse_lex, -1); - rb_define_singleton_method(rb_cYARP, "parse_lex_file", parse_lex_file, 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_cYARPDebug = rb_define_module_under(rb_cYARP, "Debug"); - rb_define_singleton_method(rb_cYARPDebug, "named_captures", named_captures, 1); - rb_define_singleton_method(rb_cYARPDebug, "unescape_none", unescape_none, 1); - rb_define_singleton_method(rb_cYARPDebug, "unescape_minimal", unescape_minimal, 1); - rb_define_singleton_method(rb_cYARPDebug, "unescape_all", unescape_all, 1); - rb_define_singleton_method(rb_cYARPDebug, "memsize", memsize, 1); - rb_define_singleton_method(rb_cYARPDebug, "profile_file", profile_file, 1); - rb_define_singleton_method(rb_cYARPDebug, "parse_serialize_file_metadata", parse_serialize_file_metadata, 2); - - // Next, initialize the other APIs. - Init_yarp_api_node(); - Init_yarp_pack(); -} diff --git a/yarp/extension.h b/yarp/extension.h deleted file mode 100644 index ebcb3d614f02ac..00000000000000 --- a/yarp/extension.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef YARP_EXT_NODE_H -#define YARP_EXT_NODE_H - -#define EXPECTED_YARP_VERSION "0.11.0" - -#include -#include -#include "yarp.h" - -VALUE yp_source_new(yp_parser_t *parser, rb_encoding *encoding); -VALUE yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding, VALUE source); -VALUE yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding); - -void Init_yarp_api_node(void); -void Init_yarp_pack(void); -YP_EXPORTED_FUNCTION void Init_yarp(void); - -#endif diff --git a/yarp/node.h b/yarp/node.h deleted file mode 100644 index 1b546f086f0004..00000000000000 --- a/yarp/node.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef YARP_NODE_H -#define YARP_NODE_H - -#include "yarp/defines.h" -#include "yarp/parser.h" - -// Append a new node onto the end of the node list. -void yp_node_list_append(yp_node_list_t *list, yp_node_t *node); - -// Clear the node but preserves the location. -void yp_node_clear(yp_node_t *node); - -// Deallocate a node and all of its children. -YP_EXPORTED_FUNCTION void yp_node_destroy(yp_parser_t *parser, struct yp_node *node); - -// This struct stores the information gathered by the yp_node_memsize function. -// It contains both the memory footprint and additionally metadata about the -// shape of the tree. -typedef struct { - size_t memsize; - size_t node_count; -} yp_memsize_t; - -// Calculates the memory footprint of a given node. -YP_EXPORTED_FUNCTION void yp_node_memsize(yp_node_t *node, yp_memsize_t *memsize); - -// Returns a string representation of the given node type. -YP_EXPORTED_FUNCTION const char * yp_node_type_to_str(yp_node_type_t node_type); - -#define YP_EMPTY_NODE_LIST ((yp_node_list_t) { .nodes = NULL, .size = 0, .capacity = 0 }) - -#endif // YARP_NODE_H - -// ScopeNodes are helper nodes, and will never -// be part of the AST. We manually declare them -// here to avoid generating them -typedef struct yp_scope_node { - yp_node_t base; - struct yp_parameters_node *parameters; - yp_node_t *body; - yp_constant_id_list_t locals; -} yp_scope_node_t; diff --git a/yarp/pack.c b/yarp/pack.c deleted file mode 100644 index 48bba4ea4917d6..00000000000000 --- a/yarp/pack.c +++ /dev/null @@ -1,493 +0,0 @@ -#include "yarp/pack.h" - -#include -#include - -static uintmax_t -strtoumaxc(const char **format); - -YP_EXPORTED_FUNCTION yp_pack_result -yp_pack_parse(yp_pack_variant variant, const char **format, const char *format_end, - yp_pack_type *type, yp_pack_signed *signed_type, yp_pack_endian *endian, yp_pack_size *size, - yp_pack_length_type *length_type, uint64_t *length, yp_pack_encoding *encoding) { - - if (*encoding == YP_PACK_ENCODING_START) { - *encoding = YP_PACK_ENCODING_US_ASCII; - } - - if (*format == format_end) { - *type = YP_PACK_END; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - *length_type = YP_PACK_LENGTH_NA; - return YP_PACK_OK; - } - - *length_type = YP_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 = YP_PACK_SPACE; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - *length_type = YP_PACK_LENGTH_NA; - *length = 0; - return YP_PACK_OK; - case '#': - while ((*format < format_end) && (**format != '\n')) { - (*format)++; - } - *type = YP_PACK_COMMENT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - *length_type = YP_PACK_LENGTH_NA; - *length = 0; - return YP_PACK_OK; - case 'C': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_AGNOSTIC_ENDIAN; - *size = YP_PACK_SIZE_8; - break; - case 'S': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_16; - break; - case 'L': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_32; - break; - case 'Q': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_64; - break; - case 'J': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_P; - break; - case 'c': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_AGNOSTIC_ENDIAN; - *size = YP_PACK_SIZE_8; - break; - case 's': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_16; - break; - case 'l': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_32; - break; - case 'q': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_64; - break; - case 'j': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_P; - break; - case 'I': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_INT; - break; - case 'i': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_SIGNED; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_INT; - break; - case 'n': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_BIG_ENDIAN; - *size = YP_PACK_SIZE_16; - length_changed_allowed = false; - break; - case 'N': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_BIG_ENDIAN; - *size = YP_PACK_SIZE_32; - length_changed_allowed = false; - break; - case 'v': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_LITTLE_ENDIAN; - *size = YP_PACK_SIZE_16; - length_changed_allowed = false; - break; - case 'V': - *type = YP_PACK_INTEGER; - *signed_type = YP_PACK_UNSIGNED; - *endian = YP_PACK_LITTLE_ENDIAN; - *size = YP_PACK_SIZE_32; - length_changed_allowed = false; - break; - case 'U': - *type = YP_PACK_UTF8; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'w': - *type = YP_PACK_BER; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'D': - case 'd': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_64; - break; - case 'F': - case 'f': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_NATIVE_ENDIAN; - *size = YP_PACK_SIZE_32; - break; - case 'E': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_LITTLE_ENDIAN; - *size = YP_PACK_SIZE_64; - break; - case 'e': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_LITTLE_ENDIAN; - *size = YP_PACK_SIZE_32; - break; - case 'G': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_BIG_ENDIAN; - *size = YP_PACK_SIZE_64; - break; - case 'g': - *type = YP_PACK_FLOAT; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_BIG_ENDIAN; - *size = YP_PACK_SIZE_32; - break; - case 'A': - *type = YP_PACK_STRING_SPACE_PADDED; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'a': - *type = YP_PACK_STRING_NULL_PADDED; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'Z': - *type = YP_PACK_STRING_NULL_TERMINATED; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'B': - *type = YP_PACK_STRING_MSB; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'b': - *type = YP_PACK_STRING_LSB; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'H': - *type = YP_PACK_STRING_HEX_HIGH; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'h': - *type = YP_PACK_STRING_HEX_LOW; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'u': - *type = YP_PACK_STRING_UU; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'M': - *type = YP_PACK_STRING_MIME; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'm': - *type = YP_PACK_STRING_BASE64; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'P': - *type = YP_PACK_STRING_FIXED; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'p': - *type = YP_PACK_STRING_POINTER; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case '@': - *type = YP_PACK_MOVE; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'X': - *type = YP_PACK_BACK; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case 'x': - *type = YP_PACK_NULL; - *signed_type = YP_PACK_SIGNED_NA; - *endian = YP_PACK_ENDIAN_NA; - *size = YP_PACK_SIZE_NA; - break; - case '%': - return YP_PACK_ERROR_UNSUPPORTED_DIRECTIVE; - default: - return YP_PACK_ERROR_UNKNOWN_DIRECTIVE; - } - - bool explicit_endian = false; - - while (*format < format_end) { - switch (**format) { - case '_': - case '!': - (*format)++; - if (*type != YP_PACK_INTEGER || !length_changed_allowed) { - return YP_PACK_ERROR_BANG_NOT_ALLOWED; - } - switch (*size) { - case YP_PACK_SIZE_SHORT: - case YP_PACK_SIZE_INT: - case YP_PACK_SIZE_LONG: - case YP_PACK_SIZE_LONG_LONG: - break; - case YP_PACK_SIZE_16: - *size = YP_PACK_SIZE_SHORT; - break; - case YP_PACK_SIZE_32: - *size = YP_PACK_SIZE_LONG; - break; - case YP_PACK_SIZE_64: - *size = YP_PACK_SIZE_LONG_LONG; - break; - case YP_PACK_SIZE_P: - break; - default: - return YP_PACK_ERROR_BANG_NOT_ALLOWED; - } - break; - case '<': - (*format)++; - if (explicit_endian) { - return YP_PACK_ERROR_DOUBLE_ENDIAN; - } - *endian = YP_PACK_LITTLE_ENDIAN; - explicit_endian = true; - break; - case '>': - (*format)++; - if (explicit_endian) { - return YP_PACK_ERROR_DOUBLE_ENDIAN; - } - *endian = YP_PACK_BIG_ENDIAN; - explicit_endian = true; - break; - default: - goto exit_modifier_loop; - } - } - -exit_modifier_loop: - - if (variant == YP_PACK_VARIANT_UNPACK && *type == YP_PACK_MOVE) { - *length = 0; - } - - if (*format < format_end) { - if (**format == '*') { - switch (*type) { - case YP_PACK_NULL: - case YP_PACK_BACK: - switch (variant) { - case YP_PACK_VARIANT_PACK: - *length_type = YP_PACK_LENGTH_FIXED; - break; - case YP_PACK_VARIANT_UNPACK: - *length_type = YP_PACK_LENGTH_MAX; - break; - } - *length = 0; - break; - - case YP_PACK_MOVE: - switch (variant) { - case YP_PACK_VARIANT_PACK: - *length_type = YP_PACK_LENGTH_FIXED; - break; - case YP_PACK_VARIANT_UNPACK: - *length_type = YP_PACK_LENGTH_RELATIVE; - break; - } - *length = 0; - break; - - case YP_PACK_STRING_UU: - *length_type = YP_PACK_LENGTH_FIXED; - *length = 0; - break; - - case YP_PACK_STRING_FIXED: - switch (variant) { - case YP_PACK_VARIANT_PACK: - *length_type = YP_PACK_LENGTH_FIXED; - *length = 1; - break; - case YP_PACK_VARIANT_UNPACK: - *length_type = YP_PACK_LENGTH_MAX; - *length = 0; - break; - } - break; - - case YP_PACK_STRING_MIME: - case YP_PACK_STRING_BASE64: - *length_type = YP_PACK_LENGTH_FIXED; - *length = 1; - break; - - default: - *length_type = YP_PACK_LENGTH_MAX; - *length = 0; - break; - } - - (*format)++; - } else if (**format >= '0' && **format <= '9') { - errno = 0; - *length_type = YP_PACK_LENGTH_FIXED; - #if UINTMAX_MAX < UINT64_MAX - #error "YARP'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 YP_PACK_ERROR_LENGTH_TOO_BIG; - } - *length = (uint64_t) length_max; - } - } - - switch (*type) { - case YP_PACK_UTF8: - /* if encoding is US-ASCII, upgrade to UTF-8 */ - if (*encoding == YP_PACK_ENCODING_US_ASCII) { - *encoding = YP_PACK_ENCODING_UTF_8; - } - break; - case YP_PACK_STRING_MIME: - case YP_PACK_STRING_BASE64: - case YP_PACK_STRING_UU: - /* keep US-ASCII (do nothing) */ - break; - default: - /* fall back to BINARY */ - *encoding = YP_PACK_ENCODING_ASCII_8BIT; - break; - } - - return YP_PACK_OK; -} - -YP_EXPORTED_FUNCTION size_t -yp_size_to_native(yp_pack_size size) { - switch (size) { - case YP_PACK_SIZE_SHORT: - return sizeof(short); - case YP_PACK_SIZE_INT: - return sizeof(int); - case YP_PACK_SIZE_LONG: - return sizeof(long); - case YP_PACK_SIZE_LONG_LONG: - return sizeof(long long); - case YP_PACK_SIZE_8: - return 1; - case YP_PACK_SIZE_16: - return 2; - case YP_PACK_SIZE_32: - return 4; - case YP_PACK_SIZE_64: - return 8; - case YP_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/yarp/pack.h b/yarp/pack.h deleted file mode 100644 index 9d6204bf7b7410..00000000000000 --- a/yarp/pack.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef YARP_PACK_H -#define YARP_PACK_H - -#include "yarp/defines.h" - -#include -#include - -typedef enum yp_pack_version { - YP_PACK_VERSION_3_2_0 -} yp_pack_version; - -typedef enum yp_pack_variant { - YP_PACK_VARIANT_PACK, - YP_PACK_VARIANT_UNPACK -} yp_pack_variant; - -typedef enum yp_pack_type { - YP_PACK_SPACE, - YP_PACK_COMMENT, - YP_PACK_INTEGER, - YP_PACK_UTF8, - YP_PACK_BER, - YP_PACK_FLOAT, - YP_PACK_STRING_SPACE_PADDED, - YP_PACK_STRING_NULL_PADDED, - YP_PACK_STRING_NULL_TERMINATED, - YP_PACK_STRING_MSB, - YP_PACK_STRING_LSB, - YP_PACK_STRING_HEX_HIGH, - YP_PACK_STRING_HEX_LOW, - YP_PACK_STRING_UU, - YP_PACK_STRING_MIME, - YP_PACK_STRING_BASE64, - YP_PACK_STRING_FIXED, - YP_PACK_STRING_POINTER, - YP_PACK_MOVE, - YP_PACK_BACK, - YP_PACK_NULL, - YP_PACK_END -} yp_pack_type; - -typedef enum yp_pack_signed { - YP_PACK_UNSIGNED, - YP_PACK_SIGNED, - YP_PACK_SIGNED_NA -} yp_pack_signed; - -typedef enum yp_pack_endian { - YP_PACK_AGNOSTIC_ENDIAN, - YP_PACK_LITTLE_ENDIAN, // aka 'VAX', or 'V' - YP_PACK_BIG_ENDIAN, // aka 'network', or 'N' - YP_PACK_NATIVE_ENDIAN, - YP_PACK_ENDIAN_NA -} yp_pack_endian; - -typedef enum yp_pack_size { - YP_PACK_SIZE_SHORT, - YP_PACK_SIZE_INT, - YP_PACK_SIZE_LONG, - YP_PACK_SIZE_LONG_LONG, - YP_PACK_SIZE_8, - YP_PACK_SIZE_16, - YP_PACK_SIZE_32, - YP_PACK_SIZE_64, - YP_PACK_SIZE_P, - YP_PACK_SIZE_NA -} yp_pack_size; - -typedef enum yp_pack_length_type { - YP_PACK_LENGTH_FIXED, - YP_PACK_LENGTH_MAX, - YP_PACK_LENGTH_RELATIVE, // special case for unpack @* - YP_PACK_LENGTH_NA -} yp_pack_length_type; - -typedef enum yp_pack_encoding { - YP_PACK_ENCODING_START, - YP_PACK_ENCODING_ASCII_8BIT, - YP_PACK_ENCODING_US_ASCII, - YP_PACK_ENCODING_UTF_8 -} yp_pack_encoding; - -typedef enum yp_pack_result { - YP_PACK_OK, - YP_PACK_ERROR_UNSUPPORTED_DIRECTIVE, - YP_PACK_ERROR_UNKNOWN_DIRECTIVE, - YP_PACK_ERROR_LENGTH_TOO_BIG, - YP_PACK_ERROR_BANG_NOT_ALLOWED, - YP_PACK_ERROR_DOUBLE_ENDIAN -} yp_pack_result; - -// Parse a single directive from a pack or unpack format string. -// -// Parameters: -// - [in] yp_pack_version version the version of Ruby -// - [in] yp_pack_variant variant pack or unpack -// - [in out] const char **format 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 -// - [in] const char *format_end the end of the format string -// - [out] yp_pack_type *type the type of the directive -// - [out] yp_pack_signed *signed_type -// whether the value is signed -// - [out] yp_pack_endian *endian the endianness of the value -// - [out] yp_pack_size *size the size of the value -// - [out] yp_pack_length_type *length_type -// what kind of length is specified -// - [out] size_t *length the length of the directive -// - [in out] yp_pack_encoding *encoding -// 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 -// YP_PACK_ENCODING_START when yp_pack_parse is called for the first -// directive in a format string -// -// Return: -// - YP_PACK_OK on success -// - YP_PACK_ERROR_* on error -// -// Notes: -// Consult Ruby documentation for the meaning of directives. -YP_EXPORTED_FUNCTION yp_pack_result -yp_pack_parse( - yp_pack_variant variant_arg, - const char **format, - const char *format_end, - yp_pack_type *type, - yp_pack_signed *signed_type, - yp_pack_endian *endian, - yp_pack_size *size, - yp_pack_length_type *length_type, - uint64_t *length, - yp_pack_encoding *encoding -); - -// YARP abstracts sizes away from the native system - this converts an abstract -// size to a native size. -YP_EXPORTED_FUNCTION size_t yp_size_to_native(yp_pack_size size); - -#endif diff --git a/yarp/parser.h b/yarp/parser.h deleted file mode 100644 index 0ae01f78da6e53..00000000000000 --- a/yarp/parser.h +++ /dev/null @@ -1,389 +0,0 @@ -#ifndef YARP_PARSER_H -#define YARP_PARSER_H - -#include "yarp/ast.h" -#include "yarp/defines.h" -#include "yarp/enc/yp_encoding.h" -#include "yarp/util/yp_constant_pool.h" -#include "yarp/util/yp_list.h" -#include "yarp/util/yp_newline_list.h" -#include "yarp/util/yp_state_stack.h" - -#include - -// 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 { - YP_LEX_STATE_BIT_BEG, - YP_LEX_STATE_BIT_END, - YP_LEX_STATE_BIT_ENDARG, - YP_LEX_STATE_BIT_ENDFN, - YP_LEX_STATE_BIT_ARG, - YP_LEX_STATE_BIT_CMDARG, - YP_LEX_STATE_BIT_MID, - YP_LEX_STATE_BIT_FNAME, - YP_LEX_STATE_BIT_DOT, - YP_LEX_STATE_BIT_CLASS, - YP_LEX_STATE_BIT_LABEL, - YP_LEX_STATE_BIT_LABELED, - YP_LEX_STATE_BIT_FITEM -} yp_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 { - YP_LEX_STATE_NONE = 0, - YP_LEX_STATE_BEG = (1 << YP_LEX_STATE_BIT_BEG), - YP_LEX_STATE_END = (1 << YP_LEX_STATE_BIT_END), - YP_LEX_STATE_ENDARG = (1 << YP_LEX_STATE_BIT_ENDARG), - YP_LEX_STATE_ENDFN = (1 << YP_LEX_STATE_BIT_ENDFN), - YP_LEX_STATE_ARG = (1 << YP_LEX_STATE_BIT_ARG), - YP_LEX_STATE_CMDARG = (1 << YP_LEX_STATE_BIT_CMDARG), - YP_LEX_STATE_MID = (1 << YP_LEX_STATE_BIT_MID), - YP_LEX_STATE_FNAME = (1 << YP_LEX_STATE_BIT_FNAME), - YP_LEX_STATE_DOT = (1 << YP_LEX_STATE_BIT_DOT), - YP_LEX_STATE_CLASS = (1 << YP_LEX_STATE_BIT_CLASS), - YP_LEX_STATE_LABEL = (1 << YP_LEX_STATE_BIT_LABEL), - YP_LEX_STATE_LABELED = (1 << YP_LEX_STATE_BIT_LABELED), - YP_LEX_STATE_FITEM = (1 << YP_LEX_STATE_BIT_FITEM), - YP_LEX_STATE_BEG_ANY = YP_LEX_STATE_BEG | YP_LEX_STATE_MID | YP_LEX_STATE_CLASS, - YP_LEX_STATE_ARG_ANY = YP_LEX_STATE_ARG | YP_LEX_STATE_CMDARG, - YP_LEX_STATE_END_ANY = YP_LEX_STATE_END | YP_LEX_STATE_ENDARG | YP_LEX_STATE_ENDFN -} yp_lex_state_t; - -typedef enum { - YP_HEREDOC_QUOTE_NONE, - YP_HEREDOC_QUOTE_SINGLE = '\'', - YP_HEREDOC_QUOTE_DOUBLE = '"', - YP_HEREDOC_QUOTE_BACKTICK = '`', -} yp_heredoc_quote_t; - -typedef enum { - YP_HEREDOC_INDENT_NONE, - YP_HEREDOC_INDENT_DASH, - YP_HEREDOC_INDENT_TILDE, -} yp_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 YP_LEX_STRING mode, and will return tokens that -// are found as part of a string. -typedef struct yp_lex_mode { - enum { - // This state is used when any given token is being lexed. - YP_LEX_DEFAULT, - - // This state is used when we're lexing as normal but inside an embedded - // expression of a string. - YP_LEX_EMBEXPR, - - // This state is used when we're lexing a variable that is embedded - // directly inside of a string with the # shorthand. - YP_LEX_EMBVAR, - - // This state is used when you are inside the content of a heredoc. - YP_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. - YP_LEX_LIST, - - // This state is used when a regular expression has been begun and we - // are looking for the terminator. - YP_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. - YP_LEX_STRING - } 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 { - // These pointers point to the beginning and end of the heredoc - // identifier. - const uint8_t *ident_start; - size_t ident_length; - - yp_heredoc_quote_t quote; - yp_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; - } heredoc; - } as; - - // The previous lex state so that it knows how to pop. - struct yp_lex_mode *prev; -} yp_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 YP_LEX_STACK_SIZE 4 - -// A forward declaration since our error handler struct accepts a parser for -// each of its function calls. -typedef struct yp_parser yp_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 { - YP_CONTEXT_BEGIN, // a begin statement - YP_CONTEXT_BLOCK_BRACES, // expressions in block arguments using braces - YP_CONTEXT_BLOCK_KEYWORDS, // expressions in block arguments using do..end - YP_CONTEXT_CASE_WHEN, // a case when statements - YP_CONTEXT_CASE_IN, // a case in statements - YP_CONTEXT_CLASS, // a class declaration - YP_CONTEXT_DEF, // a method definition - YP_CONTEXT_DEF_PARAMS, // a method definition's parameters - YP_CONTEXT_DEFAULT_PARAMS, // a method definition's default parameter - YP_CONTEXT_ELSE, // an else clause - YP_CONTEXT_ELSIF, // an elsif clause - YP_CONTEXT_EMBEXPR, // an interpolated expression - YP_CONTEXT_ENSURE, // an ensure statement - YP_CONTEXT_FOR, // a for loop - YP_CONTEXT_IF, // an if statement - YP_CONTEXT_LAMBDA_BRACES, // a lambda expression with braces - YP_CONTEXT_LAMBDA_DO_END, // a lambda expression with do..end - YP_CONTEXT_MAIN, // the top level context - YP_CONTEXT_MODULE, // a module declaration - YP_CONTEXT_PARENS, // a parenthesized expression - YP_CONTEXT_POSTEXE, // an END block - YP_CONTEXT_PREDICATE, // a predicate inside an if/elsif/unless statement - YP_CONTEXT_PREEXE, // a BEGIN block - YP_CONTEXT_RESCUE_ELSE, // a rescue else statement - YP_CONTEXT_RESCUE, // a rescue statement - YP_CONTEXT_SCLASS, // a singleton class definition - YP_CONTEXT_UNLESS, // an unless statement - YP_CONTEXT_UNTIL, // an until statement - YP_CONTEXT_WHILE, // a while statement -} yp_context_t; - -// This is a node in a linked list of contexts. -typedef struct yp_context_node { - yp_context_t context; - struct yp_context_node *prev; -} yp_context_node_t; - -// This is the type of a comment that we've found while parsing. -typedef enum { - YP_COMMENT_INLINE, - YP_COMMENT_EMBDOC, - YP_COMMENT___END__ -} yp_comment_type_t; - -// This is a node in the linked list of comments that we've found while parsing. -typedef struct yp_comment { - yp_list_node_t node; - const uint8_t *start; - const uint8_t *end; - yp_comment_type_t type; -} yp_comment_t; - -// When the encoding that is being used to parse the source is changed by YARP, -// we provide the ability here to call out to a user-defined function. -typedef void (*yp_encoding_changed_callback_t)(yp_parser_t *parser); - -// When an encoding is encountered that isn't understood by YARP, we provide -// the ability here to call out to a user-defined function to get an encoding -// struct. If the function returns something that isn't NULL, we set that to -// our encoding and use it to parse identifiers. -typedef yp_encoding_t *(*yp_encoding_decode_callback_t)(yp_parser_t *parser, const uint8_t *name, size_t width); - -// 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, yp_parser_t *parser, yp_token_t *token); -} yp_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 yp_scope { - // The IDs of the locals in the given scope. - yp_constant_id_list_t locals; - - // 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 pointer to the previous scope in the linked list. - struct yp_scope *previous; -} yp_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 yp_parser { - yp_lex_state_t lex_state; // the current state of the lexer - bool command_start; // whether or not we're at the beginning of a command - int enclosure_nesting; // tracks the current nesting of (), [], and {} - - // 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 - yp_state_stack_t do_loop_stack; - - // the stack used to determine if a do keyword belongs to the beginning of a - // block - yp_state_stack_t accepts_block_stack; - - struct { - yp_lex_mode_t *current; // the current mode of the lexer - yp_lex_mode_t stack[YP_LEX_STACK_SIZE]; // the stack of lexer modes - size_t index; // the current index into the lexer mode stack - } lex_modes; - - const uint8_t *start; // the pointer to the start of the source - const uint8_t *end; // the pointer to the end of the source - yp_token_t previous; // the previous token we were considering - yp_token_t current; // the current token we're considering - - // 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; - - yp_list_t comment_list; // the list of comments that have been found while parsing - yp_list_t warning_list; // the list of warnings that have been found while parsing - yp_list_t error_list; // the list of errors that have been found while parsing - yp_scope_t *current_scope; // the current local scope - - yp_context_node_t *current_context; // the current parsing context - bool recovering; // whether or not we're currently recovering from a syntax error - - // 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. - yp_encoding_t encoding; - - // 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; - - // When the encoding that is being used to parse the source is changed by - // YARP, we provide the ability here to call out to a user-defined function. - yp_encoding_changed_callback_t encoding_changed_callback; - - // When an encoding is encountered that isn't understood by YARP, we provide - // the ability here to call out to a user-defined function to get an - // encoding struct. If the function returns something that isn't NULL, we - // set that to our encoding and use it to parse identifiers. - yp_encoding_decode_callback_t encoding_decode_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. - yp_lex_callback_t *lex_callback; - - // 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; - - // This is the path of the file being parsed - // We use the filepath when constructing SourceFileNodes - yp_string_t filepath_string; - - // This constant pool keeps all of the constants defined throughout the file - // so that we can reference them later. - yp_constant_pool_t constant_pool; - - // This is the list of newline offsets in the source file. - yp_newline_list_t newline_list; -}; - -#endif // YARP_PARSER_H diff --git a/yarp/regexp.c b/yarp/regexp.c deleted file mode 100644 index 2aeadc1bfcfef0..00000000000000 --- a/yarp/regexp.c +++ /dev/null @@ -1,580 +0,0 @@ -#include "yarp/regexp.h" - -// This is the parser that is going to handle parsing regular expressions. -typedef struct { - const uint8_t *start; - const uint8_t *cursor; - const uint8_t *end; - yp_string_list_t *named_captures; - bool encoding_changed; - yp_encoding_t *encoding; -} yp_regexp_parser_t; - -// This initializes a new parser with the given source. -static void -yp_regexp_parser_init(yp_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end, yp_string_list_t *named_captures, bool encoding_changed, yp_encoding_t *encoding) { - *parser = (yp_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 -yp_regexp_parser_named_capture(yp_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - yp_string_t string; - yp_string_shared_init(&string, start, end); - yp_string_list_append(parser->named_captures, &string); - yp_string_free(&string); -} - -// Returns true if the next character is the end of the source. -static inline bool -yp_regexp_char_is_eof(yp_regexp_parser_t *parser) { - return parser->cursor >= parser->end; -} - -// Optionally accept a char and consume it if it exists. -static inline bool -yp_regexp_char_accept(yp_regexp_parser_t *parser, uint8_t value) { - if (!yp_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 -yp_regexp_char_expect(yp_regexp_parser_t *parser, uint8_t value) { - if (!yp_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 -yp_regexp_char_find(yp_regexp_parser_t *parser, uint8_t value) { - if (yp_regexp_char_is_eof(parser)) { - return false; - } - - const uint8_t *end = (const uint8_t *) yp_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 -yp_regexp_parse_range_quantifier(yp_regexp_parser_t *parser) { - const uint8_t *savepoint = parser->cursor; - - enum { - YP_REGEXP_RANGE_QUANTIFIER_STATE_START, - YP_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM, - YP_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM, - YP_REGEXP_RANGE_QUANTIFIER_STATE_COMMA - } state = YP_REGEXP_RANGE_QUANTIFIER_STATE_START; - - while (1) { - switch (state) { - case YP_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 = YP_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM; - break; - case ',': - parser->cursor++; - state = YP_REGEXP_RANGE_QUANTIFIER_STATE_COMMA; - break; - default: - parser->cursor = savepoint; - return true; - } - break; - case YP_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 = YP_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM; - break; - case '}': - parser->cursor++; - return true; - default: - parser->cursor = savepoint; - return true; - } - break; - case YP_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 = YP_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM; - break; - default: - parser->cursor = savepoint; - return true; - } - break; - case YP_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 -// | -// ; -static bool -yp_regexp_parse_quantifier(yp_regexp_parser_t *parser) { - switch (*parser->cursor) { - case '*': - case '+': - case '?': - parser->cursor++; - return true; - case '{': - parser->cursor++; - return yp_regexp_parse_range_quantifier(parser); - default: - // In this case there is no quantifier. - return true; - } -} - -// match-posix-class : '[' '[' ':' '^'? CHAR+ ':' ']' ']' -// ; -static bool -yp_regexp_parse_posix_class(yp_regexp_parser_t *parser) { - if (!yp_regexp_char_expect(parser, ':')) { - return false; - } - - yp_regexp_char_accept(parser, '^'); - - return ( - yp_regexp_char_find(parser, ':') && - yp_regexp_char_expect(parser, ']') && - yp_regexp_char_expect(parser, ']') - ); -} - -// Forward declaration because character sets can be nested. -static bool -yp_regexp_parse_lbracket(yp_regexp_parser_t *parser); - -// match-char-set : '[' '^'? (match-range | match-char)* ']' -// ; -static bool -yp_regexp_parse_character_set(yp_regexp_parser_t *parser) { - yp_regexp_char_accept(parser, '^'); - - while (!yp_regexp_char_is_eof(parser) && *parser->cursor != ']') { - switch (*parser->cursor++) { - case '[': - yp_regexp_parse_lbracket(parser); - break; - case '\\': - if (!yp_regexp_char_is_eof(parser)) { - parser->cursor++; - } - break; - default: - // do nothing, we've already advanced the cursor - break; - } - } - - return yp_regexp_char_expect(parser, ']'); -} - -// A left bracket can either mean a POSIX class or a character set. -static bool -yp_regexp_parse_lbracket(yp_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 (yp_regexp_parse_posix_class(parser)) return true; - - parser->cursor = reset; - } - - return yp_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 -yp_regexp_parse_expression(yp_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 { - YP_REGEXP_OPTION_STATE_INVALID, - YP_REGEXP_OPTION_STATE_TOGGLEABLE, - YP_REGEXP_OPTION_STATE_ADDABLE, - YP_REGEXP_OPTION_STATE_ADDED, - YP_REGEXP_OPTION_STATE_REMOVED -} yp_regexp_option_state_t; - -// These are the options that are configurable on the regular expression (or -// from within a group). -#define YP_REGEXP_OPTION_STATE_SLOT_MINIMUM 'a' -#define YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM 'x' -#define YP_REGEXP_OPTION_STATE_SLOTS (YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM + 1) - -// This is the set of options that are configurable on the regular expression. -typedef struct { - uint8_t values[YP_REGEXP_OPTION_STATE_SLOTS]; -} yp_regexp_options_t; - -// Initialize a new set of options to their default values. -static void -yp_regexp_options_init(yp_regexp_options_t *options) { - memset(options, YP_REGEXP_OPTION_STATE_INVALID, sizeof(uint8_t) * YP_REGEXP_OPTION_STATE_SLOTS); - options->values['i' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; - options->values['m' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; - options->values['x' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_TOGGLEABLE; - options->values['d' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_ADDABLE; - options->values['a' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_REGEXP_OPTION_STATE_ADDABLE; - options->values['u' - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM] = YP_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 -yp_regexp_options_add(yp_regexp_options_t *options, uint8_t key) { - if (key >= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM) { - key = (uint8_t) (key - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM); - - switch (options->values[key]) { - case YP_REGEXP_OPTION_STATE_INVALID: - case YP_REGEXP_OPTION_STATE_REMOVED: - return false; - case YP_REGEXP_OPTION_STATE_TOGGLEABLE: - case YP_REGEXP_OPTION_STATE_ADDABLE: - options->values[key] = YP_REGEXP_OPTION_STATE_ADDED; - return true; - case YP_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 -yp_regexp_options_remove(yp_regexp_options_t *options, uint8_t key) { - if (key >= YP_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= YP_REGEXP_OPTION_STATE_SLOT_MAXIMUM) { - key = (uint8_t) (key - YP_REGEXP_OPTION_STATE_SLOT_MINIMUM); - - switch (options->values[key]) { - case YP_REGEXP_OPTION_STATE_INVALID: - case YP_REGEXP_OPTION_STATE_ADDABLE: - return false; - case YP_REGEXP_OPTION_STATE_TOGGLEABLE: - case YP_REGEXP_OPTION_STATE_ADDED: - case YP_REGEXP_OPTION_STATE_REMOVED: - options->values[key] = YP_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) - 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 -yp_regexp_parse_group(yp_regexp_parser_t *parser) { - // First, parse any options for the group. - if (yp_regexp_char_accept(parser, '?')) { - if (yp_regexp_char_is_eof(parser)) { - return false; - } - yp_regexp_options_t options; - yp_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 = yp_regexp_char_find(parser, ')'); - - while (found && (parser->start <= parser->cursor - 2) && (*(parser->cursor - 2) == '\\')) { - found = yp_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 (yp_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 (!yp_regexp_char_find(parser, '>')) { - return false; - } - yp_regexp_parser_named_capture(parser, start, parser->cursor - 1); - break; - } - } - break; - case '\'': { // named capture group - const uint8_t *start = ++parser->cursor; - if (!yp_regexp_char_find(parser, '\'')) { - return false; - } - - yp_regexp_parser_named_capture(parser, start, parser->cursor - 1); - break; - } - case '(': // conditional expression - if (!yp_regexp_char_find(parser, ')')) { - return false; - } - break; - case 'i': case 'm': case 'x': case 'd': case 'a': case 'u': // options - while (!yp_regexp_char_is_eof(parser) && *parser->cursor != '-' && *parser->cursor != ':' && *parser->cursor != ')') { - if (!yp_regexp_options_add(&options, *parser->cursor)) { - return false; - } - parser->cursor++; - } - - if (yp_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 (!yp_regexp_char_is_eof(parser) && *parser->cursor != ':' && *parser->cursor != ')') { - if (!yp_regexp_options_remove(&options, *parser->cursor)) { - return false; - } - parser->cursor++; - } - - if (yp_regexp_char_is_eof(parser)) { - return false; - } - break; - default: - return false; - } - } - - // Now, parse the expressions within this group. - while (!yp_regexp_char_is_eof(parser) && *parser->cursor != ')') { - if (!yp_regexp_parse_expression(parser)) { - return false; - } - yp_regexp_char_accept(parser, '|'); - } - - // Finally, make sure we have a closing parenthesis. - return yp_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 -yp_regexp_parse_item(yp_regexp_parser_t *parser) { - switch (*parser->cursor++) { - case '^': - case '$': - return true; - case '\\': - if (!yp_regexp_char_is_eof(parser)) { - parser->cursor++; - } - return yp_regexp_parse_quantifier(parser); - case '(': - return yp_regexp_parse_group(parser) && yp_regexp_parse_quantifier(parser); - case '[': - return yp_regexp_parse_lbracket(parser) && yp_regexp_parse_quantifier(parser); - default: - return yp_regexp_parse_quantifier(parser); - } -} - -// expression : item+ -// ; -static bool -yp_regexp_parse_expression(yp_regexp_parser_t *parser) { - if (!yp_regexp_parse_item(parser)) { - return false; - } - - while (!yp_regexp_char_is_eof(parser) && *parser->cursor != ')' && *parser->cursor != '|') { - if (!yp_regexp_parse_item(parser)) { - return false; - } - } - - return true; -} - -// pattern : EOF -// | expression EOF -// | expression '|' pattern -// ; -static bool -yp_regexp_parse_pattern(yp_regexp_parser_t *parser) { - return ( - ( - // Exit early if the pattern is empty. - yp_regexp_char_is_eof(parser) || - // Parse the first expression in the pattern. - yp_regexp_parse_expression(parser) - ) && - ( - // Return now if we've parsed the entire pattern. - yp_regexp_char_is_eof(parser) || - // Otherwise, we should have a pipe character. - (yp_regexp_char_expect(parser, '|') && yp_regexp_parse_pattern(parser)) - ) - ); -} - -// Parse a regular expression and extract the names of all of the named capture -// groups. -YP_EXPORTED_FUNCTION bool -yp_regexp_named_capture_group_names(const uint8_t *source, size_t size, yp_string_list_t *named_captures, bool encoding_changed, yp_encoding_t *encoding) { - yp_regexp_parser_t parser; - yp_regexp_parser_init(&parser, source, source + size, named_captures, encoding_changed, encoding); - return yp_regexp_parse_pattern(&parser); -} diff --git a/yarp/regexp.h b/yarp/regexp.h deleted file mode 100644 index 6807c58398080b..00000000000000 --- a/yarp/regexp.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef YARP_REGEXP_H -#define YARP_REGEXP_H - -#include "yarp/defines.h" -#include "yarp/parser.h" -#include "yarp/enc/yp_encoding.h" -#include "yarp/util/yp_memchr.h" -#include "yarp/util/yp_string_list.h" -#include "yarp/util/yp_string.h" - -#include -#include -#include - -// Parse a regular expression and extract the names of all of the named capture -// groups. -YP_EXPORTED_FUNCTION bool yp_regexp_named_capture_group_names(const uint8_t *source, size_t size, yp_string_list_t *named_captures, bool encoding_changed, yp_encoding_t *encoding); - -#endif diff --git a/yarp/templates/ext/yarp/api_node.c.erb b/yarp/templates/ext/yarp/api_node.c.erb deleted file mode 100644 index a9f5115d7f1f45..00000000000000 --- a/yarp/templates/ext/yarp/api_node.c.erb +++ /dev/null @@ -1,211 +0,0 @@ -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" -#include "yarp/extension.h" - -extern VALUE rb_cYARP; -extern VALUE rb_cYARPNode; -extern VALUE rb_cYARPSource; -extern VALUE rb_cYARPToken; -extern VALUE rb_cYARPLocation; - -<%- nodes.each do |node| -%> -static VALUE rb_cYARP<%= node.name %>; -<%- end -%> - -static VALUE -yp_location_new(yp_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_cYARPLocation); -} - -VALUE -yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding, VALUE source) { - ID type = rb_intern(yp_token_type_to_str(token->type)); - VALUE location = yp_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_cYARPToken); -} - -static VALUE -yp_string_new(yp_string_t *string, rb_encoding *encoding) { - return rb_enc_str_new((const char *) yp_string_source(string), yp_string_length(string), encoding); -} - -// Create a YARP::Source object from the given parser. -VALUE -yp_source_new(yp_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, offsets }; - return rb_class_new_instance(2, source_argv, rb_cYARPSource); -} - -typedef struct yp_node_stack_node { - struct yp_node_stack_node *prev; - yp_node_t *visit; - bool visited; -} yp_node_stack_node_t; - -static void -yp_node_stack_push(yp_node_stack_node_t **stack, yp_node_t *visit) { - yp_node_stack_node_t *node = malloc(sizeof(yp_node_stack_node_t)); - node->prev = *stack; - node->visit = visit; - node->visited = false; - *stack = node; -} - -static yp_node_t * -yp_node_stack_pop(yp_node_stack_node_t **stack) { - yp_node_stack_node_t *current = *stack; - yp_node_t *visit = current->visit; - - *stack = current->prev; - free(current); - - return visit; -} - -VALUE -yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) { - VALUE source = yp_source_new(parser, encoding); - ID *constants = calloc(parser->constant_pool.size, sizeof(ID)); - - for (size_t index = 0; index < parser->constant_pool.capacity; index++) { - yp_constant_t constant = parser->constant_pool.constants[index]; - - if (constant.id != 0) { - constants[constant.id - 1] = rb_intern3((const char *) constant.start, constant.length, encoding); - } - } - - yp_node_stack_node_t *node_stack = NULL; - yp_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) { - yp_node_stack_pop(&node_stack); - rb_ary_push(value_stack, Qnil); - continue; - } - - yp_node_t *node = node_stack->visit; - node_stack->visited = true; - - switch (YP_NODE_TYPE(node)) { - <%- nodes.each do |node| -%> - <%- if node.fields.any? { |field| [YARP::NodeField, YARP::OptionalNodeField, YARP::NodeListField].include?(field.class) } -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - case <%= node.type %>: { - yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node; - <%- node.fields.each do |field| -%> - <%- case field -%> - <%- when YARP::NodeField, YARP::OptionalNodeField -%> - yp_node_stack_push(&node_stack, (yp_node_t *) cast-><%= field.name %>); - <%- when YARP::NodeListField -%> - for (size_t index = 0; index < cast-><%= field.name %>.size; index++) { - yp_node_stack_push(&node_stack, (yp_node_t *) cast-><%= field.name %>.nodes[index]); - } - <%- end -%> - <%- end -%> - break; - } - <%- end -%> - <%- end -%> - default: - break; - } -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - } else { - yp_node_t *node = yp_node_stack_pop(&node_stack); - - switch (YP_NODE_TYPE(node)) { - <%- nodes.each do |node| -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - case <%= node.type %>: { - <%- if node.fields.any? { |field| ![YARP::NodeField, YARP::OptionalNodeField].include?(field.class) } -%> - yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node; - <%- end -%> - VALUE argv[<%= node.fields.length + 1 %>]; - <%- node.fields.each_with_index do |field, index| -%> - - // <%= field.name %> - <%- case field -%> - <%- when YARP::NodeField, YARP::OptionalNodeField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = rb_ary_pop(value_stack); - <%- when YARP::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 YARP::StringField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = yp_string_new(&cast-><%= field.name %>, encoding); - <%- when YARP::ConstantField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - assert(cast-><%= field.name %> != 0); - argv[<%= index %>] = rb_id2sym(constants[cast-><%= field.name %> - 1]); - <%- when YARP::OptionalConstantField -%> - argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : rb_id2sym(constants[cast-><%= field.name %> - 1]); - <%- when YARP::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 YARP::LocationField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = yp_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source); - <%- when YARP::OptionalLocationField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = cast-><%= field.name %>.start == NULL ? Qnil : yp_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source); - <%- when YARP::UInt32Field -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = ULONG2NUM(cast-><%= field.name %>); - <%- when YARP::FlagsField -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - argv[<%= index %>] = ULONG2NUM(node->flags >> <%= YARP::COMMON_FLAGS %>); - <%- else -%> - <%- raise -%> - <%- end -%> - <%- end -%> - - // location - argv[<%= node.fields.length %>] = yp_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_cYARP<%= node.name %>)); - break; - } - <%- end -%> - default: - rb_raise(rb_eRuntimeError, "unknown node type: %d", YP_NODE_TYPE(node)); - } - } - } - - VALUE result = rb_ary_pop(value_stack); - free(constants); - return result; -} - -void -Init_yarp_api_node(void) { - <%- nodes.each do |node| -%> - rb_cYARP<%= node.name %> = rb_define_class_under(rb_cYARP, "<%= node.name %>", rb_cYARPNode); - <%- end -%> -} diff --git a/yarp/templates/include/yarp/ast.h.erb b/yarp/templates/include/yarp/ast.h.erb deleted file mode 100644 index 09841408eb5c33..00000000000000 --- a/yarp/templates/include/yarp/ast.h.erb +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef YARP_AST_H -#define YARP_AST_H - -#include "yarp/defines.h" -#include "yarp/util/yp_constant_pool.h" -#include "yarp/util/yp_string.h" - -#include -#include -#include - -// This enum represents every type of token in the Ruby source. -typedef enum yp_token_type { -<%- tokens.each do |token| -%> - <%= token.declaration %> -<%- end -%> - YP_TOKEN_MAXIMUM, // the maximum token value -} yp_token_type_t; - -// This struct represents a token in the Ruby source. We use it to track both -// type and location information. -typedef struct { - yp_token_type_t type; - const uint8_t *start; - const uint8_t *end; -} yp_token_t; - -// This represents a range of bytes in the source string to which a node or -// token corresponds. -typedef struct { - const uint8_t *start; - const uint8_t *end; -} yp_location_t; - -struct yp_node; - -typedef struct yp_node_list { - struct yp_node **nodes; - size_t size; - size_t capacity; -} yp_node_list_t; - -enum yp_node_type { -<%- nodes.each_with_index do |node, index| -%> - <%= node.type %> = <%= index + 1 %>, -<%- end -%> - YP_SCOPE_NODE -}; - -// Deprecated aliases -#define YP_NODE_SCOPE_NODE YP_SCOPE_NODE -<%- nodes.each do |node| -%> -#define <%= node.type.sub(/^YP_/, 'YP_NODE_') %> <%= node.type %> -<%- end -%> - -typedef uint16_t yp_node_type_t; -typedef uint16_t yp_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. -static const yp_node_flags_t YP_NODE_FLAG_NEWLINE = 0x1; - -// For easy access, we define some macros to check node type -#define YP_NODE_TYPE(node) ((enum yp_node_type)node->type) -#define YP_NODE_TYPE_P(node, type) (YP_NODE_TYPE(node) == (type)) - -// This is the overall tagged union representing a node in the syntax tree. -typedef struct yp_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. - yp_node_type_t type; - - // This represents any flags on the node - yp_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. - yp_location_t location; -} yp_node_t; -<%- nodes.each do |node| -%> - -// <%= node.name %> -// -// Type: <%= node.type %> -<%- if (node_flags = node.fields.find { |field| field.is_a? YARP::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| -%> -// YP_<%= found.human.upcase %>_<%= value.name %> -<%- end -%> -<%- end -%> -typedef struct yp_<%= node.human %> { - yp_node_t base; -<%- node.fields.grep_v(YARP::FlagsField).each do |field| -%> - <%= case field - when YARP::NodeField, YARP::OptionalNodeField then "struct #{field.c_type} *#{field.name}" - when YARP::NodeListField then "struct yp_node_list #{field.name}" - when YARP::ConstantField, YARP::OptionalConstantField then "yp_constant_id_t #{field.name}" - when YARP::ConstantListField then "yp_constant_id_list_t #{field.name}" - when YARP::StringField then "yp_string_t #{field.name}" - when YARP::LocationField, YARP::OptionalLocationField then "yp_location_t #{field.name}" - when YARP::UInt32Field then "uint32_t #{field.name}" - else raise field.class.name - end - %>; -<%- end -%> -} yp_<%= node.human %>_t; -<%- end -%> -<%- flags.each do |flag| -%> - -// <%= flag.name %> -typedef enum { - <%- flag.values.each.with_index(YARP::COMMON_FLAGS) do |value, index| -%> - YP_<%= flag.human.upcase %>_<%= value.name %> = 1 << <%= index %>, - <%- end -%> -} yp_<%= flag.human %>_t; -<%- end -%> - -#endif // YARP_AST_H diff --git a/yarp/templates/lib/yarp/mutation_visitor.rb.erb b/yarp/templates/lib/yarp/mutation_visitor.rb.erb deleted file mode 100644 index 3bb2dfb4b27616..00000000000000 --- a/yarp/templates/lib/yarp/mutation_visitor.rb.erb +++ /dev/null @@ -1,19 +0,0 @@ -module YARP - # 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 MutationVisitor < BasicVisitor - <%- 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| [YARP::NodeField, YARP::OptionalNodeField, YARP::NodeListField].include?(field.class) } -%> - <%- if fields.any? -%> - node.copy(<%= fields.map { |field| "#{field.name}: #{field.is_a?(YARP::NodeListField) ? "visit_all" : "visit"}(node.#{field.name})" }.join(", ") %>) - <%- else -%> - node.copy - <%- end -%> - end - <%- end -%> - end -end diff --git a/yarp/templates/lib/yarp/node.rb.erb b/yarp/templates/lib/yarp/node.rb.erb deleted file mode 100644 index 9cc4495986c0fd..00000000000000 --- a/yarp/templates/lib/yarp/node.rb.erb +++ /dev/null @@ -1,174 +0,0 @@ -module YARP - <%- nodes.each do |node| -%> - <%= "#{node.comment.split("\n").map { |line| line.empty? ? "#" : "# #{line}" }.join("\n ")}\n " if node.comment %>class <%= node.name -%> < Node - <%- node.fields.each do |field| -%> - # attr_reader <%= field.name %>: <%= field.rbs_class %> - 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) - # Never mark <%= node.name %> with a newline flag, mark children instead - end - <%- elsif node.newline.is_a?(String) -%> - - def set_newline_flag(newline_marked) - <%- field = node.fields.find { |f| f.name == node.newline } or raise node.newline -%> - <%- case field -%> - <%- when YARP::NodeField, YARP::OptionalNodeField -%> - <%= field.name %>.set_newline_flag(newline_marked) - <%- when YARP::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 YARP::NodeField, YARP::OptionalNodeField then field.name - when YARP::NodeListField then "*#{field.name}" - end - }.compact.join(", ") %>] - end - - # def comment_targets: () -> Array[Node | Location] - def comment_targets - [<%= node.fields.map { |field| - case field - when YARP::NodeField, YARP::LocationField then field.name - when YARP::OptionalNodeField, YARP::NodeListField, YARP::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 YARP::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 YARP::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 YARP::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.new) - inspector << inspector.header(self) - <%- node.fields.each_with_index do |field, index| -%> - <%- pointer, preadd = index == node.fields.length - 1 ? ["└── ", " "] : ["├── ", "│ "] -%> - <%- case field -%> - <%- when YARP::NodeListField -%> - inspector << "<%= pointer %><%= field.name %>: #{inspector.list("#{inspector.prefix}<%= preadd %>", <%= field.name %>)}" - <%- when YARP::ConstantListField -%> - inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n" - <%- when YARP::NodeField -%> - inspector << "<%= pointer %><%= field.name %>:\n" - inspector << inspector.child_node(<%= field.name %>, "<%= preadd %>") - <%- when YARP::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 YARP::ConstantField, YARP::OptionalConstantField, YARP::StringField, YARP::UInt32Field -%> - inspector << "<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n" - <%- when YARP::FlagsField -%> - <%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise unless flag } -%> - inspector << "<%= pointer %><%= field.name %>: #{[<%= flag.values.map { |value| "(\"#{value.name.downcase}\" if #{value.name.downcase}?)" }.join(", ") %>].compact.join(", ")}\n" - <%- when YARP::LocationField, YARP::OptionalLocationField -%> - inspector << "<%= pointer %><%= field.name %>: #{inspector.location(<%= field.name %>)}\n" - <%- else -%> - <%- raise -%> - <%- end -%> - <%- end -%> - inspector.to_str - end - end - - <%- end -%> - <%- flags.each do |flag| -%> - 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 -%> - class Visitor < BasicVisitor - <%- nodes.each do |node| -%> - # Visit a <%= node.name %> node - alias visit_<%= node.human %> visit_child_nodes -<%= "\n" if node != nodes.last -%> - <%- end -%> - end - - 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/yarp/templates/src/node.c.erb b/yarp/templates/src/node.c.erb deleted file mode 100644 index 9f231239142dcf..00000000000000 --- a/yarp/templates/src/node.c.erb +++ /dev/null @@ -1,149 +0,0 @@ -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" -#include "yarp/node.h" - -// Clear the node but preserves the location. -void yp_node_clear(yp_node_t *node) { - yp_location_t location = node->location; - memset(node, 0, sizeof(yp_node_t)); - node->location = location; -} - -static void -yp_node_memsize_node(yp_node_t *node, yp_memsize_t *memsize); - -// Calculate the size of the node list in bytes. -static size_t -yp_node_list_memsize(yp_node_list_t *node_list, yp_memsize_t *memsize) { - size_t size = sizeof(yp_node_list_t) + (node_list->capacity * sizeof(yp_node_t *)); - for (size_t index = 0; index < node_list->size; index++) { - yp_node_memsize_node(node_list->nodes[index], memsize); - } - return size; -} - -// Append a new node onto the end of the node list. -void -yp_node_list_append(yp_node_list_t *list, yp_node_t *node) { - if (list->size == list->capacity) { - list->capacity = list->capacity == 0 ? 4 : list->capacity * 2; - list->nodes = (yp_node_t **) realloc(list->nodes, sizeof(yp_node_t *) * list->capacity); - } - list->nodes[list->size++] = node; -} - -YP_EXPORTED_FUNCTION void -yp_node_destroy(yp_parser_t *parser, yp_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 -yp_node_list_free(yp_parser_t *parser, yp_node_list_t *list) { - if (list->capacity > 0) { - for (size_t index = 0; index < list->size; index++) { - yp_node_destroy(parser, list->nodes[index]); - } - free(list->nodes); - } -} - -// Deallocate the space for a yp_node_t. Similarly to yp_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. -YP_EXPORTED_FUNCTION void -yp_node_destroy(yp_parser_t *parser, yp_node_t *node) { - switch (YP_NODE_TYPE(node)) { - <%- nodes.each do |node| -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - case <%= node.type %>: { - <%- if node.fields.any? { |field| ![YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField, YARP::OptionalConstantField].include?(field.class) } -%> - yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node; - <%- end -%> - <%- node.fields.each do |field| -%> - <%- case field -%> - <%- when YARP::LocationField, YARP::OptionalLocationField, YARP::UInt32Field, YARP::FlagsField, YARP::ConstantField, YARP::OptionalConstantField -%> - <%- when YARP::NodeField -%> - yp_node_destroy(parser, (yp_node_t *)cast-><%= field.name %>); - <%- when YARP::OptionalNodeField -%> - if (cast-><%= field.name %> != NULL) { - yp_node_destroy(parser, (yp_node_t *)cast-><%= field.name %>); - } - <%- when YARP::StringField -%> - yp_string_free(&cast-><%= field.name %>); - <%- when YARP::NodeListField -%> - yp_node_list_free(parser, &cast-><%= field.name %>); - <%- when YARP::ConstantListField -%> - yp_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 -yp_node_memsize_node(yp_node_t *node, yp_memsize_t *memsize) { - memsize->node_count++; - - switch (YP_NODE_TYPE(node)) { - // We do not calculate memsize of a ScopeNode - // as it should never be generated - case YP_SCOPE_NODE: - return; - <%- nodes.each do |node| -%> -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" - case <%= node.type %>: { - yp_<%= node.human %>_t *cast = (yp_<%= node.human %>_t *) node; - memsize->memsize += sizeof(*cast); - <%- node.fields.each do |field| -%> - <%- case field -%> - <%- when YARP::ConstantField, YARP::OptionalConstantField, YARP::UInt32Field, YARP::FlagsField, YARP::LocationField, YARP::OptionalLocationField -%> - <%- when YARP::NodeField -%> - yp_node_memsize_node((yp_node_t *)cast-><%= field.name %>, memsize); - <%- when YARP::OptionalNodeField -%> - if (cast-><%= field.name %> != NULL) { - yp_node_memsize_node((yp_node_t *)cast-><%= field.name %>, memsize); - } - <%- when YARP::StringField -%> - memsize->memsize += yp_string_memsize(&cast-><%= field.name %>); - <%- when YARP::NodeListField -%> - yp_node_list_memsize(&cast-><%= field.name %>, memsize); - <%- when YARP::ConstantListField -%> - memsize->memsize += yp_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. -YP_EXPORTED_FUNCTION void -yp_node_memsize(yp_node_t *node, yp_memsize_t *memsize) { - *memsize = (yp_memsize_t) { .memsize = 0, .node_count = 0 }; - yp_node_memsize_node(node, memsize); -} - -// Returns a string representation of the given node type. -YP_EXPORTED_FUNCTION const char * -yp_node_type_to_str(yp_node_type_t node_type) -{ - switch (node_type) { -<%- nodes.each do |node| -%> - case <%= node.type %>: - return "<%= node.type %>"; -<%- end -%> - } - return ""; -} diff --git a/yarp/templates/src/prettyprint.c.erb b/yarp/templates/src/prettyprint.c.erb deleted file mode 100644 index 796d8ccafb9dd0..00000000000000 --- a/yarp/templates/src/prettyprint.c.erb +++ /dev/null @@ -1,111 +0,0 @@ -#include "yarp/defines.h" - -#include - -#include "yarp/ast.h" -#include "yarp/parser.h" -#include "yarp/util/yp_buffer.h" - -static void -prettyprint_location(yp_buffer_t *buffer, yp_parser_t *parser, yp_location_t *location) { - char printed[] = "[0000-0000]"; - snprintf(printed, sizeof(printed), "[%04ld-%04ld]", (long int)(location->start - parser->start), (long int)(location->end - parser->start)); - yp_buffer_append_str(buffer, printed, strlen(printed)); -} - -static void -prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { - switch (YP_NODE_TYPE(node)) { - // We do not need to print a ScopeNode as it's not part - // of the AST - case YP_SCOPE_NODE: - return; - <%- nodes.each do |node| -%> - case <%= node.type %>: { - yp_buffer_append_str(buffer, "<%= node.name %>(", <%= node.name.length + 1 %>); - <%- node.fields.each_with_index do |field, index| -%> - <%= "yp_buffer_append_str(buffer, \", \", 2);" if index != 0 -%> - <%- case field -%> - <%- when YARP::NodeField -%> - prettyprint_node(buffer, parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= field.name %>); - <%- when YARP::OptionalNodeField -%> - if (((yp_<%= node.human %>_t *)node)-><%= field.name %> == NULL) { - yp_buffer_append_str(buffer, "nil", 3); - } else { - prettyprint_node(buffer, parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= field.name %>); - } - <%- when YARP::StringField -%> - yp_buffer_append_str(buffer, "\"", 1); - yp_buffer_append_bytes(buffer, yp_string_source(&((yp_<%= node.human %>_t *)node)-><%= field.name %>), yp_string_length(&((yp_<%= node.human %>_t *)node)-><%= field.name %>)); - yp_buffer_append_str(buffer, "\"", 1); - <%- when YARP::NodeListField -%> - yp_buffer_append_str(buffer, "[", 1); - for (uint32_t index = 0; index < ((yp_<%= node.human %>_t *)node)-><%= field.name %>.size; index++) { - if (index != 0) yp_buffer_append_str(buffer, ", ", 2); - prettyprint_node(buffer, parser, (yp_node_t *) ((yp_<%= node.human %>_t *) node)-><%= field.name %>.nodes[index]); - } - yp_buffer_append_str(buffer, "]", 1); - <%- when YARP::ConstantField -%> - char <%= field.name %>_buffer[12]; - snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((yp_<%= node.human %>_t *)node)-><%= field.name %>); - yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); - <%- when YARP::OptionalConstantField -%> - if (((yp_<%= node.human %>_t *)node)-><%= field.name %> == 0) { - yp_buffer_append_str(buffer, "nil", 3); - } else { - char <%= field.name %>_buffer[12]; - snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((yp_<%= node.human %>_t *)node)-><%= field.name %>); - yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); - } - <%- when YARP::ConstantListField -%> - yp_buffer_append_str(buffer, "[", 1); - for (uint32_t index = 0; index < ((yp_<%= node.human %>_t *)node)-><%= field.name %>.size; index++) { - if (index != 0) yp_buffer_append_str(buffer, ", ", 2); - char <%= field.name %>_buffer[12]; - snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "%u", ((yp_<%= node.human %>_t *)node)-><%= field.name %>.ids[index]); - yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); - } - yp_buffer_append_str(buffer, "]", 1); - <%- when YARP::LocationField -%> - prettyprint_location(buffer, parser, &((yp_<%= node.human %>_t *)node)-><%= field.name %>); - <%- when YARP::OptionalLocationField -%> - if (((yp_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) { - yp_buffer_append_str(buffer, "nil", 3); - } else { - prettyprint_location(buffer, parser, &((yp_<%= node.human %>_t *)node)-><%= field.name %>); - } - <%- when YARP::UInt32Field -%> - char <%= field.name %>_buffer[12]; - snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "+%d", ((yp_<%= node.human %>_t *)node)-><%= field.name %>); - yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); - <%- when YARP::FlagsField -%> - char <%= field.name %>_buffer[12]; - snprintf(<%= field.name %>_buffer, sizeof(<%= field.name %>_buffer), "+%d", node->flags >> <%= YARP::COMMON_FLAGS %>); - yp_buffer_append_str(buffer, <%= field.name %>_buffer, strlen(<%= field.name %>_buffer)); - <%- else -%> - <%- raise -%> - <%- end -%> - <%- end -%> - yp_buffer_append_str(buffer, ")", 1); - break; - } - <%- end -%> - } -} - -void -yp_print_node(yp_parser_t *parser, yp_node_t *node) { - yp_buffer_t buffer; - if (!yp_buffer_init(&buffer)) return; - - prettyprint_node(&buffer, parser, node); - printf("%.*s\n", (int) buffer.length, buffer.value); - - yp_buffer_free(&buffer); -} - -// Pretty-prints the AST represented by the given node to the given buffer. -YP_EXPORTED_FUNCTION void -yp_prettyprint(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) { - prettyprint_node(buffer, parser, node); -} diff --git a/yarp/templates/src/serialize.c.erb b/yarp/templates/src/serialize.c.erb deleted file mode 100644 index b60bce21138acc..00000000000000 --- a/yarp/templates/src/serialize.c.erb +++ /dev/null @@ -1,295 +0,0 @@ -#include "yarp.h" - -#include - -static inline uint32_t -yp_ptrdifft_to_u32(ptrdiff_t value) { - assert(value >= 0 && ((unsigned long) value) < UINT32_MAX); - return (uint32_t) value; -} - -static inline uint32_t -yp_sizet_to_u32(size_t value) { - assert(value < UINT32_MAX); - return (uint32_t) value; -} - -static void -yp_serialize_location(yp_parser_t *parser, yp_location_t *location, yp_buffer_t *buffer) { - assert(location->start); - assert(location->end); - assert(location->start <= location->end); - - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(location->start - parser->start)); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(location->end - location->start)); -} - -static void -yp_serialize_string(yp_parser_t *parser, yp_string_t *string, yp_buffer_t *buffer) { - switch (string->type) { - case YP_STRING_SHARED: { - yp_buffer_append_u8(buffer, 1); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(yp_string_source(string) - parser->start)); - yp_buffer_append_u32(buffer, yp_sizet_to_u32(yp_string_length(string))); - break; - } - case YP_STRING_OWNED: - case YP_STRING_CONSTANT: { - uint32_t length = yp_sizet_to_u32(yp_string_length(string)); - yp_buffer_append_u8(buffer, 2); - yp_buffer_append_u32(buffer, length); - yp_buffer_append_bytes(buffer, yp_string_source(string), length); - break; - } - case YP_STRING_MAPPED: - assert(false && "Cannot serialize mapped strings."); - break; - } -} - -void -yp_serialize_node(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) { - yp_buffer_append_u8(buffer, (uint8_t) YP_NODE_TYPE(node)); - - size_t offset = buffer->length; - - yp_serialize_location(parser, &node->location, buffer); - - switch (YP_NODE_TYPE(node)) { - // We do not need to serialize a ScopeNode ever as - // it is not part of the AST - case YP_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; - yp_buffer_append_str(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */ - <%- end -%> - <%- node.fields.each do |field| -%> - <%- case field -%> - <%- when YARP::NodeField -%> - yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= field.name %>, buffer); - <%- when YARP::OptionalNodeField -%> - if (((yp_<%= node.human %>_t *)node)-><%= field.name %> == NULL) { - yp_buffer_append_u8(buffer, 0); - } else { - yp_serialize_node(parser, (yp_node_t *)((yp_<%= node.human %>_t *)node)-><%= field.name %>, buffer); - } - <%- when YARP::StringField -%> - yp_serialize_string(parser, &((yp_<%= node.human %>_t *)node)-><%= field.name %>, buffer); - <%- when YARP::NodeListField -%> - uint32_t <%= field.name %>_size = yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>.size); - yp_buffer_append_u32(buffer, <%= field.name %>_size); - for (uint32_t index = 0; index < <%= field.name %>_size; index++) { - yp_serialize_node(parser, (yp_node_t *) ((yp_<%= node.human %>_t *)node)-><%= field.name %>.nodes[index], buffer); - } - <%- when YARP::ConstantField, YARP::OptionalConstantField -%> - yp_buffer_append_u32(buffer, yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>)); - <%- when YARP::ConstantListField -%> - uint32_t <%= field.name %>_size = yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>.size); - yp_buffer_append_u32(buffer, <%= field.name %>_size); - for (uint32_t index = 0; index < <%= field.name %>_size; index++) { - yp_buffer_append_u32(buffer, yp_sizet_to_u32(((yp_<%= node.human %>_t *)node)-><%= field.name %>.ids[index])); - } - <%- when YARP::LocationField -%> - yp_serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= field.name %>, buffer); - <%- when YARP::OptionalLocationField -%> - if (((yp_<%= node.human %>_t *)node)-><%= field.name %>.start == NULL) { - yp_buffer_append_u8(buffer, 0); - } else { - yp_buffer_append_u8(buffer, 1); - yp_serialize_location(parser, &((yp_<%= node.human %>_t *)node)-><%= field.name %>, buffer); - } - <%- when YARP::UInt32Field -%> - yp_buffer_append_u32(buffer, ((yp_<%= node.human %>_t *)node)-><%= field.name %>); - <%- when YARP::FlagsField -%> - yp_buffer_append_u32(buffer, node->flags >> <%= YARP::COMMON_FLAGS %>); - <%- else -%> - <%- raise -%> - <%- end -%> - <%- end -%> - <%- if node.needs_serialized_length? -%> - // serialize length - uint32_t length = yp_sizet_to_u32(buffer->length - offset - sizeof(uint32_t)); - memcpy(buffer->value + length_offset, &length, sizeof(uint32_t)); - <%- end -%> - break; - } - <%- end -%> - } -} - -static void -yp_serialize_comment(yp_parser_t *parser, yp_comment_t *comment, yp_buffer_t *buffer) { - // serialize type - yp_buffer_append_u8(buffer, (uint8_t) comment->type); - - // serialize location - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(comment->start - parser->start)); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(comment->end - comment->start)); -} - -static void -yp_serialize_comment_list(yp_parser_t *parser, yp_list_t *list, yp_buffer_t *buffer) { - yp_buffer_append_u32(buffer, yp_sizet_to_u32(yp_list_size(list))); - - yp_comment_t *comment; - for (comment = (yp_comment_t *) list->head; comment != NULL; comment = (yp_comment_t *) comment->node.next) { - yp_serialize_comment(parser, comment, buffer); - } -} - -static void -yp_serialize_diagnostic(yp_parser_t *parser, yp_diagnostic_t *diagnostic, yp_buffer_t *buffer) { - // serialize message - size_t message_length = strlen(diagnostic->message); - yp_buffer_append_u32(buffer, yp_sizet_to_u32(message_length)); - yp_buffer_append_str(buffer, diagnostic->message, message_length); - - // serialize location - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(diagnostic->start - parser->start)); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(diagnostic->end - diagnostic->start)); -} - -static void -yp_serialize_diagnostic_list(yp_parser_t *parser, yp_list_t *list, yp_buffer_t *buffer) { - yp_buffer_append_u32(buffer, yp_sizet_to_u32(yp_list_size(list))); - - yp_diagnostic_t *diagnostic; - for (diagnostic = (yp_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (yp_diagnostic_t *) diagnostic->node.next) { - yp_serialize_diagnostic(parser, diagnostic, buffer); - } -} - -static void -yp_serialize_encoding(yp_encoding_t *encoding, yp_buffer_t *buffer) { - size_t encoding_length = strlen(encoding->name); - yp_buffer_append_u32(buffer, yp_sizet_to_u32(encoding_length)); - yp_buffer_append_str(buffer, encoding->name, encoding_length); -} - -#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" -void -yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) { - yp_serialize_encoding(&parser->encoding, buffer); - yp_serialize_comment_list(parser, &parser->comment_list, buffer); - yp_serialize_diagnostic_list(parser, &parser->error_list, buffer); - yp_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; - yp_buffer_append_zeroes(buffer, 4); - - // Next, encode the length of the constant pool. - yp_buffer_append_u32(buffer, yp_sizet_to_u32(parser->constant_pool.size)); - - // Now we're going to serialize the content of the node. - yp_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 = yp_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; - yp_buffer_append_zeroes(buffer, parser->constant_pool.size * 8); - - yp_constant_t *constant; - for (size_t index = 0; index < parser->constant_pool.capacity; index++) { - constant = &parser->constant_pool.constants[index]; - - // If we find a constant at this index, serialize it at the correct - // index in the buffer. - if (constant->id != 0) { - size_t buffer_offset = offset + ((((size_t) constant->id) - 1) * 8); - - if (constant->owned) { - // Since this is an owned 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 = yp_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); - yp_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 = yp_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 = yp_sizet_to_u32(constant->length); - memcpy(buffer->value + buffer_offset + 4, &constant_length, 4); - } - } -} - -static void -serialize_token(void *data, yp_parser_t *parser, yp_token_t *token) { - yp_buffer_t *buffer = (yp_buffer_t *) data; - - yp_buffer_append_u32(buffer, token->type); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(token->start - parser->start)); - yp_buffer_append_u32(buffer, yp_ptrdifft_to_u32(token->end - token->start)); - yp_buffer_append_u32(buffer, parser->lex_state); -} - -YP_EXPORTED_FUNCTION void -yp_lex_serialize(const uint8_t *source, size_t size, const char *filepath, yp_buffer_t *buffer) { - yp_parser_t parser; - yp_parser_init(&parser, source, size, filepath); - - yp_lex_callback_t lex_callback = (yp_lex_callback_t) { - .data = (void *) buffer, - .callback = serialize_token, - }; - - parser.lex_callback = &lex_callback; - yp_node_t *node = yp_parse(&parser); - - // Append 0 to mark end of tokens - yp_buffer_append_u8(buffer, 0); - - yp_serialize_encoding(&parser.encoding, buffer); - yp_serialize_comment_list(&parser, &parser.comment_list, buffer); - yp_serialize_diagnostic_list(&parser, &parser.error_list, buffer); - yp_serialize_diagnostic_list(&parser, &parser.warning_list, buffer); - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); -} - -// Parse and serialize both the AST and the tokens represented by the given -// source to the given buffer. -YP_EXPORTED_FUNCTION void -yp_parse_lex_serialize(const uint8_t *source, size_t size, yp_buffer_t *buffer, const char *metadata) { - yp_parser_t parser; - yp_parser_init(&parser, source, size, NULL); - if (metadata) yp_parser_metadata(&parser, metadata); - - yp_lex_callback_t lex_callback = (yp_lex_callback_t) { - .data = (void *) buffer, - .callback = serialize_token, - }; - - parser.lex_callback = &lex_callback; - yp_node_t *node = yp_parse(&parser); - - yp_buffer_append_u8(buffer, 0); - yp_serialize(&parser, node, buffer); - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); -} diff --git a/yarp/templates/src/token_type.c.erb b/yarp/templates/src/token_type.c.erb deleted file mode 100644 index d861352eec9a9c..00000000000000 --- a/yarp/templates/src/token_type.c.erb +++ /dev/null @@ -1,18 +0,0 @@ -#include - -#include "yarp/ast.h" - -// Returns a string representation of the given token type. -YP_EXPORTED_FUNCTION const char * -yp_token_type_to_str(yp_token_type_t token_type) -{ - switch (token_type) { -<%- tokens.each do |token| -%> - case YP_TOKEN_<%= token.name %>: - return "<%= token.name %>"; -<%- end -%> - case YP_TOKEN_MAXIMUM: - return "MAXIMUM"; - } - return "\0"; -} diff --git a/yarp/unescape.c b/yarp/unescape.c deleted file mode 100644 index 9da52eaea9c6e9..00000000000000 --- a/yarp/unescape.c +++ /dev/null @@ -1,618 +0,0 @@ -#include "yarp.h" - -/******************************************************************************/ -/* Character checks */ -/******************************************************************************/ - -static inline bool -yp_char_is_hexadecimal_digits(const uint8_t *string, size_t length) { - for (size_t index = 0; index < length; index++) { - if (!yp_char_is_hexadecimal_digit(string[index])) { - return false; - } - } - return true; -} - -// We don't call the char_width function unless we have to because it's -// expensive to go through the indirection of the function pointer. Instead we -// provide a fast path that will check if we can just return 1. -static inline size_t -yp_char_width(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - if (parser->encoding_changed || (*start >= 0x80)) { - return parser->encoding.char_width(start, end - start); - } else { - return 1; - } -} - -/******************************************************************************/ -/* Lookup tables for characters */ -/******************************************************************************/ - -// This is a lookup table for unescapes that only take up a single character. -static const uint8_t unescape_chars[] = { - ['\''] = '\'', - ['\\'] = '\\', - ['a'] = '\a', - ['b'] = '\b', - ['e'] = '\033', - ['f'] = '\f', - ['n'] = '\n', - ['r'] = '\r', - ['s'] = ' ', - ['t'] = '\t', - ['v'] = '\v' -}; - -// 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]; -} - -/******************************************************************************/ -/* Unescaping for segments */ -/******************************************************************************/ - -// Scan the 1-3 digits of octal into the value. Returns the number of digits -// scanned. -static inline size_t -unescape_octal(const uint8_t *backslash, uint8_t *value, const uint8_t *end) { - *value = (uint8_t) (backslash[1] - '0'); - if (backslash + 2 >= end || !yp_char_is_octal_digit(backslash[2])) { - return 2; - } - *value = (uint8_t) ((*value << 3) | (backslash[2] - '0')); - if (backslash + 3 >= end || !yp_char_is_octal_digit(backslash[3])) { - return 3; - } - *value = (uint8_t) ((*value << 3) | (backslash[3] - '0')); - return 4; -} - -// Convert a hexadecimal digit into its equivalent value. -static inline uint8_t -unescape_hexadecimal_digit(const uint8_t value) { - return (uint8_t) ((value <= '9') ? (value - '0') : (value & 0x7) + 9); -} - -// Scan the 1-2 digits of hexadecimal into the value. Returns the number of -// digits scanned. -static inline size_t -unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end, yp_list_t *error_list) { - *value = 0; - if (backslash + 2 >= end || !yp_char_is_hexadecimal_digit(backslash[2])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_HEXADECIMAL); - return 2; - } - *value = unescape_hexadecimal_digit(backslash[2]); - if (backslash + 3 >= end || !yp_char_is_hexadecimal_digit(backslash[3])) { - return 3; - } - *value = (uint8_t) ((*value << 4) | unescape_hexadecimal_digit(backslash[3])); - return 4; -} - -// 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 void -unescape_unicode(const uint8_t *string, size_t length, uint32_t *value) { - *value = 0; - for (size_t index = 0; index < length; index++) { - if (index != 0) *value <<= 4; - *value |= unescape_hexadecimal_digit(string[index]); - } -} - -// Accepts the pointer to the string to write the unicode value along with the -// 32-bit value to write. Writes the UTF-8 representation of the value to the -// string and returns the number of bytes written. -static inline size_t -unescape_unicode_write(uint8_t *dest, uint32_t value, const uint8_t *start, const uint8_t *end, yp_list_t *error_list) { - if (value <= 0x7F) { - // 0xxxxxxx - dest[0] = (uint8_t) value; - return 1; - } - - if (value <= 0x7FF) { - // 110xxxxx 10xxxxxx - dest[0] = (uint8_t) (0xC0 | (value >> 6)); - dest[1] = (uint8_t) (0x80 | (value & 0x3F)); - return 2; - } - - if (value <= 0xFFFF) { - // 1110xxxx 10xxxxxx 10xxxxxx - dest[0] = (uint8_t) (0xE0 | (value >> 12)); - dest[1] = (uint8_t) (0x80 | ((value >> 6) & 0x3F)); - dest[2] = (uint8_t) (0x80 | (value & 0x3F)); - return 3; - } - - // At this point it must be a 4 digit UTF-8 representation. If it's not, then - // the input is invalid. - if (value <= 0x10FFFF) { - // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx - dest[0] = (uint8_t) (0xF0 | (value >> 18)); - dest[1] = (uint8_t) (0x80 | ((value >> 12) & 0x3F)); - dest[2] = (uint8_t) (0x80 | ((value >> 6) & 0x3F)); - dest[3] = (uint8_t) (0x80 | (value & 0x3F)); - return 4; - } - - // If we get here, then the value is too big. This is an error, but we don't - // want to just crash, so instead we'll add an error to the error list and put - // in a replacement character instead. - if (error_list) yp_diagnostic_list_append(error_list, start, end, YP_ERR_ESCAPE_INVALID_UNICODE); - dest[0] = 0xEF; - dest[1] = 0xBF; - dest[2] = 0xBD; - return 3; -} - -typedef enum { - YP_UNESCAPE_FLAG_NONE = 0, - YP_UNESCAPE_FLAG_CONTROL = 1, - YP_UNESCAPE_FLAG_META = 2, - YP_UNESCAPE_FLAG_EXPECT_SINGLE = 4 -} yp_unescape_flag_t; - -// Unescape a single character value based on the given flags. -static inline uint8_t -unescape_char(uint8_t value, const uint8_t flags) { - if (flags & YP_UNESCAPE_FLAG_CONTROL) { - value &= 0x1f; - } - - if (flags & YP_UNESCAPE_FLAG_META) { - value |= 0x80; - } - - return value; -} - -// Read a specific escape sequence into the given destination. -static const uint8_t * -unescape( - yp_parser_t *parser, - uint8_t *dest, - size_t *dest_length, - const uint8_t *backslash, - const uint8_t *end, - const uint8_t flags, - yp_list_t *error_list -) { - switch (backslash[1]) { - case 'a': - case 'b': - case 'e': - case 'f': - case 'n': - case 'r': - case 's': - case 't': - case 'v': - if (dest) { - dest[(*dest_length)++] = unescape_char(unescape_chars[backslash[1]], flags); - } - return backslash + 2; - // \nnn octal bit pattern, where nnn is 1-3 octal digits ([0-7]) - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - uint8_t value; - const uint8_t *cursor = backslash + unescape_octal(backslash, &value, end); - - if (dest) { - dest[(*dest_length)++] = unescape_char(value, flags); - } - return cursor; - } - // \xnn hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F]) - case 'x': { - uint8_t value; - const uint8_t *cursor = backslash + unescape_hexadecimal(backslash, &value, end, error_list); - - if (dest) { - dest[(*dest_length)++] = unescape_char(value, flags); - } - return cursor; - } - // \u{nnnn ...} Unicode character(s), where each nnnn is 1-6 hexadecimal digits ([0-9a-fA-F]) - // \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F]) - case 'u': { - if ((flags & YP_UNESCAPE_FLAG_CONTROL) | (flags & YP_UNESCAPE_FLAG_META)) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS); - return backslash + 2; - } - - if ((backslash + 3) < end && backslash[2] == '{') { - const uint8_t *unicode_cursor = backslash + 3; - const uint8_t *extra_codepoints_start = NULL; - int codepoints_count = 0; - - unicode_cursor += yp_strspn_whitespace(unicode_cursor, end - unicode_cursor); - - while ((unicode_cursor < end) && (*unicode_cursor != '}')) { - const uint8_t *unicode_start = unicode_cursor; - size_t hexadecimal_length = yp_strspn_hexadecimal_digit(unicode_cursor, end - unicode_cursor); - - // \u{nnnn} character literal allows only 1-6 hexadecimal digits - if (hexadecimal_length > 6) { - if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE_LONG); - } - // there are not hexadecimal characters - else if (hexadecimal_length == 0) { - if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE); - return unicode_cursor; - } - - unicode_cursor += hexadecimal_length; - - codepoints_count++; - if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count == 2) - extra_codepoints_start = unicode_start; - - uint32_t value; - unescape_unicode(unicode_start, (size_t) (unicode_cursor - unicode_start), &value); - if (dest) { - *dest_length += unescape_unicode_write(dest + *dest_length, value, unicode_start, unicode_cursor, error_list); - } - - unicode_cursor += yp_strspn_whitespace(unicode_cursor, end - unicode_cursor); - } - - // ?\u{nnnn} character literal should contain only one codepoint and cannot be like ?\u{nnnn mmmm} - if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1) { - if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL); - } - - if (unicode_cursor < end && *unicode_cursor == '}') { - unicode_cursor++; - } else { - if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, YP_ERR_ESCAPE_INVALID_UNICODE_TERM); - } - - return unicode_cursor; - } - else if ((backslash + 5) < end && yp_char_is_hexadecimal_digits(backslash + 2, 4)) { - uint32_t value; - unescape_unicode(backslash + 2, 4, &value); - - if (dest) { - *dest_length += unescape_unicode_write(dest + *dest_length, value, backslash + 2, backslash + 6, error_list); - } - return backslash + 6; - } - - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE); - return backslash + 2; - } - // \c\M-x meta control character, where x is an ASCII printable character - // \c? delete, ASCII 7Fh (DEL) - // \cx control character, where x is an ASCII printable character - case 'c': - if (backslash + 2 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); - return end; - } - - if (flags & YP_UNESCAPE_FLAG_CONTROL) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT); - return backslash + 2; - } - - switch (backslash[2]) { - case '\\': - return unescape(parser, dest, dest_length, backslash + 2, end, flags | YP_UNESCAPE_FLAG_CONTROL, error_list); - case '?': - if (dest) { - dest[(*dest_length)++] = unescape_char(0x7f, flags); - } - return backslash + 3; - default: { - if (!char_is_ascii_printable(backslash[2])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); - return backslash + 2; - } - - if (dest) { - dest[(*dest_length)++] = unescape_char(backslash[2], flags | YP_UNESCAPE_FLAG_CONTROL); - } - return backslash + 3; - } - } - // \C-x control character, where x is an ASCII printable character - // \C-? delete, ASCII 7Fh (DEL) - case 'C': - if (backslash + 3 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); - return end; - } - - if (flags & YP_UNESCAPE_FLAG_CONTROL) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT); - return backslash + 2; - } - - if (backslash[2] != '-') { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); - return backslash + 2; - } - - switch (backslash[3]) { - case '\\': - return unescape(parser, dest, dest_length, backslash + 3, end, flags | YP_UNESCAPE_FLAG_CONTROL, error_list); - case '?': - if (dest) { - dest[(*dest_length)++] = unescape_char(0x7f, flags); - } - return backslash + 4; - default: - if (!char_is_ascii_printable(backslash[3])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_CONTROL); - return backslash + 2; - } - - if (dest) { - dest[(*dest_length)++] = unescape_char(backslash[3], flags | YP_UNESCAPE_FLAG_CONTROL); - } - return backslash + 4; - } - // \M-\C-x meta control character, where x is an ASCII printable character - // \M-\cx meta control character, where x is an ASCII printable character - // \M-x meta character, where x is an ASCII printable character - case 'M': { - if (backslash + 3 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_META); - return end; - } - - if (flags & YP_UNESCAPE_FLAG_META) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META_REPEAT); - return backslash + 2; - } - - if (backslash[2] != '-') { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META); - return backslash + 2; - } - - if (backslash[3] == '\\') { - return unescape(parser, dest, dest_length, backslash + 3, end, flags | YP_UNESCAPE_FLAG_META, error_list); - } - - if (char_is_ascii_printable(backslash[3])) { - if (dest) { - dest[(*dest_length)++] = unescape_char(backslash[3], flags | YP_UNESCAPE_FLAG_META); - } - return backslash + 4; - } - - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META); - return backslash + 3; - } - // \n - case '\n': - return backslash + 2; - // \r - case '\r': - if (backslash + 2 < end && backslash[2] == '\n') { - return backslash + 3; - } - /* fallthrough */ - // In this case we're escaping something that doesn't need escaping. - default: { - size_t width = yp_char_width(parser, backslash + 1, end); - - if (dest) { - memcpy(dest + *dest_length, backslash + 1, width); - *dest_length += width; - } - - return backslash + 1 + width; - } - } -} - -/******************************************************************************/ -/* Public functions and entrypoints */ -/******************************************************************************/ - -// Unescape the contents of the given token into the given string using the -// given unescape mode. The supported escapes are: -// -// \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 void -yp_unescape_manipulate_string_or_char_literal(yp_parser_t *parser, yp_string_t *string, yp_unescape_type_t unescape_type, bool expect_single_codepoint) { - if (unescape_type == YP_UNESCAPE_NONE) { - // If we're not unescaping then we can reference the source directly. - return; - } - - const uint8_t *backslash = yp_memchr(string->source, '\\', string->length, parser->encoding_changed, &parser->encoding); - - if (backslash == NULL) { - // Here there are no escapes, so we can reference the source directly. - return; - } - - // Here we have found an escape character, so we need to handle all escapes - // within the string. - uint8_t *allocated = malloc(string->length); - if (allocated == NULL) { - yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, YP_ERR_MALLOC_FAILED); - return; - } - - // This is the memory address where we're putting the unescaped string. - uint8_t *dest = allocated; - size_t dest_length = 0; - - // This is the current position in the source string that we're looking at. - // It's going to move along behind the backslash so that we can copy each - // segment of the string that doesn't contain an escape. - const uint8_t *cursor = string->source; - const uint8_t *end = string->source + string->length; - - // For each escape found in the source string, we will handle it and update - // the moving cursor->backslash window. - while (backslash != NULL && backslash + 1 < end) { - assert(dest_length < string->length); - - // This is the size of the segment of the string from the previous escape - // or the start of the string to the current escape. - size_t segment_size = (size_t) (backslash - cursor); - - // Here we're going to copy everything up until the escape into the - // destination buffer. - memcpy(dest + dest_length, cursor, segment_size); - dest_length += segment_size; - - switch (backslash[1]) { - case '\\': - case '\'': - dest[dest_length++] = unescape_chars[backslash[1]]; - cursor = backslash + 2; - break; - default: - if (unescape_type == YP_UNESCAPE_MINIMAL) { - // In this case we're escaping something that doesn't need escaping. - dest[dest_length++] = '\\'; - cursor = backslash + 1; - break; - } - - // This is the only type of unescaping left. In this case we need to - // handle all of the different unescapes. - assert(unescape_type == YP_UNESCAPE_ALL); - - uint8_t flags = YP_UNESCAPE_FLAG_NONE; - if (expect_single_codepoint) { - flags |= YP_UNESCAPE_FLAG_EXPECT_SINGLE; - } - - cursor = unescape(parser, dest, &dest_length, backslash, end, flags, &parser->error_list); - break; - } - - if (end > cursor) { - backslash = yp_memchr(cursor, '\\', (size_t) (end - cursor), parser->encoding_changed, &parser->encoding); - } else { - backslash = NULL; - } - } - - // We need to copy the final segment of the string after the last escape. - if (end > cursor) { - memcpy(dest + dest_length, cursor, (size_t) (end - cursor)); - } else { - cursor = end; - } - - // If the string was already allocated, then we need to free that memory - // here. That's because we're about to override it with the escaped string. - yp_string_free(string); - - // We also need to update the length at the end. This is because every escape - // reduces the length of the final string, and we don't want garbage at the - // end. - yp_string_owned_init(string, allocated, dest_length + ((size_t) (end - cursor))); -} - -YP_EXPORTED_FUNCTION void -yp_unescape_manipulate_string(yp_parser_t *parser, yp_string_t *string, yp_unescape_type_t unescape_type) { - yp_unescape_manipulate_string_or_char_literal(parser, string, unescape_type, false); -} - -void -yp_unescape_manipulate_char_literal(yp_parser_t *parser, yp_string_t *string, yp_unescape_type_t unescape_type) { - yp_unescape_manipulate_string_or_char_literal(parser, string, unescape_type, true); -} - -// This function is similar to yp_unescape_manipulate_string, except it doesn't -// actually perform any string manipulations. Instead, it calculates how long -// the unescaped character is, and returns that value -size_t -yp_unescape_calculate_difference(yp_parser_t *parser, const uint8_t *backslash, yp_unescape_type_t unescape_type, bool expect_single_codepoint) { - assert(unescape_type != YP_UNESCAPE_NONE); - - if (backslash + 1 >= parser->end) { - return 0; - } - - switch (backslash[1]) { - case '\\': - case '\'': - return 2; - default: { - if (unescape_type == YP_UNESCAPE_MINIMAL) { - return 1 + yp_char_width(parser, backslash + 1, parser->end); - } - - // This is the only type of unescaping left. In this case we need to - // handle all of the different unescapes. - assert(unescape_type == YP_UNESCAPE_ALL); - - uint8_t flags = YP_UNESCAPE_FLAG_NONE; - if (expect_single_codepoint) { - flags |= YP_UNESCAPE_FLAG_EXPECT_SINGLE; - } - - const uint8_t *cursor = unescape(parser, NULL, 0, backslash, parser->end, flags, NULL); - assert(cursor > backslash); - - return (size_t) (cursor - backslash); - } - } -} - -// This is one of the main entry points into the extension. It accepts a source -// string, a type of unescaping, and a pointer to a result string. It returns a -// boolean indicating whether or not the unescaping was successful. -YP_EXPORTED_FUNCTION bool -yp_unescape_string(const uint8_t *start, size_t length, yp_unescape_type_t unescape_type, yp_string_t *result) { - yp_parser_t parser; - yp_parser_init(&parser, start, length, NULL); - - yp_string_shared_init(result, start, start + length); - yp_unescape_manipulate_string(&parser, result, unescape_type); - - bool success = yp_list_empty_p(&parser.error_list); - yp_parser_free(&parser); - - return success; -} diff --git a/yarp/unescape.h b/yarp/unescape.h deleted file mode 100644 index fb0df9fcb08145..00000000000000 --- a/yarp/unescape.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef YARP_UNESCAPE_H -#define YARP_UNESCAPE_H - -#include "yarp/defines.h" -#include "yarp/diagnostic.h" -#include "yarp/parser.h" -#include "yarp/util/yp_char.h" -#include "yarp/util/yp_list.h" -#include "yarp/util/yp_memchr.h" -#include "yarp/util/yp_string.h" - -#include -#include -#include -#include - -// The type of unescape we are performing. -typedef enum { - // When we're creating a string inside of a list literal like %w, we - // shouldn't escape anything. - YP_UNESCAPE_NONE, - - // When we're unescaping a single-quoted string, we only need to unescape - // single quotes and backslashes. - YP_UNESCAPE_MINIMAL, - - // When we're unescaping a double-quoted string, we need to unescape all - // escapes. - YP_UNESCAPE_ALL -} yp_unescape_type_t; - -// Unescape the contents of the given token into the given string using the given unescape mode. -YP_EXPORTED_FUNCTION void yp_unescape_manipulate_string(yp_parser_t *parser, yp_string_t *string, yp_unescape_type_t unescape_type); -void yp_unescape_manipulate_char_literal(yp_parser_t *parser, yp_string_t *string, yp_unescape_type_t unescape_type); - -// Accepts a source string and a type of unescaping and returns the unescaped version. -// The caller must yp_string_free(result); after calling this function. -YP_EXPORTED_FUNCTION bool yp_unescape_string(const uint8_t *start, size_t length, yp_unescape_type_t unescape_type, yp_string_t *result); - -// Returns the number of bytes that encompass the first escape sequence in the -// given string. -size_t yp_unescape_calculate_difference(yp_parser_t *parser, const uint8_t *value, yp_unescape_type_t unescape_type, bool expect_single_codepoint); - -#endif diff --git a/yarp/util/yp_buffer.c b/yarp/util/yp_buffer.c deleted file mode 100644 index 15cdef74f88073..00000000000000 --- a/yarp/util/yp_buffer.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "yarp/util/yp_buffer.h" - -#define YP_BUFFER_INITIAL_SIZE 1024 - -// Return the size of the yp_buffer_t struct. -size_t -yp_buffer_sizeof(void) { - return sizeof(yp_buffer_t); -} - -// Initialize a yp_buffer_t with its default values. -bool -yp_buffer_init(yp_buffer_t *buffer) { - buffer->length = 0; - buffer->capacity = YP_BUFFER_INITIAL_SIZE; - - buffer->value = (char *) malloc(YP_BUFFER_INITIAL_SIZE); - return buffer->value != NULL; -} - -// Return the value of the buffer. -char * -yp_buffer_value(yp_buffer_t *buffer) { - return buffer->value; -} - -// Return the length of the buffer. -size_t -yp_buffer_length(yp_buffer_t *buffer) { - return buffer->length; -} - -// Append the given amount of space to the buffer. -static inline void -yp_buffer_append_length(yp_buffer_t *buffer, size_t length) { - size_t next_length = buffer->length + length; - - if (next_length > buffer->capacity) { - do { - buffer->capacity *= 2; - } while (next_length > buffer->capacity); - - buffer->value = realloc(buffer->value, buffer->capacity); - } - - buffer->length = next_length; -} - -// Append a generic pointer to memory to the buffer. -static inline void -yp_buffer_append(yp_buffer_t *buffer, const void *source, size_t length) { - yp_buffer_append_length(buffer, length); - memcpy(buffer->value + (buffer->length - length), source, length); -} - -// Append the given amount of space as zeroes to the buffer. -void -yp_buffer_append_zeroes(yp_buffer_t *buffer, size_t length) { - yp_buffer_append_length(buffer, length); - memset(buffer->value + (buffer->length - length), 0, length); -} - -// Append a string to the buffer. -void -yp_buffer_append_str(yp_buffer_t *buffer, const char *value, size_t length) { - yp_buffer_append(buffer, value, length); -} - -// Append a list of bytes to the buffer. -void -yp_buffer_append_bytes(yp_buffer_t *buffer, const uint8_t *value, size_t length) { - yp_buffer_append(buffer, (const char *) value, length); -} - -// Append a single byte to the buffer. -void -yp_buffer_append_u8(yp_buffer_t *buffer, uint8_t value) { - const void *source = &value; - yp_buffer_append(buffer, source, sizeof(uint8_t)); -} - -// Append a 32-bit unsigned integer to the buffer. -void -yp_buffer_append_u32(yp_buffer_t *buffer, uint32_t value) { - if (value < 128) { - yp_buffer_append_u8(buffer, (uint8_t) value); - } else { - uint32_t n = value; - while (n >= 128) { - yp_buffer_append_u8(buffer, (uint8_t) (n | 128)); - n >>= 7; - } - yp_buffer_append_u8(buffer, (uint8_t) n); - } -} - -// Free the memory associated with the buffer. -void -yp_buffer_free(yp_buffer_t *buffer) { - free(buffer->value); -} diff --git a/yarp/util/yp_buffer.h b/yarp/util/yp_buffer.h deleted file mode 100644 index c388e8d5ce0000..00000000000000 --- a/yarp/util/yp_buffer.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef YARP_BUFFER_H -#define YARP_BUFFER_H - -#include "yarp/defines.h" - -#include -#include -#include -#include -#include - -// A yp_buffer_t is a simple memory buffer that stores data in a contiguous -// block of memory. It is used to store the serialized representation of a -// YARP tree. -typedef struct { - char *value; - size_t length; - size_t capacity; -} yp_buffer_t; - -// Return the size of the yp_buffer_t struct. -YP_EXPORTED_FUNCTION size_t yp_buffer_sizeof(void); - -// Initialize a yp_buffer_t with its default values. -YP_EXPORTED_FUNCTION bool yp_buffer_init(yp_buffer_t *buffer); - -// Return the value of the buffer. -YP_EXPORTED_FUNCTION char * yp_buffer_value(yp_buffer_t *buffer); - -// Return the length of the buffer. -YP_EXPORTED_FUNCTION size_t yp_buffer_length(yp_buffer_t *buffer); - -// Append the given amount of space as zeroes to the buffer. -void yp_buffer_append_zeroes(yp_buffer_t *buffer, size_t length); - -// Append a string to the buffer. -void yp_buffer_append_str(yp_buffer_t *buffer, const char *value, size_t length); - -// Append a list of bytes to the buffer. -void yp_buffer_append_bytes(yp_buffer_t *buffer, const uint8_t *value, size_t length); - -// Append a single byte to the buffer. -void yp_buffer_append_u8(yp_buffer_t *buffer, uint8_t value); - -// Append a 32-bit unsigned integer to the buffer. -void yp_buffer_append_u32(yp_buffer_t *buffer, uint32_t value); - -// Free the memory associated with the buffer. -YP_EXPORTED_FUNCTION void yp_buffer_free(yp_buffer_t *buffer); - -#endif diff --git a/yarp/util/yp_char.c b/yarp/util/yp_char.c deleted file mode 100644 index ae0ffea6b83b38..00000000000000 --- a/yarp/util/yp_char.c +++ /dev/null @@ -1,224 +0,0 @@ -#include "yarp/util/yp_char.h" - -#define YP_CHAR_BIT_WHITESPACE (1 << 0) -#define YP_CHAR_BIT_INLINE_WHITESPACE (1 << 1) -#define YP_CHAR_BIT_REGEXP_OPTION (1 << 2) - -#define YP_NUMBER_BIT_BINARY_DIGIT (1 << 0) -#define YP_NUMBER_BIT_BINARY_NUMBER (1 << 1) -#define YP_NUMBER_BIT_OCTAL_DIGIT (1 << 2) -#define YP_NUMBER_BIT_OCTAL_NUMBER (1 << 3) -#define YP_NUMBER_BIT_DECIMAL_DIGIT (1 << 4) -#define YP_NUMBER_BIT_DECIMAL_NUMBER (1 << 5) -#define YP_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6) -#define YP_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7) - -static const uint8_t yp_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 yp_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 -}; - -static inline size_t -yp_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 && (yp_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 -yp_strspn_whitespace(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_char_kind(string, length, YP_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 -yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list) { - if (length <= 0) return 0; - - size_t size = 0; - size_t maximum = (size_t) length; - - while (size < maximum && (yp_byte_table[string[size]] & YP_CHAR_BIT_WHITESPACE)) { - if (string[size] == '\n') { - yp_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 -yp_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_char_kind(string, length, YP_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 -yp_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_char_kind(string, length, YP_CHAR_BIT_REGEXP_OPTION); -} - -static inline bool -yp_char_is_char_kind(const uint8_t b, uint8_t kind) { - return (yp_byte_table[b] & kind) != 0; -} - -// Returns true if the given character is a whitespace character. -bool -yp_char_is_whitespace(const uint8_t b) { - return yp_char_is_char_kind(b, YP_CHAR_BIT_WHITESPACE); -} - -// Returns true if the given character is an inline whitespace character. -bool -yp_char_is_inline_whitespace(const uint8_t b) { - return yp_char_is_char_kind(b, YP_CHAR_BIT_INLINE_WHITESPACE); -} - -static inline size_t -yp_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 && (yp_number_table[string[size]] & kind)) size++; - 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. -size_t -yp_strspn_binary_number(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_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. -size_t -yp_strspn_octal_number(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_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 -yp_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_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. -size_t -yp_strspn_decimal_number(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_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 -yp_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_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. -size_t -yp_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length) { - return yp_strspn_number_kind(string, length, YP_NUMBER_BIT_HEXADECIMAL_NUMBER); -} - -static inline bool -yp_char_is_number_kind(const uint8_t b, uint8_t kind) { - return (yp_number_table[b] & kind) != 0; -} - -// Returns true if the given character is a binary digit. -bool -yp_char_is_binary_digit(const uint8_t b) { - return yp_char_is_number_kind(b, YP_NUMBER_BIT_BINARY_DIGIT); -} - -// Returns true if the given character is an octal digit. -bool -yp_char_is_octal_digit(const uint8_t b) { - return yp_char_is_number_kind(b, YP_NUMBER_BIT_OCTAL_DIGIT); -} - -// Returns true if the given character is a decimal digit. -bool -yp_char_is_decimal_digit(const uint8_t b) { - return yp_char_is_number_kind(b, YP_NUMBER_BIT_DECIMAL_DIGIT); -} - -// Returns true if the given character is a hexadecimal digit. -bool -yp_char_is_hexadecimal_digit(const uint8_t b) { - return yp_char_is_number_kind(b, YP_NUMBER_BIT_HEXADECIMAL_DIGIT); -} - -#undef YP_CHAR_BIT_WHITESPACE -#undef YP_CHAR_BIT_INLINE_WHITESPACE -#undef YP_CHAR_BIT_REGEXP_OPTION - -#undef YP_NUMBER_BIT_BINARY_DIGIT -#undef YP_NUMBER_BIT_BINARY_NUMBER -#undef YP_NUMBER_BIT_OCTAL_DIGIT -#undef YP_NUMBER_BIT_OCTAL_NUMBER -#undef YP_NUMBER_BIT_DECIMAL_DIGIT -#undef YP_NUMBER_BIT_DECIMAL_NUMBER -#undef YP_NUMBER_BIT_HEXADECIMAL_NUMBER -#undef YP_NUMBER_BIT_HEXADECIMAL_DIGIT diff --git a/yarp/util/yp_char.h b/yarp/util/yp_char.h deleted file mode 100644 index e155b69d64d8c6..00000000000000 --- a/yarp/util/yp_char.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef YP_CHAR_H -#define YP_CHAR_H - -#include "yarp/defines.h" -#include "yarp/util/yp_newline_list.h" - -#include -#include - -// 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 yp_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. -size_t -yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_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. -size_t yp_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. -size_t yp_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. -size_t yp_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. -size_t yp_strspn_octal_number(const uint8_t *string, ptrdiff_t length); - -// 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. -size_t yp_strspn_decimal_number(const uint8_t *string, ptrdiff_t length); - -// 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. -size_t yp_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length); - -// 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 yp_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. -size_t yp_strspn_binary_number(const uint8_t *string, ptrdiff_t length); - -// Returns true if the given character is a whitespace character. -bool yp_char_is_whitespace(const uint8_t b); - -// Returns true if the given character is an inline whitespace character. -bool yp_char_is_inline_whitespace(const uint8_t b); - -// Returns true if the given character is a binary digit. -bool yp_char_is_binary_digit(const uint8_t b); - -// Returns true if the given character is an octal digit. -bool yp_char_is_octal_digit(const uint8_t b); - -// Returns true if the given character is a decimal digit. -bool yp_char_is_decimal_digit(const uint8_t b); - -// Returns true if the given character is a hexadecimal digit. -bool yp_char_is_hexadecimal_digit(const uint8_t b); - -#endif diff --git a/yarp/util/yp_constant_pool.c b/yarp/util/yp_constant_pool.c deleted file mode 100644 index 8be96138a1325e..00000000000000 --- a/yarp/util/yp_constant_pool.c +++ /dev/null @@ -1,180 +0,0 @@ -#include "yarp/util/yp_constant_pool.h" - -// Initialize a list of constant ids. -void -yp_constant_id_list_init(yp_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 -yp_constant_id_list_append(yp_constant_id_list_t *list, yp_constant_id_t id) { - if (list->size >= list->capacity) { - list->capacity = list->capacity == 0 ? 8 : list->capacity * 2; - list->ids = (yp_constant_id_t *) realloc(list->ids, sizeof(yp_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 -yp_constant_id_list_includes(yp_constant_id_list_t *list, yp_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 -yp_constant_id_list_memsize(yp_constant_id_list_t *list) { - return sizeof(yp_constant_id_list_t) + (list->capacity * sizeof(yp_constant_id_t)); -} - -// Free the memory associated with a list of constant ids. -void -yp_constant_id_list_free(yp_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 size_t -yp_constant_pool_hash(const uint8_t *start, size_t length) { - // This is a prime number used as the initial value for the hash function. - size_t value = 5381; - - for (size_t index = 0; index < length; index++) { - value = ((value << 5) + value) + start[index]; - } - - return value; -} - -// Resize a constant pool to a given capacity. -static inline bool -yp_constant_pool_resize(yp_constant_pool_t *pool) { - size_t next_capacity = pool->capacity * 2; - yp_constant_t *next_constants = calloc(next_capacity, sizeof(yp_constant_t)); - if (next_constants == NULL) return false; - - // For each constant in the current constant pool, rehash the content, find - // the index in the next constant pool, and insert it. - for (size_t index = 0; index < pool->capacity; index++) { - yp_constant_t *constant = &pool->constants[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 (constant->id != 0) { - size_t next_index = constant->hash % next_capacity; - - // 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_constants[next_index].id != 0) { - next_index = (next_index + 1) % next_capacity; - } - - // Here we copy over the entire constant, which includes the id so - // that they are consistent between resizes. - next_constants[next_index] = *constant; - } - } - - free(pool->constants); - pool->constants = next_constants; - pool->capacity = next_capacity; - return true; -} - -// Initialize a new constant pool with a given capacity. -bool -yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity) { - pool->constants = calloc(capacity, sizeof(yp_constant_t)); - if (pool->constants == NULL) return false; - - pool->size = 0; - pool->capacity = capacity; - return true; -} - -// Insert a constant into a constant pool and return its index in the pool. -static size_t -yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { - if (pool->size >= (pool->capacity / 4 * 3)) { - if (!yp_constant_pool_resize(pool)) return pool->capacity; - } - - size_t hash = yp_constant_pool_hash(start, length); - size_t index = hash % pool->capacity; - yp_constant_t *constant; - - while (constant = &pool->constants[index], constant->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. - if ((constant->length == length) && memcmp(constant->start, start, length) == 0) { - return index; - } - - index = (index + 1) % pool->capacity; - } - - pool->size++; - assert(pool->size < ((size_t) (1 << 31))); - - pool->constants[index] = (yp_constant_t) { - .id = (unsigned int) (pool->size & 0x7FFFFFFF), - .start = start, - .length = length, - .hash = hash - }; - - return index; -} - -// Insert a constant into a constant pool. Returns the id of the constant, or 0 -// if any potential calls to resize fail. -yp_constant_id_t -yp_constant_pool_insert_shared(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { - size_t index = yp_constant_pool_insert(pool, start, length); - return index == pool->capacity ? 0 : ((yp_constant_id_t) pool->constants[index].id); -} - -// 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. -yp_constant_id_t -yp_constant_pool_insert_owned(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { - size_t index = yp_constant_pool_insert(pool, start, length); - if (index == pool->capacity) return 0; - - yp_constant_t *constant = &pool->constants[index]; - constant->owned = true; - return ((yp_constant_id_t) constant->id); -} - -// Free the memory associated with a constant pool. -void -yp_constant_pool_free(yp_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++) { - yp_constant_t *constant = &pool->constants[index]; - - // If an id is set on this constant, then we know we have content here. - if (constant->id != 0 && constant->owned) { - free((void *) constant->start); - } - } - - free(pool->constants); -} diff --git a/yarp/util/yp_constant_pool.h b/yarp/util/yp_constant_pool.h deleted file mode 100644 index ecd3ff619e3033..00000000000000 --- a/yarp/util/yp_constant_pool.h +++ /dev/null @@ -1,74 +0,0 @@ -// The constant pool is 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 YP_CONSTANT_POOL_H -#define YP_CONSTANT_POOL_H - -#include "yarp/defines.h" - -#include -#include -#include -#include -#include - -typedef uint32_t yp_constant_id_t; - -typedef struct { - yp_constant_id_t *ids; - size_t size; - size_t capacity; -} yp_constant_id_list_t; - -// Initialize a list of constant ids. -void yp_constant_id_list_init(yp_constant_id_list_t *list); - -// Append a constant id to a list of constant ids. Returns false if any -// potential reallocations fail. -bool yp_constant_id_list_append(yp_constant_id_list_t *list, yp_constant_id_t id); - -// Checks if the current constant id list includes the given constant id. -bool -yp_constant_id_list_includes(yp_constant_id_list_t *list, yp_constant_id_t id); - -// Get the memory size of a list of constant ids. -size_t yp_constant_id_list_memsize(yp_constant_id_list_t *list); - -// Free the memory associated with a list of constant ids. -void yp_constant_id_list_free(yp_constant_id_list_t *list); - -typedef struct { - unsigned int id: 31; - bool owned: 1; - const uint8_t *start; - size_t length; - size_t hash; -} yp_constant_t; - -typedef struct { - yp_constant_t *constants; - size_t size; - size_t capacity; -} yp_constant_pool_t; - -// Define an empty constant pool. -#define YP_CONSTANT_POOL_EMPTY ((yp_constant_pool_t) { .constants = NULL, .size = 0, .capacity = 0 }) - -// Initialize a new constant pool with a given capacity. -bool yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity); - -// 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. -yp_constant_id_t yp_constant_pool_insert_shared(yp_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. -yp_constant_id_t yp_constant_pool_insert_owned(yp_constant_pool_t *pool, const uint8_t *start, size_t length); - -// Free the memory associated with a constant pool. -void yp_constant_pool_free(yp_constant_pool_t *pool); - -#endif diff --git a/yarp/util/yp_list.c b/yarp/util/yp_list.c deleted file mode 100644 index e03dd79d8d89a8..00000000000000 --- a/yarp/util/yp_list.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "yarp/util/yp_list.h" - -// Returns true if the given list is empty. -YP_EXPORTED_FUNCTION bool -yp_list_empty_p(yp_list_t *list) { - return list->head == NULL; -} - -// Returns the size of the list. -YP_EXPORTED_FUNCTION size_t -yp_list_size(yp_list_t *list) { - return list->size; -} - -// Append a node to the given list. -void -yp_list_append(yp_list_t *list, yp_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. -YP_EXPORTED_FUNCTION void -yp_list_free(yp_list_t *list) { - yp_list_node_t *node = list->head; - yp_list_node_t *next; - - while (node != NULL) { - next = node->next; - free(node); - node = next; - } - - list->size = 0; -} diff --git a/yarp/util/yp_list.h b/yarp/util/yp_list.h deleted file mode 100644 index 205a5a7eab4a8f..00000000000000 --- a/yarp/util/yp_list.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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 yp_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: -// -// typedef struct { -// yp_list_node_t node; -// int value; -// } yp_int_node_t; -// -// yp_list_t list = YP_LIST_EMPTY; -// yp_int_node_t *node = malloc(sizeof(yp_int_node_t)); -// node->value = 5; -// -// yp_list_append(&list, &node->node); -// -// The yp_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. - -#ifndef YARP_LIST_H -#define YARP_LIST_H - -#include "yarp/defines.h" - -#include -#include -#include -#include - -// This represents a node in the linked list. -typedef struct yp_list_node { - struct yp_list_node *next; -} yp_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 { - size_t size; - yp_list_node_t *head; - yp_list_node_t *tail; -} yp_list_t; - -// This represents an empty list. It's used to initialize a stack-allocated list -// as opposed to a method call. -#define YP_LIST_EMPTY ((yp_list_t) { .size = 0, .head = NULL, .tail = NULL }) - -// Returns true if the given list is empty. -YP_EXPORTED_FUNCTION bool yp_list_empty_p(yp_list_t *list); - -// Returns the size of the list. -YP_EXPORTED_FUNCTION size_t yp_list_size(yp_list_t *list); - -// Append a node to the given list. -void yp_list_append(yp_list_t *list, yp_list_node_t *node); - -// Deallocate the internal state of the given list. -YP_EXPORTED_FUNCTION void yp_list_free(yp_list_t *list); - -#endif diff --git a/yarp/util/yp_memchr.c b/yarp/util/yp_memchr.c deleted file mode 100644 index af9c14397e0b37..00000000000000 --- a/yarp/util/yp_memchr.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "yarp/util/yp_memchr.h" - -#define YP_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 * -yp_memchr(const void *memory, int character, size_t number, bool encoding_changed, yp_encoding_t *encoding) { - if (encoding_changed && encoding->multibyte && character >= YP_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); - } -} diff --git a/yarp/util/yp_memchr.h b/yarp/util/yp_memchr.h deleted file mode 100644 index 97f4b15a839b02..00000000000000 --- a/yarp/util/yp_memchr.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef YP_MEMCHR_H -#define YP_MEMCHR_H - -#include "yarp/defines.h" -#include "yarp/enc/yp_encoding.h" - -#include - -// 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 * yp_memchr(const void *source, int character, size_t number, bool encoding_changed, yp_encoding_t *encoding); - -#endif diff --git a/yarp/util/yp_newline_list.c b/yarp/util/yp_newline_list.c deleted file mode 100644 index 969b8845605019..00000000000000 --- a/yarp/util/yp_newline_list.c +++ /dev/null @@ -1,134 +0,0 @@ -#include "yarp/util/yp_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 -yp_newline_list_init(yp_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; - - list->last_index = 0; - list->last_offset = 0; - - 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 -yp_newline_list_append(yp_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 -yp_newline_list_check_append(yp_newline_list_t *list, const uint8_t *cursor) { - if (*cursor != '\n') { - return true; - } - return yp_newline_list_append(list, cursor); -} - -// Returns the line and column of the given offset, assuming we don't have any -// information about the previous index that we found. -static yp_line_column_t -yp_newline_list_line_column_search(yp_newline_list_t *list, size_t offset) { - 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 ((yp_line_column_t) { mid, 0 }); - } - - if (list->offsets[mid] < offset) { - left = mid + 1; - } else { - right = mid - 1; - } - } - - return ((yp_line_column_t) { left - 1, offset - list->offsets[left - 1] }); -} - -// Returns the line and column of the given offset, assuming we know the last -// index that we found. -static yp_line_column_t -yp_newline_list_line_column_scan(yp_newline_list_t *list, size_t offset) { - if (offset > list->last_offset) { - size_t index = list->last_index; - while (index < list->size && list->offsets[index] < offset) { - index++; - } - - if (index == list->size) { - return ((yp_line_column_t) { index - 1, offset - list->offsets[index - 1] }); - } - - return ((yp_line_column_t) { index, 0 }); - } else { - size_t index = list->last_index; - while (index > 0 && list->offsets[index] > offset) { - index--; - } - - if (index == 0) { - return ((yp_line_column_t) { 0, offset }); - } - - return ((yp_line_column_t) { index, offset - list->offsets[index - 1] }); - } -} - -// 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. -yp_line_column_t -yp_newline_list_line_column(yp_newline_list_t *list, const uint8_t *cursor) { - assert(cursor >= list->start); - size_t offset = (size_t) (cursor - list->start); - yp_line_column_t result; - - if (list->last_offset == 0) { - result = yp_newline_list_line_column_search(list, offset); - } else { - result = yp_newline_list_line_column_scan(list, offset); - } - - list->last_index = result.line; - list->last_offset = offset; - - return result; -} - -// Free the internal memory allocated for the newline list. -void -yp_newline_list_free(yp_newline_list_t *list) { - free(list->offsets); -} diff --git a/yarp/util/yp_newline_list.h b/yarp/util/yp_newline_list.h deleted file mode 100644 index 92313050084dc3..00000000000000 --- a/yarp/util/yp_newline_list.h +++ /dev/null @@ -1,61 +0,0 @@ -// 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 YP_NEWLINE_LIST_H -#define YP_NEWLINE_LIST_H - -#include "yarp/defines.h" - -#include -#include -#include -#include - -// A list of offsets of newlines in a string. The offsets are assumed to be -// sorted/inserted in ascending order. -typedef struct { - const uint8_t *start; - - size_t *offsets; - size_t size; - size_t capacity; - - size_t last_offset; - size_t last_index; -} yp_newline_list_t; - -// A line and column in a string. -typedef struct { - size_t line; - size_t column; -} yp_line_column_t; - -#define YP_NEWLINE_LIST_EMPTY ((yp_newline_list_t) { \ - .start = NULL, .offsets = NULL, .size = 0, .capacity = 0, .last_offset = 0, .last_index = 0 \ -}) - -// Initialize a new newline list with the given capacity. Returns true if the -// allocation of the offsets succeeds, otherwise returns false. -bool yp_newline_list_init(yp_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. -bool yp_newline_list_append(yp_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. -bool yp_newline_list_check_append(yp_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. -yp_line_column_t yp_newline_list_line_column(yp_newline_list_t *list, const uint8_t *cursor); - -// Free the internal memory allocated for the newline list. -void yp_newline_list_free(yp_newline_list_t *list); - -#endif diff --git a/yarp/util/yp_state_stack.c b/yarp/util/yp_state_stack.c deleted file mode 100644 index 7ff95bd61166a5..00000000000000 --- a/yarp/util/yp_state_stack.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "yarp/util/yp_state_stack.h" - -// Pushes a value onto the stack. -void -yp_state_stack_push(yp_state_stack_t *stack, bool value) { - *stack = (*stack << 1) | (value & 1); -} - -// Pops a value off the stack. -void -yp_state_stack_pop(yp_state_stack_t *stack) { - *stack >>= 1; -} - -// Returns the value at the top of the stack. -bool -yp_state_stack_p(yp_state_stack_t *stack) { - return *stack & 1; -} diff --git a/yarp/util/yp_state_stack.h b/yarp/util/yp_state_stack.h deleted file mode 100644 index 69d8d7d54b4322..00000000000000 --- a/yarp/util/yp_state_stack.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef YP_STATE_STACK_H -#define YP_STATE_STACK_H - -#include "yarp/defines.h" - -#include -#include - -// A struct that represents a stack of bools. -typedef uint32_t yp_state_stack_t; - -// Initializes the state stack to an empty stack. -#define YP_STATE_STACK_EMPTY ((yp_state_stack_t) 0) - -// Pushes a value onto the stack. -void yp_state_stack_push(yp_state_stack_t *stack, bool value); - -// Pops a value off the stack. -void yp_state_stack_pop(yp_state_stack_t *stack); - -// Returns the value at the top of the stack. -bool yp_state_stack_p(yp_state_stack_t *stack); - -#endif diff --git a/yarp/util/yp_string.c b/yarp/util/yp_string.c deleted file mode 100644 index 9ee25155a3bdfb..00000000000000 --- a/yarp/util/yp_string.c +++ /dev/null @@ -1,200 +0,0 @@ -#include "yarp/util/yp_string.h" - -// The following headers are necessary to read files using demand paging. -#ifdef _WIN32 -#include -#else -#include -#include -#include -#include -#endif - -// Initialize a shared string that is based on initial input. -void -yp_string_shared_init(yp_string_t *string, const uint8_t *start, const uint8_t *end) { - assert(start <= end); - - *string = (yp_string_t) { - .type = YP_STRING_SHARED, - .source = start, - .length = (size_t) (end - start) - }; -} - -// Initialize an owned string that is responsible for freeing allocated memory. -void -yp_string_owned_init(yp_string_t *string, uint8_t *source, size_t length) { - *string = (yp_string_t) { - .type = YP_STRING_OWNED, - .source = source, - .length = length - }; -} - -// Initialize a constant string that doesn't own its memory source. -void -yp_string_constant_init(yp_string_t *string, const char *source, size_t length) { - *string = (yp_string_t) { - .type = YP_STRING_CONSTANT, - .source = (const uint8_t *) source, - .length = length - }; -} - -static void -yp_string_mapped_init_internal(yp_string_t *string, uint8_t *source, size_t length) { - *string = (yp_string_t) { - .type = YP_STRING_MAPPED, - .source = source, - .length = length - }; -} - -// Returns the memory size associated with the string. -size_t -yp_string_memsize(const yp_string_t *string) { - size_t size = sizeof(yp_string_t); - if (string->type == YP_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 -yp_string_ensure_owned(yp_string_t *string) { - if (string->type == YP_STRING_OWNED) return; - - size_t length = yp_string_length(string); - const uint8_t *source = yp_string_source(string); - - uint8_t *memory = malloc(length); - if (!memory) return; - - yp_string_owned_init(string, memory, length); - memcpy((void *) string->source, source, length); -} - -// Returns the length associated with the string. -YP_EXPORTED_FUNCTION size_t -yp_string_length(const yp_string_t *string) { - return string->length; -} - -// Returns the start pointer associated with the string. -YP_EXPORTED_FUNCTION const uint8_t * -yp_string_source(const yp_string_t *string) { - return string->source; -} - -// Free the associated memory of the given string. -YP_EXPORTED_FUNCTION void -yp_string_free(yp_string_t *string) { - void *memory = (void *) string->source; - - if (string->type == YP_STRING_OWNED) { - free(memory); - } else if (string->type == YP_STRING_MAPPED && string->length) { -#if defined(_WIN32) - UnmapViewOfFile(memory); -#else - munmap(memory, string->length); -#endif - } -} - -bool -yp_string_mapped_init(yp_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); - uint8_t empty[] = ""; - yp_string_mapped_init_internal(string, empty, 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; - } - - yp_string_mapped_init_internal(string, source, (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); - uint8_t empty[] = ""; - yp_string_mapped_init_internal(string, empty, 0); - return true; - } - - source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); - if (source == MAP_FAILED) { - perror("Map failed"); - return false; - } - - close(fd); - yp_string_mapped_init_internal(string, source, size); - return true; -#endif -} - -// Returns the size of the yp_string_t struct. This is necessary to allocate the -// correct amount of memory in the FFI backend. -YP_EXPORTED_FUNCTION size_t -yp_string_sizeof(void) { - return sizeof(yp_string_t); -} diff --git a/yarp/util/yp_string.h b/yarp/util/yp_string.h deleted file mode 100644 index bcdf8b66d99c60..00000000000000 --- a/yarp/util/yp_string.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef YARP_STRING_H -#define YARP_STRING_H - -#include "yarp/defines.h" - -#include -#include -#include -#include -#include - -// This struct represents a string value. -typedef struct { - enum { YP_STRING_SHARED, YP_STRING_OWNED, YP_STRING_CONSTANT, YP_STRING_MAPPED } type; - const uint8_t *source; - size_t length; -} yp_string_t; - -#define YP_EMPTY_STRING ((yp_string_t) { .type = YP_STRING_CONSTANT, .source = NULL, .length = 0 }) - -// Initialize a shared string that is based on initial input. -void yp_string_shared_init(yp_string_t *string, const uint8_t *start, const uint8_t *end); - -// Initialize an owned string that is responsible for freeing allocated memory. -void yp_string_owned_init(yp_string_t *string, uint8_t *source, size_t length); - -// Initialize a constant string that doesn't own its memory source. -void yp_string_constant_init(yp_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 yp_string_t. -// The given yp_string_t should be freed using yp_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`. -YP_EXPORTED_FUNCTION bool yp_string_mapped_init(yp_string_t *string, const char *filepath); - -// Returns the memory size associated with the string. -size_t yp_string_memsize(const yp_string_t *string); - -// Ensure the string is owned. If it is not, then reinitialize it as owned and -// copy over the previous source. -void yp_string_ensure_owned(yp_string_t *string); - -// Returns the length associated with the string. -YP_EXPORTED_FUNCTION size_t yp_string_length(const yp_string_t *string); - -// Returns the start pointer associated with the string. -YP_EXPORTED_FUNCTION const uint8_t * yp_string_source(const yp_string_t *string); - -// Free the associated memory of the given string. -YP_EXPORTED_FUNCTION void yp_string_free(yp_string_t *string); - -// Returns the size of the yp_string_t struct. This is necessary to allocate the -// correct amount of memory in the FFI backend. -YP_EXPORTED_FUNCTION size_t yp_string_sizeof(void); - -#endif // YARP_STRING_H diff --git a/yarp/util/yp_string_list.c b/yarp/util/yp_string_list.c deleted file mode 100644 index 3b2b4381c500e6..00000000000000 --- a/yarp/util/yp_string_list.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "yarp/util/yp_string_list.h" - -// Initialize a yp_string_list_t with its default values. -void -yp_string_list_init(yp_string_list_t *string_list) { - string_list->strings = (yp_string_t *) malloc(sizeof(yp_string_t)); - string_list->length = 0; - string_list->capacity = 1; -} - -// Append a yp_string_t to the given string list. -void -yp_string_list_append(yp_string_list_t *string_list, yp_string_t *string) { - if (string_list->length + 1 > string_list->capacity) { - yp_string_t *original_string = string_list->strings; - string_list->capacity *= 2; - string_list->strings = (yp_string_t *) malloc(string_list->capacity * sizeof(yp_string_t)); - memcpy(string_list->strings, original_string, (string_list->length) * sizeof(yp_string_t)); - free(original_string); - } - - string_list->strings[string_list->length++] = *string; -} - -// Free the memory associated with the string list. -void -yp_string_list_free(yp_string_list_t *string_list) { - free(string_list->strings); -} diff --git a/yarp/util/yp_string_list.h b/yarp/util/yp_string_list.h deleted file mode 100644 index 0009a27a60cce4..00000000000000 --- a/yarp/util/yp_string_list.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef YARP_STRING_LIST_H -#define YARP_STRING_LIST_H - -#include "yarp/defines.h" -#include "yarp/util/yp_string.h" - -#include -#include - -typedef struct { - yp_string_t *strings; - size_t length; - size_t capacity; -} yp_string_list_t; - -// Initialize a yp_string_list_t with its default values. -YP_EXPORTED_FUNCTION void yp_string_list_init(yp_string_list_t *string_list); - -// Append a yp_string_t to the given string list. -void yp_string_list_append(yp_string_list_t *string_list, yp_string_t *string); - -// Free the memory associated with the string list. -YP_EXPORTED_FUNCTION void yp_string_list_free(yp_string_list_t *string_list); - -#endif diff --git a/yarp/util/yp_strncasecmp.c b/yarp/util/yp_strncasecmp.c deleted file mode 100644 index 1cbaf904f49c73..00000000000000 --- a/yarp/util/yp_strncasecmp.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include - -int -yp_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/yarp/util/yp_strpbrk.c b/yarp/util/yp_strpbrk.c deleted file mode 100644 index 7c0015d2890fcf..00000000000000 --- a/yarp/util/yp_strpbrk.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "yarp/util/yp_strpbrk.h" - -// This is the slow path that does care about the encoding. -static inline const uint8_t * -yp_strpbrk_multi_byte(yp_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 * -yp_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 yp_parse does not -// have the contract that the string is null-terminated. (This is desirable -// because it means the extension can call yp_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 * -yp_strpbrk(yp_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 yp_strpbrk_multi_byte(parser, source, charset, (size_t) length); - } else { - return yp_strpbrk_single_byte(source, charset, (size_t) length); - } -} diff --git a/yarp/util/yp_strpbrk.h b/yarp/util/yp_strpbrk.h deleted file mode 100644 index d0bdd5bec000cc..00000000000000 --- a/yarp/util/yp_strpbrk.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef YP_STRPBRK_H -#define YP_STRPBRK_H - -#include "yarp/defines.h" -#include "yarp/parser.h" - -#include -#include - -// 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 yp_parse does not -// have the contract that the string is null-terminated. (This is desirable -// because it means the extension can call yp_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 * yp_strpbrk(yp_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length); - -#endif diff --git a/yarp/version.h b/yarp/version.h deleted file mode 100644 index 6c7dd068d33c0f..00000000000000 --- a/yarp/version.h +++ /dev/null @@ -1,4 +0,0 @@ -#define YP_VERSION_MAJOR 0 -#define YP_VERSION_MINOR 11 -#define YP_VERSION_PATCH 0 -#define YP_VERSION "0.11.0" diff --git a/yarp/yarp.c b/yarp/yarp.c deleted file mode 100644 index 820361e25a7c01..00000000000000 --- a/yarp/yarp.c +++ /dev/null @@ -1,13955 +0,0 @@ -#include "yarp.h" - -// The YARP version and the serialization format. -const char * -yp_version(void) { - return YP_VERSION; -} - -// In heredocs, tabs automatically complete up to the next 8 spaces. This is -// defined in CRuby as TAB_WIDTH. -#define YP_TAB_WHITESPACE_SIZE 8 - -// Debugging logging will provide you will additional debugging functions as -// well as automatically replace some functions with their debugging -// counterparts. -#ifndef YP_DEBUG_LOGGING -#define YP_DEBUG_LOGGING 0 -#endif - -#if YP_DEBUG_LOGGING - -/******************************************************************************/ -/* Debugging */ -/******************************************************************************/ - -YP_ATTRIBUTE_UNUSED static const char * -debug_context(yp_context_t context) { - switch (context) { - case YP_CONTEXT_BEGIN: return "BEGIN"; - case YP_CONTEXT_CLASS: return "CLASS"; - case YP_CONTEXT_CASE_IN: return "CASE_IN"; - case YP_CONTEXT_CASE_WHEN: return "CASE_WHEN"; - case YP_CONTEXT_DEF: return "DEF"; - case YP_CONTEXT_DEF_PARAMS: return "DEF_PARAMS"; - case YP_CONTEXT_DEFAULT_PARAMS: return "DEFAULT_PARAMS"; - case YP_CONTEXT_ENSURE: return "ENSURE"; - case YP_CONTEXT_ELSE: return "ELSE"; - case YP_CONTEXT_ELSIF: return "ELSIF"; - case YP_CONTEXT_EMBEXPR: return "EMBEXPR"; - case YP_CONTEXT_BLOCK_BRACES: return "BLOCK_BRACES"; - case YP_CONTEXT_BLOCK_KEYWORDS: return "BLOCK_KEYWORDS"; - case YP_CONTEXT_FOR: return "FOR"; - case YP_CONTEXT_IF: return "IF"; - case YP_CONTEXT_MAIN: return "MAIN"; - case YP_CONTEXT_MODULE: return "MODULE"; - case YP_CONTEXT_PARENS: return "PARENS"; - case YP_CONTEXT_POSTEXE: return "POSTEXE"; - case YP_CONTEXT_PREDICATE: return "PREDICATE"; - case YP_CONTEXT_PREEXE: return "PREEXE"; - case YP_CONTEXT_RESCUE: return "RESCUE"; - case YP_CONTEXT_RESCUE_ELSE: return "RESCUE_ELSE"; - case YP_CONTEXT_SCLASS: return "SCLASS"; - case YP_CONTEXT_UNLESS: return "UNLESS"; - case YP_CONTEXT_UNTIL: return "UNTIL"; - case YP_CONTEXT_WHILE: return "WHILE"; - case YP_CONTEXT_LAMBDA_BRACES: return "LAMBDA_BRACES"; - case YP_CONTEXT_LAMBDA_DO_END: return "LAMBDA_DO_END"; - } - return NULL; -} - -YP_ATTRIBUTE_UNUSED static void -debug_contexts(yp_parser_t *parser) { - yp_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"); -} - -YP_ATTRIBUTE_UNUSED static void -debug_node(const char *message, yp_parser_t *parser, yp_node_t *node) { - yp_buffer_t buffer; - if (!yp_buffer_init(&buffer)) return; - - yp_prettyprint(parser, node, &buffer); - - fprintf(stderr, "%s\n%.*s\n", message, (int) buffer.length, buffer.value); - yp_buffer_free(&buffer); -} - -YP_ATTRIBUTE_UNUSED static void -debug_lex_mode(yp_parser_t *parser) { - yp_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 YP_LEX_DEFAULT: fprintf(stderr, "DEFAULT"); break; - case YP_LEX_EMBEXPR: fprintf(stderr, "EMBEXPR"); break; - case YP_LEX_EMBVAR: fprintf(stderr, "EMBVAR"); break; - case YP_LEX_HEREDOC: fprintf(stderr, "HEREDOC"); break; - case YP_LEX_LIST: fprintf(stderr, "LIST (terminator=%c, interpolation=%d)", lex_mode->as.list.terminator, lex_mode->as.list.interpolation); break; - case YP_LEX_REGEXP: fprintf(stderr, "REGEXP (terminator=%c)", lex_mode->as.regexp.terminator); break; - case YP_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"); -} - -YP_ATTRIBUTE_UNUSED static void -debug_state(yp_parser_t *parser) { - fprintf(stderr, "STATE: "); - bool first = true; - - if (parser->lex_state == YP_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(YP_LEX_STATE_BEG) - CHECK_STATE(YP_LEX_STATE_END) - CHECK_STATE(YP_LEX_STATE_ENDARG) - CHECK_STATE(YP_LEX_STATE_ENDFN) - CHECK_STATE(YP_LEX_STATE_ARG) - CHECK_STATE(YP_LEX_STATE_CMDARG) - CHECK_STATE(YP_LEX_STATE_MID) - CHECK_STATE(YP_LEX_STATE_FNAME) - CHECK_STATE(YP_LEX_STATE_DOT) - CHECK_STATE(YP_LEX_STATE_CLASS) - CHECK_STATE(YP_LEX_STATE_LABEL) - CHECK_STATE(YP_LEX_STATE_LABELED) - CHECK_STATE(YP_LEX_STATE_FITEM) - -#undef CHECK_STATE - - fprintf(stderr, "\n"); -} - -YP_ATTRIBUTE_UNUSED static void -debug_token(yp_token_t * token) { - fprintf(stderr, "%s: \"%.*s\"\n", yp_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(yp_parser_t *parser, yp_lex_mode_t lex_mode) { - lex_mode.prev = parser->lex_modes.current; - parser->lex_modes.index++; - - if (parser->lex_modes.index > YP_LEX_STACK_SIZE - 1) { - parser->lex_modes.current = (yp_lex_mode_t *) malloc(sizeof(yp_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(yp_parser_t *parser, bool interpolation, uint8_t delimiter) { - uint8_t incrementor = lex_mode_incrementor(delimiter); - uint8_t terminator = lex_mode_terminator(delimiter); - - yp_lex_mode_t lex_mode = { - .mode = YP_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; - } - - return lex_mode_push(parser, lex_mode); -} - -// Push on a new regexp lex mode. -static inline bool -lex_mode_push_regexp(yp_parser_t *parser, uint8_t incrementor, uint8_t terminator) { - yp_lex_mode_t lex_mode = { - .mode = YP_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(yp_parser_t *parser, bool interpolation, bool label_allowed, uint8_t incrementor, uint8_t terminator) { - yp_lex_mode_t lex_mode = { - .mode = YP_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; - } - - return lex_mode_push(parser, lex_mode); -} - -// 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(yp_parser_t *parser) { - if (parser->lex_modes.index == 0) { - parser->lex_modes.current->mode = YP_LEX_DEFAULT; - } else if (parser->lex_modes.index < YP_LEX_STACK_SIZE) { - parser->lex_modes.index--; - parser->lex_modes.current = &parser->lex_modes.stack[parser->lex_modes.index]; - } else { - parser->lex_modes.index--; - yp_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(yp_parser_t *parser, yp_lex_state_t state) { - return parser->lex_state & state; -} - -typedef enum { - YP_IGNORED_NEWLINE_NONE = 0, - YP_IGNORED_NEWLINE_ALL, - YP_IGNORED_NEWLINE_PATTERN -} yp_ignored_newline_type_t; - -static inline yp_ignored_newline_type_t -lex_state_ignored_p(yp_parser_t *parser) { - bool ignored = lex_state_p(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_CLASS | YP_LEX_STATE_FNAME | YP_LEX_STATE_DOT) && !lex_state_p(parser, YP_LEX_STATE_LABELED); - - if (ignored) { - return YP_IGNORED_NEWLINE_ALL; - } else if ((parser->lex_state & ~((unsigned int) YP_LEX_STATE_LABEL)) == (YP_LEX_STATE_ARG | YP_LEX_STATE_LABELED)) { - return YP_IGNORED_NEWLINE_PATTERN; - } else { - return YP_IGNORED_NEWLINE_NONE; - } -} - -static inline bool -lex_state_beg_p(yp_parser_t *parser) { - return lex_state_p(parser, YP_LEX_STATE_BEG_ANY) || (parser->lex_state == (YP_LEX_STATE_ARG | YP_LEX_STATE_LABELED)); -} - -static inline bool -lex_state_arg_p(yp_parser_t *parser) { - return lex_state_p(parser, YP_LEX_STATE_ARG_ANY); -} - -static inline bool -lex_state_spcarg_p(yp_parser_t *parser, bool space_seen) { - if (parser->current.end >= parser->end) { - return false; - } - return lex_state_arg_p(parser) && space_seen && !yp_char_is_whitespace(*parser->current.end); -} - -static inline bool -lex_state_end_p(yp_parser_t *parser) { - return lex_state_p(parser, YP_LEX_STATE_END_ANY); -} - -// This is the equivalent of IS_AFTER_OPERATOR in CRuby. -static inline bool -lex_state_operator_p(yp_parser_t *parser) { - return lex_state_p(parser, YP_LEX_STATE_FNAME | YP_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(yp_parser_t *parser, yp_lex_state_t state) { - parser->lex_state = state; -} - -#if YP_DEBUG_LOGGING -static inline void -debug_lex_state_set(yp_parser_t *parser, yp_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 - -/******************************************************************************/ -/* Node-related functions */ -/******************************************************************************/ - -// Retrieve the constant pool id for the given location. -static inline yp_constant_id_t -yp_parser_constant_id_location(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - return yp_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start)); -} - -// Retrieve the constant pool id for the given string. -static inline yp_constant_id_t -yp_parser_constant_id_owned(yp_parser_t *parser, const uint8_t *start, size_t length) { - return yp_constant_pool_insert_owned(&parser->constant_pool, start, length); -} - -// Retrieve the constant pool id for the given token. -static inline yp_constant_id_t -yp_parser_constant_id_token(yp_parser_t *parser, const yp_token_t *token) { - return yp_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 yp_constant_id_t -yp_parser_optional_constant_id_token(yp_parser_t *parser, const yp_token_t *token) { - return token->type == YP_TOKEN_NOT_PROVIDED ? 0 : yp_parser_constant_id_token(parser, token); -} - -// Mark any range nodes in this subtree as flipflops. -static void -yp_flip_flop(yp_node_t *node) { - switch (YP_NODE_TYPE(node)) { - case YP_AND_NODE: { - yp_and_node_t *cast = (yp_and_node_t *) node; - yp_flip_flop(cast->left); - yp_flip_flop(cast->right); - break; - } - case YP_OR_NODE: { - yp_or_node_t *cast = (yp_or_node_t *) node; - yp_flip_flop(cast->left); - yp_flip_flop(cast->right); - break; - } - case YP_PARENTHESES_NODE: { - yp_parentheses_node_t *cast = (yp_parentheses_node_t *) node; - - if ((cast->body != NULL) && YP_NODE_TYPE_P(cast->body, YP_STATEMENTS_NODE)) { - yp_statements_node_t *statements = (yp_statements_node_t *) cast->body; - if (statements->body.size == 1) yp_flip_flop(statements->body.nodes[0]); - } - - break; - } - case YP_RANGE_NODE: { - yp_range_node_t *cast = (yp_range_node_t *) node; - if (cast->left) { - yp_flip_flop(cast->left); - } - if (cast->right) { - yp_flip_flop(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. - assert(sizeof(yp_range_node_t) == sizeof(yp_flip_flop_node_t)); - node->type = YP_FLIP_FLOP_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: -// -// yp_token_t token; -// not_provided(&token, parser->previous.end); -// -static inline yp_token_t -not_provided(yp_parser_t *parser) { - return (yp_token_t) { .type = YP_TOKEN_NOT_PROVIDED, .start = parser->start, .end = parser->start }; -} - -#define YP_LOCATION_NULL_VALUE(parser) ((yp_location_t) { .start = parser->start, .end = parser->start }) -#define YP_LOCATION_TOKEN_VALUE(token) ((yp_location_t) { .start = (token)->start, .end = (token)->end }) -#define YP_LOCATION_NODE_VALUE(node) ((yp_location_t) { .start = (node)->location.start, .end = (node)->location.end }) -#define YP_LOCATION_NODE_BASE_VALUE(node) ((yp_location_t) { .start = (node)->base.location.start, .end = (node)->base.location.end }) -#define YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE ((yp_location_t) { .start = NULL, .end = NULL }) -#define YP_OPTIONAL_LOCATION_TOKEN_VALUE(token) ((token)->type == YP_TOKEN_NOT_PROVIDED ? YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE : YP_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 { - yp_location_t opening_loc; - yp_arguments_node_t *arguments; - yp_location_t closing_loc; - yp_block_node_t *block; - - // This boolean is used to tell if there is an implicit block (i.e., an - // argument passed with an & operator). - bool implicit_block; -} yp_arguments_t; - -#define YP_EMPTY_ARGUMENTS ((yp_arguments_t) { \ - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, \ - .arguments = NULL, \ - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, \ - .block = NULL, \ - .implicit_block = false \ -}) - -// Check that the set of arguments parsed for a given node is valid. This means -// checking that we don't have both an implicit and explicit block. -static void -yp_arguments_validate(yp_parser_t *parser, yp_arguments_t *arguments) { - if (arguments->block != NULL && arguments->implicit_block) { - yp_diagnostic_list_append( - &parser->error_list, - arguments->block->base.location.start, - arguments->block->base.location.end, - YP_ERR_ARGUMENT_BLOCK_MULTI - ); - } -} - -/******************************************************************************/ -/* Scope node functions */ -/******************************************************************************/ - -// Generate a scope node from the given node. -void -yp_scope_node_init(yp_node_t *node, yp_scope_node_t *scope) { - scope->base.type = YP_SCOPE_NODE; - scope->base.location.start = node->location.start; - scope->base.location.end = node->location.end; - - scope->parameters = NULL; - scope->body = NULL; - yp_constant_id_list_init(&scope->locals); - - switch (YP_NODE_TYPE(node)) { - case YP_BLOCK_NODE: { - yp_block_node_t *cast = (yp_block_node_t *) node; - if (cast->parameters) scope->parameters = cast->parameters->parameters; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - case YP_CLASS_NODE: { - yp_class_node_t *cast = (yp_class_node_t *) node; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - case YP_DEF_NODE: { - yp_def_node_t *cast = (yp_def_node_t *) node; - scope->parameters = cast->parameters; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - case YP_LAMBDA_NODE: { - yp_lambda_node_t *cast = (yp_lambda_node_t *) node; - if (cast->parameters) scope->parameters = cast->parameters->parameters; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - case YP_MODULE_NODE: { - yp_module_node_t *cast = (yp_module_node_t *) node; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - case YP_PROGRAM_NODE: { - yp_program_node_t *cast = (yp_program_node_t *) node; - scope->body = (yp_node_t *) cast->statements; - scope->locals = cast->locals; - break; - } - case YP_SINGLETON_CLASS_NODE: { - yp_singleton_class_node_t *cast = (yp_singleton_class_node_t *) node; - scope->body = cast->body; - scope->locals = cast->locals; - break; - } - default: - assert(false && "unreachable"); - break; - } -} - -/******************************************************************************/ -/* 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(yp_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)) { - yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL); - value = UINT32_MAX; - } - - free(digits); - - if (value > UINT32_MAX) { - yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL); - value = UINT32_MAX; - } - - return (uint32_t) value; -} - -// Parse out the options for a regular expression. -static inline yp_node_flags_t -yp_regular_expression_flags_create(const yp_token_t *closing) { - yp_node_flags_t flags = 0; - - if (closing->type == YP_TOKEN_REGEXP_END) { - for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) { - switch (*flag) { - case 'i': flags |= YP_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break; - case 'm': flags |= YP_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break; - case 'x': flags |= YP_REGULAR_EXPRESSION_FLAGS_EXTENDED; break; - case 'e': flags |= YP_REGULAR_EXPRESSION_FLAGS_EUC_JP; break; - case 'n': flags |= YP_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT; break; - case 's': flags |= YP_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J; break; - case 'u': flags |= YP_REGULAR_EXPRESSION_FLAGS_UTF_8; break; - case 'o': flags |= YP_REGULAR_EXPRESSION_FLAGS_ONCE; break; - default: assert(false && "unreachable"); - } - } - } - - return flags; -} - -// Allocate and initialize a new StatementsNode node. -static yp_statements_node_t * -yp_statements_node_create(yp_parser_t *parser); - -// Append a new node to the given StatementsNode node's body. -static void -yp_statements_node_body_append(yp_statements_node_t *node, yp_node_t *statement); - -// This function is here to allow us a place to extend in the future when we -// implement our own arena allocation. -static inline void * -yp_alloc_node(YP_ATTRIBUTE_UNUSED yp_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 YP_ALLOC_NODE(parser, type) (type *) yp_alloc_node(parser, sizeof(type)) - -// Allocate a new MissingNode node. -static yp_missing_node_t * -yp_missing_node_create(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - yp_missing_node_t *node = YP_ALLOC_NODE(parser, yp_missing_node_t); - *node = (yp_missing_node_t) {{ .type = YP_MISSING_NODE, .location = { .start = start, .end = end } }}; - return node; -} - -// Allocate and initialize a new alias node. -static yp_alias_node_t * -yp_alias_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *new_name, yp_node_t *old_name) { - assert(keyword->type == YP_TOKEN_KEYWORD_ALIAS); - yp_alias_node_t *node = YP_ALLOC_NODE(parser, yp_alias_node_t); - - *node = (yp_alias_node_t) { - { - .type = YP_ALIAS_NODE, - .location = { - .start = keyword->start, - .end = old_name->location.end - }, - }, - .new_name = new_name, - .old_name = old_name, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword) - }; - - return node; -} - -// Allocate a new AlternationPatternNode node. -static yp_alternation_pattern_node_t * -yp_alternation_pattern_node_create(yp_parser_t *parser, yp_node_t *left, yp_node_t *right, const yp_token_t *operator) { - yp_alternation_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_alternation_pattern_node_t); - - *node = (yp_alternation_pattern_node_t) { - { - .type = YP_ALTERNATION_PATTERN_NODE, - .location = { - .start = left->location.start, - .end = right->location.end - }, - }, - .left = left, - .right = right, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new and node. -static yp_and_node_t * -yp_and_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *operator, yp_node_t *right) { - yp_and_node_t *node = YP_ALLOC_NODE(parser, yp_and_node_t); - - *node = (yp_and_node_t) { - { - .type = YP_AND_NODE, - .location = { - .start = left->location.start, - .end = right->location.end - }, - }, - .left = left, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .right = right - }; - - return node; -} - -// Allocate an initialize a new arguments node. -static yp_arguments_node_t * -yp_arguments_node_create(yp_parser_t *parser) { - yp_arguments_node_t *node = YP_ALLOC_NODE(parser, yp_arguments_node_t); - - *node = (yp_arguments_node_t) { - { - .type = YP_ARGUMENTS_NODE, - .location = YP_LOCATION_NULL_VALUE(parser) - }, - .arguments = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Return the size of the given arguments node. -static size_t -yp_arguments_node_size(yp_arguments_node_t *node) { - return node->arguments.size; -} - -// Append an argument to an arguments node. -static void -yp_arguments_node_arguments_append(yp_arguments_node_t *node, yp_node_t *argument) { - if (yp_arguments_node_size(node) == 0) { - node->base.location.start = argument->location.start; - } - - node->base.location.end = argument->location.end; - yp_node_list_append(&node->arguments, argument); -} - -// Allocate and initialize a new ArrayNode node. -static yp_array_node_t * -yp_array_node_create(yp_parser_t *parser, const yp_token_t *opening) { - yp_array_node_t *node = YP_ALLOC_NODE(parser, yp_array_node_t); - - *node = (yp_array_node_t) { - { - .type = YP_ARRAY_NODE, - .location = YP_LOCATION_TOKEN_VALUE(opening) - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .elements = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Return the size of the given array node. -static inline size_t -yp_array_node_size(yp_array_node_t *node) { - return node->elements.size; -} - -// Append an argument to an array node. -static inline void -yp_array_node_elements_append(yp_array_node_t *node, yp_node_t *element) { - if (!node->elements.size && !node->opening_loc.start) { - node->base.location.start = element->location.start; - } - yp_node_list_append(&node->elements, element); - node->base.location.end = element->location.end; -} - -// Set the closing token and end location of an array node. -static void -yp_array_node_close_set(yp_array_node_t *node, const yp_token_t *closing) { - assert(closing->type == YP_TOKEN_BRACKET_RIGHT || closing->type == YP_TOKEN_STRING_END || closing->type == YP_TOKEN_MISSING || closing->type == YP_TOKEN_NOT_PROVIDED); - node->base.location.end = closing->end; - node->closing_loc = YP_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 yp_array_pattern_node_t * -yp_array_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *nodes) { - yp_array_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_array_pattern_node_t); - - *node = (yp_array_pattern_node_t) { - { - .type = YP_ARRAY_PATTERN_NODE, - .location = { - .start = nodes->nodes[0]->location.start, - .end = nodes->nodes[nodes->size - 1]->location.end - }, - }, - .constant = NULL, - .rest = NULL, - .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST, - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .closing_loc = YP_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++) { - yp_node_t *child = nodes->nodes[index]; - - if (!found_rest && YP_NODE_TYPE_P(child, YP_SPLAT_NODE)) { - node->rest = child; - found_rest = true; - } else if (found_rest) { - yp_node_list_append(&node->posts, child); - } else { - yp_node_list_append(&node->requireds, child); - } - } - - return node; -} - -// Allocate and initialize a new array pattern node from a single rest node. -static yp_array_pattern_node_t * -yp_array_pattern_node_rest_create(yp_parser_t *parser, yp_node_t *rest) { - yp_array_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_array_pattern_node_t); - - *node = (yp_array_pattern_node_t) { - { - .type = YP_ARRAY_PATTERN_NODE, - .location = rest->location, - }, - .constant = NULL, - .rest = rest, - .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST, - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -// Allocate and initialize a new array pattern node from a constant and opening -// and closing tokens. -static yp_array_pattern_node_t * -yp_array_pattern_node_constant_create(yp_parser_t *parser, yp_node_t *constant, const yp_token_t *opening, const yp_token_t *closing) { - yp_array_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_array_pattern_node_t); - - *node = (yp_array_pattern_node_t) { - { - .type = YP_ARRAY_PATTERN_NODE, - .location = { - .start = constant->location.start, - .end = closing->end - }, - }, - .constant = constant, - .rest = NULL, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Allocate and initialize a new array pattern node from an opening and closing -// token. -static yp_array_pattern_node_t * -yp_array_pattern_node_empty_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *closing) { - yp_array_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_array_pattern_node_t); - - *node = (yp_array_pattern_node_t) { - { - .type = YP_ARRAY_PATTERN_NODE, - .location = { - .start = opening->start, - .end = closing->end - }, - }, - .constant = NULL, - .rest = NULL, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST - }; - - return node; -} - -static inline void -yp_array_pattern_node_requireds_append(yp_array_pattern_node_t *node, yp_node_t *inner) { - yp_node_list_append(&node->requireds, inner); -} - -// Allocate and initialize a new assoc node. -static yp_assoc_node_t * -yp_assoc_node_create(yp_parser_t *parser, yp_node_t *key, const yp_token_t *operator, yp_node_t *value) { - yp_assoc_node_t *node = YP_ALLOC_NODE(parser, yp_assoc_node_t); - const uint8_t *end; - - if (value != NULL) { - end = value->location.end; - } else if (operator->type != YP_TOKEN_NOT_PROVIDED) { - end = operator->end; - } else { - end = key->location.end; - } - - *node = (yp_assoc_node_t) { - { - .type = YP_ASSOC_NODE, - .location = { - .start = key->location.start, - .end = end - }, - }, - .key = key, - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new assoc splat node. -static yp_assoc_splat_node_t * -yp_assoc_splat_node_create(yp_parser_t *parser, yp_node_t *value, const yp_token_t *operator) { - assert(operator->type == YP_TOKEN_USTAR_STAR); - yp_assoc_splat_node_t *node = YP_ALLOC_NODE(parser, yp_assoc_splat_node_t); - - *node = (yp_assoc_splat_node_t) { - { - .type = YP_ASSOC_SPLAT_NODE, - .location = { - .start = operator->start, - .end = value == NULL ? operator->end : value->location.end - }, - }, - .value = value, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate a new BackReferenceReadNode node. -static yp_back_reference_read_node_t * -yp_back_reference_read_node_create(yp_parser_t *parser, const yp_token_t *name) { - assert(name->type == YP_TOKEN_BACK_REFERENCE); - yp_back_reference_read_node_t *node = YP_ALLOC_NODE(parser, yp_back_reference_read_node_t); - - *node = (yp_back_reference_read_node_t) { - { - .type = YP_BACK_REFERENCE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name), - } - }; - - return node; -} - -// Allocate and initialize new a begin node. -static yp_begin_node_t * -yp_begin_node_create(yp_parser_t *parser, const yp_token_t *begin_keyword, yp_statements_node_t *statements) { - yp_begin_node_t *node = YP_ALLOC_NODE(parser, yp_begin_node_t); - - *node = (yp_begin_node_t) { - { - .type = YP_BEGIN_NODE, - .location = { - .start = begin_keyword->start, - .end = statements == NULL ? begin_keyword->end : statements->base.location.end - }, - }, - .begin_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(begin_keyword), - .statements = statements, - .end_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -// Set the rescue clause, optionally start, and end location of a begin node. -static void -yp_begin_node_rescue_clause_set(yp_begin_node_t *node, yp_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 -yp_begin_node_else_clause_set(yp_begin_node_t *node, yp_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 -yp_begin_node_ensure_clause_set(yp_begin_node_t *node, yp_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 -yp_begin_node_end_keyword_set(yp_begin_node_t *node, const yp_token_t *end_keyword) { - assert(end_keyword->type == YP_TOKEN_KEYWORD_END || end_keyword->type == YP_TOKEN_MISSING); - - node->base.location.end = end_keyword->end; - node->end_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword); -} - -// Allocate and initialize a new BlockArgumentNode node. -static yp_block_argument_node_t * -yp_block_argument_node_create(yp_parser_t *parser, const yp_token_t *operator, yp_node_t *expression) { - yp_block_argument_node_t *node = YP_ALLOC_NODE(parser, yp_block_argument_node_t); - - *node = (yp_block_argument_node_t) { - { - .type = YP_BLOCK_ARGUMENT_NODE, - .location = { - .start = operator->start, - .end = expression == NULL ? operator->end : expression->location.end - }, - }, - .expression = expression, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new BlockNode node. -static yp_block_node_t * -yp_block_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *opening, yp_block_parameters_node_t *parameters, yp_node_t *body, const yp_token_t *closing) { - yp_block_node_t *node = YP_ALLOC_NODE(parser, yp_block_node_t); - - *node = (yp_block_node_t) { - { - .type = YP_BLOCK_NODE, - .location = { .start = opening->start, .end = closing->end }, - }, - .locals = *locals, - .parameters = parameters, - .body = body, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) - }; - - return node; -} - -// Allocate and initialize a new BlockParameterNode node. -static yp_block_parameter_node_t * -yp_block_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, const yp_token_t *operator) { - assert(operator->type == YP_TOKEN_NOT_PROVIDED || operator->type == YP_TOKEN_UAMPERSAND || operator->type == YP_TOKEN_AMPERSAND); - yp_block_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_block_parameter_node_t); - - *node = (yp_block_parameter_node_t) { - { - .type = YP_BLOCK_PARAMETER_NODE, - .location = { - .start = operator->start, - .end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end) - }, - }, - .name = yp_parser_optional_constant_id_token(parser, name), - .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new BlockParametersNode node. -static yp_block_parameters_node_t * -yp_block_parameters_node_create(yp_parser_t *parser, yp_parameters_node_t *parameters, const yp_token_t *opening) { - yp_block_parameters_node_t *node = YP_ALLOC_NODE(parser, yp_block_parameters_node_t); - - const uint8_t *start; - if (opening->type != YP_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 != YP_TOKEN_NOT_PROVIDED) { - end = opening->end; - } else { - end = NULL; - } - - *node = (yp_block_parameters_node_t) { - { - .type = YP_BLOCK_PARAMETERS_NODE, - .location = { - .start = start, - .end = end - } - }, - .parameters = parameters, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .locals = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Set the closing location of a BlockParametersNode node. -static void -yp_block_parameters_node_closing_set(yp_block_parameters_node_t *node, const yp_token_t *closing) { - assert(closing->type == YP_TOKEN_PIPE || closing->type == YP_TOKEN_PARENTHESIS_RIGHT || closing->type == YP_TOKEN_MISSING); - - node->base.location.end = closing->end; - node->closing_loc = YP_LOCATION_TOKEN_VALUE(closing); -} - -// Allocate and initialize a new BlockLocalVariableNode node. -static yp_block_local_variable_node_t * -yp_block_local_variable_node_create(yp_parser_t *parser, const yp_token_t *name) { - assert(name->type == YP_TOKEN_IDENTIFIER || name->type == YP_TOKEN_MISSING); - yp_block_local_variable_node_t *node = YP_ALLOC_NODE(parser, yp_block_local_variable_node_t); - - *node = (yp_block_local_variable_node_t) { - { - .type = YP_BLOCK_LOCAL_VARIABLE_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name), - }, - .name = yp_parser_constant_id_token(parser, name) - }; - - return node; -} - -// Append a new block-local variable to a BlockParametersNode node. -static void -yp_block_parameters_node_append_local(yp_block_parameters_node_t *node, const yp_block_local_variable_node_t *local) { - yp_node_list_append(&node->locals, (yp_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 yp_break_node_t * -yp_break_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_arguments_node_t *arguments) { - assert(keyword->type == YP_TOKEN_KEYWORD_BREAK); - yp_break_node_t *node = YP_ALLOC_NODE(parser, yp_break_node_t); - - *node = (yp_break_node_t) { - { - .type = YP_BREAK_NODE, - .location = { - .start = keyword->start, - .end = (arguments == NULL ? keyword->end : arguments->base.location.end) - }, - }, - .arguments = arguments, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword) - }; - - return node; -} - -// Allocate and initialize a new CallNode node. This sets everything to NULL or -// YP_TOKEN_NOT_PROVIDED as appropriate such that its values can be overridden -// in the various specializations of this function. -static yp_call_node_t * -yp_call_node_create(yp_parser_t *parser) { - yp_call_node_t *node = YP_ALLOC_NODE(parser, yp_call_node_t); - - *node = (yp_call_node_t) { - { - .type = YP_CALL_NODE, - .location = YP_LOCATION_NULL_VALUE(parser), - }, - .receiver = NULL, - .call_operator_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .message_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .arguments = NULL, - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .block = NULL - }; - - return node; -} - -// Allocate and initialize a new CallNode node from an aref or an aset -// expression. -static yp_call_node_t * -yp_call_node_aref_create(yp_parser_t *parser, yp_node_t *receiver, yp_arguments_t *arguments) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location.start = receiver->location.start; - if (arguments->block != NULL) { - node->base.location.end = arguments->block->base.location.end; - } else { - node->base.location.end = arguments->closing_loc.end; - } - - 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; - - yp_string_constant_init(&node->name, "[]", 2); - return node; -} - -// Allocate and initialize a new CallNode node from a binary expression. -static yp_call_node_t * -yp_call_node_binary_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *operator, yp_node_t *argument) { - yp_call_node_t *node = yp_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 = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); - - yp_arguments_node_t *arguments = yp_arguments_node_create(parser); - yp_arguments_node_arguments_append(arguments, argument); - node->arguments = arguments; - - yp_string_shared_init(&node->name, operator->start, operator->end); - return node; -} - -// Allocate and initialize a new CallNode node from a call expression. -static yp_call_node_t * -yp_call_node_call_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *operator, yp_token_t *message, yp_arguments_t *arguments) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location.start = receiver->location.start; - if (arguments->block != NULL) { - node->base.location.end = arguments->block->base.location.end; - } else if (arguments->closing_loc.start != NULL) { - node->base.location.end = arguments->closing_loc.end; - } else if (arguments->arguments != NULL) { - node->base.location.end = arguments->arguments->base.location.end; - } else { - node->base.location.end = message->end; - } - - node->receiver = receiver; - node->call_operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); - node->message_loc = YP_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 == YP_TOKEN_AMPERSAND_DOT) { - node->base.flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION; - } - - yp_string_shared_init(&node->name, message->start, message->end); - 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 yp_call_node_t * -yp_call_node_fcall_create(yp_parser_t *parser, yp_token_t *message, yp_arguments_t *arguments) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location.start = message->start; - if (arguments->block != NULL) { - node->base.location.end = arguments->block->base.location.end; - } else if (arguments->closing_loc.start != NULL) { - node->base.location.end = arguments->closing_loc.end; - } else if (arguments->arguments != NULL) { - node->base.location.end = arguments->arguments->base.location.end; - } else { - node->base.location.end = arguments->closing_loc.end; - } - - node->message_loc = YP_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; - - yp_string_shared_init(&node->name, message->start, message->end); - return node; -} - -// Allocate and initialize a new CallNode node from a not expression. -static yp_call_node_t * -yp_call_node_not_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *message, yp_arguments_t *arguments) { - yp_call_node_t *node = yp_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 = YP_OPTIONAL_LOCATION_TOKEN_VALUE(message); - node->opening_loc = arguments->opening_loc; - node->arguments = arguments->arguments; - node->closing_loc = arguments->closing_loc; - - yp_string_constant_init(&node->name, "!", 1); - return node; -} - -// Allocate and initialize a new CallNode node from a call shorthand expression. -static yp_call_node_t * -yp_call_node_shorthand_create(yp_parser_t *parser, yp_node_t *receiver, yp_token_t *operator, yp_arguments_t *arguments) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location.start = receiver->location.start; - if (arguments->block != NULL) { - node->base.location.end = arguments->block->base.location.end; - } else { - node->base.location.end = arguments->closing_loc.end; - } - - node->receiver = receiver; - node->call_operator_loc = YP_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 == YP_TOKEN_AMPERSAND_DOT) { - node->base.flags |= YP_CALL_NODE_FLAGS_SAFE_NAVIGATION; - } - - yp_string_constant_init(&node->name, "call", 4); - return node; -} - -// Allocate and initialize a new CallNode node from a unary operator expression. -static yp_call_node_t * -yp_call_node_unary_create(yp_parser_t *parser, yp_token_t *operator, yp_node_t *receiver, const char *name) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location.start = operator->start; - node->base.location.end = receiver->location.end; - - node->receiver = receiver; - node->message_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); - - yp_string_constant_init(&node->name, 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 yp_call_node_t * -yp_call_node_variable_call_create(yp_parser_t *parser, yp_token_t *message) { - yp_call_node_t *node = yp_call_node_create(parser); - - node->base.location = YP_LOCATION_TOKEN_VALUE(message); - node->message_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(message); - - yp_string_shared_init(&node->name, message->start, message->end); - 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 -yp_call_node_variable_call_p(yp_call_node_t *node) { - return node->base.flags & YP_CALL_NODE_FLAGS_VARIABLE_CALL; -} - -// Initialize the read name by reading the write name and chopping off the '='. -static void -yp_call_write_read_name_init(yp_string_t *read_name, yp_string_t *write_name) { - size_t length = write_name->length - 1; - - void *memory = malloc(length); - memcpy(memory, write_name->source, length); - - yp_string_owned_init(read_name, (uint8_t *) memory, length); -} - -// Allocate and initialize a new CallAndWriteNode node. -static yp_call_and_write_node_t * -yp_call_and_write_node_create(yp_parser_t *parser, yp_call_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(target->block == NULL); - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_call_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_call_and_write_node_t); - - *node = (yp_call_and_write_node_t) { - { - .type = YP_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, - .opening_loc = target->opening_loc, - .arguments = target->arguments, - .closing_loc = target->closing_loc, - .read_name = YP_EMPTY_STRING, - .write_name = target->name, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - yp_call_write_read_name_init(&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 `yp_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 yp_call_operator_write_node_t * -yp_call_operator_write_node_create(yp_parser_t *parser, yp_call_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(target->block == NULL); - yp_call_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_call_operator_write_node_t); - - *node = (yp_call_operator_write_node_t) { - { - .type = YP_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, - .opening_loc = target->opening_loc, - .arguments = target->arguments, - .closing_loc = target->closing_loc, - .read_name = YP_EMPTY_STRING, - .write_name = target->name, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - yp_call_write_read_name_init(&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 `yp_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 CallOperatorOrWriteNode node. -static yp_call_or_write_node_t * -yp_call_or_write_node_create(yp_parser_t *parser, yp_call_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(target->block == NULL); - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_call_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_call_or_write_node_t); - - *node = (yp_call_or_write_node_t) { - { - .type = YP_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, - .opening_loc = target->opening_loc, - .arguments = target->arguments, - .closing_loc = target->closing_loc, - .read_name = YP_EMPTY_STRING, - .write_name = target->name, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - yp_call_write_read_name_init(&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 `yp_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 yp_capture_pattern_node_t * -yp_capture_pattern_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t *target, const yp_token_t *operator) { - yp_capture_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_capture_pattern_node_t); - - *node = (yp_capture_pattern_node_t) { - { - .type = YP_CAPTURE_PATTERN_NODE, - .location = { - .start = value->location.start, - .end = target->location.end - }, - }, - .value = value, - .target = target, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new CaseNode node. -static yp_case_node_t * -yp_case_node_create(yp_parser_t *parser, const yp_token_t *case_keyword, yp_node_t *predicate, yp_else_node_t *consequent, const yp_token_t *end_keyword) { - yp_case_node_t *node = YP_ALLOC_NODE(parser, yp_case_node_t); - - *node = (yp_case_node_t) { - { - .type = YP_CASE_NODE, - .location = { - .start = case_keyword->start, - .end = end_keyword->end - }, - }, - .predicate = predicate, - .consequent = consequent, - .case_keyword_loc = YP_LOCATION_TOKEN_VALUE(case_keyword), - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword), - .conditions = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Append a new condition to a CaseNode node. -static void -yp_case_node_condition_append(yp_case_node_t *node, yp_node_t *condition) { - assert(YP_NODE_TYPE_P(condition, YP_WHEN_NODE) || YP_NODE_TYPE_P(condition, YP_IN_NODE)); - - yp_node_list_append(&node->conditions, condition); - node->base.location.end = condition->location.end; -} - -// Set the consequent of a CaseNode node. -static void -yp_case_node_consequent_set(yp_case_node_t *node, yp_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 -yp_case_node_end_keyword_loc_set(yp_case_node_t *node, const yp_token_t *end_keyword) { - node->base.location.end = end_keyword->end; - node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword); -} - -// Allocate a new ClassNode node. -static yp_class_node_t * -yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *name, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *body, const yp_token_t *end_keyword) { - yp_class_node_t *node = YP_ALLOC_NODE(parser, yp_class_node_t); - - *node = (yp_class_node_t) { - { - .type = YP_CLASS_NODE, - .location = { .start = class_keyword->start, .end = end_keyword->end }, - }, - .locals = *locals, - .class_keyword_loc = YP_LOCATION_TOKEN_VALUE(class_keyword), - .constant_path = constant_path, - .inheritance_operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(inheritance_operator), - .superclass = superclass, - .body = body, - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword), - .name = yp_parser_constant_id_token(parser, name) - }; - - return node; -} - -// Allocate and initialize a new ClassVariableAndWriteNode node. -static yp_class_variable_and_write_node_t * -yp_class_variable_and_write_node_create(yp_parser_t *parser, yp_class_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_class_variable_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_and_write_node_t); - - *node = (yp_class_variable_and_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ClassVariableOperatorWriteNode node. -static yp_class_variable_operator_write_node_t * -yp_class_variable_operator_write_node_create(yp_parser_t *parser, yp_class_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_class_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_operator_write_node_t); - - *node = (yp_class_variable_operator_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1) - }; - - return node; -} - -// Allocate and initialize a new ClassVariableOrWriteNode node. -static yp_class_variable_or_write_node_t * -yp_class_variable_or_write_node_create(yp_parser_t *parser, yp_class_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_class_variable_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_or_write_node_t); - - *node = (yp_class_variable_or_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ClassVariableReadNode node. -static yp_class_variable_read_node_t * -yp_class_variable_read_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_CLASS_VARIABLE); - yp_class_variable_read_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_read_node_t); - - *node = (yp_class_variable_read_node_t) { - { - .type = YP_CLASS_VARIABLE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .name = yp_parser_constant_id_token(parser, token) - }; - - return node; -} - -// Initialize a new ClassVariableWriteNode node from a ClassVariableRead node. -static yp_class_variable_write_node_t * -yp_class_variable_write_node_create(yp_parser_t *parser, yp_class_variable_read_node_t *read_node, yp_token_t *operator, yp_node_t *value) { - yp_class_variable_write_node_t *node = YP_ALLOC_NODE(parser, yp_class_variable_write_node_t); - - *node = (yp_class_variable_write_node_t) { - { - .type = YP_CLASS_VARIABLE_WRITE_NODE, - .location = { - .start = read_node->base.location.start, - .end = value->location.end - }, - }, - .name = read_node->name, - .name_loc = YP_LOCATION_NODE_VALUE((yp_node_t *) read_node), - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantPathAndWriteNode node. -static yp_constant_path_and_write_node_t * -yp_constant_path_and_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_constant_path_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_and_write_node_t); - - *node = (yp_constant_path_and_write_node_t) { - { - .type = YP_CONSTANT_PATH_AND_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .target = target, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantPathOperatorWriteNode node. -static yp_constant_path_operator_write_node_t * -yp_constant_path_operator_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_constant_path_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_operator_write_node_t); - - *node = (yp_constant_path_operator_write_node_t) { - { - .type = YP_CONSTANT_PATH_OPERATOR_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .target = target, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1) - }; - - return node; -} - -// Allocate and initialize a new ConstantPathOrWriteNode node. -static yp_constant_path_or_write_node_t * -yp_constant_path_or_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_constant_path_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_or_write_node_t); - - *node = (yp_constant_path_or_write_node_t) { - { - .type = YP_CONSTANT_PATH_OR_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .target = target, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantPathNode node. -static yp_constant_path_node_t * -yp_constant_path_node_create(yp_parser_t *parser, yp_node_t *parent, const yp_token_t *delimiter, yp_node_t *child) { - yp_constant_path_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_node_t); - - *node = (yp_constant_path_node_t) { - { - .type = YP_CONSTANT_PATH_NODE, - .location = { - .start = parent == NULL ? delimiter->start : parent->location.start, - .end = child->location.end - }, - }, - .parent = parent, - .child = child, - .delimiter_loc = YP_LOCATION_TOKEN_VALUE(delimiter) - }; - - return node; -} - -// Allocate a new ConstantPathWriteNode node. -static yp_constant_path_write_node_t * -yp_constant_path_write_node_create(yp_parser_t *parser, yp_constant_path_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_constant_path_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_path_write_node_t); - - *node = (yp_constant_path_write_node_t) { - { - .type = YP_CONSTANT_PATH_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - }, - }, - .target = target, - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantAndWriteNode node. -static yp_constant_and_write_node_t * -yp_constant_and_write_node_create(yp_parser_t *parser, yp_constant_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_constant_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_and_write_node_t); - - *node = (yp_constant_and_write_node_t) { - { - .type = YP_CONSTANT_AND_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .name = target->name, - .name_loc = target->base.location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantOperatorWriteNode node. -static yp_constant_operator_write_node_t * -yp_constant_operator_write_node_create(yp_parser_t *parser, yp_constant_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_constant_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_operator_write_node_t); - - *node = (yp_constant_operator_write_node_t) { - { - .type = YP_CONSTANT_OPERATOR_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .name = target->name, - .name_loc = target->base.location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1) - }; - - return node; -} - -// Allocate and initialize a new ConstantOrWriteNode node. -static yp_constant_or_write_node_t * -yp_constant_or_write_node_create(yp_parser_t *parser, yp_constant_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_constant_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_or_write_node_t); - - *node = (yp_constant_or_write_node_t) { - { - .type = YP_CONSTANT_OR_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .name = target->name, - .name_loc = target->base.location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new ConstantReadNode node. -static yp_constant_read_node_t * -yp_constant_read_node_create(yp_parser_t *parser, const yp_token_t *name) { - assert(name->type == YP_TOKEN_CONSTANT || name->type == YP_TOKEN_MISSING); - yp_constant_read_node_t *node = YP_ALLOC_NODE(parser, yp_constant_read_node_t); - - *node = (yp_constant_read_node_t) { - { - .type = YP_CONSTANT_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name) - }, - .name = yp_parser_constant_id_token(parser, name) - }; - - return node; -} - -// Allocate a new ConstantWriteNode node. -static yp_constant_write_node_t * -yp_constant_write_node_create(yp_parser_t *parser, yp_constant_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_constant_write_node_t *node = YP_ALLOC_NODE(parser, yp_constant_write_node_t); - - *node = (yp_constant_write_node_t) { - { - .type = YP_CONSTANT_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .name = target->name, - .name_loc = target->base.location, - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new DefNode node. -static yp_def_node_t * -yp_def_node_create( - yp_parser_t *parser, - const yp_token_t *name, - yp_node_t *receiver, - yp_parameters_node_t *parameters, - yp_node_t *body, - yp_constant_id_list_t *locals, - const yp_token_t *def_keyword, - const yp_token_t *operator, - const yp_token_t *lparen, - const yp_token_t *rparen, - const yp_token_t *equal, - const yp_token_t *end_keyword -) { - yp_def_node_t *node = YP_ALLOC_NODE(parser, yp_def_node_t); - const uint8_t *end; - - if (end_keyword->type == YP_TOKEN_NOT_PROVIDED) { - end = body->location.end; - } else { - end = end_keyword->end; - } - - *node = (yp_def_node_t) { - { - .type = YP_DEF_NODE, - .location = { .start = def_keyword->start, .end = end }, - }, - .name = yp_parser_constant_id_token(parser, name), - .name_loc = YP_LOCATION_TOKEN_VALUE(name), - .receiver = receiver, - .parameters = parameters, - .body = body, - .locals = *locals, - .def_keyword_loc = YP_LOCATION_TOKEN_VALUE(def_keyword), - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .lparen_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(lparen), - .rparen_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(rparen), - .equal_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(equal), - .end_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate a new DefinedNode node. -static yp_defined_node_t * -yp_defined_node_create(yp_parser_t *parser, const yp_token_t *lparen, yp_node_t *value, const yp_token_t *rparen, const yp_location_t *keyword_loc) { - yp_defined_node_t *node = YP_ALLOC_NODE(parser, yp_defined_node_t); - - *node = (yp_defined_node_t) { - { - .type = YP_DEFINED_NODE, - .location = { - .start = keyword_loc->start, - .end = (rparen->type == YP_TOKEN_NOT_PROVIDED ? value->location.end : rparen->end) - }, - }, - .lparen_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(lparen), - .value = value, - .rparen_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(rparen), - .keyword_loc = *keyword_loc - }; - - return node; -} - -// Allocate and initialize a new ElseNode node. -static yp_else_node_t * -yp_else_node_create(yp_parser_t *parser, const yp_token_t *else_keyword, yp_statements_node_t *statements, const yp_token_t *end_keyword) { - yp_else_node_t *node = YP_ALLOC_NODE(parser, yp_else_node_t); - const uint8_t *end = NULL; - if ((end_keyword->type == YP_TOKEN_NOT_PROVIDED) && (statements != NULL)) { - end = statements->base.location.end; - } else { - end = end_keyword->end; - } - - *node = (yp_else_node_t) { - { - .type = YP_ELSE_NODE, - .location = { - .start = else_keyword->start, - .end = end, - }, - }, - .else_keyword_loc = YP_LOCATION_TOKEN_VALUE(else_keyword), - .statements = statements, - .end_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate and initialize a new EmbeddedStatementsNode node. -static yp_embedded_statements_node_t * -yp_embedded_statements_node_create(yp_parser_t *parser, const yp_token_t *opening, yp_statements_node_t *statements, const yp_token_t *closing) { - yp_embedded_statements_node_t *node = YP_ALLOC_NODE(parser, yp_embedded_statements_node_t); - - *node = (yp_embedded_statements_node_t) { - { - .type = YP_EMBEDDED_STATEMENTS_NODE, - .location = { - .start = opening->start, - .end = closing->end - } - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .statements = statements, - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) - }; - - return node; -} - -// Allocate and initialize a new EmbeddedVariableNode node. -static yp_embedded_variable_node_t * -yp_embedded_variable_node_create(yp_parser_t *parser, const yp_token_t *operator, yp_node_t *variable) { - yp_embedded_variable_node_t *node = YP_ALLOC_NODE(parser, yp_embedded_variable_node_t); - - *node = (yp_embedded_variable_node_t) { - { - .type = YP_EMBEDDED_VARIABLE_NODE, - .location = { - .start = operator->start, - .end = variable->location.end - } - }, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .variable = variable - }; - - return node; -} - -// Allocate a new EnsureNode node. -static yp_ensure_node_t * -yp_ensure_node_create(yp_parser_t *parser, const yp_token_t *ensure_keyword, yp_statements_node_t *statements, const yp_token_t *end_keyword) { - yp_ensure_node_t *node = YP_ALLOC_NODE(parser, yp_ensure_node_t); - - *node = (yp_ensure_node_t) { - { - .type = YP_ENSURE_NODE, - .location = { - .start = ensure_keyword->start, - .end = end_keyword->end - }, - }, - .ensure_keyword_loc = YP_LOCATION_TOKEN_VALUE(ensure_keyword), - .statements = statements, - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate and initialize a new FalseNode node. -static yp_false_node_t * -yp_false_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_FALSE); - yp_false_node_t *node = YP_ALLOC_NODE(parser, yp_false_node_t); - *node = (yp_false_node_t) {{ .type = YP_FALSE_NODE, .location = YP_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 yp_find_pattern_node_t * -yp_find_pattern_node_create(yp_parser_t *parser, yp_node_list_t *nodes) { - yp_find_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_find_pattern_node_t); - - yp_node_t *left = nodes->nodes[0]; - yp_node_t *right; - - if (nodes->size == 1) { - right = (yp_node_t *) yp_missing_node_create(parser, left->location.end, left->location.end); - } else { - right = nodes->nodes[nodes->size - 1]; - } - - *node = (yp_find_pattern_node_t) { - { - .type = YP_FIND_PATTERN_NODE, - .location = { - .start = left->location.start, - .end = right->location.end, - }, - }, - .constant = NULL, - .left = left, - .right = right, - .requireds = YP_EMPTY_NODE_LIST, - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .closing_loc = YP_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++) { - yp_node_list_append(&node->requireds, nodes->nodes[index]); - } - - return node; -} - -// Allocate and initialize a new FloatNode node. -static yp_float_node_t * -yp_float_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_FLOAT); - yp_float_node_t *node = YP_ALLOC_NODE(parser, yp_float_node_t); - *node = (yp_float_node_t) {{ .type = YP_FLOAT_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new FloatNode node from a FLOAT_IMAGINARY token. -static yp_imaginary_node_t * -yp_float_node_imaginary_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_FLOAT_IMAGINARY); - - yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t); - *node = (yp_imaginary_node_t) { - { - .type = YP_IMAGINARY_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_float_node_create(parser, &((yp_token_t) { - .type = YP_TOKEN_FLOAT, - .start = token->start, - .end = token->end - 1 - })) - }; - - return node; -} - -// Allocate and initialize a new FloatNode node from a FLOAT_RATIONAL token. -static yp_rational_node_t * -yp_float_node_rational_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_FLOAT_RATIONAL); - - yp_rational_node_t *node = YP_ALLOC_NODE(parser, yp_rational_node_t); - *node = (yp_rational_node_t) { - { - .type = YP_RATIONAL_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_float_node_create(parser, &((yp_token_t) { - .type = YP_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 yp_imaginary_node_t * -yp_float_node_rational_imaginary_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_FLOAT_RATIONAL_IMAGINARY); - - yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t); - *node = (yp_imaginary_node_t) { - { - .type = YP_IMAGINARY_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_float_node_rational_create(parser, &((yp_token_t) { - .type = YP_TOKEN_FLOAT_RATIONAL, - .start = token->start, - .end = token->end - 1 - })) - }; - - return node; -} - -// Allocate and initialize a new ForNode node. -static yp_for_node_t * -yp_for_node_create( - yp_parser_t *parser, - yp_node_t *index, - yp_node_t *collection, - yp_statements_node_t *statements, - const yp_token_t *for_keyword, - const yp_token_t *in_keyword, - const yp_token_t *do_keyword, - const yp_token_t *end_keyword -) { - yp_for_node_t *node = YP_ALLOC_NODE(parser, yp_for_node_t); - - *node = (yp_for_node_t) { - { - .type = YP_FOR_NODE, - .location = { - .start = for_keyword->start, - .end = end_keyword->end - }, - }, - .index = index, - .collection = collection, - .statements = statements, - .for_keyword_loc = YP_LOCATION_TOKEN_VALUE(for_keyword), - .in_keyword_loc = YP_LOCATION_TOKEN_VALUE(in_keyword), - .do_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(do_keyword), - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate and initialize a new ForwardingArgumentsNode node. -static yp_forwarding_arguments_node_t * -yp_forwarding_arguments_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_UDOT_DOT_DOT); - yp_forwarding_arguments_node_t *node = YP_ALLOC_NODE(parser, yp_forwarding_arguments_node_t); - *node = (yp_forwarding_arguments_node_t) {{ .type = YP_FORWARDING_ARGUMENTS_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new ForwardingParameterNode node. -static yp_forwarding_parameter_node_t * -yp_forwarding_parameter_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_UDOT_DOT_DOT); - yp_forwarding_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_forwarding_parameter_node_t); - *node = (yp_forwarding_parameter_node_t) {{ .type = YP_FORWARDING_PARAMETER_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new ForwardingSuper node. -static yp_forwarding_super_node_t * -yp_forwarding_super_node_create(yp_parser_t *parser, const yp_token_t *token, yp_arguments_t *arguments) { - assert(token->type == YP_TOKEN_KEYWORD_SUPER); - yp_forwarding_super_node_t *node = YP_ALLOC_NODE(parser, yp_forwarding_super_node_t); - - *node = (yp_forwarding_super_node_t) { - { - .type = YP_FORWARDING_SUPER_NODE, - .location = { - .start = token->start, - .end = arguments->block != NULL ? arguments->block->base.location.end : token->end - }, - }, - .block = arguments->block - }; - - return node; -} - -// Allocate and initialize a new hash pattern node from an opening and closing -// token. -static yp_hash_pattern_node_t * -yp_hash_pattern_node_empty_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *closing) { - yp_hash_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_hash_pattern_node_t); - - *node = (yp_hash_pattern_node_t) { - { - .type = YP_HASH_PATTERN_NODE, - .location = { - .start = opening->start, - .end = closing->end - }, - }, - .constant = NULL, - .kwrest = NULL, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .assocs = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Allocate and initialize a new hash pattern node. -static yp_hash_pattern_node_t * -yp_hash_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *assocs) { - yp_hash_pattern_node_t *node = YP_ALLOC_NODE(parser, yp_hash_pattern_node_t); - - *node = (yp_hash_pattern_node_t) { - { - .type = YP_HASH_PATTERN_NODE, - .location = { - .start = assocs->nodes[0]->location.start, - .end = assocs->nodes[assocs->size - 1]->location.end - }, - }, - .constant = NULL, - .kwrest = NULL, - .assocs = YP_EMPTY_NODE_LIST, - .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - for (size_t index = 0; index < assocs->size; index++) { - yp_node_t *assoc = assocs->nodes[index]; - yp_node_list_append(&node->assocs, assoc); - } - - return node; -} - -// Retrieve the name from a node that will become a global variable write node. -static yp_constant_id_t -yp_global_variable_write_name(yp_parser_t *parser, yp_node_t *target) { - if (YP_NODE_TYPE_P(target, YP_GLOBAL_VARIABLE_READ_NODE)) { - return ((yp_global_variable_read_node_t *) target)->name; - } - - assert(YP_NODE_TYPE_P(target, YP_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(target, YP_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 yp_parser_constant_id_location(parser, target->location.start, target->location.end); -} - -// Allocate and initialize a new GlobalVariableAndWriteNode node. -static yp_global_variable_and_write_node_t * -yp_global_variable_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_global_variable_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_and_write_node_t); - - *node = (yp_global_variable_and_write_node_t) { - { - .type = YP_GLOBAL_VARIABLE_AND_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name = yp_global_variable_write_name(parser, target), - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new GlobalVariableOperatorWriteNode node. -static yp_global_variable_operator_write_node_t * -yp_global_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_global_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_operator_write_node_t); - - *node = (yp_global_variable_operator_write_node_t) { - { - .type = YP_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name = yp_global_variable_write_name(parser, target), - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1) - }; - - return node; -} - -// Allocate and initialize a new GlobalVariableOrWriteNode node. -static yp_global_variable_or_write_node_t * -yp_global_variable_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_global_variable_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_or_write_node_t); - - *node = (yp_global_variable_or_write_node_t) { - { - .type = YP_GLOBAL_VARIABLE_OR_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name = yp_global_variable_write_name(parser, target), - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate a new GlobalVariableReadNode node. -static yp_global_variable_read_node_t * -yp_global_variable_read_node_create(yp_parser_t *parser, const yp_token_t *name) { - yp_global_variable_read_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_read_node_t); - - *node = (yp_global_variable_read_node_t) { - { - .type = YP_GLOBAL_VARIABLE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name), - }, - .name = yp_parser_constant_id_token(parser, name) - }; - - return node; -} - -// Allocate a new GlobalVariableWriteNode node. -static yp_global_variable_write_node_t * -yp_global_variable_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_global_variable_write_node_t *node = YP_ALLOC_NODE(parser, yp_global_variable_write_node_t); - - *node = (yp_global_variable_write_node_t) { - { - .type = YP_GLOBAL_VARIABLE_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - }, - }, - .name = yp_global_variable_write_name(parser, target), - .name_loc = YP_LOCATION_NODE_VALUE(target), - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate a new HashNode node. -static yp_hash_node_t * -yp_hash_node_create(yp_parser_t *parser, const yp_token_t *opening) { - assert(opening != NULL); - yp_hash_node_t *node = YP_ALLOC_NODE(parser, yp_hash_node_t); - - *node = (yp_hash_node_t) { - { - .type = YP_HASH_NODE, - .location = YP_LOCATION_TOKEN_VALUE(opening) - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_NULL_VALUE(parser), - .elements = YP_EMPTY_NODE_LIST - }; - - return node; -} - -static inline void -yp_hash_node_elements_append(yp_hash_node_t *hash, yp_node_t *element) { - yp_node_list_append(&hash->elements, element); -} - -static inline void -yp_hash_node_closing_loc_set(yp_hash_node_t *hash, yp_token_t *token) { - hash->base.location.end = token->end; - hash->closing_loc = YP_LOCATION_TOKEN_VALUE(token); -} - -// Allocate a new IfNode node. -static yp_if_node_t * -yp_if_node_create(yp_parser_t *parser, - const yp_token_t *if_keyword, - yp_node_t *predicate, - yp_statements_node_t *statements, - yp_node_t *consequent, - const yp_token_t *end_keyword -) { - yp_flip_flop(predicate); - yp_if_node_t *node = YP_ALLOC_NODE(parser, yp_if_node_t); - - const uint8_t *end; - if (end_keyword->type != YP_TOKEN_NOT_PROVIDED) { - end = end_keyword->end; - } else if (consequent != NULL) { - end = consequent->location.end; - } else if ((statements != NULL) && (statements->body.size != 0)) { - end = statements->base.location.end; - } else { - end = predicate->location.end; - } - - *node = (yp_if_node_t) { - { - .type = YP_IF_NODE, - .flags = YP_NODE_FLAG_NEWLINE, - .location = { - .start = if_keyword->start, - .end = end - }, - }, - .if_keyword_loc = YP_LOCATION_TOKEN_VALUE(if_keyword), - .predicate = predicate, - .statements = statements, - .consequent = consequent, - .end_keyword_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate and initialize new IfNode node in the modifier form. -static yp_if_node_t * -yp_if_node_modifier_create(yp_parser_t *parser, yp_node_t *statement, const yp_token_t *if_keyword, yp_node_t *predicate) { - yp_flip_flop(predicate); - yp_if_node_t *node = YP_ALLOC_NODE(parser, yp_if_node_t); - - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, statement); - - *node = (yp_if_node_t) { - { - .type = YP_IF_NODE, - .flags = YP_NODE_FLAG_NEWLINE, - .location = { - .start = statement->location.start, - .end = predicate->location.end - }, - }, - .if_keyword_loc = YP_LOCATION_TOKEN_VALUE(if_keyword), - .predicate = predicate, - .statements = statements, - .consequent = NULL, - .end_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -// Allocate and initialize an if node from a ternary expression. -static yp_if_node_t * -yp_if_node_ternary_create(yp_parser_t *parser, yp_node_t *predicate, yp_node_t *true_expression, const yp_token_t *colon, yp_node_t *false_expression) { - yp_flip_flop(predicate); - - yp_statements_node_t *if_statements = yp_statements_node_create(parser); - yp_statements_node_body_append(if_statements, true_expression); - - yp_statements_node_t *else_statements = yp_statements_node_create(parser); - yp_statements_node_body_append(else_statements, false_expression); - - yp_token_t end_keyword = not_provided(parser); - yp_else_node_t *else_node = yp_else_node_create(parser, colon, else_statements, &end_keyword); - - yp_if_node_t *node = YP_ALLOC_NODE(parser, yp_if_node_t); - - *node = (yp_if_node_t) { - { - .type = YP_IF_NODE, - .flags = YP_NODE_FLAG_NEWLINE, - .location = { - .start = predicate->location.start, - .end = false_expression->location.end, - }, - }, - .if_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .predicate = predicate, - .statements = if_statements, - .consequent = (yp_node_t *)else_node, - .end_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; - -} - -static inline void -yp_if_node_end_keyword_loc_set(yp_if_node_t *node, const yp_token_t *keyword) { - node->base.location.end = keyword->end; - node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword); -} - -static inline void -yp_else_node_end_keyword_loc_set(yp_else_node_t *node, const yp_token_t *keyword) { - node->base.location.end = keyword->end; - node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword); -} - -// Allocate and initialize a new IntegerNode node. -static yp_integer_node_t * -yp_integer_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_INTEGER); - yp_integer_node_t *node = YP_ALLOC_NODE(parser, yp_integer_node_t); - *node = (yp_integer_node_t) {{ .type = YP_INTEGER_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new IntegerNode node from an INTEGER_IMAGINARY token. -static yp_imaginary_node_t * -yp_integer_node_imaginary_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_INTEGER_IMAGINARY); - - yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t); - *node = (yp_imaginary_node_t) { - { - .type = YP_IMAGINARY_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_integer_node_create(parser, &((yp_token_t) { - .type = YP_TOKEN_INTEGER, - .start = token->start, - .end = token->end - 1 - })) - }; - - return node; -} - -// Allocate and initialize a new IntegerNode node from an INTEGER_RATIONAL token. -static yp_rational_node_t * -yp_integer_node_rational_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_INTEGER_RATIONAL); - - yp_rational_node_t *node = YP_ALLOC_NODE(parser, yp_rational_node_t); - *node = (yp_rational_node_t) { - { - .type = YP_RATIONAL_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_integer_node_create(parser, &((yp_token_t) { - .type = YP_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 yp_imaginary_node_t * -yp_integer_node_rational_imaginary_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_INTEGER_RATIONAL_IMAGINARY); - - yp_imaginary_node_t *node = YP_ALLOC_NODE(parser, yp_imaginary_node_t); - *node = (yp_imaginary_node_t) { - { - .type = YP_IMAGINARY_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .numeric = (yp_node_t *) yp_integer_node_rational_create(parser, &((yp_token_t) { - .type = YP_TOKEN_INTEGER_RATIONAL, - .start = token->start, - .end = token->end - 1 - })) - }; - - return node; -} - -// Allocate and initialize a new InNode node. -static yp_in_node_t * -yp_in_node_create(yp_parser_t *parser, yp_node_t *pattern, yp_statements_node_t *statements, const yp_token_t *in_keyword, const yp_token_t *then_keyword) { - yp_in_node_t *node = YP_ALLOC_NODE(parser, yp_in_node_t); - - const uint8_t *end; - if (statements != NULL) { - end = statements->base.location.end; - } else if (then_keyword->type != YP_TOKEN_NOT_PROVIDED) { - end = then_keyword->end; - } else { - end = pattern->location.end; - } - - *node = (yp_in_node_t) { - { - .type = YP_IN_NODE, - .location = { - .start = in_keyword->start, - .end = end - }, - }, - .pattern = pattern, - .statements = statements, - .in_loc = YP_LOCATION_TOKEN_VALUE(in_keyword), - .then_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword) - }; - - return node; -} - -// Allocate and initialize a new InstanceVariableAndWriteNode node. -static yp_instance_variable_and_write_node_t * -yp_instance_variable_and_write_node_create(yp_parser_t *parser, yp_instance_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_instance_variable_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_and_write_node_t); - - *node = (yp_instance_variable_and_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new InstanceVariableOperatorWriteNode node. -static yp_instance_variable_operator_write_node_t * -yp_instance_variable_operator_write_node_create(yp_parser_t *parser, yp_instance_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_instance_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_operator_write_node_t); - - *node = (yp_instance_variable_operator_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1) - }; - - return node; -} - -// Allocate and initialize a new InstanceVariableOrWriteNode node. -static yp_instance_variable_or_write_node_t * -yp_instance_variable_or_write_node_create(yp_parser_t *parser, yp_instance_variable_read_node_t *target, const yp_token_t *operator, yp_node_t *value) { - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_instance_variable_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_or_write_node_t); - - *node = (yp_instance_variable_or_write_node_t) { - { - .type = YP_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 = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new InstanceVariableReadNode node. -static yp_instance_variable_read_node_t * -yp_instance_variable_read_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_INSTANCE_VARIABLE); - yp_instance_variable_read_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_read_node_t); - - *node = (yp_instance_variable_read_node_t) { - { - .type = YP_INSTANCE_VARIABLE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .name = yp_parser_constant_id_token(parser, token) - }; - - return node; -} - -// Initialize a new InstanceVariableWriteNode node from an InstanceVariableRead node. -static yp_instance_variable_write_node_t * -yp_instance_variable_write_node_create(yp_parser_t *parser, yp_instance_variable_read_node_t *read_node, yp_token_t *operator, yp_node_t *value) { - yp_instance_variable_write_node_t *node = YP_ALLOC_NODE(parser, yp_instance_variable_write_node_t); - *node = (yp_instance_variable_write_node_t) { - { - .type = YP_INSTANCE_VARIABLE_WRITE_NODE, - .location = { - .start = read_node->base.location.start, - .end = value->location.end - } - }, - .name = read_node->name, - .name_loc = YP_LOCATION_NODE_BASE_VALUE(read_node), - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate a new InterpolatedRegularExpressionNode node. -static yp_interpolated_regular_expression_node_t * -yp_interpolated_regular_expression_node_create(yp_parser_t *parser, const yp_token_t *opening) { - yp_interpolated_regular_expression_node_t *node = YP_ALLOC_NODE(parser, yp_interpolated_regular_expression_node_t); - - *node = (yp_interpolated_regular_expression_node_t) { - { - .type = YP_INTERPOLATED_REGULAR_EXPRESSION_NODE, - .location = { - .start = opening->start, - .end = NULL, - }, - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(opening), - .parts = YP_EMPTY_NODE_LIST - }; - - return node; -} - -static inline void -yp_interpolated_regular_expression_node_append(yp_interpolated_regular_expression_node_t *node, yp_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; - } - yp_node_list_append(&node->parts, part); -} - -static inline void -yp_interpolated_regular_expression_node_closing_set(yp_interpolated_regular_expression_node_t *node, const yp_token_t *closing) { - node->closing_loc = YP_LOCATION_TOKEN_VALUE(closing); - node->base.location.end = closing->end; - node->base.flags |= yp_regular_expression_flags_create(closing); -} - -// Allocate and initialize a new InterpolatedStringNode node. -static yp_interpolated_string_node_t * -yp_interpolated_string_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_node_list_t *parts, const yp_token_t *closing) { - yp_interpolated_string_node_t *node = YP_ALLOC_NODE(parser, yp_interpolated_string_node_t); - - *node = (yp_interpolated_string_node_t) { - { - .type = YP_INTERPOLATED_STRING_NODE, - .location = { - .start = opening->start, - .end = closing->end, - }, - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .parts = parts == NULL ? YP_EMPTY_NODE_LIST : *parts - }; - - return node; -} - -// Append a part to an InterpolatedStringNode node. -static inline void -yp_interpolated_string_node_append(yp_interpolated_string_node_t *node, yp_node_t *part) { - if (node->parts.size == 0 && node->opening_loc.start == NULL) { - node->base.location.start = part->location.start; - } - - yp_node_list_append(&node->parts, part); - node->base.location.end = part->location.end; -} - -// Set the closing token of the given InterpolatedStringNode node. -static void -yp_interpolated_string_node_closing_set(yp_interpolated_string_node_t *node, const yp_token_t *closing) { - node->closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing); - node->base.location.end = closing->end; -} - -// Allocate and initialize a new InterpolatedSymbolNode node. -static yp_interpolated_symbol_node_t * -yp_interpolated_symbol_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_node_list_t *parts, const yp_token_t *closing) { - yp_interpolated_symbol_node_t *node = YP_ALLOC_NODE(parser, yp_interpolated_symbol_node_t); - - *node = (yp_interpolated_symbol_node_t) { - { - .type = YP_INTERPOLATED_SYMBOL_NODE, - .location = { - .start = opening->start, - .end = closing->end, - }, - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .parts = parts == NULL ? YP_EMPTY_NODE_LIST : *parts - }; - - return node; -} - -static inline void -yp_interpolated_symbol_node_append(yp_interpolated_symbol_node_t *node, yp_node_t *part) { - if (node->parts.size == 0 && node->opening_loc.start == NULL) { - node->base.location.start = part->location.start; - } - - yp_node_list_append(&node->parts, part); - node->base.location.end = part->location.end; -} - -// Allocate a new InterpolatedXStringNode node. -static yp_interpolated_x_string_node_t * -yp_interpolated_xstring_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *closing) { - yp_interpolated_x_string_node_t *node = YP_ALLOC_NODE(parser, yp_interpolated_x_string_node_t); - - *node = (yp_interpolated_x_string_node_t) { - { - .type = YP_INTERPOLATED_X_STRING_NODE, - .location = { - .start = opening->start, - .end = closing->end - }, - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .parts = YP_EMPTY_NODE_LIST - }; - - return node; -} - -static inline void -yp_interpolated_xstring_node_append(yp_interpolated_x_string_node_t *node, yp_node_t *part) { - yp_node_list_append(&node->parts, part); - node->base.location.end = part->location.end; -} - -static inline void -yp_interpolated_xstring_node_closing_set(yp_interpolated_x_string_node_t *node, const yp_token_t *closing) { - node->closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing); - node->base.location.end = closing->end; -} - -// Allocate a new KeywordHashNode node. -static yp_keyword_hash_node_t * -yp_keyword_hash_node_create(yp_parser_t *parser) { - yp_keyword_hash_node_t *node = YP_ALLOC_NODE(parser, yp_keyword_hash_node_t); - - *node = (yp_keyword_hash_node_t) { - .base = { - .type = YP_KEYWORD_HASH_NODE, - .location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }, - .elements = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Append an element to a KeywordHashNode node. -static void -yp_keyword_hash_node_elements_append(yp_keyword_hash_node_t *hash, yp_node_t *element) { - yp_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 a new KeywordParameterNode node. -static yp_keyword_parameter_node_t * -yp_keyword_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, yp_node_t *value) { - yp_keyword_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_keyword_parameter_node_t); - - *node = (yp_keyword_parameter_node_t) { - { - .type = YP_KEYWORD_PARAMETER_NODE, - .location = { - .start = name->start, - .end = value == NULL ? name->end : value->location.end - }, - }, - .name = yp_parser_constant_id_location(parser, name->start, name->end - 1), - .name_loc = YP_LOCATION_TOKEN_VALUE(name), - .value = value - }; - - return node; -} - -// Allocate a new KeywordRestParameterNode node. -static yp_keyword_rest_parameter_node_t * -yp_keyword_rest_parameter_node_create(yp_parser_t *parser, const yp_token_t *operator, const yp_token_t *name) { - yp_keyword_rest_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_keyword_rest_parameter_node_t); - - *node = (yp_keyword_rest_parameter_node_t) { - { - .type = YP_KEYWORD_REST_PARAMETER_NODE, - .location = { - .start = operator->start, - .end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end) - }, - }, - .name = yp_parser_optional_constant_id_token(parser, name), - .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate a new LambdaNode node. -static yp_lambda_node_t * -yp_lambda_node_create( - yp_parser_t *parser, - yp_constant_id_list_t *locals, - const yp_token_t *operator, - const yp_token_t *opening, - const yp_token_t *closing, - yp_block_parameters_node_t *parameters, - yp_node_t *body -) { - yp_lambda_node_t *node = YP_ALLOC_NODE(parser, yp_lambda_node_t); - - *node = (yp_lambda_node_t) { - { - .type = YP_LAMBDA_NODE, - .location = { - .start = operator->start, - .end = closing->end - }, - }, - .locals = *locals, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .parameters = parameters, - .body = body - }; - - return node; -} - -// Allocate and initialize a new LocalVariableAndWriteNode node. -static yp_local_variable_and_write_node_t * -yp_local_variable_and_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t name, uint32_t depth) { - assert(YP_NODE_TYPE_P(target, YP_LOCAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_CALL_NODE)); - assert(operator->type == YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - yp_local_variable_and_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_and_write_node_t); - - *node = (yp_local_variable_and_write_node_t) { - { - .type = YP_LOCAL_VARIABLE_AND_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .name = name, - .depth = depth - }; - - return node; -} - -// Allocate and initialize a new LocalVariableOperatorWriteNode node. -static yp_local_variable_operator_write_node_t * -yp_local_variable_operator_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t name, uint32_t depth) { - yp_local_variable_operator_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_operator_write_node_t); - - *node = (yp_local_variable_operator_write_node_t) { - { - .type = YP_LOCAL_VARIABLE_OPERATOR_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .name = name, - .operator = yp_parser_constant_id_location(parser, operator->start, operator->end - 1), - .depth = depth - }; - - return node; -} - -// Allocate and initialize a new LocalVariableOrWriteNode node. -static yp_local_variable_or_write_node_t * -yp_local_variable_or_write_node_create(yp_parser_t *parser, yp_node_t *target, const yp_token_t *operator, yp_node_t *value, yp_constant_id_t name, uint32_t depth) { - assert(YP_NODE_TYPE_P(target, YP_LOCAL_VARIABLE_READ_NODE) || YP_NODE_TYPE_P(target, YP_CALL_NODE)); - assert(operator->type == YP_TOKEN_PIPE_PIPE_EQUAL); - yp_local_variable_or_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_or_write_node_t); - - *node = (yp_local_variable_or_write_node_t) { - { - .type = YP_LOCAL_VARIABLE_OR_WRITE_NODE, - .location = { - .start = target->location.start, - .end = value->location.end - } - }, - .name_loc = target->location, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value, - .name = name, - .depth = depth - }; - - return node; -} - -// Allocate a new LocalVariableReadNode node. -static yp_local_variable_read_node_t * -yp_local_variable_read_node_create(yp_parser_t *parser, const yp_token_t *name, uint32_t depth) { - yp_local_variable_read_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_read_node_t); - - *node = (yp_local_variable_read_node_t) { - { - .type = YP_LOCAL_VARIABLE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name) - }, - .name = yp_parser_constant_id_token(parser, name), - .depth = depth - }; - - return node; -} - -// Allocate and initialize a new LocalVariableWriteNode node. -static yp_local_variable_write_node_t * -yp_local_variable_write_node_create(yp_parser_t *parser, yp_constant_id_t name, uint32_t depth, yp_node_t *value, const yp_location_t *name_loc, const yp_token_t *operator) { - yp_local_variable_write_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_write_node_t); - - *node = (yp_local_variable_write_node_t) { - { - .type = YP_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 = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new LocalVariableTargetNode node. -static yp_local_variable_target_node_t * -yp_local_variable_target_node_create(yp_parser_t *parser, const yp_token_t *name) { - yp_local_variable_target_node_t *node = YP_ALLOC_NODE(parser, yp_local_variable_target_node_t); - - *node = (yp_local_variable_target_node_t) { - { - .type = YP_LOCAL_VARIABLE_TARGET_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name) - }, - .name = yp_parser_constant_id_token(parser, name), - .depth = 0 - }; - - return node; -} - -// Allocate and initialize a new MatchPredicateNode node. -static yp_match_predicate_node_t * -yp_match_predicate_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t *pattern, const yp_token_t *operator) { - yp_match_predicate_node_t *node = YP_ALLOC_NODE(parser, yp_match_predicate_node_t); - - *node = (yp_match_predicate_node_t) { - { - .type = YP_MATCH_PREDICATE_NODE, - .location = { - .start = value->location.start, - .end = pattern->location.end - } - }, - .value = value, - .pattern = pattern, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new MatchRequiredNode node. -static yp_match_required_node_t * -yp_match_required_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t *pattern, const yp_token_t *operator) { - yp_match_required_node_t *node = YP_ALLOC_NODE(parser, yp_match_required_node_t); - - *node = (yp_match_required_node_t) { - { - .type = YP_MATCH_REQUIRED_NODE, - .location = { - .start = value->location.start, - .end = pattern->location.end - } - }, - .value = value, - .pattern = pattern, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate a new ModuleNode node. -static yp_module_node_t * -yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, const yp_token_t *name, yp_node_t *body, const yp_token_t *end_keyword) { - yp_module_node_t *node = YP_ALLOC_NODE(parser, yp_module_node_t); - - *node = (yp_module_node_t) { - { - .type = YP_MODULE_NODE, - .location = { - .start = module_keyword->start, - .end = end_keyword->end - } - }, - .locals = (locals == NULL ? ((yp_constant_id_list_t) { .ids = NULL, .size = 0, .capacity = 0 }) : *locals), - .module_keyword_loc = YP_LOCATION_TOKEN_VALUE(module_keyword), - .constant_path = constant_path, - .body = body, - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword), - .name = yp_parser_constant_id_token(parser, name) - }; - - return node; -} - -// Allocate and initialize new MultiTargetNode node. -static yp_multi_target_node_t * -yp_multi_target_node_create(yp_parser_t *parser) { - yp_multi_target_node_t *node = YP_ALLOC_NODE(parser, yp_multi_target_node_t); - - *node = (yp_multi_target_node_t) { - { - .type = YP_MULTI_TARGET_NODE, - .location = { .start = NULL, .end = NULL } - }, - .targets = YP_EMPTY_NODE_LIST, - .lparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .rparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -// Append a target to a MultiTargetNode node. -static void -yp_multi_target_node_targets_append(yp_multi_target_node_t *node, yp_node_t *target) { - yp_node_list_append(&node->targets, 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; - } -} - -// Allocate a new MultiWriteNode node. -static yp_multi_write_node_t * -yp_multi_write_node_create(yp_parser_t *parser, yp_multi_target_node_t *target, const yp_token_t *operator, yp_node_t *value) { - yp_multi_write_node_t *node = YP_ALLOC_NODE(parser, yp_multi_write_node_t); - - *node = (yp_multi_write_node_t) { - { - .type = YP_MULTI_WRITE_NODE, - .location = { - .start = target->base.location.start, - .end = value->location.end - } - }, - .targets = target->targets, - .lparen_loc = target->lparen_loc, - .rparen_loc = target->rparen_loc, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - // Explicitly do not call yp_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 yp_next_node_t * -yp_next_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_arguments_node_t *arguments) { - assert(keyword->type == YP_TOKEN_KEYWORD_NEXT); - yp_next_node_t *node = YP_ALLOC_NODE(parser, yp_next_node_t); - - *node = (yp_next_node_t) { - { - .type = YP_NEXT_NODE, - .location = { - .start = keyword->start, - .end = (arguments == NULL ? keyword->end : arguments->base.location.end) - } - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .arguments = arguments - }; - - return node; -} - -// Allocate and initialize a new NilNode node. -static yp_nil_node_t * -yp_nil_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_NIL); - yp_nil_node_t *node = YP_ALLOC_NODE(parser, yp_nil_node_t); - - *node = (yp_nil_node_t) {{ .type = YP_NIL_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new NoKeywordsParameterNode node. -static yp_no_keywords_parameter_node_t * -yp_no_keywords_parameter_node_create(yp_parser_t *parser, const yp_token_t *operator, const yp_token_t *keyword) { - assert(operator->type == YP_TOKEN_USTAR_STAR || operator->type == YP_TOKEN_STAR_STAR); - assert(keyword->type == YP_TOKEN_KEYWORD_NIL); - yp_no_keywords_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_no_keywords_parameter_node_t); - - *node = (yp_no_keywords_parameter_node_t) { - { - .type = YP_NO_KEYWORDS_PARAMETER_NODE, - .location = { - .start = operator->start, - .end = keyword->end - } - }, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword) - }; - - return node; -} - -// Allocate a new NthReferenceReadNode node. -static yp_numbered_reference_read_node_t * -yp_numbered_reference_read_node_create(yp_parser_t *parser, const yp_token_t *name) { - assert(name->type == YP_TOKEN_NUMBERED_REFERENCE); - yp_numbered_reference_read_node_t *node = YP_ALLOC_NODE(parser, yp_numbered_reference_read_node_t); - - *node = (yp_numbered_reference_read_node_t) { - { - .type = YP_NUMBERED_REFERENCE_READ_NODE, - .location = YP_LOCATION_TOKEN_VALUE(name), - }, - .number = parse_decimal_number(parser, name->start + 1, name->end) - }; - - return node; -} - -// Allocate a new OptionalParameterNode node. -static yp_optional_parameter_node_t * -yp_optional_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, const yp_token_t *operator, yp_node_t *value) { - yp_optional_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_optional_parameter_node_t); - - *node = (yp_optional_parameter_node_t) { - { - .type = YP_OPTIONAL_PARAMETER_NODE, - .location = { - .start = name->start, - .end = value->location.end - } - }, - .name = yp_parser_constant_id_token(parser, name), - .name_loc = YP_LOCATION_TOKEN_VALUE(name), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .value = value - }; - - return node; -} - -// Allocate and initialize a new OrNode node. -static yp_or_node_t * -yp_or_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *operator, yp_node_t *right) { - yp_or_node_t *node = YP_ALLOC_NODE(parser, yp_or_node_t); - - *node = (yp_or_node_t) { - { - .type = YP_OR_NODE, - .location = { - .start = left->location.start, - .end = right->location.end - } - }, - .left = left, - .right = right, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new ParametersNode node. -static yp_parameters_node_t * -yp_parameters_node_create(yp_parser_t *parser) { - yp_parameters_node_t *node = YP_ALLOC_NODE(parser, yp_parameters_node_t); - - *node = (yp_parameters_node_t) { - { - .type = YP_PARAMETERS_NODE, - .location = YP_LOCATION_TOKEN_VALUE(&parser->current) - }, - .rest = NULL, - .keyword_rest = NULL, - .block = NULL, - .requireds = YP_EMPTY_NODE_LIST, - .optionals = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST, - .keywords = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Set the location properly for the parameters node. -static void -yp_parameters_node_location_set(yp_parameters_node_t *params, yp_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 -yp_parameters_node_requireds_append(yp_parameters_node_t *params, yp_node_t *param) { - yp_parameters_node_location_set(params, param); - yp_node_list_append(¶ms->requireds, param); -} - -// Append an optional parameter to a ParametersNode node. -static void -yp_parameters_node_optionals_append(yp_parameters_node_t *params, yp_optional_parameter_node_t *param) { - yp_parameters_node_location_set(params, (yp_node_t *) param); - yp_node_list_append(¶ms->optionals, (yp_node_t *) param); -} - -// Append a post optional arguments parameter to a ParametersNode node. -static void -yp_parameters_node_posts_append(yp_parameters_node_t *params, yp_node_t *param) { - yp_parameters_node_location_set(params, param); - yp_node_list_append(¶ms->posts, param); -} - -// Set the rest parameter on a ParametersNode node. -static void -yp_parameters_node_rest_set(yp_parameters_node_t *params, yp_rest_parameter_node_t *param) { - assert(params->rest == NULL); - yp_parameters_node_location_set(params, (yp_node_t *) param); - params->rest = param; -} - -// Append a keyword parameter to a ParametersNode node. -static void -yp_parameters_node_keywords_append(yp_parameters_node_t *params, yp_node_t *param) { - yp_parameters_node_location_set(params, param); - yp_node_list_append(¶ms->keywords, param); -} - -// Set the keyword rest parameter on a ParametersNode node. -static void -yp_parameters_node_keyword_rest_set(yp_parameters_node_t *params, yp_node_t *param) { - assert(params->keyword_rest == NULL); - yp_parameters_node_location_set(params, param); - params->keyword_rest = param; -} - -// Set the block parameter on a ParametersNode node. -static void -yp_parameters_node_block_set(yp_parameters_node_t *params, yp_block_parameter_node_t *param) { - assert(params->block == NULL); - yp_parameters_node_location_set(params, (yp_node_t *) param); - params->block = param; -} - -// Allocate a new ProgramNode node. -static yp_program_node_t * -yp_program_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, yp_statements_node_t *statements) { - yp_program_node_t *node = YP_ALLOC_NODE(parser, yp_program_node_t); - - *node = (yp_program_node_t) { - { - .type = YP_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 yp_parentheses_node_t * -yp_parentheses_node_create(yp_parser_t *parser, const yp_token_t *opening, yp_node_t *body, const yp_token_t *closing) { - yp_parentheses_node_t *node = YP_ALLOC_NODE(parser, yp_parentheses_node_t); - - *node = (yp_parentheses_node_t) { - { - .type = YP_PARENTHESES_NODE, - .location = { - .start = opening->start, - .end = closing->end - } - }, - .body = body, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) - }; - - return node; -} - -// Allocate and initialize a new PinnedExpressionNode node. -static yp_pinned_expression_node_t * -yp_pinned_expression_node_create(yp_parser_t *parser, yp_node_t *expression, const yp_token_t *operator, const yp_token_t *lparen, const yp_token_t *rparen) { - yp_pinned_expression_node_t *node = YP_ALLOC_NODE(parser, yp_pinned_expression_node_t); - - *node = (yp_pinned_expression_node_t) { - { - .type = YP_PINNED_EXPRESSION_NODE, - .location = { - .start = operator->start, - .end = rparen->end - } - }, - .expression = expression, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .lparen_loc = YP_LOCATION_TOKEN_VALUE(lparen), - .rparen_loc = YP_LOCATION_TOKEN_VALUE(rparen) - }; - - return node; -} - -// Allocate and initialize a new PinnedVariableNode node. -static yp_pinned_variable_node_t * -yp_pinned_variable_node_create(yp_parser_t *parser, const yp_token_t *operator, yp_node_t *variable) { - yp_pinned_variable_node_t *node = YP_ALLOC_NODE(parser, yp_pinned_variable_node_t); - - *node = (yp_pinned_variable_node_t) { - { - .type = YP_PINNED_VARIABLE_NODE, - .location = { - .start = operator->start, - .end = variable->location.end - } - }, - .variable = variable, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new PostExecutionNode node. -static yp_post_execution_node_t * -yp_post_execution_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_token_t *opening, yp_statements_node_t *statements, const yp_token_t *closing) { - yp_post_execution_node_t *node = YP_ALLOC_NODE(parser, yp_post_execution_node_t); - - *node = (yp_post_execution_node_t) { - { - .type = YP_POST_EXECUTION_NODE, - .location = { - .start = keyword->start, - .end = closing->end - } - }, - .statements = statements, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) - }; - - return node; -} - -// Allocate and initialize a new PreExecutionNode node. -static yp_pre_execution_node_t * -yp_pre_execution_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_token_t *opening, yp_statements_node_t *statements, const yp_token_t *closing) { - yp_pre_execution_node_t *node = YP_ALLOC_NODE(parser, yp_pre_execution_node_t); - - *node = (yp_pre_execution_node_t) { - { - .type = YP_PRE_EXECUTION_NODE, - .location = { - .start = keyword->start, - .end = closing->end - } - }, - .statements = statements, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) - }; - - return node; -} - -// Allocate and initialize new RangeNode node. -static yp_range_node_t * -yp_range_node_create(yp_parser_t *parser, yp_node_t *left, const yp_token_t *operator, yp_node_t *right) { - yp_range_node_t *node = YP_ALLOC_NODE(parser, yp_range_node_t); - - *node = (yp_range_node_t) { - { - .type = YP_RANGE_NODE, - .location = { - .start = (left == NULL ? operator->start : left->location.start), - .end = (right == NULL ? operator->end : right->location.end) - } - }, - .left = left, - .right = right, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - switch (operator->type) { - case YP_TOKEN_DOT_DOT_DOT: - case YP_TOKEN_UDOT_DOT_DOT: - node->base.flags |= YP_RANGE_FLAGS_EXCLUDE_END; - break; - default: - break; - } - - return node; -} - -// Allocate and initialize a new RedoNode node. -static yp_redo_node_t * -yp_redo_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_REDO); - yp_redo_node_t *node = YP_ALLOC_NODE(parser, yp_redo_node_t); - - *node = (yp_redo_node_t) {{ .type = YP_REDO_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate a new RegularExpressionNode node. -static yp_regular_expression_node_t * -yp_regular_expression_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing) { - yp_regular_expression_node_t *node = YP_ALLOC_NODE(parser, yp_regular_expression_node_t); - - *node = (yp_regular_expression_node_t) { - { - .type = YP_REGULAR_EXPRESSION_NODE, - .flags = yp_regular_expression_flags_create(closing), - .location = { - .start = MIN(opening->start, closing->start), - .end = MAX(opening->end, closing->end) - } - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .content_loc = YP_LOCATION_TOKEN_VALUE(content), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .unescaped = YP_EMPTY_STRING - }; - - return node; -} - -// Allocate a new RequiredDestructuredParameterNode node. -static yp_required_destructured_parameter_node_t * -yp_required_destructured_parameter_node_create(yp_parser_t *parser, const yp_token_t *opening) { - yp_required_destructured_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_required_destructured_parameter_node_t); - - *node = (yp_required_destructured_parameter_node_t) { - { - .type = YP_REQUIRED_DESTRUCTURED_PARAMETER_NODE, - .location = YP_LOCATION_TOKEN_VALUE(opening) - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .parameters = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Append a new parameter to the given RequiredDestructuredParameterNode node. -static void -yp_required_destructured_parameter_node_append_parameter(yp_required_destructured_parameter_node_t *node, yp_node_t *parameter) { - yp_node_list_append(&node->parameters, parameter); -} - -// Set the closing token of the given RequiredDestructuredParameterNode node. -static void -yp_required_destructured_parameter_node_closing_set(yp_required_destructured_parameter_node_t *node, const yp_token_t *closing) { - node->closing_loc = YP_LOCATION_TOKEN_VALUE(closing); - node->base.location.end = closing->end; -} - -// Allocate a new RequiredParameterNode node. -static yp_required_parameter_node_t * -yp_required_parameter_node_create(yp_parser_t *parser, const yp_token_t *token) { - yp_required_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_required_parameter_node_t); - - *node = (yp_required_parameter_node_t) { - { - .type = YP_REQUIRED_PARAMETER_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token) - }, - .name = yp_parser_constant_id_token(parser, token) - }; - - return node; -} - -// Allocate a new RescueModifierNode node. -static yp_rescue_modifier_node_t * -yp_rescue_modifier_node_create(yp_parser_t *parser, yp_node_t *expression, const yp_token_t *keyword, yp_node_t *rescue_expression) { - yp_rescue_modifier_node_t *node = YP_ALLOC_NODE(parser, yp_rescue_modifier_node_t); - - *node = (yp_rescue_modifier_node_t) { - { - .type = YP_RESCUE_MODIFIER_NODE, - .location = { - .start = expression->location.start, - .end = rescue_expression->location.end - } - }, - .expression = expression, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .rescue_expression = rescue_expression - }; - - return node; -} - -// Allocate and initiliaze a new RescueNode node. -static yp_rescue_node_t * -yp_rescue_node_create(yp_parser_t *parser, const yp_token_t *keyword) { - yp_rescue_node_t *node = YP_ALLOC_NODE(parser, yp_rescue_node_t); - - *node = (yp_rescue_node_t) { - { - .type = YP_RESCUE_NODE, - .location = YP_LOCATION_TOKEN_VALUE(keyword) - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .operator_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .reference = NULL, - .statements = NULL, - .consequent = NULL, - .exceptions = YP_EMPTY_NODE_LIST - }; - - return node; -} - -static inline void -yp_rescue_node_operator_set(yp_rescue_node_t *node, const yp_token_t *operator) { - node->operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); -} - -// Set the reference of a rescue node, and update the location of the node. -static void -yp_rescue_node_reference_set(yp_rescue_node_t *node, yp_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 -yp_rescue_node_statements_set(yp_rescue_node_t *node, yp_statements_node_t *statements) { - node->statements = statements; - if ((statements != NULL) && (statements->body.size > 0)) { - node->base.location.end = statements->base.location.end; - } -} - -// Set the consequent of a rescue node, and update the location. -static void -yp_rescue_node_consequent_set(yp_rescue_node_t *node, yp_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 -yp_rescue_node_exceptions_append(yp_rescue_node_t *node, yp_node_t *exception) { - yp_node_list_append(&node->exceptions, exception); - node->base.location.end = exception->location.end; -} - -// Allocate a new RestParameterNode node. -static yp_rest_parameter_node_t * -yp_rest_parameter_node_create(yp_parser_t *parser, const yp_token_t *operator, const yp_token_t *name) { - yp_rest_parameter_node_t *node = YP_ALLOC_NODE(parser, yp_rest_parameter_node_t); - - *node = (yp_rest_parameter_node_t) { - { - .type = YP_REST_PARAMETER_NODE, - .location = { - .start = operator->start, - .end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end) - } - }, - .name = yp_parser_optional_constant_id_token(parser, name), - .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) - }; - - return node; -} - -// Allocate and initialize a new RetryNode node. -static yp_retry_node_t * -yp_retry_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_RETRY); - yp_retry_node_t *node = YP_ALLOC_NODE(parser, yp_retry_node_t); - - *node = (yp_retry_node_t) {{ .type = YP_RETRY_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate a new ReturnNode node. -static yp_return_node_t * -yp_return_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_arguments_node_t *arguments) { - yp_return_node_t *node = YP_ALLOC_NODE(parser, yp_return_node_t); - - *node = (yp_return_node_t) { - { - .type = YP_RETURN_NODE, - .location = { - .start = keyword->start, - .end = (arguments == NULL ? keyword->end : arguments->base.location.end) - } - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .arguments = arguments - }; - - return node; -} - -// Allocate and initialize a new SelfNode node. -static yp_self_node_t * -yp_self_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_SELF); - yp_self_node_t *node = YP_ALLOC_NODE(parser, yp_self_node_t); - - *node = (yp_self_node_t) {{ .type = YP_SELF_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate a new SingletonClassNode node. -static yp_singleton_class_node_t * -yp_singleton_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, const yp_token_t *operator, yp_node_t *expression, yp_node_t *body, const yp_token_t *end_keyword) { - yp_singleton_class_node_t *node = YP_ALLOC_NODE(parser, yp_singleton_class_node_t); - - *node = (yp_singleton_class_node_t) { - { - .type = YP_SINGLETON_CLASS_NODE, - .location = { - .start = class_keyword->start, - .end = end_keyword->end - } - }, - .locals = *locals, - .class_keyword_loc = YP_LOCATION_TOKEN_VALUE(class_keyword), - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .expression = expression, - .body = body, - .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword) - }; - - return node; -} - -// Allocate and initialize a new SourceEncodingNode node. -static yp_source_encoding_node_t * -yp_source_encoding_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD___ENCODING__); - yp_source_encoding_node_t *node = YP_ALLOC_NODE(parser, yp_source_encoding_node_t); - - *node = (yp_source_encoding_node_t) {{ .type = YP_SOURCE_ENCODING_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new SourceFileNode node. -static yp_source_file_node_t* -yp_source_file_node_create(yp_parser_t *parser, const yp_token_t *file_keyword) { - yp_source_file_node_t *node = YP_ALLOC_NODE(parser, yp_source_file_node_t); - assert(file_keyword->type == YP_TOKEN_KEYWORD___FILE__); - - *node = (yp_source_file_node_t) { - { - .type = YP_SOURCE_FILE_NODE, - .location = YP_LOCATION_TOKEN_VALUE(file_keyword), - }, - .filepath = parser->filepath_string, - }; - - return node; -} - -// Allocate and initialize a new SourceLineNode node. -static yp_source_line_node_t * -yp_source_line_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD___LINE__); - yp_source_line_node_t *node = YP_ALLOC_NODE(parser, yp_source_line_node_t); - - *node = (yp_source_line_node_t) {{ .type = YP_SOURCE_LINE_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate a new SplatNode node. -static yp_splat_node_t * -yp_splat_node_create(yp_parser_t *parser, const yp_token_t *operator, yp_node_t *expression) { - yp_splat_node_t *node = YP_ALLOC_NODE(parser, yp_splat_node_t); - - *node = (yp_splat_node_t) { - { - .type = YP_SPLAT_NODE, - .location = { - .start = operator->start, - .end = (expression == NULL ? operator->end : expression->location.end) - } - }, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .expression = expression - }; - - return node; -} - -// Allocate and initialize a new StatementsNode node. -static yp_statements_node_t * -yp_statements_node_create(yp_parser_t *parser) { - yp_statements_node_t *node = YP_ALLOC_NODE(parser, yp_statements_node_t); - - *node = (yp_statements_node_t) { - { - .type = YP_STATEMENTS_NODE, - .location = YP_LOCATION_NULL_VALUE(parser) - }, - .body = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Get the length of the given StatementsNode node's body. -static size_t -yp_statements_node_body_length(yp_statements_node_t *node) { - return node && node->body.size; -} - -// Set the location of the given StatementsNode. -static void -yp_statements_node_location_set(yp_statements_node_t *node, const uint8_t *start, const uint8_t *end) { - node->base.location = (yp_location_t) { .start = start, .end = end }; -} - -// Append a new node to the given StatementsNode node's body. -static void -yp_statements_node_body_append(yp_statements_node_t *node, yp_node_t *statement) { - if (yp_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; - } - - yp_node_list_append(&node->body, statement); - - // Every statement gets marked as a place where a newline can occur. - statement->flags |= YP_NODE_FLAG_NEWLINE; -} - -// Allocate a new StringConcatNode node. -static yp_string_concat_node_t * -yp_string_concat_node_create(yp_parser_t *parser, yp_node_t *left, yp_node_t *right) { - yp_string_concat_node_t *node = YP_ALLOC_NODE(parser, yp_string_concat_node_t); - - *node = (yp_string_concat_node_t) { - { - .type = YP_STRING_CONCAT_NODE, - .location = { - .start = left->location.start, - .end = right->location.end - } - }, - .left = left, - .right = right - }; - - return node; -} - -// Allocate a new StringNode node. -static yp_string_node_t * -yp_string_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing) { - yp_string_node_t *node = YP_ALLOC_NODE(parser, yp_string_node_t); - - *node = (yp_string_node_t) { - { - .type = YP_STRING_NODE, - .location = { - .start = (opening->type == YP_TOKEN_NOT_PROVIDED ? content->start : opening->start), - .end = (closing->type == YP_TOKEN_NOT_PROVIDED ? content->end : closing->end) - } - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .content_loc = YP_LOCATION_TOKEN_VALUE(content), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .unescaped = YP_EMPTY_STRING - }; - - return node; -} - -// Allocate and initialize a new SuperNode node. -static yp_super_node_t * -yp_super_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_arguments_t *arguments) { - assert(keyword->type == YP_TOKEN_KEYWORD_SUPER); - yp_super_node_t *node = YP_ALLOC_NODE(parser, yp_super_node_t); - - const uint8_t *end; - if (arguments->block != NULL) { - end = arguments->block->base.location.end; - } else if (arguments->closing_loc.start != NULL) { - end = arguments->closing_loc.end; - } else if (arguments->arguments != NULL) { - end = arguments->arguments->base.location.end; - } else { - assert(false && "unreachable"); - end = NULL; - } - - *node = (yp_super_node_t) { - { - .type = YP_SUPER_NODE, - .location = { - .start = keyword->start, - .end = end, - } - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .lparen_loc = arguments->opening_loc, - .arguments = arguments->arguments, - .rparen_loc = arguments->closing_loc, - .block = arguments->block - }; - - return node; -} - -// Allocate a new SymbolNode node. -static yp_symbol_node_t * -yp_symbol_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *value, const yp_token_t *closing) { - yp_symbol_node_t *node = YP_ALLOC_NODE(parser, yp_symbol_node_t); - - *node = (yp_symbol_node_t) { - { - .type = YP_SYMBOL_NODE, - .location = { - .start = (opening->type == YP_TOKEN_NOT_PROVIDED ? value->start : opening->start), - .end = (closing->type == YP_TOKEN_NOT_PROVIDED ? value->end : closing->end) - } - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .value_loc = YP_LOCATION_TOKEN_VALUE(value), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .unescaped = YP_EMPTY_STRING - }; - - return node; -} - -// Allocate and initialize a new SymbolNode node from a label. -static yp_symbol_node_t * -yp_symbol_node_label_create(yp_parser_t *parser, const yp_token_t *token) { - yp_symbol_node_t *node; - - switch (token->type) { - case YP_TOKEN_LABEL: { - yp_token_t opening = not_provided(parser); - yp_token_t closing = { .type = YP_TOKEN_LABEL_END, .start = token->end - 1, .end = token->end }; - - yp_token_t label = { .type = YP_TOKEN_LABEL, .start = token->start, .end = token->end - 1 }; - node = yp_symbol_node_create(parser, &opening, &label, &closing); - - assert((label.end - label.start) >= 0); - yp_string_shared_init(&node->unescaped, label.start, label.end); - - yp_unescape_manipulate_string(parser, &node->unescaped, YP_UNESCAPE_ALL); - break; - } - case YP_TOKEN_MISSING: { - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - - yp_token_t label = { .type = YP_TOKEN_LABEL, .start = token->start, .end = token->end }; - node = yp_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 -yp_symbol_node_label_p(yp_node_t *node) { - const uint8_t *end = NULL; - - switch (YP_NODE_TYPE(node)) { - case YP_SYMBOL_NODE: - end = ((yp_symbol_node_t *) node)->closing_loc.end; - break; - case YP_INTERPOLATED_SYMBOL_NODE: - end = ((yp_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 yp_symbol_node_t * -yp_string_node_to_symbol_node(yp_parser_t *parser, yp_string_node_t *node, const yp_token_t *opening, const yp_token_t *closing) { - yp_symbol_node_t *new_node = YP_ALLOC_NODE(parser, yp_symbol_node_t); - - *new_node = (yp_symbol_node_t) { - { - .type = YP_SYMBOL_NODE, - .location = { - .start = opening->start, - .end = closing->end - } - }, - .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .value_loc = node->content_loc, - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .unescaped = node->unescaped - }; - - // We are explicitly _not_ using yp_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 yp_string_node_t * -yp_symbol_node_to_string_node(yp_parser_t *parser, yp_symbol_node_t *node) { - yp_string_node_t *new_node = YP_ALLOC_NODE(parser, yp_string_node_t); - - *new_node = (yp_string_node_t) { - { - .type = YP_STRING_NODE, - .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 yp_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 yp_true_node_t * -yp_true_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_TRUE); - yp_true_node_t *node = YP_ALLOC_NODE(parser, yp_true_node_t); - - *node = (yp_true_node_t) {{ .type = YP_TRUE_NODE, .location = YP_LOCATION_TOKEN_VALUE(token) }}; - return node; -} - -// Allocate and initialize a new UndefNode node. -static yp_undef_node_t * -yp_undef_node_create(yp_parser_t *parser, const yp_token_t *token) { - assert(token->type == YP_TOKEN_KEYWORD_UNDEF); - yp_undef_node_t *node = YP_ALLOC_NODE(parser, yp_undef_node_t); - - *node = (yp_undef_node_t) { - { - .type = YP_UNDEF_NODE, - .location = YP_LOCATION_TOKEN_VALUE(token), - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(token), - .names = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Append a name to an undef node. -static void -yp_undef_node_append(yp_undef_node_t *node, yp_node_t *name) { - node->base.location.end = name->location.end; - yp_node_list_append(&node->names, name); -} - -// Allocate a new UnlessNode node. -static yp_unless_node_t * -yp_unless_node_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements) { - yp_flip_flop(predicate); - yp_unless_node_t *node = YP_ALLOC_NODE(parser, yp_unless_node_t); - - const uint8_t *end; - if (statements != NULL) { - end = statements->base.location.end; - } else { - end = predicate->location.end; - } - - *node = (yp_unless_node_t) { - { - .type = YP_UNLESS_NODE, - .flags = YP_NODE_FLAG_NEWLINE, - .location = { - .start = keyword->start, - .end = end - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .predicate = predicate, - .statements = statements, - .consequent = NULL, - .end_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -// Allocate and initialize new UnlessNode node in the modifier form. -static yp_unless_node_t * -yp_unless_node_modifier_create(yp_parser_t *parser, yp_node_t *statement, const yp_token_t *unless_keyword, yp_node_t *predicate) { - yp_flip_flop(predicate); - yp_unless_node_t *node = YP_ALLOC_NODE(parser, yp_unless_node_t); - - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, statement); - - *node = (yp_unless_node_t) { - { - .type = YP_UNLESS_NODE, - .flags = YP_NODE_FLAG_NEWLINE, - .location = { - .start = statement->location.start, - .end = predicate->location.end - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(unless_keyword), - .predicate = predicate, - .statements = statements, - .consequent = NULL, - .end_keyword_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE - }; - - return node; -} - -static inline void -yp_unless_node_end_keyword_loc_set(yp_unless_node_t *node, const yp_token_t *end_keyword) { - node->end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword); - node->base.location.end = end_keyword->end; -} - -// Allocate a new UntilNode node. -static yp_until_node_t * -yp_until_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_token_t *closing, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) { - yp_until_node_t *node = YP_ALLOC_NODE(parser, yp_until_node_t); - - *node = (yp_until_node_t) { - { - .type = YP_UNTIL_NODE, - .flags = flags, - .location = { - .start = keyword->start, - .end = closing->end, - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .predicate = predicate, - .statements = statements - }; - - return node; -} - -// Allocate a new UntilNode node. -static yp_until_node_t * -yp_until_node_modifier_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) { - yp_until_node_t *node = YP_ALLOC_NODE(parser, yp_until_node_t); - - *node = (yp_until_node_t) { - { - .type = YP_UNTIL_NODE, - .flags = flags, - .location = { - .start = statements->base.location.start, - .end = predicate->location.end, - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .predicate = predicate, - .statements = statements - }; - - return node; -} - -// Allocate and initialize a new WhenNode node. -static yp_when_node_t * -yp_when_node_create(yp_parser_t *parser, const yp_token_t *keyword) { - yp_when_node_t *node = YP_ALLOC_NODE(parser, yp_when_node_t); - - *node = (yp_when_node_t) { - { - .type = YP_WHEN_NODE, - .location = { - .start = keyword->start, - .end = NULL - } - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .statements = NULL, - .conditions = YP_EMPTY_NODE_LIST - }; - - return node; -} - -// Append a new condition to a when node. -static void -yp_when_node_conditions_append(yp_when_node_t *node, yp_node_t *condition) { - node->base.location.end = condition->location.end; - yp_node_list_append(&node->conditions, condition); -} - -// Set the statements list of a when node. -static void -yp_when_node_statements_set(yp_when_node_t *node, yp_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 yp_while_node_t * -yp_while_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_token_t *closing, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) { - yp_while_node_t *node = YP_ALLOC_NODE(parser, yp_while_node_t); - - *node = (yp_while_node_t) { - { - .type = YP_WHILE_NODE, - .flags = flags, - .location = { - .start = keyword->start, - .end = closing->end - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), - .predicate = predicate, - .statements = statements - }; - - return node; -} - -// Allocate a new WhileNode node. -static yp_while_node_t * -yp_while_node_modifier_create(yp_parser_t *parser, const yp_token_t *keyword, yp_node_t *predicate, yp_statements_node_t *statements, yp_node_flags_t flags) { - yp_while_node_t *node = YP_ALLOC_NODE(parser, yp_while_node_t); - - *node = (yp_while_node_t) { - { - .type = YP_WHILE_NODE, - .flags = flags, - .location = { - .start = statements->base.location.start, - .end = predicate->location.end - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, - .predicate = predicate, - .statements = statements - }; - - return node; -} - -// Allocate and initialize a new XStringNode node. -static yp_x_string_node_t * -yp_xstring_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing) { - yp_x_string_node_t *node = YP_ALLOC_NODE(parser, yp_x_string_node_t); - - *node = (yp_x_string_node_t) { - { - .type = YP_X_STRING_NODE, - .location = { - .start = opening->start, - .end = closing->end - }, - }, - .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .content_loc = YP_LOCATION_TOKEN_VALUE(content), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), - .unescaped = YP_EMPTY_STRING - }; - - return node; -} - -// Allocate a new YieldNode node. -static yp_yield_node_t * -yp_yield_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_location_t *lparen_loc, yp_arguments_node_t *arguments, const yp_location_t *rparen_loc) { - yp_yield_node_t *node = YP_ALLOC_NODE(parser, yp_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 = (yp_yield_node_t) { - { - .type = YP_YIELD_NODE, - .location = { - .start = keyword->start, - .end = end - }, - }, - .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), - .lparen_loc = *lparen_loc, - .arguments = arguments, - .rparen_loc = *rparen_loc - }; - - return node; -} - - -#undef YP_EMPTY_STRING -#undef YP_ALLOC_NODE - -/******************************************************************************/ -/* Scope-related functions */ -/******************************************************************************/ - -// Allocate and initialize a new scope. Push it onto the scope stack. -static bool -yp_parser_scope_push(yp_parser_t *parser, bool closed) { - yp_scope_t *scope = (yp_scope_t *) malloc(sizeof(yp_scope_t)); - if (scope == NULL) return false; - - *scope = (yp_scope_t) { .closed = closed, .previous = parser->current_scope }; - yp_constant_id_list_init(&scope->locals); - - parser->current_scope = scope; - return true; -} - -// Check if the current scope has a given local variables. -static int -yp_parser_local_depth(yp_parser_t *parser, yp_token_t *token) { - yp_constant_id_t constant_id = yp_parser_constant_id_token(parser, token); - yp_scope_t *scope = parser->current_scope; - int depth = 0; - - while (scope != NULL) { - if (yp_constant_id_list_includes(&scope->locals, constant_id)) return depth; - if (scope->closed) break; - - scope = scope->previous; - depth++; - } - - return -1; -} - -// Add a constant id to the local table of the current scope. -static inline void -yp_parser_local_add(yp_parser_t *parser, yp_constant_id_t constant_id) { - if (!yp_constant_id_list_includes(&parser->current_scope->locals, constant_id)) { - yp_constant_id_list_append(&parser->current_scope->locals, constant_id); - } -} - -// Add a local variable from a location to the current scope. -static yp_constant_id_t -yp_parser_local_add_location(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - yp_constant_id_t constant_id = yp_parser_constant_id_location(parser, start, end); - if (constant_id != 0) yp_parser_local_add(parser, constant_id); - return constant_id; -} - -// Add a local variable from a token to the current scope. -static inline void -yp_parser_local_add_token(yp_parser_t *parser, yp_token_t *token) { - yp_parser_local_add_location(parser, token->start, token->end); -} - -// Add a local variable from an owned string to the current scope. -static inline void -yp_parser_local_add_owned(yp_parser_t *parser, const uint8_t *start, size_t length) { - yp_constant_id_t constant_id = yp_parser_constant_id_owned(parser, start, length); - if (constant_id != 0) yp_parser_local_add(parser, constant_id); -} - -// Add a parameter name to the current scope and check whether the name of the -// parameter is unique or not. -static void -yp_parser_parameter_name_check(yp_parser_t *parser, yp_token_t *name) { - // We want to ignore any parameter name that starts with an underscore. - if ((*name->start == '_')) return; - - // Otherwise we'll fetch the constant id for the parameter name and check - // whether it's already in the current scope. - yp_constant_id_t constant_id = yp_parser_constant_id_token(parser, name); - - if (yp_constant_id_list_includes(&parser->current_scope->locals, constant_id)) { - yp_diagnostic_list_append(&parser->error_list, name->start, name->end, YP_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 -yp_parser_scope_pop(yp_parser_t *parser) { - yp_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(yp_parser_t *parser, const uint8_t *b) { - if (parser->encoding_changed) { - return parser->encoding.alpha_char(b, parser->end - b) || (*b == '_') || (*b >= 0x80); - } else if (*b < 0x80) { - return (yp_encoding_unicode_table[*b] & YP_ENCODING_ALPHABETIC_BIT ? 1 : 0) || (*b == '_'); - } else { - return (size_t) (yp_encoding_utf_8_alpha_char(b, parser->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(yp_parser_t *parser, const uint8_t *b) { - if (parser->encoding_changed) { - return parser->encoding.alnum_char(b, parser->end - b) || (*b == '_') || (*b >= 0x80); - } else if (*b < 0x80) { - return (yp_encoding_unicode_table[*b] & YP_ENCODING_ALPHANUMERIC_BIT ? 1 : 0) || (*b == '_'); - } else { - return (size_t) (yp_encoding_utf_8_alnum_char(b, parser->end - b) || 1u); - } -} - -// 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 yp_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 (yp_global_name_punctuation_hash[(i - 0x20) / 32] >> (i % 32)) & 1; -} - -static inline bool -token_is_numbered_parameter(const uint8_t *start, const uint8_t *end) { - return (end - start == 2) && (start[0] == '_') && (start[1] != '0') && (yp_char_is_decimal_digit(start[1])); -} - -static inline bool -token_is_setter_name(yp_token_t *token) { - return ( - (token->type == YP_TOKEN_IDENTIFIER) && - (token->end - token->start >= 2) && - (token->end[-1] == '=') - ); -} - -/******************************************************************************/ -/* Stack helpers */ -/******************************************************************************/ - -static inline void -yp_accepts_block_stack_push(yp_parser_t *parser, bool value) { - // Use the negation of the value to prevent stack overflow. - yp_state_stack_push(&parser->accepts_block_stack, !value); -} - -static inline void -yp_accepts_block_stack_pop(yp_parser_t *parser) { - yp_state_stack_pop(&parser->accepts_block_stack); -} - -static inline bool -yp_accepts_block_stack_p(yp_parser_t *parser) { - return !yp_state_stack_p(&parser->accepts_block_stack); -} - -static inline void -yp_do_loop_stack_push(yp_parser_t *parser, bool value) { - yp_state_stack_push(&parser->do_loop_stack, value); -} - -static inline void -yp_do_loop_stack_pop(yp_parser_t *parser) { - yp_state_stack_pop(&parser->do_loop_stack); -} - -static inline bool -yp_do_loop_stack_p(yp_parser_t *parser) { - return yp_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(yp_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(yp_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(yp_parser_t *parser) { - return peek_at(parser, parser->current.end); -} - -// Get the next string of length len in the source starting from parser->current.end. -// If the string extends beyond the end of the source, return the empty string "" -static inline const uint8_t * -peek_string(yp_parser_t *parser, size_t len) { - if (parser->current.end + len <= parser->end) { - return parser->current.end; - } else { - return (const uint8_t *) ""; - } -} - -// If the character to be read matches the given value, then returns true and -// advanced the current pointer. -static inline bool -match(yp_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(yp_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(yp_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(yp_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); -} - -// Find the start of the encoding comment. This is effectively an inlined -// version of strnstr with some modifications. -static inline const uint8_t * -parser_lex_encoding_comment_start(yp_parser_t *parser, const uint8_t *cursor, ptrdiff_t remaining) { - assert(remaining >= 0); - size_t length = (size_t) remaining; - - size_t key_length = strlen("coding:"); - if (key_length > length) return NULL; - - const uint8_t *cursor_limit = cursor + length - key_length + 1; - while ((cursor = yp_memchr(cursor, 'c', (size_t) (cursor_limit - cursor), parser->encoding_changed, &parser->encoding)) != NULL) { - if (memcmp(cursor, "coding", key_length - 1) == 0) { - size_t whitespace_after_coding = yp_strspn_inline_whitespace(cursor + key_length - 1, parser->end - (cursor + key_length - 1)); - size_t cur_pos = key_length + whitespace_after_coding; - - if (cursor[cur_pos - 1] == ':' || cursor[cur_pos - 1] == '=') { - return cursor + cur_pos; - } - } - - cursor++; - } - - return NULL; -} - -// Here we're going to check if this is a "magic" comment, and perform whatever -// actions are necessary for it here. -static void -parser_lex_encoding_comment(yp_parser_t *parser) { - const uint8_t *start = parser->current.start + 1; - const uint8_t *end = next_newline(start, parser->end - start); - if (end == NULL) end = parser->end; - - // These are the patterns we're going to match to find the encoding comment. - // This is definitely not complete or even really correct. - const uint8_t *encoding_start = parser_lex_encoding_comment_start(parser, start, end - start); - - // If we didn't find anything that matched our patterns, then return. Note - // that this does a _very_ poor job of actually finding the encoding, and - // there is a lot of work to do here to better reflect actual magic comment - // parsing from CRuby, but this at least gets us part of the way there. - if (encoding_start == NULL) return; - - // Skip any non-newline whitespace after the "coding:" or "coding=". - encoding_start += yp_strspn_inline_whitespace(encoding_start, end - encoding_start); - - // Now determine the end of the encoding string. This is either the end of - // the line, the first whitespace character, or a punctuation mark. - const uint8_t *encoding_end = yp_strpbrk(parser, encoding_start, (const uint8_t *) " \t\f\r\v\n;,", end - encoding_start); - encoding_end = encoding_end == NULL ? end : encoding_end; - - // Finally, we can determine the width of the encoding string. - size_t width = (size_t) (encoding_end - encoding_start); - - // First, we're going to call out to a user-defined callback if one was - // provided. If they return an encoding struct that we can use, then we'll - // use that here. - if (parser->encoding_decode_callback != NULL) { - yp_encoding_t *encoding = parser->encoding_decode_callback(parser, encoding_start, width); - - if (encoding != NULL) { - parser->encoding = *encoding; - return; - } - } - - // Next, we're going to check for UTF-8. This is the most common encoding. - // Extensions like utf-8 can contain extra encoding details like, - // utf-8-dos, utf-8-linux, utf-8-mac. We treat these all as utf-8 should - // treat any encoding starting utf-8 as utf-8. - if ((encoding_start + 5 <= parser->end) && (yp_strncasecmp(encoding_start, (const uint8_t *) "utf-8", 5) == 0)) { - // We don't need to do anything here because the default encoding is - // already UTF-8. We'll just return. - return; - } - - // 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 ENCODING(value, prebuilt) \ - if (width == sizeof(value) - 1 && encoding_start + width <= parser->end && yp_strncasecmp(encoding_start, (const uint8_t *) value, width) == 0) { \ - parser->encoding = prebuilt; \ - parser->encoding_changed |= true; \ - if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); \ - return; \ - } - - // Check most common first. (This is pretty arbitrary.) - ENCODING("ascii", yp_encoding_ascii); - ENCODING("ascii-8bit", yp_encoding_ascii_8bit); - ENCODING("us-ascii", yp_encoding_ascii); - ENCODING("binary", yp_encoding_ascii_8bit); - ENCODING("shift_jis", yp_encoding_shift_jis); - ENCODING("euc-jp", yp_encoding_euc_jp); - - // Then check all the others. - ENCODING("big5", yp_encoding_big5); - ENCODING("gbk", yp_encoding_gbk); - ENCODING("iso-8859-1", yp_encoding_iso_8859_1); - ENCODING("iso-8859-2", yp_encoding_iso_8859_2); - ENCODING("iso-8859-3", yp_encoding_iso_8859_3); - ENCODING("iso-8859-4", yp_encoding_iso_8859_4); - ENCODING("iso-8859-5", yp_encoding_iso_8859_5); - ENCODING("iso-8859-6", yp_encoding_iso_8859_6); - ENCODING("iso-8859-7", yp_encoding_iso_8859_7); - ENCODING("iso-8859-8", yp_encoding_iso_8859_8); - ENCODING("iso-8859-9", yp_encoding_iso_8859_9); - ENCODING("iso-8859-10", yp_encoding_iso_8859_10); - ENCODING("iso-8859-11", yp_encoding_iso_8859_11); - ENCODING("iso-8859-13", yp_encoding_iso_8859_13); - ENCODING("iso-8859-14", yp_encoding_iso_8859_14); - ENCODING("iso-8859-15", yp_encoding_iso_8859_15); - ENCODING("iso-8859-16", yp_encoding_iso_8859_16); - ENCODING("koi8-r", yp_encoding_koi8_r); - ENCODING("windows-31j", yp_encoding_windows_31j); - ENCODING("windows-1251", yp_encoding_windows_1251); - ENCODING("windows-1252", yp_encoding_windows_1252); - ENCODING("cp1251", yp_encoding_windows_1251); - ENCODING("cp1252", yp_encoding_windows_1252); - ENCODING("cp932", yp_encoding_windows_31j); - ENCODING("sjis", yp_encoding_windows_31j); - ENCODING("utf8-mac", yp_encoding_utf8_mac); - -#undef ENCODING - - // If nothing was returned by this point, 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. - yp_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, YP_ERR_INVALID_ENCODING_MAGIC_COMMENT); -} - -/******************************************************************************/ -/* Context manipulations */ -/******************************************************************************/ - -static bool -context_terminator(yp_context_t context, yp_token_t *token) { - switch (context) { - case YP_CONTEXT_MAIN: - case YP_CONTEXT_DEF_PARAMS: - return token->type == YP_TOKEN_EOF; - case YP_CONTEXT_DEFAULT_PARAMS: - return token->type == YP_TOKEN_COMMA || token->type == YP_TOKEN_PARENTHESIS_RIGHT; - case YP_CONTEXT_PREEXE: - case YP_CONTEXT_POSTEXE: - return token->type == YP_TOKEN_BRACE_RIGHT; - case YP_CONTEXT_MODULE: - case YP_CONTEXT_CLASS: - case YP_CONTEXT_SCLASS: - case YP_CONTEXT_LAMBDA_DO_END: - case YP_CONTEXT_DEF: - case YP_CONTEXT_BLOCK_KEYWORDS: - return token->type == YP_TOKEN_KEYWORD_END || token->type == YP_TOKEN_KEYWORD_RESCUE || token->type == YP_TOKEN_KEYWORD_ENSURE; - case YP_CONTEXT_WHILE: - case YP_CONTEXT_UNTIL: - case YP_CONTEXT_ELSE: - case YP_CONTEXT_FOR: - case YP_CONTEXT_ENSURE: - return token->type == YP_TOKEN_KEYWORD_END; - case YP_CONTEXT_CASE_WHEN: - return token->type == YP_TOKEN_KEYWORD_WHEN || token->type == YP_TOKEN_KEYWORD_END || token->type == YP_TOKEN_KEYWORD_ELSE; - case YP_CONTEXT_CASE_IN: - return token->type == YP_TOKEN_KEYWORD_IN || token->type == YP_TOKEN_KEYWORD_END || token->type == YP_TOKEN_KEYWORD_ELSE; - case YP_CONTEXT_IF: - case YP_CONTEXT_ELSIF: - return token->type == YP_TOKEN_KEYWORD_ELSE || token->type == YP_TOKEN_KEYWORD_ELSIF || token->type == YP_TOKEN_KEYWORD_END; - case YP_CONTEXT_UNLESS: - return token->type == YP_TOKEN_KEYWORD_ELSE || token->type == YP_TOKEN_KEYWORD_END; - case YP_CONTEXT_EMBEXPR: - return token->type == YP_TOKEN_EMBEXPR_END; - case YP_CONTEXT_BLOCK_BRACES: - return token->type == YP_TOKEN_BRACE_RIGHT; - case YP_CONTEXT_PARENS: - return token->type == YP_TOKEN_PARENTHESIS_RIGHT; - case YP_CONTEXT_BEGIN: - case YP_CONTEXT_RESCUE: - return token->type == YP_TOKEN_KEYWORD_ENSURE || token->type == YP_TOKEN_KEYWORD_RESCUE || token->type == YP_TOKEN_KEYWORD_ELSE || token->type == YP_TOKEN_KEYWORD_END; - case YP_CONTEXT_RESCUE_ELSE: - return token->type == YP_TOKEN_KEYWORD_ENSURE || token->type == YP_TOKEN_KEYWORD_END; - case YP_CONTEXT_LAMBDA_BRACES: - return token->type == YP_TOKEN_BRACE_RIGHT; - case YP_CONTEXT_PREDICATE: - return token->type == YP_TOKEN_KEYWORD_THEN || token->type == YP_TOKEN_NEWLINE || token->type == YP_TOKEN_SEMICOLON; - } - - return false; -} - -static bool -context_recoverable(yp_parser_t *parser, yp_token_t *token) { - yp_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(yp_parser_t *parser, yp_context_t context) { - yp_context_node_t *context_node = (yp_context_node_t *) malloc(sizeof(yp_context_node_t)); - if (context_node == NULL) return false; - - *context_node = (yp_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(yp_parser_t *parser) { - yp_context_node_t *prev = parser->current_context->prev; - free(parser->current_context); - parser->current_context = prev; -} - -static bool -context_p(yp_parser_t *parser, yp_context_t context) { - yp_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(yp_parser_t *parser) { - yp_context_node_t *context_node = parser->current_context; - - while (context_node != NULL) { - switch (context_node->context) { - case YP_CONTEXT_DEF: - return true; - case YP_CONTEXT_CLASS: - case YP_CONTEXT_MODULE: - case YP_CONTEXT_SCLASS: - return false; - default: - context_node = context_node->prev; - } - } - - return false; -} - -/******************************************************************************/ -/* Specific token lexers */ -/******************************************************************************/ - -static yp_token_type_t -lex_optional_float_suffix(yp_parser_t *parser) { - yp_token_type_t type = YP_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 (yp_char_is_decimal_digit(peek_offset(parser, 1))) { - parser->current.end += 2; - parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); - type = YP_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, '-')); - - if (yp_char_is_decimal_digit(*parser->current.end)) { - parser->current.end++; - parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); - type = YP_TOKEN_FLOAT; - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_FLOAT_EXPONENT); - type = YP_TOKEN_FLOAT; - } - } - - return type; -} - -static yp_token_type_t -lex_numeric_prefix(yp_parser_t *parser) { - yp_token_type_t type = YP_TOKEN_INTEGER; - - if (peek_offset(parser, -1) == '0') { - switch (*parser->current.end) { - // 0d1111 is a decimal number - case 'd': - case 'D': - parser->current.end++; - if (yp_char_is_decimal_digit(peek(parser))) { - parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_DECIMAL); - } - - break; - - // 0b1111 is a binary number - case 'b': - case 'B': - parser->current.end++; - if (yp_char_is_binary_digit(peek(parser))) { - parser->current.end += yp_strspn_binary_number(parser->current.end, parser->end - parser->current.end); - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_BINARY); - } - - break; - - // 0o1111 is an octal number - case 'o': - case 'O': - parser->current.end++; - if (yp_char_is_octal_digit(peek(parser))) { - parser->current.end += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end); - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_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 += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end); - break; - - // 0x1111 is a hexadecimal number - case 'x': - case 'X': - parser->current.end++; - if (yp_char_is_hexadecimal_digit(peek(parser))) { - parser->current.end += yp_strspn_hexadecimal_number(parser->current.end, parser->end - parser->current.end); - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_HEXADECIMAL); - } - - break; - - // 0.xxx is a float - case '.': { - type = lex_optional_float_suffix(parser); - break; - } - - // 0exxx is a float - case 'e': - case 'E': { - type = lex_optional_float_suffix(parser); - 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 += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); - - // Afterward, we'll lex as far as we can into an optional float suffix. - type = lex_optional_float_suffix(parser); - } - - // If the last character that we consumed was an underscore, then this is - // actually an invalid integer value, and we should return an invalid token. - if (peek_offset(parser, -1) == '_') { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_NUMBER_LITERAL_UNDERSCORE); - } - - return type; -} - -static yp_token_type_t -lex_numeric(yp_parser_t *parser) { - yp_token_type_t type = YP_TOKEN_INTEGER; - - if (parser->current.end < parser->end) { - type = lex_numeric_prefix(parser); - - const uint8_t *end = parser->current.end; - yp_token_type_t suffix_type = type; - - if (type == YP_TOKEN_INTEGER) { - if (match(parser, 'r')) { - suffix_type = YP_TOKEN_INTEGER_RATIONAL; - - if (match(parser, 'i')) { - suffix_type = YP_TOKEN_INTEGER_RATIONAL_IMAGINARY; - } - } else if (match(parser, 'i')) { - suffix_type = YP_TOKEN_INTEGER_IMAGINARY; - } - } else { - if (match(parser, 'r')) { - suffix_type = YP_TOKEN_FLOAT_RATIONAL; - - if (match(parser, 'i')) { - suffix_type = YP_TOKEN_FLOAT_RATIONAL_IMAGINARY; - } - } else if (match(parser, 'i')) { - suffix_type = YP_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 yp_token_type_t -lex_global_variable(yp_parser_t *parser) { - if (parser->current.end >= parser->end) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); - return YP_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 YP_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, YP_LEX_STATE_FNAME) ? YP_TOKEN_GLOBAL_VARIABLE : YP_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. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); - } - - return YP_TOKEN_GLOBAL_VARIABLE; - } - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - parser->current.end += yp_strspn_decimal_digit(parser->current.end, parser->end - parser->current.end); - return lex_state_p(parser, YP_LEX_STATE_FNAME) ? YP_TOKEN_GLOBAL_VARIABLE : YP_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. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); - } - - return YP_TOKEN_GLOBAL_VARIABLE; - } - } -} - -// This function checks if the current token matches a keyword. If it does, it -// returns true. Otherwise, it returns false. The arguments are as follows: -// -// * `value` - the literal string that we're checking for -// * `width` - the length of the token -// * `state` - the state that we should transition to if the token matches -// -static yp_token_type_t -lex_keyword(yp_parser_t *parser, const char *value, yp_lex_state_t state, yp_token_type_t type, yp_token_type_t modifier_type) { - yp_lex_state_t last_state = parser->lex_state; - - const size_t vlen = strlen(value); - if (parser->current.start + vlen <= parser->end && memcmp(parser->current.start, value, vlen) == 0) { - if (parser->lex_state & YP_LEX_STATE_FNAME) { - lex_state_set(parser, YP_LEX_STATE_ENDFN); - } else { - lex_state_set(parser, state); - if (state == YP_LEX_STATE_BEG) { - parser->command_start = true; - } - - if ((modifier_type != YP_TOKEN_EOF) && !(last_state & (YP_LEX_STATE_BEG | YP_LEX_STATE_LABELED | YP_LEX_STATE_CLASS))) { - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - return modifier_type; - } - } - - return type; - } - - return YP_TOKEN_EOF; -} - -static yp_token_type_t -lex_identifier(yp_parser_t *parser, bool previous_command_start) { - // Lex as far as we can into the current identifier. - size_t width; - while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0) { - parser->current.end += width; - } - - // Now cache the length of the identifier so that we can quickly compare it - // against known keywords. - width = (size_t) (parser->current.end - parser->current.start); - - if (parser->current.end < parser->end) { - if (((parser->current.end + 1 >= parser->end) || (parser->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, YP_LEX_STATE_LABEL | YP_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, YP_LEX_STATE_ARG | YP_LEX_STATE_LABELED); - (void) match(parser, ':'); - return YP_TOKEN_LABEL; - } - - if (parser->lex_state != YP_LEX_STATE_DOT) { - if (width == 8 && (lex_keyword(parser, "defined?", YP_LEX_STATE_ARG, YP_TOKEN_KEYWORD_DEFINED, YP_TOKEN_EOF) != YP_TOKEN_EOF)) { - return YP_TOKEN_KEYWORD_DEFINED; - } - } - - return YP_TOKEN_IDENTIFIER; - } else if (lex_state_p(parser, YP_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 YP_TOKEN_IDENTIFIER; - } - - if ( - ((lex_state_p(parser, YP_LEX_STATE_LABEL | YP_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, YP_LEX_STATE_ARG | YP_LEX_STATE_LABELED); - (void) match(parser, ':'); - return YP_TOKEN_LABEL; - } - } - - if (parser->lex_state != YP_LEX_STATE_DOT) { - yp_token_type_t type; - - switch (width) { - case 2: - if (lex_keyword(parser, "do", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_DO, YP_TOKEN_EOF) != YP_TOKEN_EOF) { - if (yp_do_loop_stack_p(parser)) { - return YP_TOKEN_KEYWORD_DO_LOOP; - } - return YP_TOKEN_KEYWORD_DO; - } - - if ((type = lex_keyword(parser, "if", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_IF, YP_TOKEN_KEYWORD_IF_MODIFIER)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "in", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_IN, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "or", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_OR, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - case 3: - if ((type = lex_keyword(parser, "and", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_AND, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "def", YP_LEX_STATE_FNAME, YP_TOKEN_KEYWORD_DEF, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "end", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_END, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "END", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_END_UPCASE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "for", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_FOR, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "nil", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_NIL, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "not", YP_LEX_STATE_ARG, YP_TOKEN_KEYWORD_NOT, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - case 4: - if ((type = lex_keyword(parser, "case", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_CASE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "else", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "next", YP_LEX_STATE_MID, YP_TOKEN_KEYWORD_NEXT, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "redo", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_REDO, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "self", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_SELF, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "then", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "true", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_TRUE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "when", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - case 5: - if ((type = lex_keyword(parser, "alias", YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM, YP_TOKEN_KEYWORD_ALIAS, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "begin", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_BEGIN, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "BEGIN", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_BEGIN_UPCASE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "break", YP_LEX_STATE_MID, YP_TOKEN_KEYWORD_BREAK, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "class", YP_LEX_STATE_CLASS, YP_TOKEN_KEYWORD_CLASS, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "elsif", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_ELSIF, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "false", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_FALSE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "retry", YP_LEX_STATE_END, YP_TOKEN_KEYWORD_RETRY, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "super", YP_LEX_STATE_ARG, YP_TOKEN_KEYWORD_SUPER, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "undef", YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM, YP_TOKEN_KEYWORD_UNDEF, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "until", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_UNTIL, YP_TOKEN_KEYWORD_UNTIL_MODIFIER)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "while", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_WHILE, YP_TOKEN_KEYWORD_WHILE_MODIFIER)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "yield", YP_LEX_STATE_ARG, YP_TOKEN_KEYWORD_YIELD, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - case 6: - if ((type = lex_keyword(parser, "ensure", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "module", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_MODULE, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "rescue", YP_LEX_STATE_MID, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_RESCUE_MODIFIER)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "return", YP_LEX_STATE_MID, YP_TOKEN_KEYWORD_RETURN, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "unless", YP_LEX_STATE_BEG, YP_TOKEN_KEYWORD_UNLESS, YP_TOKEN_KEYWORD_UNLESS_MODIFIER)) != YP_TOKEN_EOF) return type; - break; - case 8: - if ((type = lex_keyword(parser, "__LINE__", YP_LEX_STATE_END, YP_TOKEN_KEYWORD___LINE__, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - if ((type = lex_keyword(parser, "__FILE__", YP_LEX_STATE_END, YP_TOKEN_KEYWORD___FILE__, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - case 12: - if ((type = lex_keyword(parser, "__ENCODING__", YP_LEX_STATE_END, YP_TOKEN_KEYWORD___ENCODING__, YP_TOKEN_EOF)) != YP_TOKEN_EOF) return type; - break; - } - } - - return parser->encoding.isupper_char(parser->current.start, parser->end - parser->current.start) ? YP_TOKEN_CONSTANT : YP_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(yp_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: -// -// * YP_TOKEN_NOT_PROVIDED - No interpolation was found at this point. The -// caller should keep lexing. -// * YP_TOKEN_STRING_CONTENT - No interpolation was found at this point. The -// caller should return this token type. -// * YP_TOKEN_EMBEXPR_BEGIN - An embedded expression was found. The caller -// should return this token type. -// * YP_TOKEN_EMBVAR - An embedded variable was found. The caller should return -// this token type. -// -static yp_token_type_t -lex_interpolation(yp_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 YP_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 - // YP_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 YP_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 YP_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, (yp_lex_mode_t) { .mode = YP_LEX_EMBVAR }); - parser->current.end = pound + 1; - return YP_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 = variable; - return YP_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 YP_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 YP_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] != '-' && (yp_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 YP_TOKEN_STRING_CONTENT; - } - - // Otherwise, we need to return the embedded variable token and switch - // to the embedded variable lex mode. - lex_mode_push(parser, (yp_lex_mode_t) { .mode = YP_LEX_EMBVAR }); - parser->current.end = pound + 1; - return YP_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 YP_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 YP_TOKEN_STRING_CONTENT; - } - - parser->enclosure_nesting++; - - // Otherwise we'll skip past the #{ and begin lexing the embedded - // expression. - lex_mode_push(parser, (yp_lex_mode_t) { .mode = YP_LEX_EMBEXPR }); - parser->current.end = pound + 2; - parser->command_start = true; - yp_do_loop_stack_push(parser, false); - return YP_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 YP_TOKEN_NOT_PROVIDED; - } -} - -// 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 yp_token_type_t -lex_question_mark(yp_parser_t *parser) { - if (lex_state_end_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_BEG); - return YP_TOKEN_QUESTION_MARK; - } - - if (parser->current.end >= parser->end) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_QUESTION_MARK); - return YP_TOKEN_CHARACTER_LITERAL; - } - - if (yp_char_is_whitespace(*parser->current.end)) { - lex_state_set(parser, YP_LEX_STATE_BEG); - return YP_TOKEN_QUESTION_MARK; - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - - if (parser->current.start[1] == '\\') { - lex_state_set(parser, YP_LEX_STATE_END); - parser->current.end += yp_unescape_calculate_difference(parser, parser->current.start + 1, YP_UNESCAPE_ALL, true); - return YP_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 - 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, YP_LEX_STATE_END); - parser->current.end += encoding_width; - return YP_TOKEN_CHARACTER_LITERAL; - } - } - - return YP_TOKEN_QUESTION_MARK; -} - -// Lex a variable that starts with an @ sign (either an instance or class -// variable). -static yp_token_type_t -lex_at_variable(yp_parser_t *parser) { - yp_token_type_t type = match(parser, '@') ? YP_TOKEN_CLASS_VARIABLE : YP_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 == YP_TOKEN_CLASS_VARIABLE) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_VARIABLE_CLASS); - } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_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 == YP_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(yp_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 yp_comment_t * -parser_comment(yp_parser_t *parser, yp_comment_type_t type) { - yp_comment_t *comment = (yp_comment_t *) malloc(sizeof(yp_comment_t)); - if (comment == NULL) return NULL; - - *comment = (yp_comment_t) { - .type = type, - .start = parser->current.start, - .end = 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 yp_token_type_t -lex_embdoc(yp_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 { - yp_newline_list_append(&parser->newline_list, newline); - parser->current.end = newline + 1; - } - - parser->current.type = YP_TOKEN_EMBDOC_BEGIN; - parser_lex_callback(parser); - - // Now, create a comment that is going to be attached to the parser. - yp_comment_t *comment = parser_comment(parser, YP_COMMENT_EMBDOC); - if (comment == NULL) return YP_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 || yp_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 { - yp_newline_list_append(&parser->newline_list, newline); - parser->current.end = newline + 1; - } - - parser->current.type = YP_TOKEN_EMBDOC_END; - parser_lex_callback(parser); - - comment->end = parser->current.end; - yp_list_append(&parser->comment_list, (yp_list_node_t *) comment); - - return YP_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 { - yp_newline_list_append(&parser->newline_list, newline); - parser->current.end = newline + 1; - } - - parser->current.type = YP_TOKEN_EMBDOC_LINE; - parser_lex_callback(parser); - } - - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EMBDOC_TERM); - - comment->end = parser->current.end; - yp_list_append(&parser->comment_list, (yp_list_node_t *) comment); - - return YP_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(yp_parser_t *parser) { - parser->current.type = YP_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(yp_parser_t *parser) { - assert(parser->heredoc_end <= parser->end); - parser->next_start = parser->heredoc_end; - parser->heredoc_end = NULL; -} - -// 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(yp_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; - - switch (parser->lex_modes.current->mode) { - case YP_LEX_DEFAULT: - case YP_LEX_EMBEXPR: - case YP_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; - yp_newline_list_append(&parser->newline_list, parser->current.end - 1); - space_seen = true; - } - } else if (yp_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(YP_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(YP_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 + 1; - parser->current.type = YP_TOKEN_COMMENT; - parser_lex_callback(parser); - - // 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. - yp_comment_t *comment = parser_comment(parser, YP_COMMENT_INLINE); - yp_list_append(&parser->comment_list, (yp_list_node_t *) comment); - - if (parser->current.start == parser->encoding_comment_start) { - parser_lex_encoding_comment(parser); - } - - lexed_comment = true; - } - /* fallthrough */ - case '\r': - case '\n': { - 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) { - yp_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 YP_IGNORED_NEWLINE_NONE: - break; - case YP_IGNORED_NEWLINE_PATTERN: - if (parser->pattern_matching_newlines || parser->in_keyword_arg) { - if (!lexed_comment) parser_lex_ignored_newline(parser); - lex_state_set(parser, YP_LEX_STATE_BEG); - parser->command_start = true; - parser->current.type = YP_TOKEN_NEWLINE; - return; - } - /* fallthrough */ - case YP_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 += yp_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 += yp_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, YP_LEX_STATE_BEG); - parser->command_start = true; - parser->current.type = YP_TOKEN_NEWLINE; - return; - } - - if (!lexed_comment) parser_lex_ignored_newline(parser); - lex_state_set(parser, YP_LEX_STATE_DOT); - parser->current.start = next_content; - parser->current.end = next_content + 1; - parser->next_start = NULL; - LEX(YP_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, YP_LEX_STATE_DOT); - parser->current.start = next_content; - parser->current.end = next_content + 2; - parser->next_start = NULL; - LEX(YP_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, YP_LEX_STATE_BEG); - parser->command_start = true; - parser->current.type = YP_TOKEN_NEWLINE; - if (!lexed_comment) parser_lex_callback(parser); - return; - } - - // , - case ',': - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - LEX(YP_TOKEN_COMMA); - - // ( - case '(': { - yp_token_type_t type = YP_TOKEN_PARENTHESIS_LEFT; - - if (space_seen && (lex_state_arg_p(parser) || parser->lex_state == (YP_LEX_STATE_END | YP_LEX_STATE_LABEL))) { - type = YP_TOKEN_PARENTHESIS_LEFT_PARENTHESES; - } - - parser->enclosure_nesting++; - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - yp_do_loop_stack_push(parser, false); - LEX(type); - } - - // ) - case ')': - parser->enclosure_nesting--; - lex_state_set(parser, YP_LEX_STATE_ENDFN); - yp_do_loop_stack_pop(parser); - LEX(YP_TOKEN_PARENTHESIS_RIGHT); - - // ; - case ';': - lex_state_set(parser, YP_LEX_STATE_BEG); - parser->command_start = true; - LEX(YP_TOKEN_SEMICOLON); - - // [ [] []= - case '[': - parser->enclosure_nesting++; - yp_token_type_t type = YP_TOKEN_BRACKET_LEFT; - - if (lex_state_operator_p(parser)) { - if (match(parser, ']')) { - parser->enclosure_nesting--; - lex_state_set(parser, YP_LEX_STATE_ARG); - LEX(match(parser, '=') ? YP_TOKEN_BRACKET_LEFT_RIGHT_EQUAL : YP_TOKEN_BRACKET_LEFT_RIGHT); - } - - lex_state_set(parser, YP_LEX_STATE_ARG | YP_LEX_STATE_LABEL); - LEX(type); - } - - if (lex_state_beg_p(parser) || (lex_state_arg_p(parser) && (space_seen || lex_state_p(parser, YP_LEX_STATE_LABELED)))) { - type = YP_TOKEN_BRACKET_LEFT_ARRAY; - } - - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - yp_do_loop_stack_push(parser, false); - LEX(type); - - // ] - case ']': - parser->enclosure_nesting--; - lex_state_set(parser, YP_LEX_STATE_END); - yp_do_loop_stack_pop(parser); - LEX(YP_TOKEN_BRACKET_RIGHT); - - // { - case '{': { - yp_token_type_t type = YP_TOKEN_BRACE_LEFT; - - if (parser->enclosure_nesting == parser->lambda_enclosure_nesting) { - // This { begins a lambda - parser->command_start = true; - lex_state_set(parser, YP_LEX_STATE_BEG); - type = YP_TOKEN_LAMBDA_BEGIN; - } else if (lex_state_p(parser, YP_LEX_STATE_LABELED)) { - // This { begins a hash literal - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - } else if (lex_state_p(parser, YP_LEX_STATE_ARG_ANY | YP_LEX_STATE_END | YP_LEX_STATE_ENDFN)) { - // This { begins a block - parser->command_start = true; - lex_state_set(parser, YP_LEX_STATE_BEG); - } else if (lex_state_p(parser, YP_LEX_STATE_ENDARG)) { - // This { begins a block on a command - parser->command_start = true; - lex_state_set(parser, YP_LEX_STATE_BEG); - } else { - // This { begins a hash literal - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - } - - parser->enclosure_nesting++; - parser->brace_nesting++; - yp_do_loop_stack_push(parser, false); - - LEX(type); - } - - // } - case '}': - parser->enclosure_nesting--; - yp_do_loop_stack_pop(parser); - - if ((parser->lex_modes.current->mode == YP_LEX_EMBEXPR) && (parser->brace_nesting == 0)) { - lex_mode_pop(parser); - LEX(YP_TOKEN_EMBEXPR_END); - } - - parser->brace_nesting--; - lex_state_set(parser, YP_LEX_STATE_END); - LEX(YP_TOKEN_BRACE_RIGHT); - - // * ** **= *= - case '*': { - if (match(parser, '*')) { - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_STAR_STAR_EQUAL); - } - - yp_token_type_t type = YP_TOKEN_STAR_STAR; - - if (lex_state_spcarg_p(parser, space_seen) || lex_state_beg_p(parser)) { - type = YP_TOKEN_USTAR_STAR; - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(type); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_STAR_EQUAL); - } - - yp_token_type_t type = YP_TOKEN_STAR; - - if (lex_state_spcarg_p(parser, space_seen)) { - yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_PREFIX_STAR); - type = YP_TOKEN_USTAR; - } else if (lex_state_beg_p(parser)) { - type = YP_TOKEN_USTAR; - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(type); - } - - // ! != !~ !@ - case '!': - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - if (match(parser, '@')) { - LEX(YP_TOKEN_BANG); - } - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - if (match(parser, '=')) { - LEX(YP_TOKEN_BANG_EQUAL); - } - - if (match(parser, '~')) { - LEX(YP_TOKEN_BANG_TILDE); - } - - LEX(YP_TOKEN_BANG); - - // = => =~ == === =begin - case '=': - if (current_token_starts_line(parser) && memcmp(peek_string(parser, 5), "begin", 5) == 0 && yp_char_is_whitespace(peek_offset(parser, 5))) { - yp_token_type_t type = lex_embdoc(parser); - - if (type == YP_TOKEN_EOF) { - LEX(type); - } - - goto lex_next_token; - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - if (match(parser, '>')) { - LEX(YP_TOKEN_EQUAL_GREATER); - } - - if (match(parser, '~')) { - LEX(YP_TOKEN_EQUAL_TILDE); - } - - if (match(parser, '=')) { - LEX(match(parser, '=') ? YP_TOKEN_EQUAL_EQUAL_EQUAL : YP_TOKEN_EQUAL_EQUAL); - } - - LEX(YP_TOKEN_EQUAL); - - // < << <<= <= <=> - case '<': - if (match(parser, '<')) { - if ( - !lex_state_p(parser, YP_LEX_STATE_DOT | YP_LEX_STATE_CLASS) && - !lex_state_end_p(parser) && - (!lex_state_p(parser, YP_LEX_STATE_ARG_ANY) || lex_state_p(parser, YP_LEX_STATE_LABELED) || space_seen) - ) { - const uint8_t *end = parser->current.end; - - yp_heredoc_quote_t quote = YP_HEREDOC_QUOTE_NONE; - yp_heredoc_indent_t indent = YP_HEREDOC_INDENT_NONE; - - if (match(parser, '-')) { - indent = YP_HEREDOC_INDENT_DASH; - } - else if (match(parser, '~')) { - indent = YP_HEREDOC_INDENT_TILDE; - } - - if (match(parser, '`')) { - quote = YP_HEREDOC_QUOTE_BACKTICK; - } - else if (match(parser, '"')) { - quote = YP_HEREDOC_QUOTE_DOUBLE; - } - else if (match(parser, '\'')) { - quote = YP_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 == YP_HEREDOC_QUOTE_NONE && (width = char_is_identifier(parser, parser->current.end)) == 0) { - parser->current.end = end; - } else { - if (quote == YP_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 != (yp_heredoc_quote_t) (*parser->current.end)) { - parser->current.end++; - } - } - - size_t ident_length = (size_t) (parser->current.end - ident_start); - if (quote != YP_HEREDOC_QUOTE_NONE && !match(parser, (uint8_t) quote)) { - // TODO: handle unterminated heredoc - } - - lex_mode_push(parser, (yp_lex_mode_t) { - .mode = YP_LEX_HEREDOC, - .as.heredoc = { - .ident_start = ident_start, - .ident_length = ident_length, - .next_start = parser->current.end, - .quote = quote, - .indent = indent - } - }); - - 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. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_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. - yp_newline_list_append(&parser->newline_list, body_start); - body_start++; - } - - parser->next_start = body_start; - } else { - parser->next_start = parser->heredoc_end; - } - - LEX(YP_TOKEN_HEREDOC_START); - } - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_LESS_LESS_EQUAL); - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - if (lex_state_p(parser, YP_LEX_STATE_CLASS)) parser->command_start = true; - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(YP_TOKEN_LESS_LESS); - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - if (lex_state_p(parser, YP_LEX_STATE_CLASS)) parser->command_start = true; - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - if (match(parser, '=')) { - if (match(parser, '>')) { - LEX(YP_TOKEN_LESS_EQUAL_GREATER); - } - - LEX(YP_TOKEN_LESS_EQUAL); - } - - LEX(YP_TOKEN_LESS); - - // > >> >>= >= - case '>': - if (match(parser, '>')) { - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - LEX(match(parser, '=') ? YP_TOKEN_GREATER_GREATER_EQUAL : YP_TOKEN_GREATER_GREATER); - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(match(parser, '=') ? YP_TOKEN_GREATER_EQUAL : YP_TOKEN_GREATER); - - // double-quoted string literal - case '"': { - bool label_allowed = (lex_state_p(parser, YP_LEX_STATE_LABEL | YP_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser); - lex_mode_push_string(parser, true, label_allowed, '\0', '"'); - LEX(YP_TOKEN_STRING_BEGIN); - } - - // xstring literal - case '`': { - if (lex_state_p(parser, YP_LEX_STATE_FNAME)) { - lex_state_set(parser, YP_LEX_STATE_ENDFN); - LEX(YP_TOKEN_BACKTICK); - } - - if (lex_state_p(parser, YP_LEX_STATE_DOT)) { - if (previous_command_start) { - lex_state_set(parser, YP_LEX_STATE_CMDARG); - } else { - lex_state_set(parser, YP_LEX_STATE_ARG); - } - - LEX(YP_TOKEN_BACKTICK); - } - - lex_mode_push_string(parser, true, false, '\0', '`'); - LEX(YP_TOKEN_BACKTICK); - } - - // single-quoted string literal - case '\'': { - bool label_allowed = (lex_state_p(parser, YP_LEX_STATE_LABEL | YP_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser); - lex_mode_push_string(parser, false, label_allowed, '\0', '\''); - LEX(YP_TOKEN_STRING_BEGIN); - } - - // ? character literal - case '?': - LEX(lex_question_mark(parser)); - - // & && &&= &= - case '&': { - if (match(parser, '&')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - - if (match(parser, '=')) { - LEX(YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL); - } - - LEX(YP_TOKEN_AMPERSAND_AMPERSAND); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_AMPERSAND_EQUAL); - } - - if (match(parser, '.')) { - lex_state_set(parser, YP_LEX_STATE_DOT); - LEX(YP_TOKEN_AMPERSAND_DOT); - } - - yp_token_type_t type = YP_TOKEN_AMPERSAND; - if (lex_state_spcarg_p(parser, space_seen) || lex_state_beg_p(parser)) { - type = YP_TOKEN_UAMPERSAND; - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(type); - } - - // | || ||= |= - case '|': - if (match(parser, '|')) { - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PIPE_PIPE_EQUAL); - } - - if (lex_state_p(parser, YP_LEX_STATE_BEG)) { - parser->current.end--; - LEX(YP_TOKEN_PIPE); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PIPE_PIPE); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PIPE_EQUAL); - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - } - - LEX(YP_TOKEN_PIPE); - - // + += +@ - case '+': { - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - - if (match(parser, '@')) { - LEX(YP_TOKEN_UPLUS); - } - - LEX(YP_TOKEN_PLUS); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PLUS_EQUAL); - } - - bool spcarg = lex_state_spcarg_p(parser, space_seen); - if (spcarg) { - yp_diagnostic_list_append( - &parser->warning_list, - parser->current.start, - parser->current.end, - YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS - ); - } - - if (lex_state_beg_p(parser) || spcarg) { - lex_state_set(parser, YP_LEX_STATE_BEG); - - if (yp_char_is_decimal_digit(peek(parser))) { - parser->current.end++; - yp_token_type_t type = lex_numeric(parser); - lex_state_set(parser, YP_LEX_STATE_END); - LEX(type); - } - - LEX(YP_TOKEN_UPLUS); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PLUS); - } - - // - -= -@ - case '-': { - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - - if (match(parser, '@')) { - LEX(YP_TOKEN_UMINUS); - } - - LEX(YP_TOKEN_MINUS); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_MINUS_EQUAL); - } - - if (match(parser, '>')) { - lex_state_set(parser, YP_LEX_STATE_ENDFN); - LEX(YP_TOKEN_MINUS_GREATER); - } - - bool spcarg = lex_state_spcarg_p(parser, space_seen); - if (spcarg) { - yp_diagnostic_list_append( - &parser->warning_list, - parser->current.start, - parser->current.end, - YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS - ); - } - - if (lex_state_beg_p(parser) || spcarg) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(yp_char_is_decimal_digit(peek(parser)) ? YP_TOKEN_UMINUS_NUM : YP_TOKEN_UMINUS); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_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, YP_CONTEXT_DEFAULT_PARAMS) && - context_p(parser, YP_CONTEXT_DEF_PARAMS) - ) { - if (lex_state_p(parser, YP_LEX_STATE_END)) { - lex_state_set(parser, YP_LEX_STATE_BEG); - } else { - lex_state_set(parser, YP_LEX_STATE_ENDARG); - } - LEX(YP_TOKEN_UDOT_DOT_DOT); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(beg_p ? YP_TOKEN_UDOT_DOT_DOT : YP_TOKEN_DOT_DOT_DOT); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(beg_p ? YP_TOKEN_UDOT_DOT : YP_TOKEN_DOT_DOT); - } - - lex_state_set(parser, YP_LEX_STATE_DOT); - LEX(YP_TOKEN_DOT); - } - - // integer - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - yp_token_type_t type = lex_numeric(parser); - lex_state_set(parser, YP_LEX_STATE_END); - LEX(type); - } - - // :: symbol - case ':': - if (match(parser, ':')) { - if (lex_state_beg_p(parser) || lex_state_p(parser, YP_LEX_STATE_CLASS) || (lex_state_p(parser, YP_LEX_STATE_ARG_ANY) && space_seen)) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_UCOLON_COLON); - } - - lex_state_set(parser, YP_LEX_STATE_DOT); - LEX(YP_TOKEN_COLON_COLON); - } - - if (lex_state_end_p(parser) || yp_char_is_whitespace(peek(parser)) || peek(parser) == '#') { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_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, YP_LEX_STATE_FNAME); - LEX(YP_TOKEN_SYMBOL_BEGIN); - - // / /= - case '/': - if (lex_state_beg_p(parser)) { - lex_mode_push_regexp(parser, '\0', '/'); - LEX(YP_TOKEN_REGEXP_BEGIN); - } - - if (match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_SLASH_EQUAL); - } - - if (lex_state_spcarg_p(parser, space_seen)) { - yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_SLASH); - lex_mode_push_regexp(parser, '\0', '/'); - LEX(YP_TOKEN_REGEXP_BEGIN); - } - - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(YP_TOKEN_SLASH); - - // ^ ^= - case '^': - if (lex_state_operator_p(parser)) { - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - LEX(match(parser, '=') ? YP_TOKEN_CARET_EQUAL : YP_TOKEN_CARET); - - // ~ ~@ - case '~': - if (lex_state_operator_p(parser)) { - (void) match(parser, '@'); - lex_state_set(parser, YP_LEX_STATE_ARG); - } else { - lex_state_set(parser, YP_LEX_STATE_BEG); - } - - LEX(YP_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)) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT); - LEX(YP_TOKEN_PERCENT); - } - - if (!lex_state_beg_p(parser) && match(parser, '=')) { - lex_state_set(parser, YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PERCENT_EQUAL); - } - else if( - lex_state_beg_p(parser) || - (lex_state_p(parser, YP_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)) { - 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; - yp_newline_list_append(&parser->newline_list, parser->current.end - 1); - } else { - parser->current.end++; - } - - if (parser->current.end < parser->end) { - LEX(YP_TOKEN_STRING_BEGIN); - } - } - - switch (peek(parser)) { - case 'i': { - parser->current.end++; - - if (parser->current.end < parser->end) { - lex_mode_push_list(parser, false, *parser->current.end++); - } - - LEX(YP_TOKEN_PERCENT_LOWER_I); - } - case 'I': { - parser->current.end++; - - if (parser->current.end < parser->end) { - lex_mode_push_list(parser, true, *parser->current.end++); - } - - LEX(YP_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)); - yp_newline_list_check_append(&parser->newline_list, parser->current.end); - parser->current.end++; - } - - LEX(YP_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)); - yp_newline_list_check_append(&parser->newline_list, parser->current.end); - parser->current.end++; - } - - LEX(YP_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)); - yp_newline_list_check_append(&parser->newline_list, parser->current.end); - parser->current.end++; - } - - LEX(YP_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, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM); - parser->current.end++; - } - - LEX(YP_TOKEN_SYMBOL_BEGIN); - } - case 'w': { - parser->current.end++; - - if (parser->current.end < parser->end) { - lex_mode_push_list(parser, false, *parser->current.end++); - } - - LEX(YP_TOKEN_PERCENT_LOWER_W); - } - case 'W': { - parser->current.end++; - - if (parser->current.end < parser->end) { - lex_mode_push_list(parser, true, *parser->current.end++); - } - - LEX(YP_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++; - } - - LEX(YP_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. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT); - goto lex_next_token; - } - } - - lex_state_set(parser, lex_state_operator_p(parser) ? YP_LEX_STATE_ARG : YP_LEX_STATE_BEG); - LEX(YP_TOKEN_PERCENT); - } - - // global variable - case '$': { - yp_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 == YP_LEX_EMBVAR) { - lex_mode_pop(parser); - } - - lex_state_set(parser, YP_LEX_STATE_END); - LEX(type); - } - - // instance variable, class variable - case '@': - lex_state_set(parser, parser->lex_state & YP_LEX_STATE_FNAME ? YP_LEX_STATE_ENDFN : YP_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) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_TOKEN); - goto lex_next_token; - } - - parser->current.end = parser->current.start + width; - } - - yp_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)) - ) - { - parser->current.end = parser->end; - parser->current.type = YP_TOKEN___END__; - parser_lex_callback(parser); - - yp_comment_t *comment = parser_comment(parser, YP_COMMENT___END__); - yp_list_append(&parser->comment_list, (yp_list_node_t *) comment); - - LEX(YP_TOKEN_EOF); - } - - yp_lex_state_t last_state = parser->lex_state; - - if (type == YP_TOKEN_IDENTIFIER || type == YP_TOKEN_CONSTANT) { - if (lex_state_p(parser, YP_LEX_STATE_BEG_ANY | YP_LEX_STATE_ARG_ANY | YP_LEX_STATE_DOT)) { - if (previous_command_start) { - lex_state_set(parser, YP_LEX_STATE_CMDARG); - } else { - lex_state_set(parser, YP_LEX_STATE_ARG); - } - } else if (parser->lex_state == YP_LEX_STATE_FNAME) { - lex_state_set(parser, YP_LEX_STATE_ENDFN); - } else { - lex_state_set(parser, YP_LEX_STATE_END); - } - } - - if ( - !(last_state & (YP_LEX_STATE_DOT | YP_LEX_STATE_FNAME)) && - (type == YP_TOKEN_IDENTIFIER) && - ((yp_parser_local_depth(parser, &parser->current) != -1) || - token_is_numbered_parameter(parser->current.start, parser->current.end)) - ) { - lex_state_set(parser, YP_LEX_STATE_END | YP_LEX_STATE_LABEL); - } - - LEX(type); - } - } - } - case YP_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 = yp_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end); - if (peek_offset(parser, (ptrdiff_t)whitespace) == '\n') { - whitespace += 1; - } - } else { - whitespace = yp_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(YP_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(YP_TOKEN_EOF); - } - - // Here we'll get a list of the places where strpbrk should break, - // and then find the first one. - yp_lex_mode_t *lex_mode = parser->lex_modes.current; - const uint8_t *breakpoints = lex_mode->as.list.breakpoints; - const uint8_t *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - - while (breakpoint != NULL) { - // If we hit a null byte, skip directly past it. - if (*breakpoint == '\0') { - breakpoint = yp_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 (yp_char_is_whitespace(*breakpoint)) { - parser->current.end = breakpoint; - LEX(YP_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) { - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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; - LEX(YP_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, YP_LEX_STATE_END); - LEX(YP_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 == '\\') { - yp_unescape_type_t unescape_type = lex_mode->as.list.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL; - size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false); - if (difference == 0) { - // we're at the end of the file - breakpoint = NULL; - continue; - } - - // If the result is an escaped newline ... - if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; - parser_flush_heredoc_end(parser); - LEX(YP_TOKEN_STRING_CONTENT); - } else { - // ... else track the newline. - yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); - } - } - - breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); - continue; - } - - // If we hit a #, then we will attempt to lex interpolation. - if (*breakpoint == '#') { - yp_token_type_t type = lex_interpolation(parser, breakpoint); - if (type != YP_TOKEN_NOT_PROVIDED) { - LEX(type); - } - - // 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 = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - continue; - } - - // 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); - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - lex_mode->as.list.nesting++; - continue; - } - - // If we were unable to find a breakpoint, then this token hits the end of - // the file. - LEX(YP_TOKEN_EOF); - - case YP_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(YP_TOKEN_EOF); - } - - // Get a reference to the current mode. - yp_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 = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - - while (breakpoint != NULL) { - // If we hit a null byte, skip directly past it. - if (*breakpoint == '\0') { - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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 YP_TOKEN_REGEXP_BEGIN and then again - // with YP_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 != YP_TOKEN_REGEXP_BEGIN) - && parser->heredoc_end == NULL - ) { - yp_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. - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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) { - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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; - LEX(YP_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 += yp_strspn_regexp_option(parser->current.end, parser->end - parser->current.end); - - lex_mode_pop(parser); - lex_state_set(parser, YP_LEX_STATE_END); - LEX(YP_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 == '\\') { - size_t difference = yp_unescape_calculate_difference(parser, breakpoint, YP_UNESCAPE_ALL, false); - if (difference == 0) { - // we're at the end of the file - breakpoint = NULL; - continue; - } - - // If the result is an escaped newline ... - if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; - parser_flush_heredoc_end(parser); - LEX(YP_TOKEN_STRING_CONTENT); - } else { - // ... else track the newline. - yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); - } - } - - breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); - continue; - } - - // If we hit a #, then we will attempt to lex interpolation. - if (*breakpoint == '#') { - yp_token_type_t type = lex_interpolation(parser, breakpoint); - if (type != YP_TOKEN_NOT_PROVIDED) { - LEX(type); - } - - // 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 = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - continue; - } - - // 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); - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - lex_mode->as.regexp.nesting++; - continue; - } - - // At this point, the breakpoint is NULL which means we were unable to - // find anything before the end of the file. - LEX(YP_TOKEN_EOF); - } - case YP_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(YP_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. - const uint8_t *breakpoints = parser->lex_modes.current->as.string.breakpoints; - const uint8_t *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - - while (breakpoint != NULL) { - // If we hit the incrementor, then we'll increment then nesting and - // continue lexing. - if ( - parser->lex_modes.current->as.string.incrementor != '\0' && - *breakpoint == parser->lex_modes.current->as.string.incrementor - ) { - parser->lex_modes.current->as.string.nesting++; - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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 == parser->lex_modes.current->as.string.terminator) { - // If this terminator doesn't actually close the string, then we need - // to continue on past it. - if (parser->lex_modes.current->as.string.nesting > 0) { - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - parser->lex_modes.current->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; - LEX(YP_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; - yp_newline_list_append(&parser->newline_list, parser->current.end - 1); - } else { - parser->current.end = breakpoint + 1; - } - - if ( - parser->lex_modes.current->as.string.label_allowed && - (peek(parser) == ':') && - (peek_offset(parser, 1) != ':') - ) { - parser->current.end++; - lex_state_set(parser, YP_LEX_STATE_ARG | YP_LEX_STATE_LABELED); - lex_mode_pop(parser); - LEX(YP_TOKEN_LABEL_END); - } - - lex_state_set(parser, YP_LEX_STATE_END); - lex_mode_pop(parser); - LEX(YP_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) { - yp_newline_list_append(&parser->newline_list, breakpoint); - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - continue; - } else { - parser->current.end = breakpoint + 1; - parser_flush_heredoc_end(parser); - LEX(YP_TOKEN_STRING_CONTENT); - } - } - - switch (*breakpoint) { - case '\0': - // Skip directly past the null character. - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - break; - case '\\': { - // 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. - yp_unescape_type_t unescape_type = parser->lex_modes.current->as.string.interpolation ? YP_UNESCAPE_ALL : YP_UNESCAPE_MINIMAL; - size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false); - if (difference == 0) { - // we're at the end of the file - breakpoint = NULL; - break; - } - - // If the result is an escaped newline ... - if (breakpoint[difference - 1] == '\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->current.end = breakpoint + difference; - parser_flush_heredoc_end(parser); - LEX(YP_TOKEN_STRING_CONTENT); - } else { - // ... else track the newline. - yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); - } - } - - breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); - break; - } - case '#': { - yp_token_type_t type = lex_interpolation(parser, breakpoint); - if (type != YP_TOKEN_NOT_PROVIDED) { - LEX(type); - } - - // 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 = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - break; - } - default: - assert(false && "unreachable"); - } - } - - // If we've hit the end of the string, then this is an unterminated - // string. In that case we'll return the EOF token. - parser->current.end = parser->end; - LEX(YP_TOKEN_EOF); - } - case YP_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(YP_TOKEN_EOF); - } - - // Now let's grab the information about the identifier off of the current - // lex mode. - const uint8_t *ident_start = parser->lex_modes.current->as.heredoc.ident_start; - size_t ident_length = parser->lex_modes.current->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 (parser->lex_modes.current->as.heredoc.indent != YP_HEREDOC_INDENT_NONE) { - start += yp_strspn_inline_whitespace(start, parser->end - start); - } - - if ((start + ident_length <= parser->end) && (memcmp(start, ident_start, ident_length) == 0)) { - bool matched = true; - bool at_end = false; - - size_t eol_length = match_eol_at(parser, start + ident_length); - if (eol_length) { - parser->current.end = start + ident_length + eol_length; - yp_newline_list_append(&parser->newline_list, parser->current.end - 1); - } else if (parser->end == (start + ident_length)) { - parser->current.end = start + ident_length; - at_end = true; - } else { - matched = false; - } - - if (matched) { - if (*parser->lex_modes.current->as.heredoc.next_start == '\\') { - parser->next_start = NULL; - } else { - parser->next_start = parser->lex_modes.current->as.heredoc.next_start; - parser->heredoc_end = parser->current.end; - } - - lex_mode_pop(parser); - if (!at_end) { - lex_state_set(parser, YP_LEX_STATE_END); - } - LEX(YP_TOKEN_HEREDOC_END); - } - } - } - - // 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\\#"; - - yp_heredoc_quote_t quote = parser->lex_modes.current->as.heredoc.quote; - if (quote == YP_HEREDOC_QUOTE_SINGLE) { - breakpoints[2] = '\0'; - } - - const uint8_t *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - - while (breakpoint != NULL) { - switch (*breakpoint) { - case '\0': - // Skip directly past the null character. - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - break; - case '\n': { - if (parser->heredoc_end != NULL && (parser->heredoc_end > breakpoint)) { - parser_flush_heredoc_end(parser); - parser->current.end = breakpoint + 1; - LEX(YP_TOKEN_STRING_CONTENT); - } - - yp_newline_list_append(&parser->newline_list, breakpoint); - - const uint8_t *start = breakpoint + 1; - if (parser->lex_modes.current->as.heredoc.indent != YP_HEREDOC_INDENT_NONE) { - start += yp_strspn_inline_whitespace(start, parser->end - start); - } - - // 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 ( - (start + ident_length <= parser->end) && - (memcmp(start, ident_start, ident_length) == 0) - ) { - // Heredoc terminators must be followed by a newline, CRLF, or EOF to be valid. - if ( - start + ident_length == parser->end || - match_eol_at(parser, start + ident_length) - ) { - parser->current.end = breakpoint + 1; - LEX(YP_TOKEN_STRING_CONTENT); - } - } - - // Otherwise we hit a newline and it wasn't followed by a - // terminator, so we can continue parsing. - breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); - 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. - size_t eol_length = match_eol_at(parser, breakpoint + 1); - if (eol_length) { - breakpoint += eol_length; - } else { - yp_unescape_type_t unescape_type = (quote == YP_HEREDOC_QUOTE_SINGLE) ? YP_UNESCAPE_MINIMAL : YP_UNESCAPE_ALL; - size_t difference = yp_unescape_calculate_difference(parser, breakpoint, unescape_type, false); - if (difference == 0) { - // we're at the end of the file - breakpoint = NULL; - break; - } - - yp_newline_list_check_append(&parser->newline_list, breakpoint + difference - 1); - - breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); - } - - break; - } - case '#': { - yp_token_type_t type = lex_interpolation(parser, breakpoint); - if (type != YP_TOKEN_NOT_PROVIDED) { - LEX(type); - } - - // 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 = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); - break; - } - default: - assert(false && "unreachable"); - } - } - - // If we've hit the end of the string, then this is an unterminated - // heredoc. In that case we'll return the EOF token. - parser->current.end = parser->end; - LEX(YP_TOKEN_EOF); - } - } - - assert(false && "unreachable"); -} - -#undef LEX - -/******************************************************************************/ -/* Parse functions */ -/******************************************************************************/ - -// When we are parsing certain content, we need to unescape the content to -// provide to the consumers of the parser. The following functions accept a range -// of characters from the source and unescapes into the provided type. -// -// We have functions for unescaping regular expression nodes, string nodes, -// symbol nodes, and xstring nodes -static yp_regular_expression_node_t * -yp_regular_expression_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) { - yp_regular_expression_node_t *node = yp_regular_expression_node_create(parser, opening, content, closing); - - assert((content->end - content->start) >= 0); - yp_string_shared_init(&node->unescaped, content->start, content->end); - - yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type); - return node; -} - -static yp_symbol_node_t * -yp_symbol_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) { - yp_symbol_node_t *node = yp_symbol_node_create(parser, opening, content, closing); - - assert((content->end - content->start) >= 0); - yp_string_shared_init(&node->unescaped, content->start, content->end); - - yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type); - return node; -} - -static yp_string_node_t * -yp_char_literal_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) { - yp_string_node_t *node = yp_string_node_create(parser, opening, content, closing); - - assert((content->end - content->start) >= 0); - yp_string_shared_init(&node->unescaped, content->start, content->end); - - yp_unescape_manipulate_char_literal(parser, &node->unescaped, unescape_type); - return node; -} - -static yp_string_node_t * -yp_string_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing, yp_unescape_type_t unescape_type) { - yp_string_node_t *node = yp_string_node_create(parser, opening, content, closing); - - assert((content->end - content->start) >= 0); - yp_string_shared_init(&node->unescaped, content->start, content->end); - - yp_unescape_manipulate_string(parser, &node->unescaped, unescape_type); - return node; -} - -static yp_x_string_node_t * -yp_xstring_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *opening, const yp_token_t *content, const yp_token_t *closing) { - yp_x_string_node_t *node = yp_xstring_node_create(parser, opening, content, closing); - - assert((content->end - content->start) >= 0); - yp_string_shared_init(&node->unescaped, content->start, content->end); - - yp_unescape_manipulate_string(parser, &node->unescaped, YP_UNESCAPE_ALL); - return node; -} - -// Returns true if the current token is of the specified type. -static inline bool -match_type_p(yp_parser_t *parser, yp_token_type_t type) { - return parser->current.type == type; -} - -// Returns true if the current token is of any of the specified types. -static bool -match_any_type_p(yp_parser_t *parser, size_t count, ...) { - va_list types; - va_start(types, count); - - for (size_t index = 0; index < count; index++) { - if (match_type_p(parser, va_arg(types, yp_token_type_t))) { - va_end(types); - return true; - } - } - - va_end(types); - return false; -} - -// 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 { - YP_BINDING_POWER_UNSET = 0, // used to indicate this token cannot be used as an infix operator - YP_BINDING_POWER_STATEMENT = 2, - YP_BINDING_POWER_MODIFIER = 4, // if unless until while in - YP_BINDING_POWER_MODIFIER_RESCUE = 6, // rescue - YP_BINDING_POWER_COMPOSITION = 8, // and or - YP_BINDING_POWER_NOT = 10, // not - YP_BINDING_POWER_MATCH = 12, // => - YP_BINDING_POWER_DEFINED = 14, // defined? - YP_BINDING_POWER_ASSIGNMENT = 16, // = += -= *= /= %= &= |= ^= &&= ||= <<= >>= **= - YP_BINDING_POWER_TERNARY = 18, // ?: - YP_BINDING_POWER_RANGE = 20, // .. ... - YP_BINDING_POWER_LOGICAL_OR = 22, // || - YP_BINDING_POWER_LOGICAL_AND = 24, // && - YP_BINDING_POWER_EQUALITY = 26, // <=> == === != =~ !~ - YP_BINDING_POWER_COMPARISON = 28, // > >= < <= - YP_BINDING_POWER_BITWISE_OR = 30, // | ^ - YP_BINDING_POWER_BITWISE_AND = 32, // & - YP_BINDING_POWER_SHIFT = 34, // << >> - YP_BINDING_POWER_TERM = 36, // + - - YP_BINDING_POWER_FACTOR = 38, // * / % - YP_BINDING_POWER_UMINUS = 40, // -@ - YP_BINDING_POWER_EXPONENT = 42, // ** - YP_BINDING_POWER_UNARY = 44, // ! ~ +@ - YP_BINDING_POWER_INDEX = 46, // [] []= - YP_BINDING_POWER_CALL = 48, // :: . - YP_BINDING_POWER_MAX = 50 -} yp_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 { - yp_binding_power_t left; - yp_binding_power_t right; - bool binary; -} yp_binding_powers_t; - -#define BINDING_POWER_ASSIGNMENT { YP_BINDING_POWER_UNARY, YP_BINDING_POWER_ASSIGNMENT, true } -#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true } -#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true } -#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false } - -yp_binding_powers_t yp_binding_powers[YP_TOKEN_MAXIMUM] = { - // if unless until while in rescue - [YP_TOKEN_KEYWORD_IF_MODIFIER] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MODIFIER), - [YP_TOKEN_KEYWORD_UNLESS_MODIFIER] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MODIFIER), - [YP_TOKEN_KEYWORD_UNTIL_MODIFIER] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MODIFIER), - [YP_TOKEN_KEYWORD_WHILE_MODIFIER] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MODIFIER), - [YP_TOKEN_KEYWORD_IN] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MODIFIER), - - // rescue modifier - [YP_TOKEN_KEYWORD_RESCUE_MODIFIER] = { - YP_BINDING_POWER_ASSIGNMENT, - YP_BINDING_POWER_MODIFIER_RESCUE + 1, - true - }, - - // and or - [YP_TOKEN_KEYWORD_AND] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_COMPOSITION), - [YP_TOKEN_KEYWORD_OR] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_COMPOSITION), - - // => - [YP_TOKEN_EQUAL_GREATER] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_MATCH), - - // &&= &= ^= = >>= <<= -= %= |= += /= *= **= - [YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_CARET_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_GREATER_GREATER_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_LESS_LESS_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_MINUS_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_PERCENT_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_PIPE_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_PLUS_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_SLASH_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT, - [YP_TOKEN_STAR_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT, - - // ?: - [YP_TOKEN_QUESTION_MARK] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_TERNARY), - - // .. ... - [YP_TOKEN_DOT_DOT] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_RANGE), - [YP_TOKEN_DOT_DOT_DOT] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_RANGE), - - // || - [YP_TOKEN_PIPE_PIPE] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_LOGICAL_OR), - - // && - [YP_TOKEN_AMPERSAND_AMPERSAND] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_LOGICAL_AND), - - // != !~ == === =~ <=> - [YP_TOKEN_BANG_EQUAL] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - [YP_TOKEN_BANG_TILDE] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - [YP_TOKEN_EQUAL_EQUAL] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - [YP_TOKEN_EQUAL_EQUAL_EQUAL] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - [YP_TOKEN_EQUAL_TILDE] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - [YP_TOKEN_LESS_EQUAL_GREATER] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EQUALITY), - - // > >= < <= - [YP_TOKEN_GREATER] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_COMPARISON), - [YP_TOKEN_GREATER_EQUAL] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_COMPARISON), - [YP_TOKEN_LESS] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_COMPARISON), - [YP_TOKEN_LESS_EQUAL] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_COMPARISON), - - // ^ | - [YP_TOKEN_CARET] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_BITWISE_OR), - [YP_TOKEN_PIPE] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_BITWISE_OR), - - // & - [YP_TOKEN_AMPERSAND] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_BITWISE_AND), - - // >> << - [YP_TOKEN_GREATER_GREATER] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_SHIFT), - [YP_TOKEN_LESS_LESS] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_SHIFT), - - // - + - [YP_TOKEN_MINUS] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_TERM), - [YP_TOKEN_PLUS] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_TERM), - - // % / * - [YP_TOKEN_PERCENT] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_FACTOR), - [YP_TOKEN_SLASH] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_FACTOR), - [YP_TOKEN_STAR] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_FACTOR), - [YP_TOKEN_USTAR] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_FACTOR), - - // -@ - [YP_TOKEN_UMINUS] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UMINUS), - [YP_TOKEN_UMINUS_NUM] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UMINUS), - - // ** - [YP_TOKEN_STAR_STAR] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_EXPONENT), - [YP_TOKEN_USTAR_STAR] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UNARY), - - // ! ~ +@ - [YP_TOKEN_BANG] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UNARY), - [YP_TOKEN_TILDE] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UNARY), - [YP_TOKEN_UPLUS] = RIGHT_ASSOCIATIVE_UNARY(YP_BINDING_POWER_UNARY), - - // [ - [YP_TOKEN_BRACKET_LEFT] = LEFT_ASSOCIATIVE(YP_BINDING_POWER_INDEX), - - // :: . &. - [YP_TOKEN_COLON_COLON] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_CALL), - [YP_TOKEN_DOT] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_CALL), - [YP_TOKEN_AMPERSAND_DOT] = RIGHT_ASSOCIATIVE(YP_BINDING_POWER_CALL) -}; - -#undef BINDING_POWER_ASSIGNMENT -#undef LEFT_ASSOCIATIVE -#undef RIGHT_ASSOCIATIVE -#undef RIGHT_ASSOCIATIVE_UNARY - -// If the current token is of the specified type, lex forward by one token and -// return true. Otherwise, return false. For example: -// -// if (accept(parser, YP_TOKEN_COLON)) { ... } -// -static bool -accept(yp_parser_t *parser, yp_token_type_t type) { - if (match_type_p(parser, type)) { - parser_lex(parser); - return true; - } - return false; -} - -// If the current token is of any of the specified types, lex forward by one -// token and return true. Otherwise, return false. For example: -// -// if (accept_any(parser, 2, YP_TOKEN_COLON, YP_TOKEN_SEMICOLON)) { ... } -// -static bool -accept_any(yp_parser_t *parser, size_t count, ...) { - va_list types; - va_start(types, count); - - for (size_t index = 0; index < count; index++) { - if (match_type_p(parser, va_arg(types, yp_token_type_t))) { - parser_lex(parser); - va_end(types); - return true; - } - } - - va_end(types); - 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 -expect(yp_parser_t *parser, yp_token_type_t type, yp_diagnostic_id_t diag_id) { - if (accept(parser, type)) return; - - yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id); - - parser->previous = - (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; -} - -static void -expect_any(yp_parser_t *parser, yp_diagnostic_id_t diag_id, size_t count, ...) { - va_list types; - va_start(types, count); - - for (size_t index = 0; index < count; index++) { - if (accept(parser, va_arg(types, yp_token_type_t))) { - va_end(types); - return; - } - } - - va_end(types); - - yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id); - parser->previous = - (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; -} - -static yp_node_t * -parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id); - -// 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(yp_token_type_t type) { - switch (type) { - case YP_TOKEN_EQUAL_GREATER: - case YP_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 YP_TOKEN_BRACE_RIGHT: - case YP_TOKEN_BRACKET_RIGHT: - case YP_TOKEN_COLON: - case YP_TOKEN_COMMA: - case YP_TOKEN_EMBEXPR_END: - case YP_TOKEN_EOF: - case YP_TOKEN_LAMBDA_BEGIN: - case YP_TOKEN_KEYWORD_DO: - case YP_TOKEN_KEYWORD_DO_LOOP: - case YP_TOKEN_KEYWORD_END: - case YP_TOKEN_KEYWORD_ELSE: - case YP_TOKEN_KEYWORD_ELSIF: - case YP_TOKEN_KEYWORD_ENSURE: - case YP_TOKEN_KEYWORD_THEN: - case YP_TOKEN_KEYWORD_RESCUE: - case YP_TOKEN_KEYWORD_WHEN: - case YP_TOKEN_NEWLINE: - case YP_TOKEN_PARENTHESIS_RIGHT: - case YP_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(yp_binding_powers[type].left == YP_BINDING_POWER_UNSET); - return false; - case YP_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 YP_TOKEN_UCOLON_COLON: - case YP_TOKEN_UMINUS: - case YP_TOKEN_UMINUS_NUM: - case YP_TOKEN_UPLUS: - case YP_TOKEN_BANG: - case YP_TOKEN_TILDE: - case YP_TOKEN_UDOT_DOT: - case YP_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 yp_binding_powers[type].left == YP_BINDING_POWER_UNSET; - } -} - -// Parse an expression with the given binding power that may be optionally -// prefixed by the * operator. -static yp_node_t * -parse_starred_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { - if (accept(parser, YP_TOKEN_USTAR)) { - yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); - return (yp_node_t *) yp_splat_node_create(parser, &operator, expression); - } - - return parse_expression(parser, binding_power, diag_id); -} - -// Convert the given node into a valid target node. -static yp_node_t * -parse_target(yp_parser_t *parser, yp_node_t *target) { - switch (YP_NODE_TYPE(target)) { - case YP_MISSING_NODE: - return target; - case YP_CLASS_VARIABLE_READ_NODE: - assert(sizeof(yp_class_variable_target_node_t) == sizeof(yp_class_variable_read_node_t)); - target->type = YP_CLASS_VARIABLE_TARGET_NODE; - return target; - case YP_CONSTANT_PATH_NODE: - assert(sizeof(yp_constant_path_target_node_t) == sizeof(yp_constant_path_node_t)); - target->type = YP_CONSTANT_PATH_TARGET_NODE; - return target; - case YP_CONSTANT_READ_NODE: - assert(sizeof(yp_constant_target_node_t) == sizeof(yp_constant_read_node_t)); - target->type = YP_CONSTANT_TARGET_NODE; - return target; - case YP_BACK_REFERENCE_READ_NODE: - assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_back_reference_read_node_t)); - /* fallthrough */ - case YP_NUMBERED_REFERENCE_READ_NODE: - assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_numbered_reference_read_node_t)); - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY); - /* fallthrough */ - case YP_GLOBAL_VARIABLE_READ_NODE: - assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_global_variable_read_node_t)); - target->type = YP_GLOBAL_VARIABLE_TARGET_NODE; - return target; - case YP_LOCAL_VARIABLE_READ_NODE: - assert(sizeof(yp_local_variable_target_node_t) == sizeof(yp_local_variable_read_node_t)); - target->type = YP_LOCAL_VARIABLE_TARGET_NODE; - return target; - case YP_INSTANCE_VARIABLE_READ_NODE: - assert(sizeof(yp_instance_variable_target_node_t) == sizeof(yp_instance_variable_read_node_t)); - target->type = YP_INSTANCE_VARIABLE_TARGET_NODE; - return target; - case YP_MULTI_TARGET_NODE: - return target; - case YP_SPLAT_NODE: { - yp_splat_node_t *splat = (yp_splat_node_t *) target; - - if (splat->expression != NULL) { - splat->expression = parse_target(parser, splat->expression); - } - - yp_multi_target_node_t *multi_target = yp_multi_target_node_create(parser); - yp_multi_target_node_targets_append(multi_target, (yp_node_t *) splat); - - return (yp_node_t *) multi_target; - } - case YP_CALL_NODE: { - yp_call_node_t *call = (yp_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->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 yp_location_t message = call->message_loc; - - yp_parser_local_add_location(parser, message.start, message.end); - yp_node_destroy(parser, target); - - const yp_token_t name = { .type = YP_TOKEN_IDENTIFIER, .start = message.start, .end = message.end }; - target = (yp_node_t *) yp_local_variable_read_node_create(parser, &name, 0); - - assert(sizeof(yp_local_variable_target_node_t) == sizeof(yp_local_variable_read_node_t)); - target->type = YP_LOCAL_VARIABLE_TARGET_NODE; - - if (token_is_numbered_parameter(message.start, message.end)) { - yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); - } - - return target; - } - - // 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 =. - size_t length = yp_string_length(&call->name); - - uint8_t *name = calloc(length + 1, sizeof(uint8_t)); - if (name == NULL) return NULL; - - memcpy(name, yp_string_source(&call->name), length); - name[length] = '='; - - // Now switch the name to the new string. - yp_string_free(&call->name); - yp_string_owned_init(&call->name, name, length + 1); - - return target; - } - - // 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 ( - (call->call_operator_loc.start == NULL) && - (call->message_loc.start[0] == '[') && - (call->message_loc.end[-1] == ']') && - (call->block == NULL) - ) { - // Free the previous name and replace it with "[]=". - yp_string_free(&call->name); - yp_string_constant_init(&call->name, "[]=", 3); - return target; - } - } - /* 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. - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_UNEXPECTED); - return target; - } -} - -// Convert the given node into a valid write node. -static yp_node_t * -parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_node_t *value) { - switch (YP_NODE_TYPE(target)) { - case YP_MISSING_NODE: - return target; - case YP_CLASS_VARIABLE_READ_NODE: { - yp_class_variable_write_node_t *node = yp_class_variable_write_node_create(parser, (yp_class_variable_read_node_t *) target, operator, value); - yp_node_destroy(parser, target); - return (yp_node_t *) node; - } - case YP_CONSTANT_PATH_NODE: - return (yp_node_t *) yp_constant_path_write_node_create(parser, (yp_constant_path_node_t *) target, operator, value); - case YP_CONSTANT_READ_NODE: { - yp_constant_write_node_t *node = yp_constant_write_node_create(parser, (yp_constant_read_node_t *) target, operator, value); - yp_node_destroy(parser, target); - return (yp_node_t *) node; - } - case YP_BACK_REFERENCE_READ_NODE: - case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY); - /* fallthrough */ - case YP_GLOBAL_VARIABLE_READ_NODE: { - yp_global_variable_write_node_t *node = yp_global_variable_write_node_create(parser, target, operator, value); - yp_node_destroy(parser, target); - return (yp_node_t *) node; - } - case YP_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *local_read = (yp_local_variable_read_node_t *) target; - - yp_constant_id_t constant_id = local_read->name; - uint32_t depth = local_read->depth; - - yp_location_t name_loc = target->location; - yp_node_destroy(parser, target); - - return (yp_node_t *) yp_local_variable_write_node_create(parser, constant_id, depth, value, &name_loc, operator); - } - case YP_INSTANCE_VARIABLE_READ_NODE: { - yp_node_t *write_node = (yp_node_t *) yp_instance_variable_write_node_create(parser, (yp_instance_variable_read_node_t *) target, operator, value); - yp_node_destroy(parser, target); - return write_node; - } - case YP_MULTI_TARGET_NODE: - return (yp_node_t *) yp_multi_write_node_create(parser, (yp_multi_target_node_t *) target, operator, value); - case YP_SPLAT_NODE: { - yp_splat_node_t *splat = (yp_splat_node_t *) target; - - if (splat->expression != NULL) { - splat->expression = parse_write(parser, splat->expression, operator, value); - } - - yp_multi_target_node_t *multi_target = yp_multi_target_node_create(parser); - yp_multi_target_node_targets_append(multi_target, (yp_node_t *) splat); - - return (yp_node_t *) yp_multi_write_node_create(parser, multi_target, operator, value); - } - case YP_CALL_NODE: { - yp_call_node_t *call = (yp_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->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 yp_location_t message = call->message_loc; - - yp_parser_local_add_location(parser, message.start, message.end); - yp_node_destroy(parser, target); - - yp_constant_id_t constant_id = yp_parser_constant_id_location(parser, message.start, message.end); - target = (yp_node_t *) yp_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator); - - if (token_is_numbered_parameter(message.start, message.end)) { - yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); - } - - return target; - } - - // 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. - yp_arguments_node_t *arguments = yp_arguments_node_create(parser); - call->arguments = arguments; - yp_arguments_node_arguments_append(arguments, value); - target->location.end = arguments->base.location.end; - - // 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 =. - size_t length = yp_string_length(&call->name); - - uint8_t *name = calloc(length + 1, sizeof(uint8_t)); - if (name == NULL) return NULL; - - memcpy(name, yp_string_source(&call->name), length); - name[length] = '='; - - // Now switch the name to the new string. - yp_string_free(&call->name); - yp_string_owned_init(&call->name, name, length + 1); - - return target; - } - - // 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 ( - (call->call_operator_loc.start == NULL) && - (call->message_loc.start[0] == '[') && - (call->message_loc.end[-1] == ']') && - (call->block == NULL) - ) { - if (call->arguments == NULL) { - call->arguments = yp_arguments_node_create(parser); - } - - yp_arguments_node_arguments_append(call->arguments, value); - target->location.end = value->location.end; - - // Free the previous name and replace it with "[]=". - yp_string_free(&call->name); - yp_string_constant_init(&call->name, "[]=", 3); - 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. - yp_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. - yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); - 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 yp_node_t * -parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t binding_power) { - yp_token_t operator = not_provided(parser); - - // The first_target parameter can be NULL in the case that we're parsing a - // location that we know requires a multi write, as in the case of a for loop. - // In this case we will set up the parsing loop slightly differently. - if (first_target != NULL) { - first_target = parse_target(parser, first_target); - - if (!match_type_p(parser, YP_TOKEN_COMMA)) { - return first_target; - } - } - - yp_multi_target_node_t *result = yp_multi_target_node_create(parser); - if (first_target != NULL) { - yp_multi_target_node_targets_append(result, first_target); - } - - bool has_splat = false; - - if (first_target == NULL || accept(parser, YP_TOKEN_COMMA)) { - do { - if (accept(parser, YP_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_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_MULTI_ASSIGN_MULTI_SPLATS); - } - - yp_token_t star_operator = parser->previous; - yp_node_t *name = NULL; - - if (token_begins_expression_p(parser->current.type)) { - name = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); - name = parse_target(parser, name); - } - - yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &star_operator, name); - yp_multi_target_node_targets_append(result, splat); - has_splat = true; - } else if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - // Here we have a parenthesized list of targets. We'll recurse down into - // the parentheses by calling parse_targets again and then finish out - // the node when it returns. - - yp_token_t lparen = parser->previous; - yp_node_t *first_child_target = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN); - yp_node_t *child_target = parse_targets(parser, first_child_target, YP_BINDING_POWER_STATEMENT); - - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_AFTER_MULTI); - yp_token_t rparen = parser->previous; - - if (YP_NODE_TYPE_P(child_target, YP_MULTI_TARGET_NODE) && first_target == NULL && result->targets.size == 0) { - yp_node_destroy(parser, (yp_node_t *) result); - result = (yp_multi_target_node_t *) child_target; - result->base.location.start = lparen.start; - result->base.location.end = rparen.end; - result->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); - result->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); - } else { - yp_multi_target_node_t *target; - - if (YP_NODE_TYPE_P(child_target, YP_MULTI_TARGET_NODE)) { - target = (yp_multi_target_node_t *) child_target; - } else { - target = yp_multi_target_node_create(parser); - yp_multi_target_node_targets_append(target, child_target); - } - - target->base.location.start = lparen.start; - target->base.location.end = rparen.end; - target->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); - target->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); - - yp_multi_target_node_targets_append(result, (yp_node_t *) target); - } - } else { - if (!token_begins_expression_p(parser->current.type) && !match_type_p(parser, YP_TOKEN_USTAR)) { - if (first_target == NULL && result->targets.size == 0) { - // If we get here, then we weren't able to parse anything at all, so - // we need to return a missing node. - yp_node_destroy(parser, (yp_node_t *) result); - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_FOR_INDEX); - return (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); - } - - // If we get here, then we have a trailing , in a multi write node. - // We need to indicate this somehow in the tree, so we'll add an - // anonymous splat. - yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &parser->previous, NULL); - yp_multi_target_node_targets_append(result, splat); - return (yp_node_t *) result; - } - - yp_node_t *target = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA); - target = parse_target(parser, target); - - yp_multi_target_node_targets_append(result, target); - } - } while (accept(parser, YP_TOKEN_COMMA)); - } - - return (yp_node_t *) result; -} - -// Parse a list of statements separated by newlines or semicolons. -static yp_statements_node_t * -parse_statements(yp_parser_t *parser, yp_context_t context) { - // First, skip past any optional terminators that might be at the beginning of - // the statements. - while (accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE)); - - // If we have a terminator, then we can just return NULL. - if (context_terminator(context, &parser->current)) return NULL; - - yp_statements_node_t *statements = yp_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) { - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); - yp_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 (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - // If we have a terminator, then we will continue parsing the statements - // list. - while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_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 (YP_NODE_TYPE_P(node, YP_MISSING_NODE)) { - parser_lex(parser); - - while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)); - if (context_terminator(context, &parser->current)) break; - } else { - expect(parser, YP_TOKEN_NEWLINE, YP_ERR_EXPECT_EOL_AFTER_STATEMENT); - } - } - - context_pop(parser); - return statements; -} - -// Parse all of the elements of a hash. -static void -parse_assocs(yp_parser_t *parser, yp_node_t *node) { - assert(YP_NODE_TYPE_P(node, YP_HASH_NODE) || YP_NODE_TYPE_P(node, YP_KEYWORD_HASH_NODE)); - - while (true) { - yp_node_t *element; - - switch (parser->current.type) { - case YP_TOKEN_USTAR_STAR: { - parser_lex(parser); - yp_token_t operator = parser->previous; - yp_node_t *value = NULL; - - if (token_begins_expression_p(parser->current.type)) { - value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); - } else if (yp_parser_local_depth(parser, &operator) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); - } - - element = (yp_node_t *) yp_assoc_splat_node_create(parser, value, &operator); - break; - } - case YP_TOKEN_LABEL: { - parser_lex(parser); - - yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous); - yp_token_t operator = not_provided(parser); - yp_node_t *value = NULL; - - if (token_begins_expression_p(parser->current.type)) { - value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_EXPRESSION_AFTER_LABEL); - } - - element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value); - break; - } - default: { - yp_node_t *key = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_KEY); - yp_token_t operator; - - if (yp_symbol_node_label_p(key)) { - operator = not_provided(parser); - } else { - expect(parser, YP_TOKEN_EQUAL_GREATER, YP_ERR_HASH_ROCKET); - operator = parser->previous; - } - - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); - element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value); - break; - } - } - - if (YP_NODE_TYPE_P(node, YP_HASH_NODE)) { - yp_hash_node_elements_append((yp_hash_node_t *) node, element); - } else { - yp_keyword_hash_node_elements_append((yp_keyword_hash_node_t *) node, element); - } - - // If there's no comma after the element, then we're done. - if (!accept(parser, YP_TOKEN_COMMA)) return; - - // 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 (match_any_type_p(parser, 2, YP_TOKEN_USTAR_STAR, YP_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. - return; - } -} - -// Parse a list of arguments. -static void -parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_forwarding, yp_token_type_t terminator) { - yp_binding_power_t binding_power = yp_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 ( - match_any_type_p(parser, 2, terminator, YP_TOKEN_EOF) || - (binding_power != YP_BINDING_POWER_UNSET && binding_power < YP_BINDING_POWER_RANGE) || - context_terminator(parser->current_context->context, &parser->current) - ) { - return; - } - - bool parsed_bare_hash = false; - bool parsed_block_argument = false; - - while (!match_type_p(parser, YP_TOKEN_EOF)) { - if (parsed_block_argument) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_AFTER_BLOCK); - } - - yp_node_t *argument = NULL; - - switch (parser->current.type) { - case YP_TOKEN_USTAR_STAR: - case YP_TOKEN_LABEL: { - if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_BARE_HASH); - } - - yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); - argument = (yp_node_t *)hash; - - if (!match_any_type_p(parser, 7, terminator, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON, YP_TOKEN_EOF, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_KEYWORD_DO, YP_TOKEN_PARENTHESIS_RIGHT)) { - parse_assocs(parser, (yp_node_t *) hash); - } - - parsed_bare_hash = true; - break; - } - case YP_TOKEN_UAMPERSAND: { - parser_lex(parser); - yp_token_t operator = parser->previous; - yp_node_t *expression = NULL; - - if (token_begins_expression_p(parser->current.type)) { - expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT); - } else if (yp_parser_local_depth(parser, &operator) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_AMP); - } - - argument = (yp_node_t *)yp_block_argument_node_create(parser, &operator, expression); - parsed_block_argument = true; - arguments->implicit_block = true; - break; - } - case YP_TOKEN_USTAR: { - parser_lex(parser); - yp_token_t operator = parser->previous; - - if (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_COMMA)) { - if (yp_parser_local_depth(parser, &parser->previous) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_STAR); - } - - argument = (yp_node_t *) yp_splat_node_create(parser, &operator, NULL); - } else { - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT); - - if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, operator.start, expression->location.end, YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT); - } - - argument = (yp_node_t *) yp_splat_node_create(parser, &operator, expression); - } - - break; - } - case YP_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. - yp_token_t operator = parser->previous; - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_RANGE, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - argument = (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); - } else { - if (yp_parser_local_depth(parser, &parser->previous) == -1) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); - } - - argument = (yp_node_t *)yp_forwarding_arguments_node_create(parser, &parser->previous); - break; - } - } - } - /* fallthrough */ - default: { - if (argument == NULL) { - argument = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT); - } - - if (yp_symbol_node_label_p(argument) || accept(parser, YP_TOKEN_EQUAL_GREATER)) { - if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_BARE_HASH); - } - - yp_token_t operator; - if (parser->previous.type == YP_TOKEN_EQUAL_GREATER) { - operator = parser->previous; - } else { - operator = not_provided(parser); - } - - yp_keyword_hash_node_t *bare_hash = yp_keyword_hash_node_create(parser); - - // Finish parsing the one we are part way through - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); - - argument = (yp_node_t *) yp_assoc_node_create(parser, argument, &operator, value); - yp_keyword_hash_node_elements_append(bare_hash, argument); - argument = (yp_node_t *) bare_hash; - - // Then parse more if we have a comma - if (accept(parser, YP_TOKEN_COMMA) && ( - token_begins_expression_p(parser->current.type) || - match_any_type_p(parser, 2, YP_TOKEN_USTAR_STAR, YP_TOKEN_LABEL) - )) { - parse_assocs(parser, (yp_node_t *) bare_hash); - } - - parsed_bare_hash = true; - } - - break; - } - } - - yp_arguments_node_arguments_append(arguments->arguments, argument); - - // If parsing the argument failed, we need to stop parsing arguments. - if (YP_NODE_TYPE_P(argument, YP_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 != YP_TOKEN_EOF) accept(parser, YP_TOKEN_NEWLINE); - - if (parser->previous.type == YP_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 (!accept(parser, YP_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 (match_type_p(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 yp_required_destructured_parameter_node_t * -parse_required_destructured_parameter(yp_parser_t *parser) { - expect(parser, YP_TOKEN_PARENTHESIS_LEFT, YP_ERR_EXPECT_LPAREN_REQ_PARAMETER); - - yp_token_t opening = parser->previous; - yp_required_destructured_parameter_node_t *node = yp_required_destructured_parameter_node_create(parser, &opening); - bool parsed_splat = false; - - do { - yp_node_t *param; - - if (node->parameters.size > 0 && match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - if (parsed_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); - } - - param = (yp_node_t *) yp_splat_node_create(parser, &parser->previous, NULL); - yp_required_destructured_parameter_node_append_parameter(node, param); - break; - } - - if (match_type_p(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - param = (yp_node_t *) parse_required_destructured_parameter(parser); - } else if (accept(parser, YP_TOKEN_USTAR)) { - if (parsed_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); - } - - yp_token_t star = parser->previous; - yp_node_t *value = NULL; - - if (accept(parser, YP_TOKEN_IDENTIFIER)) { - yp_token_t name = parser->previous; - value = (yp_node_t *) yp_required_parameter_node_create(parser, &name); - yp_parser_local_add_token(parser, &name); - } - - param = (yp_node_t *) yp_splat_node_create(parser, &star, value); - parsed_splat = true; - } else { - expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EXPECT_IDENT_REQ_PARAMETER); - yp_token_t name = parser->previous; - - param = (yp_node_t *) yp_required_parameter_node_create(parser, &name); - yp_parser_local_add_token(parser, &name); - } - - yp_required_destructured_parameter_node_append_parameter(node, param); - } while (accept(parser, YP_TOKEN_COMMA)); - - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_REQ_PARAMETER); - yp_required_destructured_parameter_node_closing_set(node, &parser->previous); - - return node; -} - -// This represents the different order states we can be in when parsing -// method parameters. -typedef enum { - YP_PARAMETERS_NO_CHANGE = 0, // Extra state for tokens that should not change the state - YP_PARAMETERS_ORDER_NOTHING_AFTER = 1, - YP_PARAMETERS_ORDER_KEYWORDS_REST, - YP_PARAMETERS_ORDER_KEYWORDS, - YP_PARAMETERS_ORDER_REST, - YP_PARAMETERS_ORDER_AFTER_OPTIONAL, - YP_PARAMETERS_ORDER_OPTIONAL, - YP_PARAMETERS_ORDER_NAMED, - YP_PARAMETERS_ORDER_NONE, - -} yp_parameters_order_t; - -// This matches parameters tokens with parameters state. -static yp_parameters_order_t parameters_ordering[YP_TOKEN_MAXIMUM] = { - [0] = YP_PARAMETERS_NO_CHANGE, - [YP_TOKEN_UAMPERSAND] = YP_PARAMETERS_ORDER_NOTHING_AFTER, - [YP_TOKEN_AMPERSAND] = YP_PARAMETERS_ORDER_NOTHING_AFTER, - [YP_TOKEN_UDOT_DOT_DOT] = YP_PARAMETERS_ORDER_NOTHING_AFTER, - [YP_TOKEN_IDENTIFIER] = YP_PARAMETERS_ORDER_NAMED, - [YP_TOKEN_PARENTHESIS_LEFT] = YP_PARAMETERS_ORDER_NAMED, - [YP_TOKEN_EQUAL] = YP_PARAMETERS_ORDER_OPTIONAL, - [YP_TOKEN_LABEL] = YP_PARAMETERS_ORDER_KEYWORDS, - [YP_TOKEN_USTAR] = YP_PARAMETERS_ORDER_AFTER_OPTIONAL, - [YP_TOKEN_STAR] = YP_PARAMETERS_ORDER_AFTER_OPTIONAL, - [YP_TOKEN_USTAR_STAR] = YP_PARAMETERS_ORDER_KEYWORDS_REST, - [YP_TOKEN_STAR_STAR] = YP_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(yp_parser_t *parser, yp_token_t *token, yp_parameters_order_t *current) { - yp_parameters_order_t state = parameters_ordering[token->type]; - if (state == YP_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 == YP_PARAMETERS_ORDER_OPTIONAL && state == YP_PARAMETERS_ORDER_NAMED) { - *current = YP_PARAMETERS_ORDER_AFTER_OPTIONAL; - return; - } else if (*current == YP_PARAMETERS_ORDER_AFTER_OPTIONAL && state == YP_PARAMETERS_ORDER_NAMED) { - return; - } - - if (token->type == YP_TOKEN_USTAR && *current == YP_PARAMETERS_ORDER_AFTER_OPTIONAL) { - yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_STAR); - } - - if (*current == YP_PARAMETERS_ORDER_NOTHING_AFTER || state > *current) { - // We know what transition we failed on, so we can provide a better error here. - yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_ORDER); - } else if (state < *current) { - *current = state; - } -} - -// Parse a list of parameters on a method definition. -static yp_parameters_node_t * -parse_parameters( - yp_parser_t *parser, - yp_binding_power_t binding_power, - bool uses_parentheses, - bool allows_trailing_comma, - bool allows_forwarding_parameter -) { - yp_parameters_node_t *params = yp_parameters_node_create(parser); - bool looping = true; - - yp_do_loop_stack_push(parser, false); - yp_parameters_order_t order = YP_PARAMETERS_ORDER_NONE; - - do { - switch (parser->current.type) { - case YP_TOKEN_PARENTHESIS_LEFT: { - update_parameter_state(parser, &parser->current, &order); - yp_node_t *param = (yp_node_t *) parse_required_destructured_parameter(parser); - - if (order > YP_PARAMETERS_ORDER_AFTER_OPTIONAL) { - yp_parameters_node_requireds_append(params, param); - } else { - yp_parameters_node_posts_append(params, param); - } - break; - } - case YP_TOKEN_UAMPERSAND: - case YP_TOKEN_AMPERSAND: { - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_token_t name; - - if (accept(parser, YP_TOKEN_IDENTIFIER)) { - name = parser->previous; - yp_parser_parameter_name_check(parser, &name); - yp_parser_local_add_token(parser, &name); - } else { - name = not_provided(parser); - yp_parser_local_add_token(parser, &operator); - } - - yp_block_parameter_node_t *param = yp_block_parameter_node_create(parser, &name, &operator); - if (params->block == NULL) { - yp_parameters_node_block_set(params, param); - } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_BLOCK_MULTI); - yp_parameters_node_posts_append(params, (yp_node_t *) param); - } - - break; - } - case YP_TOKEN_UDOT_DOT_DOT: { - if (!allows_forwarding_parameter) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); - } - if (order > YP_PARAMETERS_ORDER_NOTHING_AFTER) { - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - - yp_parser_local_add_token(parser, &parser->previous); - yp_forwarding_parameter_node_t *param = yp_forwarding_parameter_node_create(parser, &parser->previous); - yp_parameters_node_keyword_rest_set(params, (yp_node_t *)param); - } else { - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - } - break; - } - case YP_TOKEN_CLASS_VARIABLE: - case YP_TOKEN_IDENTIFIER: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_INSTANCE_VARIABLE: - case YP_TOKEN_GLOBAL_VARIABLE: { - parser_lex(parser); - switch (parser->previous.type) { - case YP_TOKEN_CONSTANT: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CONSTANT); - break; - case YP_TOKEN_INSTANCE_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_IVAR); - break; - case YP_TOKEN_GLOBAL_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_GLOBAL); - break; - case YP_TOKEN_CLASS_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CLASS); - break; - default: break; - } - - if (parser->current.type == YP_TOKEN_EQUAL) { - update_parameter_state(parser, &parser->current, &order); - } else { - update_parameter_state(parser, &parser->previous, &order); - } - - yp_token_t name = parser->previous; - yp_parser_parameter_name_check(parser, &name); - yp_parser_local_add_token(parser, &name); - - if (accept(parser, YP_TOKEN_EQUAL)) { - yp_token_t operator = parser->previous; - context_push(parser, YP_CONTEXT_DEFAULT_PARAMS); - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT); - - yp_optional_parameter_node_t *param = yp_optional_parameter_node_create(parser, &name, &operator, value); - yp_parameters_node_optionals_append(params, param); - 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 > YP_PARAMETERS_ORDER_AFTER_OPTIONAL) { - yp_required_parameter_node_t *param = yp_required_parameter_node_create(parser, &name); - yp_parameters_node_requireds_append(params, (yp_node_t *) param); - } else { - yp_required_parameter_node_t *param = yp_required_parameter_node_create(parser, &name); - yp_parameters_node_posts_append(params, (yp_node_t *) param); - } - - break; - } - case YP_TOKEN_LABEL: { - if (!uses_parentheses) parser->in_keyword_arg = true; - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - - yp_token_t name = parser->previous; - yp_token_t local = name; - local.end -= 1; - - yp_parser_parameter_name_check(parser, &local); - yp_parser_local_add_token(parser, &local); - - switch (parser->current.type) { - case YP_TOKEN_COMMA: - case YP_TOKEN_PARENTHESIS_RIGHT: - case YP_TOKEN_PIPE: { - yp_node_t *param = (yp_node_t *) yp_keyword_parameter_node_create(parser, &name, NULL); - yp_parameters_node_keywords_append(params, param); - break; - } - case YP_TOKEN_SEMICOLON: - case YP_TOKEN_NEWLINE: { - if (uses_parentheses) { - looping = false; - break; - } - - yp_node_t *param = (yp_node_t *) yp_keyword_parameter_node_create(parser, &name, NULL); - yp_parameters_node_keywords_append(params, param); - break; - } - default: { - yp_node_t *value = NULL; - if (token_begins_expression_p(parser->current.type)) { - context_push(parser, YP_CONTEXT_DEFAULT_PARAMS); - value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT_KW); - context_pop(parser); - } - - yp_node_t *param = (yp_node_t *) yp_keyword_parameter_node_create(parser, &name, value); - yp_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 YP_TOKEN_USTAR: - case YP_TOKEN_STAR: { - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_token_t name; - - if (accept(parser, YP_TOKEN_IDENTIFIER)) { - name = parser->previous; - yp_parser_parameter_name_check(parser, &name); - yp_parser_local_add_token(parser, &name); - } else { - name = not_provided(parser); - yp_parser_local_add_token(parser, &operator); - } - - yp_rest_parameter_node_t *param = yp_rest_parameter_node_create(parser, &operator, &name); - if (params->rest == NULL) { - yp_parameters_node_rest_set(params, param); - } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI); - yp_parameters_node_posts_append(params, (yp_node_t *) param); - } - - break; - } - case YP_TOKEN_STAR_STAR: - case YP_TOKEN_USTAR_STAR: { - update_parameter_state(parser, &parser->current, &order); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *param; - - if (accept(parser, YP_TOKEN_KEYWORD_NIL)) { - param = (yp_node_t *) yp_no_keywords_parameter_node_create(parser, &operator, &parser->previous); - } else { - yp_token_t name; - - if (accept(parser, YP_TOKEN_IDENTIFIER)) { - name = parser->previous; - yp_parser_parameter_name_check(parser, &name); - yp_parser_local_add_token(parser, &name); - } else { - name = not_provided(parser); - yp_parser_local_add_token(parser, &operator); - } - - param = (yp_node_t *) yp_keyword_rest_parameter_node_create(parser, &operator, &name); - } - - if (params->keyword_rest == NULL) { - yp_parameters_node_keyword_rest_set(params, param); - } else { - yp_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI); - yp_parameters_node_posts_append(params, param); - } - - break; - } - default: - if (parser->previous.type == YP_TOKEN_COMMA) { - if (allows_trailing_comma) { - // If we get here, then we have a trailing comma in a block - // parameter list. We need to create an anonymous rest parameter to - // represent it. - yp_token_t name = not_provided(parser); - yp_rest_parameter_node_t *param = yp_rest_parameter_node_create(parser, &parser->previous, &name); - - if (params->rest == NULL) { - yp_parameters_node_rest_set(params, param); - } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI); - yp_parameters_node_posts_append(params, (yp_node_t *) param); - } - } else { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PARAMETER_WILD_LOOSE_COMMA); - } - } - - looping = false; - break; - } - - if (looping && uses_parentheses) { - accept(parser, YP_TOKEN_NEWLINE); - } - } while (looping && accept(parser, YP_TOKEN_COMMA)); - - yp_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) { - yp_node_destroy(parser, (yp_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(yp_parser_t *parser, yp_begin_node_t *parent_node) { - yp_rescue_node_t *current = NULL; - - while (accept(parser, YP_TOKEN_KEYWORD_RESCUE)) { - yp_rescue_node_t *rescue = yp_rescue_node_create(parser, &parser->previous); - - switch (parser->current.type) { - case YP_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); - yp_rescue_node_operator_set(rescue, &parser->previous); - - yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE); - reference = parse_target(parser, reference); - - yp_rescue_node_reference_set(rescue, reference); - break; - } - case YP_TOKEN_NEWLINE: - case YP_TOKEN_SEMICOLON: - case YP_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) || match_type_p(parser, YP_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 { - yp_node_t *expression = parse_starred_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_RESCUE_EXPRESSION); - yp_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 (match_any_type_p(parser, 3, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON, YP_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 (accept(parser, YP_TOKEN_EQUAL_GREATER)) { - yp_rescue_node_operator_set(rescue, &parser->previous); - - yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE); - reference = parse_target(parser, reference); - - yp_rescue_node_reference_set(rescue, reference); - break; - } - } while (accept(parser, YP_TOKEN_COMMA)); - } - } - } - - if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - accept(parser, YP_TOKEN_KEYWORD_THEN); - } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_RESCUE_TERM); - } - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_RESCUE); - if (statements) { - yp_rescue_node_statements_set(rescue, statements); - } - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - if (current == NULL) { - yp_begin_node_rescue_clause_set(parent_node, rescue); - } else { - yp_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 (accept(parser, YP_TOKEN_KEYWORD_ELSE)) { - yp_token_t else_keyword = parser->previous; - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - - yp_statements_node_t *else_statements = NULL; - if (!match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_END, YP_TOKEN_KEYWORD_ENSURE)) { - yp_accepts_block_stack_push(parser, true); - else_statements = parse_statements(parser, YP_CONTEXT_RESCUE_ELSE); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - yp_else_node_t *else_clause = yp_else_node_create(parser, &else_keyword, else_statements, &parser->current); - yp_begin_node_else_clause_set(parent_node, else_clause); - } - - if (accept(parser, YP_TOKEN_KEYWORD_ENSURE)) { - yp_token_t ensure_keyword = parser->previous; - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - - yp_statements_node_t *ensure_statements = NULL; - if (!match_type_p(parser, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - ensure_statements = parse_statements(parser, YP_CONTEXT_ENSURE); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - yp_ensure_node_t *ensure_clause = yp_ensure_node_create(parser, &ensure_keyword, ensure_statements, &parser->current); - yp_begin_node_ensure_clause_set(parent_node, ensure_clause); - } - - if (parser->current.type == YP_TOKEN_KEYWORD_END) { - yp_begin_node_end_keyword_set(parent_node, &parser->current); - } else { - yp_token_t end_keyword = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; - yp_begin_node_end_keyword_set(parent_node, &end_keyword); - } -} - -static inline yp_begin_node_t * -parse_rescues_as_begin(yp_parser_t *parser, yp_statements_node_t *statements) { - yp_token_t no_begin_token = not_provided(parser); - yp_begin_node_t *begin_node = yp_begin_node_create(parser, &no_begin_token, statements); - parse_rescues(parser, begin_node); - - // 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 yp_block_parameters_node_t * -parse_block_parameters( - yp_parser_t *parser, - bool allows_trailing_comma, - const yp_token_t *opening, - bool is_lambda_literal -) { - yp_parameters_node_t *parameters = NULL; - if (!match_type_p(parser, YP_TOKEN_SEMICOLON)) { - parameters = parse_parameters( - parser, - is_lambda_literal ? YP_BINDING_POWER_DEFINED : YP_BINDING_POWER_INDEX, - false, - allows_trailing_comma, - false - ); - } - - yp_block_parameters_node_t *block_parameters = yp_block_parameters_node_create(parser, parameters, opening); - if (accept(parser, YP_TOKEN_SEMICOLON)) { - do { - expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE); - yp_parser_local_add_token(parser, &parser->previous); - - yp_block_local_variable_node_t *local = yp_block_local_variable_node_create(parser, &parser->previous); - yp_block_parameters_node_append_local(block_parameters, local); - } while (accept(parser, YP_TOKEN_COMMA)); - } - - return block_parameters; -} - -// Parse a block. -static yp_block_node_t * -parse_block(yp_parser_t *parser) { - yp_token_t opening = parser->previous; - accept(parser, YP_TOKEN_NEWLINE); - - yp_accepts_block_stack_push(parser, true); - yp_parser_scope_push(parser, false); - yp_block_parameters_node_t *parameters = NULL; - - if (accept(parser, YP_TOKEN_PIPE)) { - yp_token_t block_parameters_opening = parser->previous; - - if (match_type_p(parser, YP_TOKEN_PIPE)) { - parameters = yp_block_parameters_node_create(parser, NULL, &block_parameters_opening); - parser->command_start = true; - parser_lex(parser); - } else { - parameters = parse_block_parameters(parser, true, &block_parameters_opening, false); - accept(parser, YP_TOKEN_NEWLINE); - parser->command_start = true; - expect(parser, YP_TOKEN_PIPE, YP_ERR_BLOCK_PARAM_PIPE_TERM); - } - - yp_block_parameters_node_closing_set(parameters, &parser->previous); - } - - accept(parser, YP_TOKEN_NEWLINE); - yp_node_t *statements = NULL; - - if (opening.type == YP_TOKEN_BRACE_LEFT) { - if (!match_type_p(parser, YP_TOKEN_BRACE_RIGHT)) { - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_BLOCK_BRACES); - } - - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BLOCK_TERM_BRACE); - } else { - if (!match_type_p(parser, YP_TOKEN_KEYWORD_END)) { - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE)) { - yp_accepts_block_stack_push(parser, true); - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_BLOCK_KEYWORDS); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(statements == NULL || YP_NODE_TYPE_P(statements, YP_STATEMENTS_NODE)); - statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); - } - } - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BLOCK_TERM_END); - } - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - yp_accepts_block_stack_pop(parser); - return yp_block_node_create(parser, &locals, &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(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_block) { - bool found = false; - - if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - found |= true; - arguments->opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - - if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - } else { - arguments->arguments = yp_arguments_node_create(parser); - - yp_accepts_block_stack_push(parser, true); - parse_arguments(parser, arguments, true, YP_TOKEN_PARENTHESIS_RIGHT); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_ARGUMENT_TERM_PAREN); - yp_accepts_block_stack_pop(parser); - - arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - } - } else if ((token_begins_expression_p(parser->current.type) || match_any_type_p(parser, 3, YP_TOKEN_USTAR, YP_TOKEN_USTAR_STAR, YP_TOKEN_UAMPERSAND)) && !match_type_p(parser, YP_TOKEN_BRACE_LEFT)) { - found |= true; - yp_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. - arguments->arguments = yp_arguments_node_create(parser); - parse_arguments(parser, arguments, true, YP_TOKEN_EOF); - - yp_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) { - if (accept(parser, YP_TOKEN_BRACE_LEFT)) { - found |= true; - arguments->block = parse_block(parser); - } else if (yp_accepts_block_stack_p(parser) && accept(parser, YP_TOKEN_KEYWORD_DO)) { - found |= true; - arguments->block = parse_block(parser); - } - } - - yp_arguments_validate(parser, arguments); - return found; -} - -static inline yp_node_t * -parse_conditional(yp_parser_t *parser, yp_context_t context) { - yp_token_t keyword = parser->previous; - - context_push(parser, YP_CONTEXT_PREDICATE); - yp_diagnostic_id_t error_id = context == YP_CONTEXT_IF ? YP_ERR_CONDITIONAL_IF_PREDICATE : YP_ERR_CONDITIONAL_UNLESS_PREDICATE; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, error_id); - - // Predicates are closed by a term, a "then", or a term and then a "then". - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - accept(parser, YP_TOKEN_KEYWORD_THEN); - - context_pop(parser); - yp_statements_node_t *statements = NULL; - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_ELSIF, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = parse_statements(parser, context); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - yp_token_t end_keyword = not_provided(parser); - yp_node_t *parent = NULL; - - switch (context) { - case YP_CONTEXT_IF: - parent = (yp_node_t *) yp_if_node_create(parser, &keyword, predicate, statements, NULL, &end_keyword); - break; - case YP_CONTEXT_UNLESS: - parent = (yp_node_t *) yp_unless_node_create(parser, &keyword, predicate, statements); - break; - default: - assert(false && "unreachable"); - break; - } - - yp_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 == YP_CONTEXT_IF) { - while (accept(parser, YP_TOKEN_KEYWORD_ELSIF)) { - yp_token_t elsif_keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, YP_ERR_CONDITIONAL_ELSIF_PREDICATE); - - // Predicates are closed by a term, a "then", or a term and then a "then". - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - accept(parser, YP_TOKEN_KEYWORD_THEN); - - yp_accepts_block_stack_push(parser, true); - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_ELSIF); - yp_accepts_block_stack_pop(parser); - - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - - yp_node_t *elsif = (yp_node_t *) yp_if_node_create(parser, &elsif_keyword, predicate, statements, NULL, &end_keyword); - ((yp_if_node_t *) current)->consequent = elsif; - current = elsif; - } - } - - if (match_type_p(parser, YP_TOKEN_KEYWORD_ELSE)) { - parser_lex(parser); - yp_token_t else_keyword = parser->previous; - - yp_accepts_block_stack_push(parser, true); - yp_statements_node_t *else_statements = parse_statements(parser, YP_CONTEXT_ELSE); - yp_accepts_block_stack_pop(parser); - - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM_ELSE); - - yp_else_node_t *else_node = yp_else_node_create(parser, &else_keyword, else_statements, &parser->previous); - - switch (context) { - case YP_CONTEXT_IF: - ((yp_if_node_t *) current)->consequent = (yp_node_t *) else_node; - break; - case YP_CONTEXT_UNLESS: - ((yp_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. - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM); - } - - // Set the appropriate end location for all of the nodes in the subtree. - switch (context) { - case YP_CONTEXT_IF: { - yp_node_t *current = parent; - bool recursing = true; - - while (recursing) { - switch (YP_NODE_TYPE(current)) { - case YP_IF_NODE: - yp_if_node_end_keyword_loc_set((yp_if_node_t *) current, &parser->previous); - current = ((yp_if_node_t *) current)->consequent; - recursing = current != NULL; - break; - case YP_ELSE_NODE: - yp_else_node_end_keyword_loc_set((yp_else_node_t *) current, &parser->previous); - recursing = false; - break; - default: { - recursing = false; - break; - } - } - } - break; - } - case YP_CONTEXT_UNLESS: - yp_unless_node_end_keyword_loc_set((yp_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 YP_CASE_KEYWORD YP_TOKEN_KEYWORD___ENCODING__: case YP_TOKEN_KEYWORD___FILE__: case YP_TOKEN_KEYWORD___LINE__: \ - case YP_TOKEN_KEYWORD_ALIAS: case YP_TOKEN_KEYWORD_AND: case YP_TOKEN_KEYWORD_BEGIN: case YP_TOKEN_KEYWORD_BEGIN_UPCASE: \ - case YP_TOKEN_KEYWORD_BREAK: case YP_TOKEN_KEYWORD_CASE: case YP_TOKEN_KEYWORD_CLASS: case YP_TOKEN_KEYWORD_DEF: \ - case YP_TOKEN_KEYWORD_DEFINED: case YP_TOKEN_KEYWORD_DO: case YP_TOKEN_KEYWORD_DO_LOOP: case YP_TOKEN_KEYWORD_ELSE: \ - case YP_TOKEN_KEYWORD_ELSIF: case YP_TOKEN_KEYWORD_END: case YP_TOKEN_KEYWORD_END_UPCASE: case YP_TOKEN_KEYWORD_ENSURE: \ - case YP_TOKEN_KEYWORD_FALSE: case YP_TOKEN_KEYWORD_FOR: case YP_TOKEN_KEYWORD_IF: case YP_TOKEN_KEYWORD_IN: \ - case YP_TOKEN_KEYWORD_MODULE: case YP_TOKEN_KEYWORD_NEXT: case YP_TOKEN_KEYWORD_NIL: case YP_TOKEN_KEYWORD_NOT: \ - case YP_TOKEN_KEYWORD_OR: case YP_TOKEN_KEYWORD_REDO: case YP_TOKEN_KEYWORD_RESCUE: case YP_TOKEN_KEYWORD_RETRY: \ - case YP_TOKEN_KEYWORD_RETURN: case YP_TOKEN_KEYWORD_SELF: case YP_TOKEN_KEYWORD_SUPER: case YP_TOKEN_KEYWORD_THEN: \ - case YP_TOKEN_KEYWORD_TRUE: case YP_TOKEN_KEYWORD_UNDEF: case YP_TOKEN_KEYWORD_UNLESS: case YP_TOKEN_KEYWORD_UNTIL: \ - case YP_TOKEN_KEYWORD_WHEN: case YP_TOKEN_KEYWORD_WHILE: case YP_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 YP_CASE_OPERATOR YP_TOKEN_AMPERSAND: case YP_TOKEN_BACKTICK: case YP_TOKEN_BANG_EQUAL: \ - case YP_TOKEN_BANG_TILDE: case YP_TOKEN_BANG: case YP_TOKEN_BRACKET_LEFT_RIGHT_EQUAL: \ - case YP_TOKEN_BRACKET_LEFT_RIGHT: case YP_TOKEN_CARET: case YP_TOKEN_EQUAL_EQUAL_EQUAL: case YP_TOKEN_EQUAL_EQUAL: \ - case YP_TOKEN_EQUAL_TILDE: case YP_TOKEN_GREATER_EQUAL: case YP_TOKEN_GREATER_GREATER: case YP_TOKEN_GREATER: \ - case YP_TOKEN_LESS_EQUAL_GREATER: case YP_TOKEN_LESS_EQUAL: case YP_TOKEN_LESS_LESS: case YP_TOKEN_LESS: \ - case YP_TOKEN_MINUS: case YP_TOKEN_PERCENT: case YP_TOKEN_PIPE: case YP_TOKEN_PLUS: case YP_TOKEN_SLASH: \ - case YP_TOKEN_STAR_STAR: case YP_TOKEN_STAR: case YP_TOKEN_TILDE: case YP_TOKEN_UAMPERSAND: case YP_TOKEN_UMINUS: \ - case YP_TOKEN_UMINUS_NUM: case YP_TOKEN_UPLUS: case YP_TOKEN_USTAR: case YP_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 YP_CASE_PRIMITIVE YP_TOKEN_INTEGER: case YP_TOKEN_INTEGER_IMAGINARY: case YP_TOKEN_INTEGER_RATIONAL: \ - case YP_TOKEN_INTEGER_RATIONAL_IMAGINARY: case YP_TOKEN_FLOAT: case YP_TOKEN_FLOAT_IMAGINARY: \ - case YP_TOKEN_FLOAT_RATIONAL: case YP_TOKEN_FLOAT_RATIONAL_IMAGINARY: case YP_TOKEN_SYMBOL_BEGIN: \ - case YP_TOKEN_REGEXP_BEGIN: case YP_TOKEN_BACKTICK: case YP_TOKEN_PERCENT_LOWER_X: case YP_TOKEN_PERCENT_LOWER_I: \ - case YP_TOKEN_PERCENT_LOWER_W: case YP_TOKEN_PERCENT_UPPER_I: case YP_TOKEN_PERCENT_UPPER_W: \ - case YP_TOKEN_STRING_BEGIN: case YP_TOKEN_KEYWORD_NIL: case YP_TOKEN_KEYWORD_SELF: case YP_TOKEN_KEYWORD_TRUE: \ - case YP_TOKEN_KEYWORD_FALSE: case YP_TOKEN_KEYWORD___FILE__: case YP_TOKEN_KEYWORD___LINE__: \ - case YP_TOKEN_KEYWORD___ENCODING__: case YP_TOKEN_MINUS_GREATER: case YP_TOKEN_HEREDOC_START: \ - case YP_TOKEN_UMINUS_NUM: case YP_TOKEN_CHARACTER_LITERAL - -// This macro allows you to define a case statement for all of the token types -// that could begin a parameter. -#define YP_CASE_PARAMETER YP_TOKEN_UAMPERSAND: case YP_TOKEN_AMPERSAND: case YP_TOKEN_UDOT_DOT_DOT: \ - case YP_TOKEN_IDENTIFIER: case YP_TOKEN_LABEL: case YP_TOKEN_USTAR: case YP_TOKEN_STAR: case YP_TOKEN_STAR_STAR: \ - case YP_TOKEN_USTAR_STAR: case YP_TOKEN_CONSTANT: case YP_TOKEN_INSTANCE_VARIABLE: case YP_TOKEN_GLOBAL_VARIABLE: \ - case YP_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 YP_CASE_WRITABLE YP_CLASS_VARIABLE_READ_NODE: case YP_CONSTANT_PATH_NODE: \ - case YP_CONSTANT_READ_NODE: case YP_GLOBAL_VARIABLE_READ_NODE: case YP_LOCAL_VARIABLE_READ_NODE: \ - case YP_INSTANCE_VARIABLE_READ_NODE: case YP_MULTI_TARGET_NODE: case YP_BACK_REFERENCE_READ_NODE: \ - case YP_NUMBERED_REFERENCE_READ_NODE - -// 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 yp_node_t * -parse_string_part(yp_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 YP_TOKEN_STRING_CONTENT: { - yp_unescape_type_t unescape_type = YP_UNESCAPE_ALL; - - if (parser->lex_modes.current->mode == YP_LEX_HEREDOC) { - if (parser->lex_modes.current->as.heredoc.indent == YP_HEREDOC_INDENT_TILDE) { - // If we're in a tilde heredoc, we want to unescape it later - // because we don't want unescaped newlines to disappear - // before we handle them in the dedent. - unescape_type = YP_UNESCAPE_NONE; - } else if (parser->lex_modes.current->as.heredoc.quote == YP_HEREDOC_QUOTE_SINGLE) { - unescape_type = YP_UNESCAPE_MINIMAL; - } - } - - parser_lex(parser); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - - return (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, unescape_type); - } - // 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 YP_TOKEN_EMBEXPR_BEGIN: { - yp_lex_state_t state = parser->lex_state; - int brace_nesting = parser->brace_nesting; - - parser->brace_nesting = 0; - lex_state_set(parser, YP_LEX_STATE_BEG); - parser_lex(parser); - - yp_token_t opening = parser->previous; - yp_statements_node_t *statements = NULL; - - if (!match_type_p(parser, YP_TOKEN_EMBEXPR_END)) { - yp_accepts_block_stack_push(parser, true); - statements = parse_statements(parser, YP_CONTEXT_EMBEXPR); - yp_accepts_block_stack_pop(parser); - } - - parser->brace_nesting = brace_nesting; - lex_state_set(parser, state); - - expect(parser, YP_TOKEN_EMBEXPR_END, YP_ERR_EMBEXPR_END); - yp_token_t closing = parser->previous; - - return (yp_node_t *) yp_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 YP_TOKEN_EMBVAR: { - lex_state_set(parser, YP_LEX_STATE_BEG); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_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 YP_TOKEN_BACK_REFERENCE: - parser_lex(parser); - variable = (yp_node_t *) yp_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 YP_TOKEN_NUMBERED_REFERENCE: - parser_lex(parser); - variable = (yp_node_t *) yp_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 YP_TOKEN_GLOBAL_VARIABLE: - parser_lex(parser); - variable = (yp_node_t *) yp_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 YP_TOKEN_INSTANCE_VARIABLE: - parser_lex(parser); - variable = (yp_node_t *) yp_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 YP_TOKEN_CLASS_VARIABLE: - parser_lex(parser); - variable = (yp_node_t *) yp_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: - expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EMBVAR_INVALID); - variable = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); - break; - } - - return (yp_node_t *) yp_embedded_variable_node_create(parser, &operator, variable); - } - default: - parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CANNOT_PARSE_STRING_PART); - return NULL; - } -} - -static yp_node_t * -parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_state) { - yp_token_t opening = parser->previous; - - if (lex_mode->mode != YP_LEX_STRING) { - if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state); - yp_token_t symbol; - - switch (parser->current.type) { - case YP_TOKEN_IDENTIFIER: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_INSTANCE_VARIABLE: - case YP_TOKEN_CLASS_VARIABLE: - case YP_TOKEN_GLOBAL_VARIABLE: - case YP_TOKEN_NUMBERED_REFERENCE: - case YP_TOKEN_BACK_REFERENCE: - case YP_CASE_KEYWORD: - parser_lex(parser); - symbol = parser->previous; - break; - case YP_CASE_OPERATOR: - lex_state_set(parser, next_state == YP_LEX_STATE_NONE ? YP_LEX_STATE_ENDFN : next_state); - parser_lex(parser); - symbol = parser->previous; - break; - default: - expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_SYMBOL_INVALID); - symbol = parser->previous; - break; - } - - yp_token_t closing = not_provided(parser); - return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &symbol, &closing, YP_UNESCAPE_ALL); - } - - if (lex_mode->as.string.interpolation) { - // If we have the end of the symbol, then we can return an empty symbol. - if (match_type_p(parser, YP_TOKEN_STRING_END)) { - if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state); - parser_lex(parser); - - yp_token_t content = not_provided(parser); - yp_token_t closing = parser->previous; - return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &closing, YP_UNESCAPE_NONE); - } - - // Now we can parse the first part of the symbol. - yp_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 && YP_NODE_TYPE_P(part, YP_STRING_NODE) && match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state); - parser_lex(parser); - - return (yp_node_t *) yp_string_node_to_symbol_node(parser, (yp_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. - yp_node_list_t node_list = YP_EMPTY_NODE_LIST; - if (part) yp_node_list_append(&node_list, part); - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - if ((part = parse_string_part(parser)) != NULL) { - yp_node_list_append(&node_list, part); - } - } - - if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state); - expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_INTERPOLATED); - - return (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous); - } - - yp_token_t content; - if (accept(parser, YP_TOKEN_STRING_CONTENT)) { - content = parser->previous; - } else { - content = (yp_token_t) { .type = YP_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end }; - } - - if (next_state != YP_LEX_STATE_NONE) { - lex_state_set(parser, next_state); - } - expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_DYNAMIC); - - return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); -} - -// Parse an argument to undef which can either be a bare word, a -// symbol, a constant, or an interpolated symbol. -static inline yp_node_t * -parse_undef_argument(yp_parser_t *parser) { - switch (parser->current.type) { - case YP_CASE_KEYWORD: - case YP_CASE_OPERATOR: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - - return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); - } - case YP_TOKEN_SYMBOL_BEGIN: { - yp_lex_mode_t lex_mode = *parser->lex_modes.current; - parser_lex(parser); - - return parse_symbol(parser, &lex_mode, YP_LEX_STATE_NONE); - } - default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_UNDEF_ARGUMENT); - return (yp_node_t *) yp_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 YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM -// between the first and second arguments. -static inline yp_node_t * -parse_alias_argument(yp_parser_t *parser, bool first) { - switch (parser->current.type) { - case YP_CASE_OPERATOR: - case YP_CASE_KEYWORD: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_IDENTIFIER: { - if (first) { - lex_state_set(parser, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM); - } - - parser_lex(parser); - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - - return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); - } - case YP_TOKEN_SYMBOL_BEGIN: { - yp_lex_mode_t lex_mode = *parser->lex_modes.current; - parser_lex(parser); - - return parse_symbol(parser, &lex_mode, first ? YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM : YP_LEX_STATE_NONE); - } - case YP_TOKEN_BACK_REFERENCE: - parser_lex(parser); - return (yp_node_t *) yp_back_reference_read_node_create(parser, &parser->previous); - case YP_TOKEN_NUMBERED_REFERENCE: - parser_lex(parser); - return (yp_node_t *) yp_numbered_reference_read_node_create(parser, &parser->previous); - case YP_TOKEN_GLOBAL_VARIABLE: - parser_lex(parser); - return (yp_node_t *) yp_global_variable_read_node_create(parser, &parser->previous); - default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ALIAS_ARGUMENT); - return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); - } -} - -// Parse an identifier into either a local variable read or a call. -static yp_node_t * -parse_variable_call(yp_parser_t *parser) { - yp_node_flags_t flags = 0; - - if (!match_type_p(parser, YP_TOKEN_PARENTHESIS_LEFT) && (parser->previous.end[-1] != '!') && (parser->previous.end[-1] != '?')) { - int depth; - if ((depth = yp_parser_local_depth(parser, &parser->previous)) != -1) { - return (yp_node_t *) yp_local_variable_read_node_create(parser, &parser->previous, (uint32_t) depth); - } - - flags |= YP_CALL_NODE_FLAGS_VARIABLE_CALL; - } - - yp_call_node_t *node = yp_call_node_variable_call_create(parser, &parser->previous); - node->base.flags |= flags; - - return (yp_node_t *) node; -} - -static inline yp_token_t -parse_method_definition_name(yp_parser_t *parser) { - switch (parser->current.type) { - case YP_CASE_KEYWORD: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_IDENTIFIER: - parser_lex(parser); - return parser->previous; - case YP_CASE_OPERATOR: - lex_state_set(parser, YP_LEX_STATE_ENDFN); - parser_lex(parser); - return parser->previous; - default: - return not_provided(parser); - } -} - -// Calculate the common leading whitespace for each line in a heredoc. -static int -parse_heredoc_common_whitespace(yp_parser_t *parser, yp_node_list_t *nodes) { - int common_whitespace = -1; - - for (size_t index = 0; index < nodes->size; index++) { - yp_node_t *node = nodes->nodes[index]; - - if (!YP_NODE_TYPE_P(node, YP_STRING_NODE)) continue; - const yp_location_t *content_loc = &((yp_string_node_t *) node)->content_loc; - - // If the previous node wasn't a string node, we don't want to trim - // whitespace. This could happen after an interpolated expression or - // variable. - if (index == 0 || YP_NODE_TYPE_P(nodes->nodes[index - 1], YP_STRING_NODE)) { - int cur_whitespace; - const uint8_t *cur_char = content_loc->start; - - while (cur_char && cur_char < content_loc->end) { - // Any empty newlines aren't included in the minimum whitespace - // calculation. - size_t eol_length; - while ((eol_length = match_eol_at(parser, cur_char))) { - cur_char += eol_length; - } - - if (cur_char == content_loc->end) break; - - cur_whitespace = 0; - - while (yp_char_is_inline_whitespace(*cur_char) && cur_char < content_loc->end) { - if (cur_char[0] == '\t') { - cur_whitespace = (cur_whitespace / YP_TAB_WHITESPACE_SIZE + 1) * YP_TAB_WHITESPACE_SIZE; - } else { - cur_whitespace++; - } - cur_char++; - } - - // If we hit a newline, then we have encountered a line that - // contains only whitespace, and it shouldn't be considered in - // the calculation of common leading whitespace. - eol_length = match_eol_at(parser, cur_char); - if (eol_length) { - cur_char += eol_length; - continue; - } - - if (cur_whitespace < common_whitespace || common_whitespace == -1) { - common_whitespace = cur_whitespace; - } - - cur_char = next_newline(cur_char + 1, parser->end - (cur_char + 1)); - if (cur_char) cur_char++; - } - } - } - - return common_whitespace; -} - -// Take a heredoc node that is indented by a ~ and trim the leading whitespace. -static void -parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t quote) { - yp_node_list_t *nodes; - - if (quote == YP_HEREDOC_QUOTE_BACKTICK) { - nodes = &((yp_interpolated_x_string_node_t *) node)->parts; - } else { - nodes = &((yp_interpolated_string_node_t *) node)->parts; - } - - // First, calculate how much common whitespace we need to trim. If there is - // none or it's 0, then we can return early. - int common_whitespace; - if ((common_whitespace = parse_heredoc_common_whitespace(parser, nodes)) <= 0) return; - - // 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++) { - yp_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 (!YP_NODE_TYPE_P(node, YP_STRING_NODE)) { - nodes->nodes[write_index++] = node; - dedent_next = false; - continue; - } - - // Get a reference to the string struct that is being held by the string - // node. This is the value we're going to actual manipulate. - yp_string_t *string = &(((yp_string_node_t *) node)->unescaped); - yp_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 = yp_string_length(string); - uint8_t *source_start = (uint8_t *) string->source; - - const uint8_t *source_cursor = source_start; - 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. - uint8_t *dest_cursor = source_start; - - while (source_cursor < source_end) { - // If we need to dedent the next element within the heredoc or the next - // line within the string node, then we'll do it here. - if (dedent_next) { - int 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) && yp_char_is_inline_whitespace(*source_cursor) && trimmed_whitespace < common_whitespace) { - if (*source_cursor == '\t') { - trimmed_whitespace = (trimmed_whitespace / YP_TAB_WHITESPACE_SIZE + 1) * YP_TAB_WHITESPACE_SIZE; - if (trimmed_whitespace > common_whitespace) break; - } else { - trimmed_whitespace++; - } - - source_cursor++; - dest_length--; - } - } - - // At this point we have dedented all that we need to, so we need to find - // the next newline. - const uint8_t *breakpoint = next_newline(source_cursor, source_end - source_cursor); - - if (breakpoint == NULL) { - // If there isn't another newline, then we can just move the rest of the - // string and break from the loop. - memmove(dest_cursor, source_cursor, (size_t) (source_end - source_cursor)); - break; - } - - // Otherwise, we need to move everything including the newline, and - // then set the dedent_next flag to true. - if (breakpoint < source_end) breakpoint++; - memmove(dest_cursor, source_cursor, (size_t) (breakpoint - source_cursor)); - dest_cursor += (breakpoint - source_cursor); - source_cursor = breakpoint; - dedent_next = true; - } - - // We only want to write this node into the list if it has any content. - if (dest_length == 0) { - yp_node_destroy(parser, node); - } else { - string->length = dest_length; - yp_unescape_manipulate_string(parser, string, (quote == YP_HEREDOC_QUOTE_SINGLE) ? YP_UNESCAPE_MINIMAL : YP_UNESCAPE_ALL); - 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 yp_node_t * -parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id); - -// Accept any number of constants joined by :: delimiters. -static yp_node_t * -parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { - // Now, if there are any :: operators that follow, parse them as constant - // path nodes. - while (accept(parser, YP_TOKEN_COLON_COLON)) { - yp_token_t delimiter = parser->previous; - expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); - - yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - node = (yp_node_t *)yp_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 (!match_any_type_p(parser, 2, YP_TOKEN_BRACKET_LEFT, YP_TOKEN_PARENTHESIS_LEFT)) { - return node; - } - - yp_token_t opening; - yp_token_t closing; - yp_node_t *inner = NULL; - - if (accept(parser, YP_TOKEN_BRACKET_LEFT)) { - opening = parser->previous; - accept(parser, YP_TOKEN_NEWLINE); - - if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { - inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET); - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET); - } - - closing = parser->previous; - } else { - parser_lex(parser); - opening = parser->previous; - - if (!accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_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 (yp_node_t *) yp_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 (YP_NODE_TYPE(inner)) { - case YP_ARRAY_PATTERN_NODE: { - yp_array_pattern_node_t *pattern_node = (yp_array_pattern_node_t *) inner; - - if (pattern_node->constant == NULL) { - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; - - pattern_node->constant = node; - pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); - pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - - return (yp_node_t *) pattern_node; - } - - break; - } - case YP_FIND_PATTERN_NODE: { - yp_find_pattern_node_t *pattern_node = (yp_find_pattern_node_t *) inner; - - if (pattern_node->constant == NULL) { - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; - - pattern_node->constant = node; - pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); - pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - - return (yp_node_t *) pattern_node; - } - - break; - } - case YP_HASH_PATTERN_NODE: { - yp_hash_pattern_node_t *pattern_node = (yp_hash_pattern_node_t *) inner; - - if (pattern_node->constant == NULL) { - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; - - pattern_node->constant = node; - pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); - pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - - return (yp_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. - yp_array_pattern_node_t *pattern_node = yp_array_pattern_node_constant_create(parser, node, &opening, &closing); - yp_array_pattern_node_requireds_append(pattern_node, inner); - return (yp_node_t *) pattern_node; -} - -// Parse a rest pattern. -static yp_splat_node_t * -parse_pattern_rest(yp_parser_t *parser) { - assert(parser->previous.type == YP_TOKEN_USTAR); - yp_token_t operator = parser->previous; - yp_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 (accept(parser, YP_TOKEN_IDENTIFIER)) { - yp_token_t identifier = parser->previous; - yp_parser_local_add_token(parser, &identifier); - name = (yp_node_t *) yp_local_variable_target_node_create(parser, &identifier); - } - - // Finally we can return the created node. - return yp_splat_node_create(parser, &operator, name); -} - -// Parse a keyword rest node. -static yp_node_t * -parse_pattern_keyword_rest(yp_parser_t *parser) { - assert(parser->current.type == YP_TOKEN_USTAR_STAR); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *value = NULL; - - if (accept(parser, YP_TOKEN_KEYWORD_NIL)) { - return (yp_node_t *) yp_no_keywords_parameter_node_create(parser, &operator, &parser->previous); - } - - if (accept(parser, YP_TOKEN_IDENTIFIER)) { - yp_parser_local_add_token(parser, &parser->previous); - value = (yp_node_t *) yp_local_variable_target_node_create(parser, &parser->previous); - } - - return (yp_node_t *) yp_assoc_splat_node_create(parser, value, &operator); -} - -// Parse a hash pattern. -static yp_hash_pattern_node_t * -parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) { - if (YP_NODE_TYPE_P(first_assoc, YP_ASSOC_NODE)) { - if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_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. - yp_node_t *value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY); - - yp_assoc_node_t *assoc = (yp_assoc_node_t *) first_assoc; - assoc->base.location.end = value->location.end; - assoc->value = value; - } else { - yp_node_t *key = ((yp_assoc_node_t *) first_assoc)->key; - - if (YP_NODE_TYPE_P(key, YP_SYMBOL_NODE)) { - const yp_location_t *value_loc = &((yp_symbol_node_t *) key)->value_loc; - yp_parser_local_add_location(parser, value_loc->start, value_loc->end); - } - } - } - - yp_node_list_t assocs = YP_EMPTY_NODE_LIST; - yp_node_list_append(&assocs, first_assoc); - - // If there are any other assocs, then we'll parse them now. - while (accept(parser, YP_TOKEN_COMMA)) { - // Here we need to break to support trailing commas. - if (match_any_type_p(parser, 6, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - break; - } - - yp_node_t *assoc; - - if (match_type_p(parser, YP_TOKEN_USTAR_STAR)) { - assoc = parse_pattern_keyword_rest(parser); - } else { - expect(parser, YP_TOKEN_LABEL, YP_ERR_PATTERN_LABEL_AFTER_COMMA); - yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous); - yp_node_t *value = NULL; - - if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY); - } else { - const yp_location_t *value_loc = &((yp_symbol_node_t *) key)->value_loc; - yp_parser_local_add_location(parser, value_loc->start, value_loc->end); - } - - yp_token_t operator = not_provided(parser); - assoc = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value); - } - - yp_node_list_append(&assocs, assoc); - } - - yp_hash_pattern_node_t *node = yp_hash_pattern_node_node_list_create(parser, &assocs); - free(assocs.nodes); - - return node; -} - -// Parse a pattern expression primitive. -static yp_node_t * -parse_pattern_primitive(yp_parser_t *parser, yp_diagnostic_id_t diag_id) { - switch (parser->current.type) { - case YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - yp_parser_local_add_token(parser, &parser->previous); - return (yp_node_t *) yp_local_variable_target_node_create(parser, &parser->previous); - } - case YP_TOKEN_BRACKET_LEFT_ARRAY: { - yp_token_t opening = parser->current; - parser_lex(parser); - - if (accept(parser, YP_TOKEN_BRACKET_RIGHT)) { - // If we have an empty array pattern, then we'll just return a new - // array pattern node. - return (yp_node_t *)yp_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. - yp_node_t *inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET); - - accept(parser, YP_TOKEN_NEWLINE); - - expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET); - yp_token_t closing = parser->previous; - - switch (YP_NODE_TYPE(inner)) { - case YP_ARRAY_PATTERN_NODE: { - yp_array_pattern_node_t *pattern_node = (yp_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 = YP_LOCATION_TOKEN_VALUE(&opening); - pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - - return (yp_node_t *) pattern_node; - } - - break; - } - case YP_FIND_PATTERN_NODE: { - yp_find_pattern_node_t *pattern_node = (yp_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 = YP_LOCATION_TOKEN_VALUE(&opening); - pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - - return (yp_node_t *) pattern_node; - } - - break; - } - default: - break; - } - - yp_array_pattern_node_t *node = yp_array_pattern_node_empty_create(parser, &opening, &closing); - yp_array_pattern_node_requireds_append(node, inner); - return (yp_node_t *) node; - } - case YP_TOKEN_BRACE_LEFT: { - bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; - parser->pattern_matching_newlines = false; - - yp_hash_pattern_node_t *node; - yp_token_t opening = parser->current; - parser_lex(parser); - - if (accept(parser, YP_TOKEN_BRACE_RIGHT)) { - // If we have an empty hash pattern, then we'll just return a new hash - // pattern node. - node = yp_hash_pattern_node_empty_create(parser, &opening, &parser->previous); - } else { - yp_node_t *key; - - switch (parser->current.type) { - case YP_TOKEN_LABEL: - parser_lex(parser); - key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous); - break; - case YP_TOKEN_USTAR_STAR: - key = parse_pattern_keyword_rest(parser); - break; - case YP_TOKEN_STRING_BEGIN: - key = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_HASH_KEY); - if (!yp_symbol_node_label_p(key)) { - yp_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, YP_ERR_PATTERN_HASH_KEY_LABEL); - } - - break; - default: - parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_HASH_KEY); - key = (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end); - break; - } - - yp_token_t operator = not_provided(parser); - node = parse_pattern_hash(parser, (yp_node_t *) yp_assoc_node_create(parser, key, &operator, NULL)); - - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_PATTERN_TERM_BRACE); - yp_token_t closing = parser->previous; - - node->base.location.start = opening.start; - node->base.location.end = closing.end; - - node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); - node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); - } - - parser->pattern_matching_newlines = previous_pattern_matching_newlines; - return (yp_node_t *) node; - } - case YP_TOKEN_UDOT_DOT: - case YP_TOKEN_UDOT_DOT_DOT: { - yp_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 YP_CASE_PRIMITIVE: { - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); - return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); - } - default: { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); - yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); - return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); - } - } - } - case YP_CASE_PRIMITIVE: { - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_MAX, diag_id); - - // Now that we have a primitive, we need to check if it's part of a range. - if (accept_any(parser, 2, YP_TOKEN_DOT_DOT, YP_TOKEN_DOT_DOT_DOT)) { - yp_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 YP_CASE_PRIMITIVE: { - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); - return (yp_node_t *) yp_range_node_create(parser, node, &operator, right); - } - default: - return (yp_node_t *) yp_range_node_create(parser, node, &operator, NULL); - } - } - - return node; - } - case YP_TOKEN_CARET: { - parser_lex(parser); - yp_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 YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_local_variable_read_node_create(parser, &parser->previous, 0); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_INSTANCE_VARIABLE: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_instance_variable_read_node_create(parser, &parser->previous); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_CLASS_VARIABLE: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_class_variable_read_node_create(parser, &parser->previous); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_GLOBAL_VARIABLE: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_global_variable_read_node_create(parser, &parser->previous); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_NUMBERED_REFERENCE: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_numbered_reference_read_node_create(parser, &parser->previous); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_BACK_REFERENCE: { - parser_lex(parser); - yp_node_t *variable = (yp_node_t *) yp_back_reference_read_node_create(parser, &parser->previous); - - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - case YP_TOKEN_PARENTHESIS_LEFT: { - bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; - parser->pattern_matching_newlines = false; - - yp_token_t lparen = parser->current; - parser_lex(parser); - - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN); - parser->pattern_matching_newlines = previous_pattern_matching_newlines; - - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN); - return (yp_node_t *) yp_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. - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN); - yp_node_t *variable = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); - return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); - } - } - } - case YP_TOKEN_UCOLON_COLON: { - yp_token_t delimiter = parser->current; - parser_lex(parser); - - expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); - yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - yp_constant_path_node_t *node = yp_constant_path_node_create(parser, NULL, &delimiter, child); - - return parse_pattern_constant_path(parser, (yp_node_t *)node); - } - case YP_TOKEN_CONSTANT: { - yp_token_t constant = parser->current; - parser_lex(parser); - - yp_node_t *node = (yp_node_t *) yp_constant_read_node_create(parser, &constant); - return parse_pattern_constant_path(parser, node); - } - default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id); - return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); - } -} - -// Parse any number of primitives joined by alternation and ended optionally by -// assignment. -static yp_node_t * -parse_pattern_primitives(yp_parser_t *parser, yp_diagnostic_id_t diag_id) { - yp_node_t *node = NULL; - - do { - yp_token_t operator = parser->previous; - - switch (parser->current.type) { - case YP_TOKEN_IDENTIFIER: - case YP_TOKEN_BRACKET_LEFT_ARRAY: - case YP_TOKEN_BRACE_LEFT: - case YP_TOKEN_CARET: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_UCOLON_COLON: - case YP_TOKEN_UDOT_DOT: - case YP_TOKEN_UDOT_DOT_DOT: - case YP_CASE_PRIMITIVE: { - if (node == NULL) { - node = parse_pattern_primitive(parser, diag_id); - } else { - yp_node_t *right = parse_pattern_primitive(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE); - node = (yp_node_t *) yp_alternation_pattern_node_create(parser, node, right, &operator); - } - - break; - } - case YP_TOKEN_PARENTHESIS_LEFT: { - parser_lex(parser); - if (node != NULL) { - yp_node_destroy(parser, node); - } - node = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN); - - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN); - break; - } - default: { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id); - yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); - - if (node == NULL) { - node = right; - } else { - node = (yp_node_t *) yp_alternation_pattern_node_create(parser, node, right, &operator); - } - - break; - } - } - } while (accept(parser, YP_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 (accept(parser, YP_TOKEN_EQUAL_GREATER)) { - yp_token_t operator = parser->previous; - - expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_PATTERN_IDENT_AFTER_HROCKET); - yp_token_t identifier = parser->previous; - yp_parser_local_add_token(parser, &identifier); - - yp_node_t *target = (yp_node_t *) yp_local_variable_target_node_create(parser, &identifier); - node = (yp_node_t *) yp_capture_pattern_node_create(parser, node, target, &operator); - } - - return node; -} - -// Parse a pattern matching expression. -static yp_node_t * -parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id) { - yp_node_t *node = NULL; - - bool leading_rest = false; - bool trailing_rest = false; - - switch (parser->current.type) { - case YP_TOKEN_LABEL: { - parser_lex(parser); - yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous); - yp_token_t operator = not_provided(parser); - - return (yp_node_t *) parse_pattern_hash(parser, (yp_node_t *) yp_assoc_node_create(parser, key, &operator, NULL)); - } - case YP_TOKEN_USTAR_STAR: { - node = parse_pattern_keyword_rest(parser); - return (yp_node_t *) parse_pattern_hash(parser, node); - } - case YP_TOKEN_USTAR: { - if (top_pattern) { - parser_lex(parser); - node = (yp_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 (yp_symbol_node_label_p(node)) { - yp_token_t operator = not_provided(parser); - return (yp_node_t *) parse_pattern_hash(parser, (yp_node_t *) yp_assoc_node_create(parser, node, &operator, NULL)); - } - - if (top_pattern && match_type_p(parser, YP_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. - yp_node_list_t nodes = YP_EMPTY_NODE_LIST; - yp_node_list_append(&nodes, node); - - // Gather up all of the patterns into the list. - while (accept(parser, YP_TOKEN_COMMA)) { - // Break early here in case we have a trailing comma. - if (match_any_type_p(parser, 5, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - break; - } - - if (accept(parser, YP_TOKEN_USTAR)) { - node = (yp_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) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_REST); - } - - trailing_rest = true; - } else { - node = parse_pattern_primitives(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA); - } - - yp_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 (YP_NODE_TYPE_P(nodes.nodes[0], YP_SPLAT_NODE) && YP_NODE_TYPE_P(nodes.nodes[nodes.size - 1], YP_SPLAT_NODE)) { - node = (yp_node_t *) yp_find_pattern_node_create(parser, &nodes); - } else { - node = (yp_node_t *) yp_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 = (yp_node_t *) yp_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(yp_node_t *node) { - switch (YP_NODE_TYPE(node)) { - case YP_INTEGER_NODE: - case YP_FLOAT_NODE: - node->location.start--; - break; - case YP_RATIONAL_NODE: - node->location.start--; - parse_negative_numeric(((yp_rational_node_t *) node)->numeric); - break; - case YP_IMAGINARY_NODE: - node->location.start--; - parse_negative_numeric(((yp_imaginary_node_t *) node)->numeric); - break; - default: - assert(false && "unreachable"); - break; - } -} - -// Parse an expression that begins with the previous node that we just lexed. -static inline yp_node_t * -parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { - switch (parser->current.type) { - case YP_TOKEN_BRACKET_LEFT_ARRAY: { - parser_lex(parser); - - yp_array_node_t *array = yp_array_node_create(parser, &parser->previous); - yp_accepts_block_stack_push(parser, true); - bool parsed_bare_hash = false; - - while (!match_any_type_p(parser, 2, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_EOF)) { - // Handle the case where we don't have a comma and we have a newline followed by a right bracket. - if (accept(parser, YP_TOKEN_NEWLINE) && match_type_p(parser, YP_TOKEN_BRACKET_RIGHT)) { - break; - } - - if (yp_array_node_size(array) != 0) { - expect(parser, YP_TOKEN_COMMA, YP_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 (match_type_p(parser, YP_TOKEN_BRACKET_RIGHT)) break; - - yp_node_t *element; - - if (accept(parser, YP_TOKEN_USTAR)) { - yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION_AFTER_STAR); - element = (yp_node_t *) yp_splat_node_create(parser, &operator, expression); - } else if (match_any_type_p(parser, 2, YP_TOKEN_LABEL, YP_TOKEN_USTAR_STAR)) { - if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EXPRESSION_BARE_HASH); - } - - yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); - element = (yp_node_t *)hash; - - if (!match_any_type_p(parser, 8, YP_TOKEN_EOF, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON, YP_TOKEN_EOF, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_KEYWORD_DO, YP_TOKEN_PARENTHESIS_RIGHT)) { - parse_assocs(parser, (yp_node_t *) hash); - } - - parsed_bare_hash = true; - } else { - element = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION); - - if (yp_symbol_node_label_p(element) || accept(parser, YP_TOKEN_EQUAL_GREATER)) { - if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPRESSION_BARE_HASH); - } - - yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); - - yp_token_t operator; - if (parser->previous.type == YP_TOKEN_EQUAL_GREATER) { - operator = parser->previous; - } else { - operator = not_provided(parser); - } - - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); - yp_node_t *assoc = (yp_node_t *) yp_assoc_node_create(parser, element, &operator, value); - yp_keyword_hash_node_elements_append(hash, assoc); - - element = (yp_node_t *)hash; - if (accept(parser, YP_TOKEN_COMMA) && !match_type_p(parser, YP_TOKEN_BRACKET_RIGHT)) { - parse_assocs(parser, (yp_node_t *) hash); - } - - parsed_bare_hash = true; - } - } - - yp_array_node_elements_append(array, element); - if (YP_NODE_TYPE_P(element, YP_MISSING_NODE)) break; - } - - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_ARRAY_TERM); - yp_array_node_close_set(array, &parser->previous); - yp_accepts_block_stack_pop(parser); - - return (yp_node_t *) array; - } - case YP_TOKEN_PARENTHESIS_LEFT: - case YP_TOKEN_PARENTHESIS_LEFT_PARENTHESES: { - yp_token_t opening = parser->current; - parser_lex(parser); - while (accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_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 (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_EOF)) { - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - return (yp_node_t *) yp_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. - yp_accepts_block_stack_push(parser, true); - yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); - while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_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 (match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - if (opening.type == YP_TOKEN_PARENTHESIS_LEFT_PARENTHESES) { - lex_state_set(parser, YP_LEX_STATE_ENDARG); - } - parser_lex(parser); - yp_accepts_block_stack_pop(parser); - - // 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. - if (binding_power == YP_BINDING_POWER_STATEMENT && YP_NODE_TYPE_P(statement, YP_MULTI_TARGET_NODE)) { - yp_node_t *target; - yp_multi_target_node_t *multi_target = (yp_multi_target_node_t *) statement; - - yp_location_t lparen_loc = YP_LOCATION_TOKEN_VALUE(&opening); - yp_location_t rparen_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - - if (multi_target->lparen_loc.start == NULL) { - multi_target->base.location.start = lparen_loc.start; - multi_target->base.location.end = rparen_loc.end; - multi_target->lparen_loc = lparen_loc; - multi_target->rparen_loc = rparen_loc; - target = (yp_node_t *) multi_target; - } else { - yp_multi_target_node_t *parent_target = yp_multi_target_node_create(parser); - yp_multi_target_node_targets_append(parent_target, (yp_node_t *) multi_target); - target = (yp_node_t *) parent_target; - } - - return parse_targets(parser, target, YP_BINDING_POWER_INDEX); - } - - // 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. - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, statement); - - return (yp_node_t *) yp_parentheses_node_create(parser, &opening, (yp_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, YP_CONTEXT_PARENS); - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, statement); - - while (!match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - // Ignore semicolon without statements before them - if (accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE)) continue; - - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); - yp_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 (match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) parser->recovering = false; - break; - } - - if (!accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) break; - } - - context_pop(parser); - yp_accepts_block_stack_pop(parser); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - - return (yp_node_t *) yp_parentheses_node_create(parser, &opening, (yp_node_t *) statements, &parser->previous); - } - case YP_TOKEN_BRACE_LEFT: { - yp_accepts_block_stack_push(parser, true); - parser_lex(parser); - yp_hash_node_t *node = yp_hash_node_create(parser, &parser->previous); - - if (!match_any_type_p(parser, 2, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_EOF)) { - parse_assocs(parser, (yp_node_t *) node); - accept(parser, YP_TOKEN_NEWLINE); - } - - yp_accepts_block_stack_pop(parser); - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_HASH_TERM); - yp_hash_node_closing_loc_set(node, &parser->previous); - - return (yp_node_t *) node; - } - case YP_TOKEN_CHARACTER_LITERAL: { - parser_lex(parser); - - yp_token_t opening = parser->previous; - opening.type = YP_TOKEN_STRING_BEGIN; - opening.end = opening.start + 1; - - yp_token_t content = parser->previous; - content.type = YP_TOKEN_STRING_CONTENT; - content.start = content.start + 1; - - yp_token_t closing = not_provided(parser); - - return (yp_node_t *) yp_char_literal_node_create_and_unescape(parser, &opening, &content, &closing, YP_UNESCAPE_ALL); - } - case YP_TOKEN_CLASS_VARIABLE: { - parser_lex(parser); - yp_node_t *node = (yp_node_t *) yp_class_variable_read_node_create(parser, &parser->previous); - - if (binding_power == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_CONSTANT: { - parser_lex(parser); - yp_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 ( - match_type_p(parser, YP_TOKEN_PARENTHESIS_LEFT) || - (binding_power <= YP_BINDING_POWER_ASSIGNMENT && (token_begins_expression_p(parser->current.type) || match_any_type_p(parser, 3, YP_TOKEN_UAMPERSAND, YP_TOKEN_USTAR, YP_TOKEN_USTAR_STAR))) || - (yp_accepts_block_stack_p(parser) && match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_DO, YP_TOKEN_BRACE_LEFT)) - ) { - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, true); - return (yp_node_t *) yp_call_node_fcall_create(parser, &constant, &arguments); - } - - yp_node_t *node = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - - if ((binding_power == YP_BINDING_POWER_STATEMENT) && match_type_p(parser, YP_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(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_UCOLON_COLON: { - parser_lex(parser); - - yp_token_t delimiter = parser->previous; - expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); - - yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - yp_node_t *node = (yp_node_t *)yp_constant_path_node_create(parser, NULL, &delimiter, constant); - - if ((binding_power == YP_BINDING_POWER_STATEMENT) && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_UDOT_DOT: - case YP_TOKEN_UDOT_DOT_DOT: { - yp_token_t operator = parser->current; - parser_lex(parser); - - yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); - } - case YP_TOKEN_FLOAT: - parser_lex(parser); - return (yp_node_t *) yp_float_node_create(parser, &parser->previous); - case YP_TOKEN_FLOAT_IMAGINARY: - parser_lex(parser); - return (yp_node_t *) yp_float_node_imaginary_create(parser, &parser->previous); - case YP_TOKEN_FLOAT_RATIONAL: - parser_lex(parser); - return (yp_node_t *) yp_float_node_rational_create(parser, &parser->previous); - case YP_TOKEN_FLOAT_RATIONAL_IMAGINARY: - parser_lex(parser); - return (yp_node_t *) yp_float_node_rational_imaginary_create(parser, &parser->previous); - case YP_TOKEN_NUMBERED_REFERENCE: { - parser_lex(parser); - yp_node_t *node = (yp_node_t *) yp_numbered_reference_read_node_create(parser, &parser->previous); - - if (binding_power == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_GLOBAL_VARIABLE: { - parser_lex(parser); - yp_node_t *node = (yp_node_t *) yp_global_variable_read_node_create(parser, &parser->previous); - - if (binding_power == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_BACK_REFERENCE: { - parser_lex(parser); - yp_node_t *node = (yp_node_t *) yp_back_reference_read_node_create(parser, &parser->previous); - - if (binding_power == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - yp_token_t identifier = parser->previous; - yp_node_t *node = parse_variable_call(parser); - - if (YP_NODE_TYPE_P(node, YP_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. - yp_call_node_t *call = (yp_call_node_t *) node; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - - if (parse_arguments_list(parser, &arguments, true)) { - // Since we found arguments, we need to turn off the - // variable call bit in the flags. - call->base.flags &= (yp_node_flags_t) ~YP_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->base.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 ( - (binding_power <= YP_BINDING_POWER_ASSIGNMENT && (token_begins_expression_p(parser->current.type) || match_any_type_p(parser, 3, YP_TOKEN_UAMPERSAND, YP_TOKEN_USTAR, YP_TOKEN_USTAR_STAR))) || - (yp_accepts_block_stack_p(parser) && match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_DO, YP_TOKEN_BRACE_LEFT)) - ) { - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, true); - - yp_call_node_t *fcall = yp_call_node_fcall_create(parser, &identifier, &arguments); - yp_node_destroy(parser, node); - return (yp_node_t *) fcall; - } - } - - if ((binding_power == YP_BINDING_POWER_STATEMENT) && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_HEREDOC_START: { - assert(parser->lex_modes.current->mode == YP_LEX_HEREDOC); - yp_heredoc_quote_t quote = parser->lex_modes.current->as.heredoc.quote; - yp_heredoc_indent_t indent = parser->lex_modes.current->as.heredoc.indent; - - yp_node_t *node; - if (quote == YP_HEREDOC_QUOTE_BACKTICK) { - node = (yp_node_t *) yp_interpolated_xstring_node_create(parser, &parser->current, &parser->current); - } else { - node = (yp_node_t *) yp_interpolated_string_node_create(parser, &parser->current, NULL, &parser->current); - } - - parser_lex(parser); - yp_node_t *part; - - while (!match_any_type_p(parser, 2, YP_TOKEN_HEREDOC_END, YP_TOKEN_EOF)) { - if ((part = parse_string_part(parser)) == NULL) continue; - - if (quote == YP_HEREDOC_QUOTE_BACKTICK) { - yp_interpolated_xstring_node_append((yp_interpolated_x_string_node_t *) node, part); - } else { - yp_interpolated_string_node_append((yp_interpolated_string_node_t *) node, part); - } - } - - lex_state_set(parser, YP_LEX_STATE_END); - expect(parser, YP_TOKEN_HEREDOC_END, YP_ERR_HEREDOC_TERM); - - if (quote == YP_HEREDOC_QUOTE_BACKTICK) { - assert(YP_NODE_TYPE_P(node, YP_INTERPOLATED_X_STRING_NODE)); - yp_interpolated_xstring_node_closing_set(((yp_interpolated_x_string_node_t *) node), &parser->previous); - node->location = ((yp_interpolated_x_string_node_t *) node)->opening_loc; - } else { - assert(YP_NODE_TYPE_P(node, YP_INTERPOLATED_STRING_NODE)); - yp_interpolated_string_node_closing_set((yp_interpolated_string_node_t *) node, &parser->previous); - node->location = ((yp_interpolated_string_node_t *) node)->opening_loc; - } - - // If this is a heredoc that is indented with a ~, then we need to dedent - // each line by the common leading whitespace. - if (indent == YP_HEREDOC_INDENT_TILDE) { - parse_heredoc_dedent(parser, node, quote); - } - - // If there's a string immediately following this heredoc, then it's a - // concatenatation. In this case we'll parse the next string and create a - // node in the tree that concatenates the two strings. - if (parser->current.type == YP_TOKEN_STRING_BEGIN) { - return (yp_node_t *) yp_string_concat_node_create( - parser, - node, - parse_expression(parser, YP_BINDING_POWER_CALL, YP_ERR_CANNOT_PARSE_EXPRESSION) - ); - } else { - return node; - } - } - case YP_TOKEN_INSTANCE_VARIABLE: { - parser_lex(parser); - yp_node_t *node = (yp_node_t *) yp_instance_variable_read_node_create(parser, &parser->previous); - - if (binding_power == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - node = parse_targets(parser, node, YP_BINDING_POWER_INDEX); - } - - return node; - } - case YP_TOKEN_INTEGER: - parser_lex(parser); - return (yp_node_t *) yp_integer_node_create(parser, &parser->previous); - case YP_TOKEN_INTEGER_IMAGINARY: - parser_lex(parser); - return (yp_node_t *) yp_integer_node_imaginary_create(parser, &parser->previous); - case YP_TOKEN_INTEGER_RATIONAL: - parser_lex(parser); - return (yp_node_t *) yp_integer_node_rational_create(parser, &parser->previous); - case YP_TOKEN_INTEGER_RATIONAL_IMAGINARY: - parser_lex(parser); - return (yp_node_t *) yp_integer_node_rational_imaginary_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD___ENCODING__: - parser_lex(parser); - return (yp_node_t *) yp_source_encoding_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD___FILE__: - parser_lex(parser); - return (yp_node_t *) yp_source_file_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD___LINE__: - parser_lex(parser); - return (yp_node_t *) yp_source_line_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_ALIAS: { - parser_lex(parser); - yp_token_t keyword = parser->previous; - - yp_node_t *new_name = parse_alias_argument(parser, true); - yp_node_t *old_name = parse_alias_argument(parser, false); - - switch (YP_NODE_TYPE(new_name)) { - case YP_SYMBOL_NODE: - case YP_INTERPOLATED_SYMBOL_NODE: { - if (!YP_NODE_TYPE_P(old_name, YP_SYMBOL_NODE) && !YP_NODE_TYPE_P(old_name, YP_INTERPOLATED_SYMBOL_NODE)) { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); - } - break; - } - case YP_BACK_REFERENCE_READ_NODE: - case YP_NUMBERED_REFERENCE_READ_NODE: - case YP_GLOBAL_VARIABLE_READ_NODE: { - if (YP_NODE_TYPE_P(old_name, YP_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_GLOBAL_VARIABLE_READ_NODE)) { - if (YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE)) { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); - } - } else { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); - } - break; - } - default: - break; - } - - return (yp_node_t *) yp_alias_node_create(parser, &keyword, new_name, old_name); - } - case YP_TOKEN_KEYWORD_CASE: { - parser_lex(parser); - yp_token_t case_keyword = parser->previous; - yp_node_t *predicate = NULL; - - if ( - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON) || - match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_IN, YP_TOKEN_KEYWORD_END) || - !token_begins_expression_p(parser->current.type) - ) { - predicate = NULL; - } else { - predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CASE_EXPRESSION_AFTER_CASE); - while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)); - } - - if (accept(parser, YP_TOKEN_KEYWORD_END)) { - return (yp_node_t *) yp_case_node_create(parser, &case_keyword, predicate, NULL, &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. - yp_token_t end_keyword = not_provided(parser); - yp_case_node_t *case_node = yp_case_node_create(parser, &case_keyword, predicate, NULL, &end_keyword); - - if (match_type_p(parser, YP_TOKEN_KEYWORD_WHEN)) { - // 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 (accept(parser, YP_TOKEN_KEYWORD_WHEN)) { - yp_token_t when_keyword = parser->previous; - yp_when_node_t *when_node = yp_when_node_create(parser, &when_keyword); - - do { - if (accept(parser, YP_TOKEN_USTAR)) { - yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); - - yp_splat_node_t *splat_node = yp_splat_node_create(parser, &operator, expression); - yp_when_node_conditions_append(when_node, (yp_node_t *) splat_node); - - if (YP_NODE_TYPE_P(expression, YP_MISSING_NODE)) break; - } else { - yp_node_t *condition = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CASE_EXPRESSION_AFTER_WHEN); - yp_when_node_conditions_append(when_node, condition); - - if (YP_NODE_TYPE_P(condition, YP_MISSING_NODE)) break; - } - } while (accept(parser, YP_TOKEN_COMMA)); - - if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - accept(parser, YP_TOKEN_KEYWORD_THEN); - } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER); - } - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_END)) { - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_CASE_WHEN); - if (statements != NULL) { - yp_when_node_statements_set(when_node, statements); - } - } - - yp_case_node_condition_append(case_node, (yp_node_t *) when_node); - } - } else { - // 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 (match_type_p(parser, YP_TOKEN_KEYWORD_IN)) { - bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; - parser->pattern_matching_newlines = true; - - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - parser->command_start = false; - parser_lex(parser); - - yp_token_t in_keyword = parser->previous; - yp_node_t *pattern = parse_pattern(parser, true, YP_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 (accept(parser, YP_TOKEN_KEYWORD_IF_MODIFIER)) { - yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_IF_PREDICATE); - pattern = (yp_node_t *) yp_if_node_modifier_create(parser, pattern, &keyword, predicate); - } else if (accept(parser, YP_TOKEN_KEYWORD_UNLESS_MODIFIER)) { - yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_UNLESS_PREDICATE); - pattern = (yp_node_t *) yp_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. - yp_token_t then_keyword; - if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - if (accept(parser, YP_TOKEN_KEYWORD_THEN)) { - then_keyword = parser->previous; - } else { - then_keyword = not_provided(parser); - } - } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER); - then_keyword = parser->previous; - } - - // Now we can actually parse the statements associated with the in - // node. - yp_statements_node_t *statements; - if (match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_IN, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_END)) { - statements = NULL; - } else { - statements = parse_statements(parser, YP_CONTEXT_CASE_IN); - } - - // Now that we have the full pattern and statements, we can create the - // node and attach it to the case node. - yp_node_t *condition = (yp_node_t *) yp_in_node_create(parser, pattern, statements, &in_keyword, &then_keyword); - yp_case_node_condition_append(case_node, condition); - } - } - - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - if (accept(parser, YP_TOKEN_KEYWORD_ELSE)) { - if (case_node->conditions.size < 1) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CASE_LONELY_ELSE); - } - - yp_token_t else_keyword = parser->previous; - yp_else_node_t *else_node; - - if (!match_type_p(parser, YP_TOKEN_KEYWORD_END)) { - else_node = yp_else_node_create(parser, &else_keyword, parse_statements(parser, YP_CONTEXT_ELSE), &parser->current); - } else { - else_node = yp_else_node_create(parser, &else_keyword, NULL, &parser->current); - } - - yp_case_node_consequent_set(case_node, else_node); - } - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CASE_TERM); - yp_case_node_end_keyword_loc_set(case_node, &parser->previous); - return (yp_node_t *) case_node; - } - case YP_TOKEN_KEYWORD_BEGIN: { - parser_lex(parser); - - yp_token_t begin_keyword = parser->previous; - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - yp_statements_node_t *begin_statements = NULL; - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - begin_statements = parse_statements(parser, YP_CONTEXT_BEGIN); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - yp_begin_node_t *begin_node = yp_begin_node_create(parser, &begin_keyword, begin_statements); - parse_rescues(parser, begin_node); - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BEGIN_TERM); - begin_node->base.location.end = parser->previous.end; - yp_begin_node_end_keyword_set(begin_node, &parser->previous); - - if ((begin_node->else_clause != NULL) && (begin_node->rescue_clause == NULL)) { - yp_diagnostic_list_append( - &parser->error_list, - begin_node->else_clause->base.location.start, - begin_node->else_clause->base.location.end, - YP_ERR_BEGIN_LONELY_ELSE - ); - } - - return (yp_node_t *) begin_node; - } - case YP_TOKEN_KEYWORD_BEGIN_UPCASE: { - parser_lex(parser); - yp_token_t keyword = parser->previous; - - expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_BEGIN_UPCASE_BRACE); - yp_token_t opening = parser->previous; - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_PREEXE); - - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BEGIN_UPCASE_TERM); - return (yp_node_t *) yp_pre_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); - } - case YP_TOKEN_KEYWORD_BREAK: - case YP_TOKEN_KEYWORD_NEXT: - case YP_TOKEN_KEYWORD_RETURN: { - parser_lex(parser); - - yp_token_t keyword = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - - if ( - token_begins_expression_p(parser->current.type) || - match_any_type_p(parser, 2, YP_TOKEN_USTAR, YP_TOKEN_USTAR_STAR) - ) { - yp_binding_power_t binding_power = yp_binding_powers[parser->current.type].left; - - if (binding_power == YP_BINDING_POWER_UNSET || binding_power >= YP_BINDING_POWER_RANGE) { - arguments.arguments = yp_arguments_node_create(parser); - parse_arguments(parser, &arguments, false, YP_TOKEN_EOF); - } - } - - switch (keyword.type) { - case YP_TOKEN_KEYWORD_BREAK: - return (yp_node_t *) yp_break_node_create(parser, &keyword, arguments.arguments); - case YP_TOKEN_KEYWORD_NEXT: - return (yp_node_t *) yp_next_node_create(parser, &keyword, arguments.arguments); - case YP_TOKEN_KEYWORD_RETURN: { - if ( - (parser->current_context->context == YP_CONTEXT_CLASS) || - (parser->current_context->context == YP_CONTEXT_MODULE) - ) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_RETURN_INVALID); - } - return (yp_node_t *) yp_return_node_create(parser, &keyword, arguments.arguments); - } - default: - assert(false && "unreachable"); - return (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end); - } - } - case YP_TOKEN_KEYWORD_SUPER: { - parser_lex(parser); - - yp_token_t keyword = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, true); - - if (arguments.opening_loc.start == NULL && arguments.arguments == NULL) { - return (yp_node_t *) yp_forwarding_super_node_create(parser, &keyword, &arguments); - } - - return (yp_node_t *) yp_super_node_create(parser, &keyword, &arguments); - } - case YP_TOKEN_KEYWORD_YIELD: { - parser_lex(parser); - - yp_token_t keyword = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, false); - - return (yp_node_t *) yp_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc); - } - case YP_TOKEN_KEYWORD_CLASS: { - parser_lex(parser); - yp_token_t class_keyword = parser->previous; - yp_do_loop_stack_push(parser, false); - - if (accept(parser, YP_TOKEN_LESS_LESS)) { - yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_NOT, YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS); - - yp_parser_scope_push(parser, true); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - - yp_node_t *statements = NULL; - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_SCLASS); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(statements == NULL || YP_NODE_TYPE_P(statements, YP_STATEMENTS_NODE)); - statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); - } - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM); - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - yp_do_loop_stack_pop(parser); - return (yp_node_t *) yp_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous); - } - - yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_CLASS_NAME); - yp_token_t name = parser->previous; - if (name.type != YP_TOKEN_CONSTANT) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_CLASS_NAME); - } - - yp_token_t inheritance_operator; - yp_node_t *superclass; - - if (match_type_p(parser, YP_TOKEN_LESS)) { - inheritance_operator = parser->current; - lex_state_set(parser, YP_LEX_STATE_BEG); - - parser->command_start = true; - parser_lex(parser); - - superclass = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CLASS_SUPERCLASS); - } else { - inheritance_operator = not_provided(parser); - superclass = NULL; - } - - yp_parser_scope_push(parser, true); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - yp_node_t *statements = NULL; - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_CLASS); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(statements == NULL || YP_NODE_TYPE_P(statements, YP_STATEMENTS_NODE)); - statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); - } - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM); - - if (context_def_p(parser)) { - yp_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, YP_ERR_CLASS_IN_METHOD); - } - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - yp_do_loop_stack_pop(parser); - return (yp_node_t *) yp_class_node_create(parser, &locals, &class_keyword, constant_path, &name, &inheritance_operator, superclass, statements, &parser->previous); - } - case YP_TOKEN_KEYWORD_DEF: { - yp_token_t def_keyword = parser->current; - - yp_node_t *receiver = NULL; - yp_token_t operator = not_provided(parser); - yp_token_t name = not_provided(parser); - - context_push(parser, YP_CONTEXT_DEF_PARAMS); - parser_lex(parser); - - switch (parser->current.type) { - case YP_CASE_OPERATOR: - yp_parser_scope_push(parser, true); - lex_state_set(parser, YP_LEX_STATE_ENDFN); - parser_lex(parser); - name = parser->previous; - break; - case YP_TOKEN_IDENTIFIER: { - yp_parser_scope_push(parser, true); - parser_lex(parser); - - if (match_any_type_p(parser, 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON)) { - receiver = parse_variable_call(parser); - - lex_state_set(parser, YP_LEX_STATE_FNAME); - parser_lex(parser); - - operator = parser->previous; - name = parse_method_definition_name(parser); - - if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER); - } - } else { - name = parser->previous; - } - - break; - } - case YP_TOKEN_CONSTANT: - case YP_TOKEN_INSTANCE_VARIABLE: - case YP_TOKEN_CLASS_VARIABLE: - case YP_TOKEN_GLOBAL_VARIABLE: - case YP_TOKEN_KEYWORD_NIL: - case YP_TOKEN_KEYWORD_SELF: - case YP_TOKEN_KEYWORD_TRUE: - case YP_TOKEN_KEYWORD_FALSE: - case YP_TOKEN_KEYWORD___FILE__: - case YP_TOKEN_KEYWORD___LINE__: - case YP_TOKEN_KEYWORD___ENCODING__: { - yp_parser_scope_push(parser, true); - parser_lex(parser); - yp_token_t identifier = parser->previous; - - if (match_any_type_p(parser, 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON)) { - lex_state_set(parser, YP_LEX_STATE_FNAME); - parser_lex(parser); - operator = parser->previous; - - switch (identifier.type) { - case YP_TOKEN_CONSTANT: - receiver = (yp_node_t *) yp_constant_read_node_create(parser, &identifier); - break; - case YP_TOKEN_INSTANCE_VARIABLE: - receiver = (yp_node_t *) yp_instance_variable_read_node_create(parser, &identifier); - break; - case YP_TOKEN_CLASS_VARIABLE: - receiver = (yp_node_t *) yp_class_variable_read_node_create(parser, &identifier); - break; - case YP_TOKEN_GLOBAL_VARIABLE: - receiver = (yp_node_t *) yp_global_variable_read_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD_NIL: - receiver = (yp_node_t *) yp_nil_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD_SELF: - receiver = (yp_node_t *) yp_self_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD_TRUE: - receiver = (yp_node_t *) yp_true_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD_FALSE: - receiver = (yp_node_t *)yp_false_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD___FILE__: - receiver = (yp_node_t *) yp_source_file_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD___LINE__: - receiver = (yp_node_t *) yp_source_line_node_create(parser, &identifier); - break; - case YP_TOKEN_KEYWORD___ENCODING__: - receiver = (yp_node_t *) yp_source_encoding_node_create(parser, &identifier); - break; - default: - break; - } - - name = parse_method_definition_name(parser); - if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER); - } - } else { - name = identifier; - } - break; - } - case YP_TOKEN_PARENTHESIS_LEFT: { - parser_lex(parser); - yp_token_t lparen = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_DEF_RECEIVER); - - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - yp_token_t rparen = parser->previous; - - lex_state_set(parser, YP_LEX_STATE_FNAME); - expect_any(parser, YP_ERR_DEF_RECEIVER_TERM, 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON); - - operator = parser->previous; - receiver = (yp_node_t *) yp_parentheses_node_create(parser, &lparen, expression, &rparen); - - yp_parser_scope_push(parser, true); - name = parse_method_definition_name(parser); - break; - } - default: - yp_parser_scope_push(parser, true); - name = parse_method_definition_name(parser); - - if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME); - } - break; - } - - yp_token_t lparen; - yp_token_t rparen; - yp_parameters_node_t *params; - - switch (parser->current.type) { - case YP_TOKEN_PARENTHESIS_LEFT: { - parser_lex(parser); - lparen = parser->previous; - - if (match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - params = NULL; - } else { - params = parse_parameters(parser, YP_BINDING_POWER_DEFINED, true, false, true); - } - - lex_state_set(parser, YP_LEX_STATE_BEG); - parser->command_start = true; - - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_DEF_PARAMS_TERM_PAREN); - rparen = parser->previous; - break; - } - case YP_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 == YP_TOKEN_LABEL) { - lex_state_set(parser, parser->lex_state | YP_LEX_STATE_LABEL); - } - - lparen = not_provided(parser); - rparen = not_provided(parser); - params = parse_parameters(parser, YP_BINDING_POWER_DEFINED, false, false, true); - break; - } - default: { - lparen = not_provided(parser); - rparen = not_provided(parser); - params = NULL; - break; - } - } - - context_pop(parser); - yp_node_t *statements = NULL; - yp_token_t equal; - yp_token_t end_keyword; - - if (accept(parser, YP_TOKEN_EQUAL)) { - if (token_is_setter_name(&name)) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_DEF_ENDLESS_SETTER); - } - equal = parser->previous; - - context_push(parser, YP_CONTEXT_DEF); - statements = (yp_node_t *) yp_statements_node_create(parser); - - yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_DEFINED + 1, YP_ERR_DEF_ENDLESS); - - if (accept(parser, YP_TOKEN_KEYWORD_RESCUE_MODIFIER)) { - yp_token_t rescue_keyword = parser->previous; - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE); - yp_rescue_modifier_node_t *rescue_node = yp_rescue_modifier_node_create(parser, statement, &rescue_keyword, value); - statement = (yp_node_t *)rescue_node; - } - - yp_statements_node_body_append((yp_statements_node_t *) statements, statement); - context_pop(parser); - end_keyword = not_provided(parser); - } else { - equal = not_provided(parser); - - if (lparen.type == YP_TOKEN_NOT_PROVIDED) { - lex_state_set(parser, YP_LEX_STATE_BEG); - parser->command_start = true; - expect_any(parser, YP_ERR_DEF_PARAMS_TERM, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } else { - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - } - - yp_accepts_block_stack_push(parser, true); - yp_do_loop_stack_push(parser, false); - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_DEF); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(statements == NULL || YP_NODE_TYPE_P(statements, YP_STATEMENTS_NODE)); - statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); - } - - yp_accepts_block_stack_pop(parser); - yp_do_loop_stack_pop(parser); - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_DEF_TERM); - end_keyword = parser->previous; - } - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - - return (yp_node_t *) yp_def_node_create( - parser, - &name, - receiver, - params, - statements, - &locals, - &def_keyword, - &operator, - &lparen, - &rparen, - &equal, - &end_keyword - ); - } - case YP_TOKEN_KEYWORD_DEFINED: { - parser_lex(parser); - yp_token_t keyword = parser->previous; - - yp_token_t lparen; - yp_token_t rparen; - yp_node_t *expression; - - if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - lparen = parser->previous; - expression = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_DEFINED_EXPRESSION); - - if (parser->recovering) { - rparen = not_provided(parser); - } else { - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - rparen = parser->previous; - } - } else { - lparen = not_provided(parser); - rparen = not_provided(parser); - expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_DEFINED_EXPRESSION); - } - - return (yp_node_t *) yp_defined_node_create( - parser, - &lparen, - expression, - &rparen, - &YP_LOCATION_TOKEN_VALUE(&keyword) - ); - } - case YP_TOKEN_KEYWORD_END_UPCASE: { - parser_lex(parser); - yp_token_t keyword = parser->previous; - - expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_END_UPCASE_BRACE); - yp_token_t opening = parser->previous; - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_POSTEXE); - - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_END_UPCASE_TERM); - return (yp_node_t *) yp_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); - } - case YP_TOKEN_KEYWORD_FALSE: - parser_lex(parser); - return (yp_node_t *)yp_false_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_FOR: { - parser_lex(parser); - yp_token_t for_keyword = parser->previous; - - yp_node_t *index = parse_targets(parser, NULL, YP_BINDING_POWER_INDEX); - yp_do_loop_stack_push(parser, true); - - expect(parser, YP_TOKEN_KEYWORD_IN, YP_ERR_FOR_IN); - yp_token_t in_keyword = parser->previous; - - yp_node_t *collection = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_FOR_COLLECTION); - yp_do_loop_stack_pop(parser); - - yp_token_t do_keyword; - if (accept(parser, YP_TOKEN_KEYWORD_DO_LOOP)) { - do_keyword = parser->previous; - } else { - do_keyword = not_provided(parser); - } - - accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE); - yp_statements_node_t *statements = NULL; - - if (!accept(parser, YP_TOKEN_KEYWORD_END)) { - statements = parse_statements(parser, YP_CONTEXT_FOR); - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_FOR_TERM); - } - - return (yp_node_t *) yp_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous); - } - case YP_TOKEN_KEYWORD_IF: - parser_lex(parser); - return parse_conditional(parser, YP_CONTEXT_IF); - case YP_TOKEN_KEYWORD_UNDEF: { - parser_lex(parser); - yp_undef_node_t *undef = yp_undef_node_create(parser, &parser->previous); - yp_node_t *name = parse_undef_argument(parser); - - if (YP_NODE_TYPE_P(name, YP_MISSING_NODE)) { - yp_node_destroy(parser, name); - } else { - yp_undef_node_append(undef, name); - - while (match_type_p(parser, YP_TOKEN_COMMA)) { - lex_state_set(parser, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM); - parser_lex(parser); - name = parse_undef_argument(parser); - - if (YP_NODE_TYPE_P(name, YP_MISSING_NODE)) { - yp_node_destroy(parser, name); - break; - } - - yp_undef_node_append(undef, name); - } - } - - return (yp_node_t *) undef; - } - case YP_TOKEN_KEYWORD_NOT: { - parser_lex(parser); - - yp_token_t message = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - yp_node_t *receiver = NULL; - - accept(parser, YP_TOKEN_NEWLINE); - - if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - arguments.opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - - if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - } else { - receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_NOT_EXPRESSION); - yp_flip_flop(receiver); - - if (!parser->recovering) { - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - } - } - } else { - receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_NOT_EXPRESSION); - yp_flip_flop(receiver); - } - - return (yp_node_t *) yp_call_node_not_create(parser, receiver, &message, &arguments); - } - case YP_TOKEN_KEYWORD_UNLESS: - parser_lex(parser); - return parse_conditional(parser, YP_CONTEXT_UNLESS); - case YP_TOKEN_KEYWORD_MODULE: { - parser_lex(parser); - - yp_token_t module_keyword = parser->previous; - yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_MODULE_NAME); - yp_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 (YP_NODE_TYPE_P(constant_path, YP_MISSING_NODE)) { - yp_token_t missing = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; - return (yp_node_t *) yp_module_node_create(parser, NULL, &module_keyword, constant_path, &missing, NULL, &missing); - } - - while (accept(parser, YP_TOKEN_COLON_COLON)) { - yp_token_t double_colon = parser->previous; - - expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); - yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - - constant_path = (yp_node_t *) yp_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 != YP_TOKEN_CONSTANT) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_MODULE_NAME); - } - - yp_parser_scope_push(parser, true); - accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE); - yp_node_t *statements = NULL; - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_MODULE); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(statements == NULL || YP_NODE_TYPE_P(statements, YP_STATEMENTS_NODE)); - statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); - } - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_MODULE_TERM); - - if (context_def_p(parser)) { - yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, YP_ERR_MODULE_IN_METHOD); - } - - return (yp_node_t *) yp_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous); - } - case YP_TOKEN_KEYWORD_NIL: - parser_lex(parser); - return (yp_node_t *) yp_nil_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_REDO: - parser_lex(parser); - return (yp_node_t *) yp_redo_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_RETRY: - parser_lex(parser); - return (yp_node_t *) yp_retry_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_SELF: - parser_lex(parser); - return (yp_node_t *) yp_self_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_TRUE: - parser_lex(parser); - return (yp_node_t *) yp_true_node_create(parser, &parser->previous); - case YP_TOKEN_KEYWORD_UNTIL: { - yp_do_loop_stack_push(parser, true); - parser_lex(parser); - yp_token_t keyword = parser->previous; - - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_UNTIL_PREDICATE); - yp_do_loop_stack_pop(parser); - - accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - yp_statements_node_t *statements = NULL; - - if (!accept(parser, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = parse_statements(parser, YP_CONTEXT_UNTIL); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_UNTIL_TERM); - } - - return (yp_node_t *) yp_until_node_create(parser, &keyword, &parser->previous, predicate, statements, 0); - } - case YP_TOKEN_KEYWORD_WHILE: { - yp_do_loop_stack_push(parser, true); - parser_lex(parser); - yp_token_t keyword = parser->previous; - - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_WHILE_PREDICATE); - yp_do_loop_stack_pop(parser); - - accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - yp_statements_node_t *statements = NULL; - - if (!accept(parser, YP_TOKEN_KEYWORD_END)) { - yp_accepts_block_stack_push(parser, true); - statements = parse_statements(parser, YP_CONTEXT_WHILE); - yp_accepts_block_stack_pop(parser); - accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_WHILE_TERM); - } - - return (yp_node_t *) yp_while_node_create(parser, &keyword, &parser->previous, predicate, statements, 0); - } - case YP_TOKEN_PERCENT_LOWER_I: { - parser_lex(parser); - yp_array_node_t *array = yp_array_node_create(parser, &parser->previous); - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - accept(parser, YP_TOKEN_WORDS_SEP); - if (match_type_p(parser, YP_TOKEN_STRING_END)) break; - - expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_I_LOWER_ELEMENT); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - - yp_node_t *symbol = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_MINIMAL); - yp_array_node_elements_append(array, symbol); - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_LOWER_TERM); - yp_array_node_close_set(array, &parser->previous); - - return (yp_node_t *) array; - } - case YP_TOKEN_PERCENT_UPPER_I: { - parser_lex(parser); - yp_array_node_t *array = yp_array_node_create(parser, &parser->previous); - - // This is the current node that we are parsing that will be added to the - // list of elements. - yp_node_t *current = NULL; - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - switch (parser->current.type) { - case YP_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. - yp_array_node_elements_append(array, current); - current = NULL; - } - - parser_lex(parser); - break; - } - case YP_TOKEN_STRING_CONTENT: { - yp_token_t opening = not_provided(parser); - yp_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. - parser_lex(parser); - current = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_node_t *part = parse_string_part(parser); - yp_interpolated_symbol_node_append((yp_interpolated_symbol_node_t *) current, part); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_symbol_node_t *interpolated = - yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); - yp_interpolated_symbol_node_append(interpolated, current); - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_symbol_node_append(interpolated, part); - current = (yp_node_t *) interpolated; - } else { - assert(false && "unreachable"); - } - - break; - } - case YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - current = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_symbol_node_t *interpolated = yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); - - current = (yp_node_t *) yp_symbol_node_to_string_node(parser, (yp_symbol_node_t *) current); - yp_interpolated_symbol_node_append(interpolated, current); - interpolated->base.location.start = current->location.start; - start_location_set = true; - current = (yp_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. - } - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_symbol_node_append((yp_interpolated_symbol_node_t *) current, part); - if (!start_location_set) { - current->location.start = part->location.start; - } - break; - } - case YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - current = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_symbol_node_t *interpolated = yp_interpolated_symbol_node_create(parser, &opening, NULL, &closing); - - current = (yp_node_t *) yp_symbol_node_to_string_node(parser, (yp_symbol_node_t *) current); - yp_interpolated_symbol_node_append(interpolated, current); - interpolated->base.location.start = current->location.start; - start_location_set = true; - current = (yp_node_t *) interpolated; - } else if (YP_NODE_TYPE_P(current, YP_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"); - } - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_symbol_node_append((yp_interpolated_symbol_node_t *) current, part); - if (!start_location_set) { - current->location.start = part->location.start; - } - break; - } - default: - expect(parser, YP_TOKEN_STRING_CONTENT, YP_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) { - yp_array_node_elements_append(array, current); - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_UPPER_TERM); - yp_array_node_close_set(array, &parser->previous); - - return (yp_node_t *) array; - } - case YP_TOKEN_PERCENT_LOWER_W: { - parser_lex(parser); - yp_array_node_t *array = yp_array_node_create(parser, &parser->previous); - - // skip all leading whitespaces - accept(parser, YP_TOKEN_WORDS_SEP); - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - accept(parser, YP_TOKEN_WORDS_SEP); - if (match_type_p(parser, YP_TOKEN_STRING_END)) break; - - expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_W_LOWER_ELEMENT); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_node_t *string = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_MINIMAL); - yp_array_node_elements_append(array, string); - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_LOWER_TERM); - yp_array_node_close_set(array, &parser->previous); - - return (yp_node_t *) array; - } - case YP_TOKEN_PERCENT_UPPER_W: { - parser_lex(parser); - yp_array_node_t *array = yp_array_node_create(parser, &parser->previous); - - // This is the current node that we are parsing that will be added to the - // list of elements. - yp_node_t *current = NULL; - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - switch (parser->current.type) { - case YP_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. - yp_array_node_elements_append(array, current); - current = NULL; - } - - parser_lex(parser); - break; - } - case YP_TOKEN_STRING_CONTENT: { - 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 = parse_string_part(parser); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_node_t *part = parse_string_part(parser); - yp_interpolated_string_node_append((yp_interpolated_string_node_t *) current, part); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_string_node_t *interpolated = - yp_interpolated_string_node_create(parser, &opening, NULL, &closing); - yp_interpolated_string_node_append(interpolated, current); - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_string_node_append(interpolated, part); - current = (yp_node_t *) interpolated; - } else { - assert(false && "unreachable"); - } - - break; - } - case YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - current = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, NULL, &closing); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_string_node_t *interpolated = yp_interpolated_string_node_create(parser, &opening, NULL, &closing); - yp_interpolated_string_node_append(interpolated, current); - current = (yp_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. - } - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_string_node_append((yp_interpolated_string_node_t *) current, part); - break; - } - case YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - current = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, NULL, &closing); - } else if (YP_NODE_TYPE_P(current, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_interpolated_string_node_t *interpolated = yp_interpolated_string_node_create(parser, &opening, NULL, &closing); - yp_interpolated_string_node_append(interpolated, current); - current = (yp_node_t *) interpolated; - } else if (YP_NODE_TYPE_P(current, YP_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"); - } - - yp_node_t *part = parse_string_part(parser); - yp_interpolated_string_node_append((yp_interpolated_string_node_t *) current, part); - break; - } - default: - expect(parser, YP_TOKEN_STRING_CONTENT, YP_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) { - yp_array_node_elements_append(array, current); - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_UPPER_TERM); - yp_array_node_close_set(array, &parser->previous); - - return (yp_node_t *) array; - } - case YP_TOKEN_REGEXP_BEGIN: { - yp_token_t opening = parser->current; - parser_lex(parser); - - if (match_type_p(parser, YP_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. - yp_token_t content = (yp_token_t) { - .type = YP_TOKEN_STRING_CONTENT, - .start = parser->previous.end, - .end = parser->previous.end - }; - - parser_lex(parser); - return (yp_node_t *) yp_regular_expression_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); - } - - yp_interpolated_regular_expression_node_t *node; - - if (match_type_p(parser, YP_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. - yp_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 (accept(parser, YP_TOKEN_REGEXP_END)) { - return (yp_node_t *) yp_regular_expression_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); - } - - // If we get here, then we have interpolation so we'll need to create - // a regular expression node with interpolation. - node = yp_interpolated_regular_expression_node_create(parser, &opening); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_node_t *part = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); - yp_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 = yp_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. - while (!match_any_type_p(parser, 2, YP_TOKEN_REGEXP_END, YP_TOKEN_EOF)) { - yp_node_t *part = parse_string_part(parser); - if (part != NULL) { - yp_interpolated_regular_expression_node_append(node, part); - } - } - - expect(parser, YP_TOKEN_REGEXP_END, YP_ERR_REGEXP_TERM); - yp_interpolated_regular_expression_node_closing_set(node, &parser->previous); - - return (yp_node_t *) node; - } - case YP_TOKEN_BACKTICK: - case YP_TOKEN_PERCENT_LOWER_X: { - parser_lex(parser); - yp_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 (match_type_p(parser, YP_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. - yp_token_t content = (yp_token_t) { - .type = YP_TOKEN_STRING_CONTENT, - .start = parser->previous.end, - .end = parser->previous.end - }; - - parser_lex(parser); - return (yp_node_t *) yp_xstring_node_create(parser, &opening, &content, &parser->previous); - } - - yp_interpolated_x_string_node_t *node; - - if (match_type_p(parser, YP_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. - yp_token_t content = parser->current; - parser_lex(parser); - - if (accept(parser, YP_TOKEN_STRING_END)) { - return (yp_node_t *) yp_xstring_node_create_and_unescape(parser, &opening, &content, &parser->previous); - } - - // If we get here, then we have interpolation so we'll need to create - // a string node with interpolation. - node = yp_interpolated_xstring_node_create(parser, &opening, &opening); - - yp_token_t opening = not_provided(parser); - yp_token_t closing = not_provided(parser); - yp_node_t *part = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); - yp_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 = yp_interpolated_xstring_node_create(parser, &opening, &opening); - } - - while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { - yp_node_t *part = parse_string_part(parser); - if (part != NULL) { - yp_interpolated_xstring_node_append(node, part); - } - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_XSTRING_TERM); - yp_interpolated_xstring_node_closing_set(node, &parser->previous); - return (yp_node_t *) node; - } - case YP_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 != YP_BINDING_POWER_STATEMENT) { - return (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end); - } - - yp_token_t operator = parser->previous; - yp_node_t *name = NULL; - - if (token_begins_expression_p(parser->current.type)) { - name = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); - } - - yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &operator, name); - return parse_targets(parser, splat, YP_BINDING_POWER_INDEX); - } - case YP_TOKEN_BANG: { - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_BANG); - yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!"); - - yp_flip_flop(receiver); - return (yp_node_t *) node; - } - case YP_TOKEN_TILDE: { - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_TILDE); - yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "~"); - - return (yp_node_t *) node; - } - case YP_TOKEN_UMINUS: { - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS); - yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "-@"); - - return (yp_node_t *) node; - } - case YP_TOKEN_UMINUS_NUM: { - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *node = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS); - - switch (YP_NODE_TYPE(node)) { - case YP_INTEGER_NODE: - case YP_FLOAT_NODE: - case YP_RATIONAL_NODE: - case YP_IMAGINARY_NODE: - parse_negative_numeric(node); - break; - default: - node = (yp_node_t *) yp_call_node_unary_create(parser, &operator, node, "-@"); - break; - } - - return node; - } - case YP_TOKEN_MINUS_GREATER: { - int previous_lambda_enclosure_nesting = parser->lambda_enclosure_nesting; - parser->lambda_enclosure_nesting = parser->enclosure_nesting; - - yp_accepts_block_stack_push(parser, true); - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_parser_scope_push(parser, false); - yp_block_parameters_node_t *params; - - switch (parser->current.type) { - case YP_TOKEN_PARENTHESIS_LEFT: { - yp_token_t opening = parser->current; - parser_lex(parser); - - if (match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - params = yp_block_parameters_node_create(parser, NULL, &opening); - } else { - params = parse_block_parameters(parser, false, &opening, true); - } - - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); - - yp_block_parameters_node_closing_set(params, &parser->previous); - break; - } - case YP_CASE_PARAMETER: { - yp_accepts_block_stack_push(parser, false); - yp_token_t opening = not_provided(parser); - params = parse_block_parameters(parser, false, &opening, true); - yp_accepts_block_stack_pop(parser); - break; - } - default: { - params = NULL; - break; - } - } - - yp_token_t opening; - yp_node_t *body = NULL; - parser->lambda_enclosure_nesting = previous_lambda_enclosure_nesting; - - if (accept(parser, YP_TOKEN_LAMBDA_BEGIN)) { - opening = parser->previous; - - if (!accept(parser, YP_TOKEN_BRACE_RIGHT)) { - body = (yp_node_t *) parse_statements(parser, YP_CONTEXT_LAMBDA_BRACES); - expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_LAMBDA_TERM_BRACE); - } - } else { - expect(parser, YP_TOKEN_KEYWORD_DO, YP_ERR_LAMBDA_OPEN); - opening = parser->previous; - - if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_END, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - yp_accepts_block_stack_push(parser, true); - body = (yp_node_t *) parse_statements(parser, YP_CONTEXT_LAMBDA_DO_END); - yp_accepts_block_stack_pop(parser); - } - - if (match_any_type_p(parser, 2, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { - assert(body == NULL || YP_NODE_TYPE_P(body, YP_STATEMENTS_NODE)); - body = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) body); - } - - expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_LAMBDA_TERM_END); - } - - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_parser_scope_pop(parser); - yp_accepts_block_stack_pop(parser); - return (yp_node_t *) yp_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, params, body); - } - case YP_TOKEN_UPLUS: { - parser_lex(parser); - - yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_PLUS); - yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "+@"); - - return (yp_node_t *) node; - } - case YP_TOKEN_STRING_BEGIN: { - yp_node_t *result = NULL; - - while (match_type_p(parser, YP_TOKEN_STRING_BEGIN)) { - assert(parser->lex_modes.current->mode == YP_LEX_STRING); - bool lex_interpolation = parser->lex_modes.current->as.string.interpolation; - - yp_node_t *node = NULL; - yp_token_t opening = parser->current; - parser_lex(parser); - - if (accept(parser, YP_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. - yp_token_t content = (yp_token_t) { - .type = YP_TOKEN_STRING_CONTENT, - .start = parser->previous.start, - .end = parser->previous.start - }; - - node = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_NONE); - } else if (accept(parser, YP_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. - yp_token_t opening = not_provided(parser); - yp_token_t content = (yp_token_t) { - .type = YP_TOKEN_STRING_CONTENT, - .start = parser->previous.start, - .end = parser->previous.start - }; - - node = (yp_node_t *) yp_symbol_node_create(parser, &opening, &content, &parser->previous); - } else if (!lex_interpolation) { - // If we don't accept interpolation then we expect the - // string to start with a single string content node. - expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_EXPECT_STRING_CONTENT); - yp_token_t 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 (match_type_p(parser, YP_TOKEN_STRING_CONTENT)) { - yp_node_list_t parts = YP_EMPTY_NODE_LIST; - - yp_token_t delimiters = not_provided(parser); - yp_node_t *part = (yp_node_t *) yp_string_node_create_and_unescape(parser, &delimiters, &content, &delimiters, YP_UNESCAPE_MINIMAL); - yp_node_list_append(&parts, part); - - while (accept(parser, YP_TOKEN_STRING_CONTENT)) { - part = (yp_node_t *) yp_string_node_create_and_unescape(parser, &delimiters, &parser->previous, &delimiters, YP_UNESCAPE_MINIMAL); - yp_node_list_append(&parts, part); - } - - expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM); - node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); - } else if (accept(parser, YP_TOKEN_LABEL_END)) { - node = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); - } else { - expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM); - node = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_MINIMAL); - } - } else if (match_type_p(parser, YP_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. - yp_token_t content = parser->current; - parser_lex(parser); - - if (accept(parser, YP_TOKEN_STRING_END)) { - node = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); - } else if (accept(parser, YP_TOKEN_LABEL_END)) { - node = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); - } else { - // If we get here, then we have interpolation so we'll need to create - // a string or symbol node with interpolation. - yp_node_list_t parts = YP_EMPTY_NODE_LIST; - yp_token_t string_opening = not_provided(parser); - yp_token_t string_closing = not_provided(parser); - yp_node_t *part = (yp_node_t *) yp_string_node_create_and_unescape(parser, &string_opening, &parser->previous, &string_closing, YP_UNESCAPE_ALL); - yp_node_list_append(&parts, part); - - while (!match_any_type_p(parser, 3, YP_TOKEN_STRING_END, YP_TOKEN_LABEL_END, YP_TOKEN_EOF)) { - yp_node_t *part = parse_string_part(parser); - if (part != NULL) yp_node_list_append(&parts, part); - } - - if (accept(parser, YP_TOKEN_LABEL_END)) { - node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); - } else { - expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM); - node = (yp_node_t *) yp_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. - yp_node_list_t parts = YP_EMPTY_NODE_LIST; - - while (!match_any_type_p(parser, 3, YP_TOKEN_STRING_END, YP_TOKEN_LABEL_END, YP_TOKEN_EOF)) { - yp_node_t *part = parse_string_part(parser); - if (part != NULL) yp_node_list_append(&parts, part); - } - - if (accept(parser, YP_TOKEN_LABEL_END)) { - node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); - } else { - expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM); - node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); - } - } - - if (result == 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 (YP_NODE_TYPE_P(node, YP_SYMBOL_NODE) || YP_NODE_TYPE_P(node, YP_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. - result = 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 (!YP_NODE_TYPE_P(node, YP_STRING_NODE) && !YP_NODE_TYPE_P(node, YP_INTERPOLATED_STRING_NODE)) { - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_STRING_CONCATENATION); - } - - // Either way we will create a concat node to hold the - // strings together. - result = (yp_node_t *) yp_string_concat_node_create(parser, result, node); - } - } - - return result; - } - case YP_TOKEN_SYMBOL_BEGIN: { - yp_lex_mode_t lex_mode = *parser->lex_modes.current; - parser_lex(parser); - - return parse_symbol(parser, &lex_mode, YP_LEX_STATE_END); - } - default: - if (context_recoverable(parser, &parser->current)) { - parser->recovering = true; - } - - return (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end); - } -} - -static inline yp_node_t * -parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { - yp_node_t *value = parse_starred_expression(parser, binding_power, diag_id); - - if (previous_binding_power == YP_BINDING_POWER_STATEMENT && (YP_NODE_TYPE_P(value, YP_SPLAT_NODE) || match_type_p(parser, YP_TOKEN_COMMA))) { - yp_token_t opening = not_provided(parser); - yp_array_node_t *array = yp_array_node_create(parser, &opening); - - yp_array_node_elements_append(array, value); - value = (yp_node_t *) array; - - while (accept(parser, YP_TOKEN_COMMA)) { - yp_node_t *element = parse_starred_expression(parser, binding_power, YP_ERR_ARRAY_ELEMENT); - yp_array_node_elements_append(array, element); - if (YP_NODE_TYPE_P(element, YP_MISSING_NODE)) break; - } - } - - return value; -} - -static inline yp_node_t * -parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power) { - yp_token_t token = parser->current; - - switch (token.type) { - case YP_TOKEN_EQUAL: { - switch (YP_NODE_TYPE(node)) { - case YP_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. - yp_call_node_t *call_node = (yp_call_node_t *) node; - if (yp_call_node_variable_call_p(call_node)) { - yp_parser_local_add_location(parser, call_node->message_loc.start, call_node->message_loc.end); - } - } - /* fallthrough */ - case YP_CASE_WRITABLE: { - parser_lex(parser); - yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); - return parse_write(parser, node, &token, value); - } - case YP_SPLAT_NODE: { - yp_splat_node_t *splat_node = (yp_splat_node_t *) node; - - switch (YP_NODE_TYPE(splat_node->expression)) { - case YP_CASE_WRITABLE: - parser_lex(parser); - yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); - return parse_write(parser, (yp_node_t *) splat_node, &token, value); - default: - break; - } - } - /* fallthrough */ - 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. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); - return node; - } - } - case YP_TOKEN_AMPERSAND_AMPERSAND_EQUAL: { - switch (YP_NODE_TYPE(node)) { - case YP_BACK_REFERENCE_READ_NODE: - case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); - /* fallthrough */ - case YP_GLOBAL_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_global_variable_and_write_node_create(parser, node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CLASS_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_class_variable_and_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CONSTANT_PATH_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - return (yp_node_t *) yp_constant_path_and_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); - } - case YP_CONSTANT_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_constant_and_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_INSTANCE_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_instance_variable_and_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth); - - yp_node_destroy(parser, node); - return result; - } - case YP_CALL_NODE: { - yp_call_node_t *call_node = (yp_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 (yp_call_node_variable_call_p(call_node)) { - yp_location_t message_loc = call_node->message_loc; - yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); - - if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); - } - - parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, constant_id, 0); - - yp_node_destroy(parser, node); - return result; - } - - parser_lex(parser); - node = parse_target(parser, node); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - return (yp_node_t *) yp_call_and_write_node_create(parser, (yp_call_node_t *) node, &token, value); - } - case YP_MULTI_WRITE_NODE: { - parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_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. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); - return node; - } - } - case YP_TOKEN_PIPE_PIPE_EQUAL: { - switch (YP_NODE_TYPE(node)) { - case YP_BACK_REFERENCE_READ_NODE: - case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); - /* fallthrough */ - case YP_GLOBAL_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_global_variable_or_write_node_create(parser, node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CLASS_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_class_variable_or_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CONSTANT_PATH_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - return (yp_node_t *) yp_constant_path_or_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); - } - case YP_CONSTANT_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_constant_or_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_INSTANCE_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_instance_variable_or_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth); - - yp_node_destroy(parser, node); - return result; - } - case YP_CALL_NODE: { - yp_call_node_t *call_node = (yp_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 (yp_call_node_variable_call_p(call_node)) { - yp_location_t message_loc = call_node->message_loc; - yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); - - if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); - } - - parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, constant_id, 0); - - yp_node_destroy(parser, node); - return result; - } - - parser_lex(parser); - node = parse_target(parser, node); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - return (yp_node_t *) yp_call_or_write_node_create(parser, (yp_call_node_t *) node, &token, value); - } - case YP_MULTI_WRITE_NODE: { - parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_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. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); - return node; - } - } - case YP_TOKEN_AMPERSAND_EQUAL: - case YP_TOKEN_CARET_EQUAL: - case YP_TOKEN_GREATER_GREATER_EQUAL: - case YP_TOKEN_LESS_LESS_EQUAL: - case YP_TOKEN_MINUS_EQUAL: - case YP_TOKEN_PERCENT_EQUAL: - case YP_TOKEN_PIPE_EQUAL: - case YP_TOKEN_PLUS_EQUAL: - case YP_TOKEN_SLASH_EQUAL: - case YP_TOKEN_STAR_EQUAL: - case YP_TOKEN_STAR_STAR_EQUAL: { - switch (YP_NODE_TYPE(node)) { - case YP_BACK_REFERENCE_READ_NODE: - case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); - /* fallthrough */ - case YP_GLOBAL_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_global_variable_operator_write_node_create(parser, node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CLASS_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_class_variable_operator_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_CONSTANT_PATH_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_constant_path_operator_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); - } - case YP_CONSTANT_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_constant_operator_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_INSTANCE_VARIABLE_READ_NODE: { - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); - - yp_node_destroy(parser, node); - return result; - } - case YP_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth); - - yp_node_destroy(parser, node); - return result; - } - case YP_CALL_NODE: { - yp_call_node_t *call_node = (yp_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 (yp_call_node_variable_call_p(call_node)) { - yp_location_t message_loc = call_node->message_loc; - yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); - - if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); - } - - parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, constant_id, 0); - - yp_node_destroy(parser, node); - return result; - } - - node = parse_target(parser, node); - parser_lex(parser); - - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value); - } - case YP_MULTI_WRITE_NODE: { - parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_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. - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return node; - } - } - case YP_TOKEN_AMPERSAND_AMPERSAND: - case YP_TOKEN_KEYWORD_AND: { - parser_lex(parser); - - yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_and_node_create(parser, node, &token, right); - } - case YP_TOKEN_KEYWORD_OR: - case YP_TOKEN_PIPE_PIPE: { - parser_lex(parser); - - yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_or_node_create(parser, node, &token, right); - } - case YP_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, - // - // /(?bar)/ =~ foo - // - // In this case, `foo` should be a method call and not a local yet. - parser_lex(parser); - yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - - // 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 (YP_NODE_TYPE_P(node, YP_REGULAR_EXPRESSION_NODE)) { - yp_string_list_t named_captures; - yp_string_list_init(&named_captures); - - const yp_location_t *content_loc = &((yp_regular_expression_node_t *) node)->content_loc; - - if (yp_regexp_named_capture_group_names(content_loc->start, (size_t) (content_loc->end - content_loc->start), &named_captures, parser->encoding_changed, &parser->encoding)) { - for (size_t index = 0; index < named_captures.length; index++) { - yp_string_t *name = &named_captures.strings[index]; - assert(name->type == YP_STRING_SHARED); - - yp_parser_local_add_location(parser, name->source, name->source + name->length); - } - } - - yp_string_list_free(&named_captures); - } - - return (yp_node_t *) yp_call_node_binary_create(parser, node, &token, argument); - } - case YP_TOKEN_UAMPERSAND: - case YP_TOKEN_USTAR: - case YP_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 YP_TOKEN_BANG_EQUAL: - case YP_TOKEN_BANG_TILDE: - case YP_TOKEN_EQUAL_EQUAL: - case YP_TOKEN_EQUAL_EQUAL_EQUAL: - case YP_TOKEN_LESS_EQUAL_GREATER: - case YP_TOKEN_GREATER: - case YP_TOKEN_GREATER_EQUAL: - case YP_TOKEN_LESS: - case YP_TOKEN_LESS_EQUAL: - case YP_TOKEN_CARET: - case YP_TOKEN_PIPE: - case YP_TOKEN_AMPERSAND: - case YP_TOKEN_GREATER_GREATER: - case YP_TOKEN_LESS_LESS: - case YP_TOKEN_MINUS: - case YP_TOKEN_PLUS: - case YP_TOKEN_PERCENT: - case YP_TOKEN_SLASH: - case YP_TOKEN_STAR: - case YP_TOKEN_STAR_STAR: { - parser_lex(parser); - - yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - return (yp_node_t *) yp_call_node_binary_create(parser, node, &token, argument); - } - case YP_TOKEN_AMPERSAND_DOT: - case YP_TOKEN_DOT: { - parser_lex(parser); - yp_token_t operator = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - - // This if statement handles the foo.() syntax. - if (match_type_p(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - parse_arguments_list(parser, &arguments, true); - return (yp_node_t *) yp_call_node_shorthand_create(parser, node, &operator, &arguments); - } - - yp_token_t message; - - switch (parser->current.type) { - case YP_CASE_OPERATOR: - case YP_CASE_KEYWORD: - case YP_TOKEN_CONSTANT: - case YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - message = parser->previous; - break; - } - default: { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_DEF_NAME); - message = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; - } - } - - parse_arguments_list(parser, &arguments, true); - yp_call_node_t *call = yp_call_node_call_create(parser, node, &operator, &message, &arguments); - - if ( - (previous_binding_power == YP_BINDING_POWER_STATEMENT) && - arguments.arguments == NULL && - arguments.opening_loc.start == NULL && - match_type_p(parser, YP_TOKEN_COMMA) - ) { - return parse_targets(parser, (yp_node_t *) call, YP_BINDING_POWER_INDEX); - } else { - return (yp_node_t *) call; - } - } - case YP_TOKEN_DOT_DOT: - case YP_TOKEN_DOT_DOT_DOT: { - parser_lex(parser); - - yp_node_t *right = NULL; - if (token_begins_expression_p(parser->current.type)) { - right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); - } - - return (yp_node_t *) yp_range_node_create(parser, node, &token, right); - } - case YP_TOKEN_KEYWORD_IF_MODIFIER: { - yp_token_t keyword = parser->current; - parser_lex(parser); - - yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_IF_PREDICATE); - return (yp_node_t *) yp_if_node_modifier_create(parser, node, &keyword, predicate); - } - case YP_TOKEN_KEYWORD_UNLESS_MODIFIER: { - yp_token_t keyword = parser->current; - parser_lex(parser); - - yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNLESS_PREDICATE); - return (yp_node_t *) yp_unless_node_modifier_create(parser, node, &keyword, predicate); - } - case YP_TOKEN_KEYWORD_UNTIL_MODIFIER: { - parser_lex(parser); - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, node); - - yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNTIL_PREDICATE); - return (yp_node_t *) yp_until_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0); - } - case YP_TOKEN_KEYWORD_WHILE_MODIFIER: { - parser_lex(parser); - yp_statements_node_t *statements = yp_statements_node_create(parser); - yp_statements_node_body_append(statements, node); - - yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_WHILE_PREDICATE); - return (yp_node_t *) yp_while_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0); - } - case YP_TOKEN_QUESTION_MARK: { - parser_lex(parser); - yp_node_t *true_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_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. - yp_token_t colon = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; - yp_node_t *false_expression = (yp_node_t *) yp_missing_node_create(parser, colon.start, colon.end); - - return (yp_node_t *) yp_if_node_ternary_create(parser, node, true_expression, &colon, false_expression); - } - - accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_COLON, YP_ERR_TERNARY_COLON); - - yp_token_t colon = parser->previous; - yp_node_t *false_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_TERNARY_EXPRESSION_FALSE); - - return (yp_node_t *) yp_if_node_ternary_create(parser, node, true_expression, &colon, false_expression); - } - case YP_TOKEN_COLON_COLON: { - parser_lex(parser); - yp_token_t delimiter = parser->previous; - - switch (parser->current.type) { - case YP_TOKEN_CONSTANT: { - parser_lex(parser); - yp_node_t *path; - - if ( - (parser->current.type == YP_TOKEN_PARENTHESIS_LEFT) || - (token_begins_expression_p(parser->current.type) || match_any_type_p(parser, 3, YP_TOKEN_UAMPERSAND, YP_TOKEN_USTAR, YP_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(). - yp_token_t message = parser->previous; - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - - parse_arguments_list(parser, &arguments, true); - path = (yp_node_t *) yp_call_node_call_create(parser, node, &delimiter, &message, &arguments); - } else { - // Otherwise, this is a constant path. That would look like Foo::Bar. - yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); - path = (yp_node_t *)yp_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 == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - return parse_targets(parser, path, YP_BINDING_POWER_INDEX); - } - - return path; - } - case YP_CASE_OPERATOR: - case YP_CASE_KEYWORD: - case YP_TOKEN_IDENTIFIER: { - parser_lex(parser); - yp_token_t message = parser->previous; - - // If we have an identifier following a '::' operator, then it is for - // sure a method call. - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, true); - yp_call_node_t *call = yp_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 == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - return parse_targets(parser, (yp_node_t *) call, YP_BINDING_POWER_INDEX); - } - - return (yp_node_t *) call; - } - case YP_TOKEN_PARENTHESIS_LEFT: { - // If we have a parenthesis following a '::' operator, then it is the - // method call shorthand. That would look like Foo::(bar). - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - parse_arguments_list(parser, &arguments, true); - - return (yp_node_t *) yp_call_node_shorthand_create(parser, node, &delimiter, &arguments); - } - default: { - yp_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); - yp_node_t *child = (yp_node_t *) yp_missing_node_create(parser, delimiter.start, delimiter.end); - return (yp_node_t *)yp_constant_path_node_create(parser, node, &delimiter, child); - } - } - } - case YP_TOKEN_KEYWORD_RESCUE_MODIFIER: { - parser_lex(parser); - accept(parser, YP_TOKEN_NEWLINE); - yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE); - - return (yp_node_t *) yp_rescue_modifier_node_create(parser, node, &token, value); - } - case YP_TOKEN_BRACKET_LEFT: { - parser_lex(parser); - - yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - arguments.opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - - if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { - yp_accepts_block_stack_push(parser, true); - arguments.arguments = yp_arguments_node_create(parser); - - parse_arguments(parser, &arguments, false, YP_TOKEN_BRACKET_RIGHT); - yp_accepts_block_stack_pop(parser); - - expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_EXPECT_RBRACKET); - } - - arguments.closing_loc = YP_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 == YP_BINDING_POWER_STATEMENT && match_type_p(parser, YP_TOKEN_COMMA)) { - yp_call_node_t *aref = yp_call_node_aref_create(parser, node, &arguments); - return parse_targets(parser, (yp_node_t *) aref, YP_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. - if (accept(parser, YP_TOKEN_BRACE_LEFT)) { - arguments.block = parse_block(parser); - } else if (yp_accepts_block_stack_p(parser) && accept(parser, YP_TOKEN_KEYWORD_DO)) { - arguments.block = parse_block(parser); - } - - yp_arguments_validate(parser, &arguments); - return (yp_node_t *) yp_call_node_aref_create(parser, node, &arguments); - } - case YP_TOKEN_KEYWORD_IN: { - bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; - parser->pattern_matching_newlines = true; - - yp_token_t operator = parser->current; - parser->command_start = false; - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - - parser_lex(parser); - - yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_IN); - parser->pattern_matching_newlines = previous_pattern_matching_newlines; - - return (yp_node_t *) yp_match_predicate_node_create(parser, node, pattern, &operator); - } - case YP_TOKEN_EQUAL_GREATER: { - bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; - parser->pattern_matching_newlines = true; - - yp_token_t operator = parser->current; - parser->command_start = false; - lex_state_set(parser, YP_LEX_STATE_BEG | YP_LEX_STATE_LABEL); - - parser_lex(parser); - - yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET); - parser->pattern_matching_newlines = previous_pattern_matching_newlines; - - return (yp_node_t *) yp_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 yp_node_t * -parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { - yp_token_t recovery = parser->previous; - yp_node_t *node = parse_expression_prefix(parser, binding_power); - - // 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. - if (YP_NODE_TYPE_P(node, YP_MISSING_NODE)) { - yp_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, diag_id); - return node; - } - - // 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. - yp_binding_powers_t current_binding_powers; - while ( - current_binding_powers = yp_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); - } - - return node; -} - -static yp_node_t * -parse_program(yp_parser_t *parser) { - yp_parser_scope_push(parser, !parser->current_scope); - parser_lex(parser); - - yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_MAIN); - if (!statements) { - statements = yp_statements_node_create(parser); - } - yp_constant_id_list_t locals = parser->current_scope->locals; - yp_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 (yp_statements_node_body_length(statements) == 0) { - yp_statements_node_location_set(statements, parser->start, parser->start); - } - - return (yp_node_t *) yp_program_node_create(parser, &locals, statements); -} - -// Read a 32-bit unsigned integer from a pointer. This function is used to read -// the metadata that is passed into the parser from the Ruby implementation. It -// handles aligned and unaligned reads. -static uint32_t -yp_metadata_read_u32(const char *ptr) { - if (((uintptr_t) ptr) % sizeof(uint32_t) == 0) { - return *((uint32_t *) ptr); - } else { - uint32_t value; - memcpy(&value, ptr, sizeof(uint32_t)); - return value; - } -} - -// Process any additional metadata being passed into a call to the parser via -// the yp_parse_serialize function. Since the source of these calls will be from -// Ruby implementation internals we assume it is from a trusted source. -// -// Currently, this is only passing in variable scoping surrounding an eval, but -// eventually it will be extended to hold any additional metadata. This data -// is serialized to reduce the calling complexity for a foreign function call -// vs a foreign runtime making a bindable in-memory version of a C structure. -// -// metadata is assumed to be a valid pointer pointing to well-formed data. The -// format is described below: -// -// ```text -// [ -// filepath_size: uint32_t, -// filepath: char*, -// scopes_count: uint32_t, -// [ -// locals_count: uint32_t, -// [local_size: uint32_t, local: char*]* -// ]* -// ] -// ``` -void -yp_parser_metadata(yp_parser_t *parser, const char *metadata) { - uint32_t filepath_size = yp_metadata_read_u32(metadata); - metadata += 4; - - if (filepath_size) { - yp_string_t filepath_string; - yp_string_constant_init(&filepath_string, metadata, filepath_size); - - parser->filepath_string = filepath_string; - metadata += filepath_size; - } - - uint32_t scopes_count = yp_metadata_read_u32(metadata); - metadata += 4; - - for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) { - uint32_t locals_count = yp_metadata_read_u32(metadata); - metadata += 4; - - yp_parser_scope_push(parser, scope_index == 0); - - for (size_t local_index = 0; local_index < locals_count; local_index++) { - uint32_t local_size = yp_metadata_read_u32(metadata); - metadata += 4; - - uint8_t *constant = malloc(local_size); - memcpy(constant, metadata, local_size); - - yp_parser_local_add_owned(parser, constant, (size_t) local_size); - metadata += local_size; - } - } -} - -/******************************************************************************/ -/* External functions */ -/******************************************************************************/ - -// Initialize a parser with the given start and end pointers. -YP_EXPORTED_FUNCTION void -yp_parser_init(yp_parser_t *parser, const uint8_t *source, size_t size, const char *filepath) { - assert(source != NULL); - - // Set filepath to the file that was passed - if (!filepath) filepath = ""; - yp_string_t filepath_string; - yp_string_constant_init(&filepath_string, filepath, strlen(filepath)); - - *parser = (yp_parser_t) { - .lex_state = YP_LEX_STATE_BEG, - .command_start = true, - .enclosure_nesting = 0, - .lambda_enclosure_nesting = -1, - .brace_nesting = 0, - .do_loop_stack = YP_STATE_STACK_EMPTY, - .accepts_block_stack = YP_STATE_STACK_EMPTY, - .lex_modes = { - .index = 0, - .stack = {{ .mode = YP_LEX_DEFAULT }}, - .current = &parser->lex_modes.stack[0], - }, - .start = source, - .end = source + size, - .previous = { .type = YP_TOKEN_EOF, .start = source, .end = source }, - .current = { .type = YP_TOKEN_EOF, .start = source, .end = source }, - .next_start = NULL, - .heredoc_end = NULL, - .comment_list = YP_LIST_EMPTY, - .warning_list = YP_LIST_EMPTY, - .error_list = YP_LIST_EMPTY, - .current_scope = NULL, - .current_context = NULL, - .recovering = false, - .encoding = yp_encoding_utf_8, - .encoding_changed = false, - .encoding_changed_callback = NULL, - .encoding_decode_callback = NULL, - .encoding_comment_start = source, - .lex_callback = NULL, - .pattern_matching_newlines = false, - .in_keyword_arg = false, - .filepath_string = filepath_string, - .constant_pool = YP_CONSTANT_POOL_EMPTY, - .newline_list = YP_NEWLINE_LIST_EMPTY - }; - - yp_accepts_block_stack_push(parser, true); - - // 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. - size_t constant_size = size / 95; - yp_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; - yp_newline_list_init(&parser->newline_list, source, newline_size < 4 ? 4 : newline_size); - - // 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 YARP changes the encoding it -// is using to parse based on the magic comment. -YP_EXPORTED_FUNCTION void -yp_parser_register_encoding_changed_callback(yp_parser_t *parser, yp_encoding_changed_callback_t callback) { - parser->encoding_changed_callback = callback; -} - -// Register a callback that will be called when YARP encounters a magic comment -// with an encoding referenced that it doesn't understand. The callback should -// return NULL if it also doesn't understand the encoding or it should return a -// pointer to a yp_encoding_t struct that contains the functions necessary to -// parse identifiers. -YP_EXPORTED_FUNCTION void -yp_parser_register_encoding_decode_callback(yp_parser_t *parser, yp_encoding_decode_callback_t callback) { - parser->encoding_decode_callback = callback; -} - -// Free all of the memory associated with the comment list. -static inline void -yp_comment_list_free(yp_list_t *list) { - yp_list_node_t *node, *next; - - for (node = list->head; node != NULL; node = next) { - next = node->next; - - yp_comment_t *comment = (yp_comment_t *) node; - free(comment); - } -} - -// Free any memory associated with the given parser. -YP_EXPORTED_FUNCTION void -yp_parser_free(yp_parser_t *parser) { - yp_string_free(&parser->filepath_string); - yp_diagnostic_list_free(&parser->error_list); - yp_diagnostic_list_free(&parser->warning_list); - yp_comment_list_free(&parser->comment_list); - yp_constant_pool_free(&parser->constant_pool); - yp_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. - yp_constant_id_list_free(&parser->current_scope->locals); - yp_parser_scope_pop(parser); - } - - while (parser->lex_modes.index >= YP_LEX_STACK_SIZE) { - lex_mode_pop(parser); - } -} - -// Parse the Ruby source associated with the given parser and return the tree. -YP_EXPORTED_FUNCTION yp_node_t * -yp_parse(yp_parser_t *parser) { - return parse_program(parser); -} - -YP_EXPORTED_FUNCTION void -yp_serialize(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) { - yp_buffer_append_str(buffer, "YARP", 4); - yp_buffer_append_u8(buffer, YP_VERSION_MAJOR); - yp_buffer_append_u8(buffer, YP_VERSION_MINOR); - yp_buffer_append_u8(buffer, YP_VERSION_PATCH); - - yp_serialize_content(parser, node, buffer); - yp_buffer_append_str(buffer, "\0", 1); -} - -// Parse and serialize the AST represented by the given source to the given -// buffer. -YP_EXPORTED_FUNCTION void -yp_parse_serialize(const uint8_t *source, size_t size, yp_buffer_t *buffer, const char *metadata) { - yp_parser_t parser; - yp_parser_init(&parser, source, size, NULL); - if (metadata) yp_parser_metadata(&parser, metadata); - - yp_node_t *node = yp_parse(&parser); - yp_serialize(&parser, node, buffer); - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); -} - -#undef YP_LOCATION_NULL_VALUE -#undef YP_LOCATION_TOKEN_VALUE -#undef YP_LOCATION_NODE_VALUE -#undef YP_LOCATION_NODE_BASE_VALUE -#undef YP_CASE_KEYWORD -#undef YP_CASE_OPERATOR -#undef YP_CASE_WRITABLE diff --git a/yarp/yarp.h b/yarp/yarp.h deleted file mode 100644 index 378efe0c93746d..00000000000000 --- a/yarp/yarp.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef YARP_H -#define YARP_H - -#include "yarp/defines.h" -#include "yarp/ast.h" -#include "yarp/diagnostic.h" -#include "yarp/node.h" -#include "yarp/pack.h" -#include "yarp/parser.h" -#include "yarp/regexp.h" -#include "yarp/unescape.h" -#include "yarp/util/yp_buffer.h" -#include "yarp/util/yp_char.h" -#include "yarp/util/yp_memchr.h" -#include "yarp/util/yp_strpbrk.h" -#include "yarp/version.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#endif - -void yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer); - -void yp_print_node(yp_parser_t *parser, yp_node_t *node); - -void yp_parser_metadata(yp_parser_t *parser, const char *metadata); - -// Generate a scope node from the given node. -void yp_scope_node_init(yp_node_t *node, yp_scope_node_t *dest); - -// The YARP version and the serialization format. -YP_EXPORTED_FUNCTION const char * yp_version(void); - -// Initialize a parser with the given start and end pointers. -YP_EXPORTED_FUNCTION void yp_parser_init(yp_parser_t *parser, const uint8_t *source, size_t size, const char *filepath); - -// Register a callback that will be called whenever YARP changes the encoding it -// is using to parse based on the magic comment. -YP_EXPORTED_FUNCTION void yp_parser_register_encoding_changed_callback(yp_parser_t *parser, yp_encoding_changed_callback_t callback); - -// Register a callback that will be called when YARP encounters a magic comment -// with an encoding referenced that it doesn't understand. The callback should -// return NULL if it also doesn't understand the encoding or it should return a -// pointer to a yp_encoding_t struct that contains the functions necessary to -// parse identifiers. -YP_EXPORTED_FUNCTION void yp_parser_register_encoding_decode_callback(yp_parser_t *parser, yp_encoding_decode_callback_t callback); - -// Free any memory associated with the given parser. -YP_EXPORTED_FUNCTION void yp_parser_free(yp_parser_t *parser); - -// Parse the Ruby source associated with the given parser and return the tree. -YP_EXPORTED_FUNCTION yp_node_t * yp_parse(yp_parser_t *parser); - -// Pretty-prints the AST represented by the given node to the given buffer. -YP_EXPORTED_FUNCTION void yp_prettyprint(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer); - -// Serialize the AST represented by the given node to the given buffer. -YP_EXPORTED_FUNCTION void yp_serialize(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer); - -// Parse the given source to the AST and serialize the AST to the given buffer. -YP_EXPORTED_FUNCTION void yp_parse_serialize(const uint8_t *source, size_t size, yp_buffer_t *buffer, const char *metadata); - -// Lex the given source and serialize to the given buffer. -YP_EXPORTED_FUNCTION void yp_lex_serialize(const uint8_t *source, size_t size, const char *filepath, yp_buffer_t *buffer); - -// Parse and serialize both the AST and the tokens represented by the given -// source to the given buffer. -YP_EXPORTED_FUNCTION void yp_parse_lex_serialize(const uint8_t *source, size_t size, yp_buffer_t *buffer, const char *metadata); - -// Returns a string representation of the given token type. -YP_EXPORTED_FUNCTION const char * yp_token_type_to_str(yp_token_type_t token_type); - -#endif diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c deleted file mode 100644 index 802c85d808ec82..00000000000000 --- a/yarp/yarp_compiler.c +++ /dev/null @@ -1,2092 +0,0 @@ -#include "yarp.h" - -#define OLD_ISEQ NEW_ISEQ -#undef NEW_ISEQ - -#define NEW_ISEQ(node, name, type, line_no) \ - yp_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) \ - yp_new_child_iseq(iseq, (node), parser, rb_fstring(name), iseq, (type), (line_no)) - -#define YP_COMPILE(node) \ - yp_compile_node(iseq, (node), ret, src, popped, compile_context) - -#define YP_COMPILE_POPPED(node) \ - yp_compile_node(iseq, (node), ret, src, true, compile_context) - -#define YP_COMPILE_NOT_POPPED(node) \ - yp_compile_node(iseq, (node), ret, src, false, compile_context) - -rb_iseq_t * -yp_iseq_new_with_opt(yp_scope_node_t *node, yp_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 yp_node_t *node) -{ - const char *start = (const char *)node->location.start; - const char *end = (const char *)node->location.end; - size_t length = end - start; - VALUE number = rb_int_parse_cstr(start, length, NULL, NULL, -10, RB_INT_PARSE_DEFAULT); - - return number; -} - -static VALUE -parse_float(const yp_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 yp_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 (YP_NODE_TYPE_P(((yp_rational_node_t *)node)->numeric, YP_NODE_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(YP_NODE_TYPE_P(((yp_rational_node_t *)node)->numeric, YP_NODE_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(yp_imaginary_node_t *node) -{ - VALUE imaginary_part; - switch (YP_NODE_TYPE(node->numeric)) { - case YP_NODE_FLOAT_NODE: { - imaginary_part = parse_float(node->numeric); - break; - } - case YP_NODE_INTEGER_NODE: { - imaginary_part = parse_integer(node->numeric); - break; - } - case YP_NODE_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(yp_string_t *string) -{ - return rb_str_new((const char *) yp_string_source(string), yp_string_length(string)); -} - -static inline ID -parse_symbol(const uint8_t *start, const uint8_t *end) -{ - return rb_intern2((const char *) start, end - start); -} - -static inline ID -parse_node_symbol(yp_node_t *node) { - return parse_symbol(node->location.start, node->location.end); -} - -static inline ID -parse_string_symbol(yp_string_t *string) { - const uint8_t *start = yp_string_source(string); - return parse_symbol(start, start + yp_string_length(string)); -} - -static inline ID -parse_location_symbol(yp_location_t *location) { - return parse_symbol(location->start, location->end); -} - -static int -yp_optimizable_range_item_p(yp_node_t *node) -{ - return (!node || node->type == YP_NODE_INTEGER_NODE || node->type == YP_NODE_NIL_NODE); -} - -static bool -yp_static_node_literal_p(yp_node_t *node) -{ - switch(node->type) { - case YP_NODE_FALSE_NODE: - case YP_NODE_FLOAT_NODE: - case YP_NODE_IMAGINARY_NODE: - case YP_NODE_INTEGER_NODE: - case YP_NODE_NIL_NODE: - case YP_NODE_RATIONAL_NODE: - case YP_NODE_SELF_NODE: - case YP_NODE_STRING_NODE: - case YP_NODE_SOURCE_ENCODING_NODE: - case YP_NODE_SOURCE_FILE_NODE: - case YP_NODE_SOURCE_LINE_NODE: - case YP_NODE_SYMBOL_NODE: - case YP_NODE_TRUE_NODE: - return true; - default: - return false; - } -} - -static inline VALUE -yp_static_literal_value(yp_node_t *node) -{ - switch(node->type) { - case YP_NODE_NIL_NODE: - return Qnil; - case YP_NODE_TRUE_NODE: - return Qtrue; - case YP_NODE_FALSE_NODE: - return Qfalse; - // TODO: Implement this method for the other literal nodes described above - default: - rb_raise(rb_eArgError, "Don't have a literal value for this type"); - return Qfalse; - } -} - -static void -yp_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const yp_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, yp_compile_context_t *compile_context); - -static void -yp_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, yp_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) -{ - yp_parser_t *parser = compile_context->parser; - yp_newline_list_t newline_list = parser->newline_list; - int lineno = (int)yp_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; - - yp_compile_branch_condition(iseq, seq, cond, then_label, else_label, src, popped, compile_context); - - 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) { - ADD_INSN(seq, &dummy_line_node, putnil); - } - else { - ADD_LABEL(seq, label); - } - ADD_SEQ(ret, seq); - return; -} - -static void yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *context); - -static void -yp_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const yp_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) -{ - yp_parser_t *parser = compile_context->parser; - yp_newline_list_t newline_list = parser->newline_list; - int lineno = (int) yp_newline_list_line_column(&newline_list, cond->location.start).line; - NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); - -again: - switch (YP_NODE_TYPE(cond)) { - case YP_NODE_AND_NODE: { - yp_and_node_t *and_node = (yp_and_node_t *)cond; - yp_compile_logical(iseq, ret, and_node->left, NULL, else_label, src, popped, compile_context); - cond = and_node->right; - goto again; - } - case YP_NODE_OR_NODE: { - yp_or_node_t *or_node = (yp_or_node_t *)cond; - yp_compile_logical(iseq, ret, or_node->left, then_label, NULL, src, popped, compile_context); - cond = or_node->right; - goto again; - } - case YP_NODE_FALSE_NODE: - case YP_NODE_NIL_NODE: - ADD_INSNL(ret, &dummy_line_node, jump, else_label); - return; - case YP_NODE_FLOAT_NODE: - case YP_NODE_IMAGINARY_NODE: - case YP_NODE_INTEGER_NODE: - case YP_NODE_LAMBDA_NODE: - case YP_NODE_RATIONAL_NODE: - case YP_NODE_REGULAR_EXPRESSION_NODE: - case YP_NODE_STRING_NODE: - case YP_NODE_SYMBOL_NODE: - case YP_NODE_TRUE_NODE: - ADD_INSNL(ret, &dummy_line_node, jump, then_label); - return; - // TODO: Several more nodes in this case statement - default: - { - DECL_ANCHOR(cond_seq); - INIT_ANCHOR(cond_seq); - - yp_compile_node(iseq, cond, cond_seq, src, false, compile_context); - 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 -yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body, yp_node_t *node_else, yp_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) { - NODE 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; - - yp_compile_branch_condition(iseq, cond_seq, predicate, then_label, else_label, src, popped, compile_context); - 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) { - yp_compile_node(iseq, (yp_node_t *)node_body, then_seq, src, popped, compile_context); - } - else { - if (!popped) { - ADD_INSN(ret, &line_node, putnil); - } - } - - if (else_label->refcnt) { - end_label = NEW_LABEL(line); - ADD_INSNL(then_seq, &line_node, jump, end_label); - if (!popped) { - ADD_INSN(then_seq, &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) { - yp_compile_node(iseq, (yp_node_t *)(((yp_else_node_t *)node_else)->statements), else_seq, src, popped, compile_context); - } - else { - if (!popped) { - ADD_INSN(ret, &line_node, putnil); - } - } - - ADD_SEQ(ret, else_seq); - } - - if (end_label) { - ADD_LABEL(ret, end_label); - } - - if (popped) { - ADD_INSN(ret, &line_node, pop); - } - return; -} - -static void -yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_node_type type, yp_statements_node_t *statements, yp_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) -{ - 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 & YP_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); - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_LABEL(ret, next_catch_label); - ADD_INSN(ret, &dummy_line_node, 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) { - YP_COMPILE_POPPED((yp_node_t *)statements); - } - - ADD_LABEL(ret, next_label); - - if (type == YP_NODE_WHILE_NODE) { - yp_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, compile_context); - } - else if (type == YP_NODE_UNTIL_NODE) { - yp_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, compile_context); - } - - ADD_LABEL(ret, end_label); - ADD_ADJUST_RESTORE(ret, adjust_label); - - ADD_INSN(ret, &dummy_line_node, putnil); - - ADD_LABEL(ret, break_label); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - 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 -yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) -{ - size_t parts_size = parts.size; - - if (parts_size > 0) { - for (size_t index = 0; index < parts_size; index++) { - yp_node_t *part = parts.nodes[index]; - - if (YP_NODE_TYPE_P(part, YP_NODE_STRING_NODE)) { - yp_string_node_t *string_node = (yp_string_node_t *) part; - ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->unescaped)); - } - else { - YP_COMPILE(part); - ADD_INSN(ret, &dummy_line_node, 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 { - ADD_INSN(ret, &dummy_line_node, putnil); - } -} -static int -yp_lookup_local_index(rb_iseq_t *iseq, yp_compile_context_t *compile_context, yp_constant_id_t constant_id) -{ - st_data_t local_index; - - int num_params = ISEQ_BODY(iseq)->param.size; - - if (!st_lookup(compile_context->index_lookup_table, constant_id, &local_index)) { - rb_bug("This local does not exist"); - } - - return num_params - (int)local_index; -} - -static int -yp_lookup_local_index_with_depth(rb_iseq_t *iseq, yp_compile_context_t *compile_context, yp_constant_id_t constant_id, uint32_t depth) -{ - for(uint32_t i = 0; i < depth; i++) { - compile_context = compile_context->previous; - iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq; - } - - return yp_lookup_local_index(iseq, compile_context, constant_id); -} - -// This returns the CRuby ID which maps to the yp_constant_id_t -// -// Constant_ids in YARP are indexes of the constants in YARP's constant pool. -// We add a constants mapping on the compile_context 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 -yp_constant_id_lookup(yp_compile_context_t *compile_context, yp_constant_id_t constant_id) -{ - return compile_context->constants[constant_id - 1]; -} - -static rb_iseq_t * -yp_new_child_iseq(rb_iseq_t *iseq, yp_scope_node_t * node, yp_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 = yp_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 -yp_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const yp_node_t *constant_path_node, const NODE *line_node, const uint8_t * src, bool popped, yp_compile_context_t *compile_context) -{ - if (constant_path_node->type == YP_NODE_CONSTANT_PATH_NODE) { - yp_node_t *parent = ((yp_constant_path_node_t *)constant_path_node)->parent; - if (parent) { - /* Bar::Foo */ - YP_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; - } -} - -/* - * Compiles a YARP node into instruction sequences - * - * iseq - The current instruction sequence object (used for locals) - * node - The yarp node to compile - * ret - The linked list of instruction sequences to append instructions onto - * popped - True if compiling something with no side effects, so instructions don't - * need to be added - * compile_context - Stores parser and local information - */ -static void -yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) -{ - yp_parser_t *parser = compile_context->parser; - yp_newline_list_t newline_list = parser->newline_list; - int lineno = (int)yp_newline_list_line_column(&newline_list, node->location.start).line; - NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); - - switch (YP_NODE_TYPE(node)) { - case YP_NODE_ALIAS_NODE: { - yp_alias_node_t *alias_node = (yp_alias_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)); - - YP_COMPILE(alias_node->new_name); - YP_COMPILE(alias_node->old_name); - - ADD_SEND(ret, &dummy_line_node, id_core_set_method_alias, INT2FIX(3)); - return; - } - case YP_NODE_AND_NODE: { - yp_and_node_t *and_node = (yp_and_node_t *) node; - - LABEL *end_label = NEW_LABEL(lineno); - YP_COMPILE(and_node->left); - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - YP_COMPILE(and_node->right); - ADD_LABEL(ret, end_label); - return; - } - case YP_NODE_ARGUMENTS_NODE: { - yp_arguments_node_t *arguments_node = (yp_arguments_node_t *) node; - yp_node_list_t node_list = arguments_node->arguments; - for (size_t index = 0; index < node_list.size; index++) { - YP_COMPILE(node_list.nodes[index]); - } - return; - } - case YP_NODE_ARRAY_NODE: { - yp_array_node_t *array_node = (yp_array_node_t *) node; - yp_node_list_t elements = array_node->elements; - if (elements.size == 1 && yp_static_node_literal_p(elements.nodes[0])) { - VALUE ary = rb_ary_hidden_new(1); - rb_ary_push(ary, yp_static_literal_value(elements.nodes[0])); - OBJ_FREEZE(ary); - - ADD_INSN1(ret, &dummy_line_node, duparray, ary); - } - else { - for (size_t index = 0; index < elements.size; index++) { - YP_COMPILE(elements.nodes[index]); - } - - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, newarray, INT2FIX(elements.size)); - } - } - - return; - } - case YP_NODE_ASSOC_NODE: { - yp_assoc_node_t *assoc_node = (yp_assoc_node_t *) node; - YP_COMPILE(assoc_node->key); - if (assoc_node->value) { - YP_COMPILE(assoc_node->value); - } - return; - } - case YP_NODE_ASSOC_SPLAT_NODE: { - yp_assoc_splat_node_t *assoc_splat_node = (yp_assoc_splat_node_t *)node; - YP_COMPILE(assoc_splat_node->value); - - // TODO: Not sure this is accurate, look at FLUSH_CHUNK in the compiler - ADD_INSN1(ret, &dummy_line_node, newarraykwsplat, INT2FIX(0)); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_BACK_REFERENCE_READ_NODE: { - if (!popped) { - // Since a back reference is `$`, 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 YP_NODE_BEGIN_NODE: { - yp_begin_node_t *begin_node = (yp_begin_node_t *) node; - if (begin_node->statements) { - YP_COMPILE((yp_node_t *)begin_node->statements); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - return; - } - case YP_NODE_BREAK_NODE: { - yp_break_node_t *break_node = (yp_break_node_t *) node; - if (break_node->arguments) { - YP_COMPILE_NOT_POPPED((yp_node_t *)break_node->arguments); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label); - - return; - } - case YP_NODE_CALL_NODE: { - yp_call_node_t *call_node = (yp_call_node_t *) node; - - ID method_id = parse_string_symbol(&call_node->name); - int flags = 0; - int orig_argc = 0; - - if (call_node->receiver == NULL) { - ADD_INSN(ret, &dummy_line_node, putself); - } else { - YP_COMPILE_NOT_POPPED(call_node->receiver); - } - - if (call_node->arguments == NULL) { - if (flags & VM_CALL_FCALL) { - flags |= VM_CALL_VCALL; - } - } else { - yp_arguments_node_t *arguments = call_node->arguments; - YP_COMPILE((yp_node_t *) arguments); - orig_argc = (int)arguments->arguments.size; - } - - VALUE block_iseq = Qnil; - if (call_node->block != NULL) { - // Scope associated with the block - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)call_node->block, &scope_node); - - const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(&scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); - ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq; - ADD_SEND_WITH_BLOCK(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq); - } - else { - if (block_iseq == Qnil && flags == 0) { - flags |= VM_CALL_ARGS_SIMPLE; - } - - if (call_node->receiver == NULL) { - flags |= VM_CALL_FCALL; - - if (block_iseq == Qnil && call_node->arguments == NULL) { - flags |= VM_CALL_VCALL; - } - } - - ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(orig_argc), INT2FIX(flags)); - } - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_CLASS_NODE: { - yp_class_node_t *class_node = (yp_class_node_t *)node; - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)class_node, &scope_node); - - ID class_id = yp_constant_id_lookup(compile_context, class_node->name); - - VALUE class_name = rb_str_freeze(rb_sprintf("", rb_id2str(class_id))); - - const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&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) | - yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, popped, compile_context); - - if (class_node->superclass) { - YP_COMPILE(class_node->superclass); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(class_id), class_iseq, INT2FIX(flags)); - RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_CLASS_VARIABLE_AND_WRITE_NODE: { - yp_class_variable_and_write_node_t *class_variable_and_write_node = (yp_class_variable_and_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - ID class_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(class_variable_and_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { - yp_class_variable_operator_write_node_t *class_variable_operator_write_node = (yp_class_variable_operator_write_node_t*) node; - - ID class_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - YP_COMPILE_NOT_POPPED(class_variable_operator_write_node->value); - ID method_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN2(ret, &dummy_line_node, setclassvariable, - class_variable_name_val, - get_cvar_ic_value(iseq, class_variable_name_id)); - - return; - } - case YP_NODE_CLASS_VARIABLE_OR_WRITE_NODE: { - yp_class_variable_or_write_node_t *class_variable_or_write_node = (yp_class_variable_or_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - ID class_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(class_variable_or_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_CLASS_VARIABLE_READ_NODE: { - if (!popped) { - yp_class_variable_read_node_t *class_variable_read_node = (yp_class_variable_read_node_t *) node; - ID cvar_name = yp_constant_id_lookup(compile_context, class_variable_read_node->name); - ADD_INSN2( - ret, - &dummy_line_node, - getclassvariable, - ID2SYM(cvar_name), - get_cvar_ic_value(iseq, cvar_name) - ); - } - return; - } - case YP_NODE_CLASS_VARIABLE_WRITE_NODE: { - yp_class_variable_write_node_t *write_node = (yp_class_variable_write_node_t *) node; - YP_COMPILE_NOT_POPPED(write_node->value); - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ID cvar_name = yp_constant_id_lookup(compile_context, write_node->name); - ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name)); - return; - } - case YP_NODE_CONSTANT_PATH_NODE: { - yp_constant_path_node_t *constant_path_node = (yp_constant_path_node_t*) node; - if (constant_path_node->parent) { - YP_COMPILE(constant_path_node->parent); - } - ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(parse_node_symbol((yp_node_t *)constant_path_node->child))); - return; - } - case YP_NODE_CONSTANT_PATH_WRITE_NODE: { - yp_constant_path_write_node_t *constant_path_write_node = (yp_constant_path_write_node_t*) node; - YP_COMPILE(constant_path_write_node->value); - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ID constant_var_name = parse_location_symbol(&constant_path_write_node->target->base.location); - - ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); - ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_var_name)); - return; - } - - case YP_NODE_CONSTANT_READ_NODE: { - yp_constant_read_node_t *constant_read_node = (yp_constant_read_node_t *) node; - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(parse_node_symbol((yp_node_t *)constant_read_node))); - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_CONSTANT_AND_WRITE_NODE: { - yp_constant_and_write_node_t *constant_and_write_node = (yp_constant_and_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - VALUE constant_name = ID2SYM(parse_location_symbol(&constant_and_write_node->name_loc)); - - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name); - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(constant_and_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_CONSTANT_OPERATOR_WRITE_NODE: { - yp_constant_operator_write_node_t *constant_operator_write_node = (yp_constant_operator_write_node_t*) node; - - ID constant_name = parse_location_symbol(&constant_operator_write_node->name_loc); - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(constant_name)); - - YP_COMPILE_NOT_POPPED(constant_operator_write_node->value); - ID method_id = yp_constant_id_lookup(compile_context, 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)); - - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_CONSTANT_OR_WRITE_NODE: { - yp_constant_or_write_node_t *constant_or_write_node = (yp_constant_or_write_node_t*) node; - - LABEL *set_label= NEW_LABEL(lineno); - LABEL *end_label = NEW_LABEL(lineno); - - ADD_INSN(ret, &dummy_line_node, putnil); - VALUE constant_name = ID2SYM(parse_location_symbol(&constant_or_write_node->name_loc)); - - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), constant_name, Qtrue); - - ADD_INSNL(ret, &dummy_line_node, branchunless, set_label); - - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - ADD_LABEL(ret, set_label); - YP_COMPILE_NOT_POPPED(constant_or_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_CONSTANT_WRITE_NODE: { - yp_constant_write_node_t *constant_write_node = (yp_constant_write_node_t *) node; - YP_COMPILE_NOT_POPPED(constant_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); - ID constant_name = parse_location_symbol(&constant_write_node->name_loc); - ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(constant_name)); - return; - } - case YP_NODE_DEF_NODE: { - yp_def_node_t *def_node = (yp_def_node_t *) node; - ID method_name = parse_location_symbol(&def_node->name_loc); - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)def_node, &scope_node); - rb_iseq_t *method_iseq = NEW_ISEQ(&scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); - - 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 YP_NODE_DEFINED_NODE: { - ADD_INSN(ret, &dummy_line_node, putself); - yp_defined_node_t *defined_node = (yp_defined_node_t *)node; - // TODO: Correct defined_type - enum defined_type dtype = DEFINED_CONST; - VALUE sym = parse_integer(defined_node->value); - - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(dtype), sym, rb_iseq_defined_string(dtype)); - return; - } - case YP_NODE_EMBEDDED_STATEMENTS_NODE: { - yp_embedded_statements_node_t *embedded_statements_node = (yp_embedded_statements_node_t *)node; - - if (embedded_statements_node->statements) { - YP_COMPILE((yp_node_t *) (embedded_statements_node->statements)); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - // TODO: Concatenate the strings that exist here - return; - } - case YP_NODE_EMBEDDED_VARIABLE_NODE: { - yp_embedded_variable_node_t *embedded_node = (yp_embedded_variable_node_t *)node; - YP_COMPILE(embedded_node->variable); - return; - } - case YP_NODE_FALSE_NODE: - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); - } - return; - case YP_NODE_FLIP_FLOP_NODE: { - // TODO: The labels here are wrong, figure out why..... - yp_flip_flop_node_t *flip_flop_node = (yp_flip_flop_node_t *)node; - - LABEL *lend = NEW_LABEL(lineno); - LABEL *then_label = NEW_LABEL(lineno); - LABEL *else_label = NEW_LABEL(lineno); - //TODO: int again = type == NODE_FLIP2; - int again = 0; - - rb_num_t cnt = ISEQ_FLIP_CNT_INCREMENT(ISEQ_BODY(iseq)->local_iseq) - + VM_SVAR_FLIPFLOP_START; - VALUE key = INT2FIX(cnt); - - ADD_INSN2(ret, &dummy_line_node, getspecial, key, INT2FIX(0)); - ADD_INSNL(ret, &dummy_line_node, branchif, lend); - - YP_COMPILE(flip_flop_node->left); - /* *flip == 0 */ - 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); - } - - /* *flip == 1 */ - ADD_LABEL(ret, lend); - YP_COMPILE(flip_flop_node->right); - 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); - ADD_LABEL(ret, then_label); - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSNL(ret, &dummy_line_node, jump, lend); - ADD_LABEL(ret, else_label); - ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); - ADD_LABEL(ret, lend); - return; - } - case YP_NODE_FLOAT_NODE: { - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_float(node)); - } - return; - } - case YP_NODE_GLOBAL_VARIABLE_AND_WRITE_NODE: { - yp_global_variable_and_write_node_t *global_variable_and_write_node = (yp_global_variable_and_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, global_variable_and_write_node->name)); - - ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(global_variable_and_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name); - ADD_LABEL(ret, end_label); - - return; - } - case YP_NODE_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { - yp_global_variable_operator_write_node_t *global_variable_operator_write_node = (yp_global_variable_operator_write_node_t*) node; - - VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, global_variable_operator_write_node->name)); - ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); - - YP_COMPILE_NOT_POPPED(global_variable_operator_write_node->value); - ID method_id = yp_constant_id_lookup(compile_context, 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)); - - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name); - - return; - } - case YP_NODE_GLOBAL_VARIABLE_OR_WRITE_NODE: { - yp_global_variable_or_write_node_t *global_variable_or_write_node = (yp_global_variable_or_write_node_t*) node; - - LABEL *set_label= NEW_LABEL(lineno); - LABEL *end_label = NEW_LABEL(lineno); - - ADD_INSN(ret, &dummy_line_node, putnil); - VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, 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); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - ADD_LABEL(ret, set_label); - YP_COMPILE_NOT_POPPED(global_variable_or_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name); - ADD_LABEL(ret, end_label); - - return; - } - case YP_NODE_GLOBAL_VARIABLE_READ_NODE: { - yp_global_variable_read_node_t *global_variable_read_node = (yp_global_variable_read_node_t *)node; - VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, global_variable_read_node->name)); - ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: { - yp_global_variable_write_node_t *write_node = (yp_global_variable_write_node_t *) node; - YP_COMPILE_NOT_POPPED(write_node->value); - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - ID ivar_name = yp_constant_id_lookup(compile_context, write_node->name); - ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name)); - return; - } - case YP_NODE_HASH_NODE: { - yp_hash_node_t *hash_node = (yp_hash_node_t *) node; - yp_node_list_t elements = hash_node->elements; - - if (elements.size == 1) { - assert(elements.nodes[0]->type == YP_NODE_ASSOC_NODE); - yp_assoc_node_t *assoc_node = (yp_assoc_node_t *) elements.nodes[0]; - - if (yp_static_node_literal_p(assoc_node->key) && - yp_static_node_literal_p(assoc_node->value)) { - VALUE hash = rb_hash_new_with_size(1); - hash = rb_obj_hide(hash); - OBJ_FREEZE(hash); - ADD_INSN1(ret, &dummy_line_node, duphash, hash); - return; - } - } - - for (size_t index = 0; index < elements.size; index++) { - YP_COMPILE(elements.nodes[index]); - } - - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements.size * 2)); - } - return; - } - case YP_NODE_IF_NODE: { - const int line = (int)yp_newline_list_line_column(&(parser->newline_list), node->location.start).line; - yp_if_node_t *if_node = (yp_if_node_t *)node; - yp_statements_node_t *node_body = if_node->statements; - yp_node_t *node_else = if_node->consequent; - yp_node_t *predicate = if_node->predicate; - - yp_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context); - return; - } - case YP_NODE_IMAGINARY_NODE: { - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_imaginary((yp_imaginary_node_t *)node)); - } - return; - } - case YP_NODE_INSTANCE_VARIABLE_AND_WRITE_NODE: { - yp_instance_variable_and_write_node_t *instance_variable_and_write_node = (yp_instance_variable_and_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - ID instance_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(instance_variable_and_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { - yp_instance_variable_operator_write_node_t *instance_variable_operator_write_node = (yp_instance_variable_operator_write_node_t*) node; - - ID instance_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - YP_COMPILE_NOT_POPPED(instance_variable_operator_write_node->value); - ID method_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSN2(ret, &dummy_line_node, setinstancevariable, - instance_variable_name_val, - get_ivar_ic_value(iseq, instance_variable_name_id)); - - return; - } - case YP_NODE_INSTANCE_VARIABLE_OR_WRITE_NODE: { - yp_instance_variable_or_write_node_t *instance_variable_or_write_node = (yp_instance_variable_or_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - ID instance_variable_name_id = yp_constant_id_lookup(compile_context, 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)); - - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(instance_variable_or_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - 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 YP_NODE_INSTANCE_VARIABLE_READ_NODE: { - if (!popped) { - yp_instance_variable_read_node_t *instance_variable_read_node = (yp_instance_variable_read_node_t *) node; - ID ivar_name = yp_constant_id_lookup(compile_context, instance_variable_read_node->name); - ADD_INSN2(ret, &dummy_line_node, getinstancevariable, - ID2SYM(ivar_name), - get_ivar_ic_value(iseq, ivar_name)); - } - return; - } - case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: { - yp_instance_variable_write_node_t *write_node = (yp_instance_variable_write_node_t *) node; - YP_COMPILE_NOT_POPPED(write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ID ivar_name = yp_constant_id_lookup(compile_context, write_node->name); - ADD_INSN2(ret, &dummy_line_node, setinstancevariable, - ID2SYM(ivar_name), - get_ivar_ic_value(iseq, ivar_name)); - return; - } - case YP_NODE_INTEGER_NODE: { - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_integer(node)); - } - return; - } - case YP_NODE_INTERPOLATED_REGULAR_EXPRESSION_NODE: { - yp_interpolated_regular_expression_node_t *interp_regular_expression_node= (yp_interpolated_regular_expression_node_t *) node; - yp_interpolated_node_compile(interp_regular_expression_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); - if (interp_regular_expression_node->parts.size > 1) { - ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(0), INT2FIX((int)(interp_regular_expression_node->parts.size))); - } - - return; - } - case YP_NODE_INTERPOLATED_STRING_NODE: { - yp_interpolated_string_node_t *interp_string_node = (yp_interpolated_string_node_t *) node; - yp_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); - - size_t parts_size = interp_string_node->parts.size; - if (parts_size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); - } - return; - } - case YP_NODE_INTERPOLATED_SYMBOL_NODE: { - yp_interpolated_symbol_node_t *interp_symbol_node = (yp_interpolated_symbol_node_t *) node; - yp_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); - - 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 { - ADD_INSN(ret, &dummy_line_node, pop); - } - - return; - } - case YP_NODE_INTERPOLATED_X_STRING_NODE: { - yp_interpolated_x_string_node_t *interp_x_string_node = (yp_interpolated_x_string_node_t *) node; - ADD_INSN(ret, &dummy_line_node, putself); - yp_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); - - 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, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_KEYWORD_HASH_NODE: { - yp_keyword_hash_node_t *keyword_hash_node = (yp_keyword_hash_node_t *) node; - yp_node_list_t elements = keyword_hash_node->elements; - - for (size_t index = 0; index < elements.size; index++) { - YP_COMPILE(elements.nodes[index]); - } - - ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements.size * 2)); - return; - } - case YP_NODE_LAMBDA_NODE: { - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)node, &scope_node); - - const rb_iseq_t *block = NEW_CHILD_ISEQ(&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); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_LOCAL_VARIABLE_AND_WRITE_NODE: { - yp_local_variable_and_write_node_t *local_variable_and_write_node = (yp_local_variable_and_write_node_t*) node; - - LABEL *end_label = NEW_LABEL(lineno); - - yp_constant_id_t constant_id = local_variable_and_write_node->name; - int depth = local_variable_and_write_node->depth; - int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); - ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchunless, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - YP_COMPILE_NOT_POPPED(local_variable_and_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth); - ADD_LABEL(ret, end_label); - - return; - } - case YP_NODE_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { - yp_local_variable_operator_write_node_t *local_variable_operator_write_node = (yp_local_variable_operator_write_node_t*) node; - - yp_constant_id_t constant_id = local_variable_operator_write_node->name; - - int depth = local_variable_operator_write_node->depth; - int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); - ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); - - YP_COMPILE_NOT_POPPED(local_variable_operator_write_node->value); - ID method_id = yp_constant_id_lookup(compile_context, 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)); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth); - - return; - } - case YP_NODE_LOCAL_VARIABLE_OR_WRITE_NODE: { - yp_local_variable_or_write_node_t *local_variable_or_write_node = (yp_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); - - yp_constant_id_t constant_id = local_variable_or_write_node->name; - int depth = local_variable_or_write_node->depth; - int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); - ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - ADD_LABEL(ret, set_label); - YP_COMPILE_NOT_POPPED(local_variable_or_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth); - ADD_LABEL(ret, end_label); - - return; - } - case YP_NODE_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *local_read_node = (yp_local_variable_read_node_t *) node; - - if (!popped) { - int index = yp_lookup_local_index(iseq, compile_context, local_read_node->name); - ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->depth); - } - return; - } - case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: { - yp_local_variable_write_node_t *local_write_node = (yp_local_variable_write_node_t *) node; - YP_COMPILE_NOT_POPPED(local_write_node->value); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - - yp_constant_id_t constant_id = local_write_node->name; - int index = yp_lookup_local_index(iseq, compile_context, constant_id); - - ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth); - return; - } - case YP_NODE_MISSING_NODE: { - rb_bug("A yp_missing_node_t should not exist in YARP's AST."); - return; - } - case YP_NODE_MODULE_NODE: { - yp_module_node_t *module_node = (yp_module_node_t *)node; - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)module_node, &scope_node); - - ID module_id = yp_constant_id_lookup(compile_context, module_node->name); - VALUE module_name = rb_str_freeze(rb_sprintf("", rb_id2str(module_id))); - - const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&scope_node, module_name, ISEQ_TYPE_CLASS, lineno); - - const int flags = VM_DEFINECLASS_TYPE_MODULE | - yp_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node, src, popped, compile_context); - - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(module_id), module_iseq, INT2FIX(flags)); - RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_MULTI_WRITE_NODE: { - yp_multi_write_node_t *multi_write_node = (yp_multi_write_node_t *)node; - YP_COMPILE(multi_write_node->value); - - // TODO: int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); - int flag = 0x00; - - ADD_INSN(ret, &dummy_line_node, dup); - ADD_INSN2(ret, &dummy_line_node, expandarray, INT2FIX(multi_write_node->targets.size), INT2FIX(flag)); - yp_node_list_t node_list = multi_write_node->targets; - - for (size_t index = 0; index < node_list.size; index++) { - YP_COMPILE(node_list.nodes[index]); - } - - return; - } - case YP_NODE_NEXT_NODE: { - yp_next_node_t *next_node = (yp_next_node_t *) node; - if (next_node->arguments) { - YP_COMPILE_NOT_POPPED((yp_node_t *)next_node->arguments); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - ADD_INSN(ret, &dummy_line_node, pop); - ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label); - - return; - } - case YP_NODE_NIL_NODE: - if (!popped) { - ADD_INSN(ret, &dummy_line_node, putnil); - } - return; - case YP_NODE_NUMBERED_REFERENCE_READ_NODE: { - if (!popped) { - uint32_t reference_number = ((yp_numbered_reference_read_node_t *)node)->number; - ADD_INSN2(ret, &dummy_line_node, getspecial, INT2FIX(1), INT2FIX(reference_number << 1)); - } - return; - } - case YP_NODE_OR_NODE: { - yp_or_node_t *or_node = (yp_or_node_t *) node; - - LABEL *end_label = NEW_LABEL(lineno); - YP_COMPILE(or_node->left); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, dup); - } - ADD_INSNL(ret, &dummy_line_node, branchif, end_label); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - YP_COMPILE(or_node->right); - ADD_LABEL(ret, end_label); - - return; - } - case YP_NODE_OPTIONAL_PARAMETER_NODE: { - yp_optional_parameter_node_t *optional_parameter_node = (yp_optional_parameter_node_t *)node; - YP_COMPILE_NOT_POPPED(optional_parameter_node->value); - - int index = yp_lookup_local_index(iseq, compile_context, optional_parameter_node->name); - - ADD_SETLOCAL(ret, &dummy_line_node, index, 0); - - return; - } - case YP_NODE_PARENTHESES_NODE: { - yp_parentheses_node_t *parentheses_node = (yp_parentheses_node_t *) node; - - if (parentheses_node->body == NULL) { - ADD_INSN(ret, &dummy_line_node, putnil); - } else { - YP_COMPILE(parentheses_node->body); - } - - return; - } - case YP_NODE_PROGRAM_NODE: { - yp_program_node_t *program_node = (yp_program_node_t *) node; - - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)node, &scope_node); - if (program_node->statements->body.size == 0) { - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN(ret, &dummy_line_node, leave); - } else { - yp_scope_node_t *res_node = &scope_node; - YP_COMPILE((yp_node_t *) res_node); - } - - return; - } - case YP_NODE_RANGE_NODE: { - yp_range_node_t *range_node = (yp_range_node_t *) node; - bool exclusive = (range_node->operator_loc.end - range_node->operator_loc.start) == 3; - - if (yp_optimizable_range_item_p(range_node->left) && yp_optimizable_range_item_p(range_node->right)) { - if (!popped) { - yp_node_t *left = range_node->left; - yp_node_t *right = range_node->right; - VALUE val = rb_range_new( - left && YP_NODE_TYPE_P(left, YP_NODE_INTEGER_NODE) ? parse_integer(left) : Qnil, - right && YP_NODE_TYPE_P(right, YP_NODE_INTEGER_NODE) ? parse_integer(right) : Qnil, - exclusive - ); - ADD_INSN1(ret, &dummy_line_node, putobject, val); - RB_OBJ_WRITTEN(iseq, Qundef, val); - } - } - else { - if (range_node->left == NULL) { - ADD_INSN(ret, &dummy_line_node, putnil); - } else { - YP_COMPILE(range_node->left); - } - - if (range_node->right == NULL) { - ADD_INSN(ret, &dummy_line_node, putnil); - } else { - YP_COMPILE(range_node->right); - } - - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, newrange, INT2FIX(exclusive)); - } - } - return; - } - case YP_NODE_RATIONAL_NODE: { - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_rational(node)); - } - return; - } - case YP_NODE_REDO_NODE: { - ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label); - return; - } - case YP_NODE_REGULAR_EXPRESSION_NODE: { - if (!popped) { - yp_regular_expression_node_t *regular_expression_node = (yp_regular_expression_node_t *) node; - VALUE regex_str = parse_string(®ular_expression_node->unescaped); - // TODO: Replace 0 with regex options - VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), 0); - ADD_INSN1(ret, &dummy_line_node, putobject, regex); - } - return; - } - case YP_NODE_RETURN_NODE: { - yp_arguments_node_t *arguments = ((yp_return_node_t *)node)->arguments; - - if (arguments) { - YP_COMPILE((yp_node_t *)arguments); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - ADD_TRACE(ret, RUBY_EVENT_RETURN); - ADD_INSN(ret, &dummy_line_node, leave); - - if (!popped) { - ADD_INSN(ret, &dummy_line_node, putnil); - } - return; - } - case YP_NODE_SCOPE_NODE: { - yp_scope_node_t *scope_node = (yp_scope_node_t *)node; - yp_constant_id_list_t locals = scope_node->locals; - - yp_parameters_node_t *parameters_node = (yp_parameters_node_t *)scope_node->parameters; - yp_node_list_t requireds_list = YP_EMPTY_NODE_LIST; - yp_node_list_t optionals_list = YP_EMPTY_NODE_LIST; - - - if (parameters_node) { - requireds_list = parameters_node->requireds; - optionals_list = parameters_node->optionals; - } - - size_t size = locals.size; - - // Index lookup table buffer size is only the number of the locals - st_table *index_lookup_table = st_init_numtable(); - - VALUE idtmp = 0; - rb_ast_id_table_t *tbl = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + size * sizeof(ID)); - tbl->size = (int)size; - - // First param gets 0, second param 1, param n... - // Calculate the local index for all locals - for (size_t i = 0; i < size; i++) { - yp_constant_id_t constant_id = locals.ids[i]; - ID local = yp_constant_id_lookup(compile_context, constant_id); - tbl->ids[i] = local; - st_insert(index_lookup_table, constant_id, i); - } - - yp_compile_context_t scope_compile_context = { - .parser = parser, - .previous = compile_context, - .constants = compile_context->constants, - .index_lookup_table = index_lookup_table - }; - - ISEQ_BODY(iseq)->param.lead_num = (int)requireds_list.size; - ISEQ_BODY(iseq)->param.opt_num = (int)optionals_list.size; - // TODO: Set all the other nums (good comment by lead_num illustrating what they are) - ISEQ_BODY(iseq)->param.size = (unsigned int)size; - - if (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++) { - label = NEW_LABEL(lineno); - opt_table[i] = label; - ADD_LABEL(ret, label); - yp_node_t *optional_node = optionals_list.nodes[i]; - yp_compile_node(iseq, optional_node, ret, src, false, &scope_compile_context); - } - - // Set the last label - label = NEW_LABEL(lineno); - opt_table[optionals_list.size] = label; - ADD_LABEL(ret, label); - - ISEQ_BODY(iseq)->param.flags.has_opt = TRUE; - ISEQ_BODY(iseq)->param.opt_table = (const VALUE *)opt_table; - } - - iseq_set_local_table(iseq, tbl); - - switch (ISEQ_BODY(iseq)->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(ISEQ_BODY(iseq)->location.first_lineno, -1); - ADD_INSN (ret, &dummy_line_node, nop); - ADD_LABEL(ret, start); - - if (scope_node->body) { - yp_compile_node(iseq, (yp_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - - 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; - - /* 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; - } - default: - if (scope_node->body) { - yp_compile_node(iseq, (yp_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - } - - free(index_lookup_table); - - ADD_INSN(ret, &dummy_line_node, leave); - return; - } - case YP_NODE_SELF_NODE: - if (!popped) { - ADD_INSN(ret, &dummy_line_node, putself); - } - return; - case YP_NODE_SINGLETON_CLASS_NODE: { - yp_singleton_class_node_t *singleton_class_node = (yp_singleton_class_node_t *)node; - yp_scope_node_t scope_node; - yp_scope_node_init((yp_node_t *)singleton_class_node, &scope_node); - - const rb_iseq_t *singleton_class = NEW_ISEQ(&scope_node, rb_fstring_lit("singleton class"), - ISEQ_TYPE_CLASS, lineno); - - YP_COMPILE(singleton_class_node->expression); - ADD_INSN(ret, &dummy_line_node, putnil); - ID singletonclass; - CONST_ID(singletonclass, "singletonclass"); - - ADD_INSN3(ret, &dummy_line_node, defineclass, - ID2SYM(singletonclass), singleton_class, - INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS)); - RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_class); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - return; - } - case YP_NODE_SOURCE_ENCODING_NODE: { - const char *encoding = compile_context->parser->encoding.name; - if (!popped) { - rb_encoding *enc = rb_find_encoding(rb_str_new_cstr(encoding)); - if (!enc) { - rb_bug("Encoding not found!"); - } - ADD_INSN1(ret, &dummy_line_node, putobject, rb_enc_from_encoding(enc)); - } - return; - } - case YP_NODE_SOURCE_FILE_NODE: { - yp_source_file_node_t *source_file_node = (yp_source_file_node_t *)node; - - if (!popped) { - VALUE filepath; - if (source_file_node->filepath.length == 0) { - filepath = rb_fstring_lit(""); - } - else { - filepath = parse_string(&source_file_node->filepath); - } - - ADD_INSN1(ret, &dummy_line_node, putstring, filepath); - } - return; - } - case YP_NODE_SOURCE_LINE_NODE: { - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, INT2FIX(lineno)); - } - return; - } - case YP_NODE_SPLAT_NODE: { - yp_splat_node_t *splat_node = (yp_splat_node_t *)node; - YP_COMPILE(splat_node->expression); - - ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - return; - } - case YP_NODE_STATEMENTS_NODE: { - yp_statements_node_t *statements_node = (yp_statements_node_t *) node; - yp_node_list_t node_list = statements_node->body; - for (size_t index = 0; index < node_list.size - 1; index++) { - YP_COMPILE_POPPED(node_list.nodes[index]); - } - if (node_list.size > 0) { - YP_COMPILE(node_list.nodes[node_list.size - 1]); - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } - return; - } - case YP_NODE_STRING_CONCAT_NODE: { - yp_string_concat_node_t *str_concat_node = (yp_string_concat_node_t *)node; - YP_COMPILE(str_concat_node->left); - YP_COMPILE(str_concat_node->right); - return; - } - case YP_NODE_STRING_NODE: { - if (!popped) { - yp_string_node_t *string_node = (yp_string_node_t *) node; - ADD_INSN1(ret, &dummy_line_node, putstring, parse_string(&string_node->unescaped)); - } - return; - } - case YP_NODE_SYMBOL_NODE: { - yp_symbol_node_t *symbol_node = (yp_symbol_node_t *) node; - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(parse_string_symbol(&symbol_node->unescaped))); - } - return; - } - case YP_NODE_TRUE_NODE: - if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - } - return; - case YP_NODE_UNDEF_NODE: { - yp_undef_node_t *undef_node = (yp_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)); - - YP_COMPILE(undef_node->names.nodes[index]); - - ADD_SEND(ret, &dummy_line_node, rb_intern("core#undef_method"), INT2NUM(2)); - - if (index < undef_node->names.size - 1) - ADD_INSN(ret, &dummy_line_node, pop); - } - - return; - } - case YP_NODE_UNLESS_NODE: { - const int line = (int)yp_newline_list_line_column(&(parser->newline_list), node->location.start).line; - yp_unless_node_t *unless_node = (yp_unless_node_t *)node; - yp_statements_node_t *node_body = unless_node->statements; - yp_node_t *node_else = (yp_node_t *)(unless_node->consequent); - yp_node_t *predicate = unless_node->predicate; - - yp_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context); - return; - } - case YP_NODE_UNTIL_NODE: { - yp_until_node_t *until_node = (yp_until_node_t *)node; - yp_statements_node_t *statements = until_node->statements; - yp_node_t *predicate = until_node->predicate; - yp_node_flags_t flags = node->flags; - - yp_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context); - return; - } - case YP_NODE_WHILE_NODE: { - yp_while_node_t *while_node = (yp_while_node_t *)node; - yp_statements_node_t *statements = while_node->statements; - yp_node_t *predicate = while_node->predicate; - yp_node_flags_t flags = node->flags; - - yp_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context); - return; - } - case YP_NODE_X_STRING_NODE: { - yp_x_string_node_t *xstring_node = (yp_x_string_node_t *) node; - ADD_INSN(ret, &dummy_line_node, putself); - ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&xstring_node->unescaped)); - ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); - return; - } - case YP_NODE_YIELD_NODE: { - unsigned int flag = 0; - struct rb_callinfo_kwarg *keywords = NULL; - - VALUE argc = INT2FIX(0); - - ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, keywords, FALSE)); - - if (popped) { - ADD_INSN(ret, &dummy_line_node, pop); - } - - 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", yp_node_type_to_str(node->type)); - return; - } -} - -static VALUE -rb_translate_yarp(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_compile_context_t *compile_context) -{ - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - RUBY_ASSERT(node->type == YP_NODE_PROGRAM_NODE || node->type == YP_NODE_SCOPE_NODE); - - yp_compile_node(iseq, node, ret, node->location.start, false, compile_context); - iseq_set_sequence(iseq, ret); - return Qnil; -} - -#undef NEW_ISEQ -#define NEW_ISEQ OLD_ISEQ - -#undef NEW_CHILD_ISEQ -#define NEW_CHILD_ISEQ OLD_CHILD_ISEQ diff --git a/yarp/yarp_init.c b/yarp/yarp_init.c deleted file mode 100644 index 4684e99db65744..00000000000000 --- a/yarp/yarp_init.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "yarp/extension.h" - -void ruby_init_ext(const char *name, void (*init)(void)); - -void -Init_YARP(void) -{ - ruby_init_ext("yarp/yarp.so", Init_yarp); -} diff --git a/yjit.rb b/yjit.rb index 57c4efff8b896d..ada3f0c0e911ab 100644 --- a/yjit.rb +++ b/yjit.rb @@ -258,16 +258,33 @@ def _print_stats(out: $stderr) # :nodoc: print_counters(stats, out: out, prefix: 'guard_send_', prompt: 'method call exit reasons: ') print_counters(stats, out: out, prefix: 'guard_invokeblock_', prompt: 'invokeblock exit reasons: ') print_counters(stats, out: out, prefix: 'guard_invokesuper_', prompt: 'invokesuper exit reasons: ') - print_counters(stats, out: out, prefix: 'leave_', prompt: 'leave exit reasons: ') print_counters(stats, out: out, prefix: 'gbpp_', prompt: 'getblockparamproxy exit reasons: ') print_counters(stats, out: out, prefix: 'getivar_', prompt: 'getinstancevariable exit reasons:') print_counters(stats, out: out, prefix: 'setivar_', prompt: 'setinstancevariable exit reasons:') - print_counters(stats, out: out, prefix: 'definedivar_', prompt: 'definedivar exit reasons:') - print_counters(stats, out: out, prefix: 'opt_aref_', prompt: 'opt_aref exit reasons: ') - print_counters(stats, out: out, prefix: 'opt_aref_with_', prompt: 'opt_aref_with exit reasons: ') - print_counters(stats, out: out, prefix: 'expandarray_', prompt: 'expandarray exit reasons: ') + %w[ + branchif + branchnil + branchunless + definedivar + expandarray + jump + leave + objtostring + opt_aref + opt_aref_with + opt_aset + opt_case_dispatch + opt_div + opt_getconstant_path + opt_minus + opt_mod + opt_mult + opt_plus + setlocal + ].each do |insn| + print_counters(stats, out: out, prefix: "#{insn}_", prompt: "#{insn} exit reasons:", optional: true) + end print_counters(stats, out: out, prefix: 'lshift_', prompt: 'left shift (ltlt) exit reasons: ') - print_counters(stats, out: out, prefix: 'opt_getconstant_path_', prompt: 'opt_getconstant_path exit reasons: ') print_counters(stats, out: out, prefix: 'invalidate_', prompt: 'invalidation reasons: ') # Number of failed compiler invocations @@ -307,6 +324,7 @@ def _print_stats(out: $stderr) # :nodoc: out.puts "versions_per_block: " + format_number(13, "%4.3f" % (stats[:compiled_block_count].fdiv(stats[:compiled_blockid_count]))) end out.puts "compiled_branch_count: " + format_number(13, stats[:compiled_branch_count]) + out.puts "compile_time_ms: " + format_number(13, stats[:compile_time_ns] / (1000 * 1000)) out.puts "block_next_count: " + format_number(13, stats[:block_next_count]) out.puts "defer_count: " + format_number(13, stats[:defer_count]) out.puts "defer_empty_count: " + format_number(13, stats[:defer_empty_count]) @@ -380,15 +398,19 @@ def total_exit_count(stats, prefix: "exit_") # :nodoc: total end - def print_counters(counters, out:, prefix:, prompt:) # :nodoc: - out.puts(prompt) + def print_counters(counters, out:, prefix:, prompt:, optional: false) # :nodoc: counters = counters.filter { |key, _| key.start_with?(prefix) } counters.filter! { |_, value| value != 0 } counters.transform_keys! { |key| key.to_s.delete_prefix(prefix) } if counters.empty? - out.puts(" (all relevant counters are zero)") + unless optional + out.puts(prompt) + out.puts(" (all relevant counters are zero)") + end return + else + out.puts(prompt) end counters = counters.to_a diff --git a/yjit/Cargo.lock b/yjit/Cargo.lock index 08ae1bd487fa84..e9a59cb771eca5 100644 --- a/yjit/Cargo.lock +++ b/yjit/Cargo.lock @@ -34,16 +34,9 @@ version = "0.2.124" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" -[[package]] -name = "stats_alloc" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0e04424e733e69714ca1bbb9204c1a57f09f5493439520f9f68c132ad25eec" - [[package]] name = "yjit" version = "0.1.0" dependencies = [ "capstone", - "stats_alloc", ] diff --git a/yjit/Cargo.toml b/yjit/Cargo.toml index 8cd593e4eea3ec..2194402cdd4389 100644 --- a/yjit/Cargo.toml +++ b/yjit/Cargo.toml @@ -16,13 +16,12 @@ crate-type = ["staticlib"] # No required dependencies to simplify build process. TODO: Link to yet to be # written rationale. Optional For development and testing purposes capstone = { version = "0.10.0", optional = true } -stats_alloc = { version = "0.1.10", optional = true } [features] # NOTE: Development builds select a set of these via configure.ac # For debugging, `make V=1` shows exact cargo invocation. disasm = ["capstone"] -stats = ["stats_alloc"] +stats = [] [profile.dev] opt-level = 0 diff --git a/yjit/bindgen/src/main.rs b/yjit/bindgen/src/main.rs index baa71fc6cf3fc0..db93672a3d47d0 100644 --- a/yjit/bindgen/src/main.rs +++ b/yjit/bindgen/src/main.rs @@ -449,6 +449,7 @@ fn main() { .allowlist_function("rb_obj_class") .allowlist_function("rb_obj_is_proc") .allowlist_function("rb_vm_base_ptr") + .allowlist_function("rb_ec_stack_check") // We define VALUE manually, don't import it .blocklist_type("VALUE") diff --git a/yjit/src/asm/mod.rs b/yjit/src/asm/mod.rs index 989fcd2a0fc94a..75478814c250f5 100644 --- a/yjit/src/asm/mod.rs +++ b/yjit/src/asm/mod.rs @@ -59,6 +59,9 @@ pub struct CodeBlock { // Current writing position write_pos: usize, + // The index of the last page with written bytes + last_page_idx: usize, + // Total number of bytes written to past pages past_page_bytes: usize, @@ -119,6 +122,7 @@ impl CodeBlock { mem_size, page_size, write_pos: 0, + last_page_idx: 0, past_page_bytes: 0, page_end_reserve: 0, label_addrs: Vec::new(), @@ -203,11 +207,15 @@ impl CodeBlock { assert!(!cb.has_dropped_bytes()); }); - // Update past_page_bytes for code_size() - self.past_page_bytes += self.current_page_bytes(); + // Update past_page_bytes for code_size() if this is a new page + if self.last_page_idx < page_idx { + self.past_page_bytes += self.current_page_bytes(); + } // Start the next code from dst_pos self.write_pos = dst_pos; + // Update the last_page_idx if page_idx points to the furthest page + self.last_page_idx = usize::max(self.last_page_idx, page_idx); } !self.dropped_bytes } @@ -805,6 +813,7 @@ mod tests #[test] fn test_code_size() { + // Write 4 bytes in the first page let mut cb = CodeBlock::new_dummy(CodeBlock::PREFERRED_CODE_PAGE_SIZE * 2); cb.write_bytes(&[0, 0, 0, 0]); assert_eq!(cb.code_size(), 4); @@ -813,7 +822,18 @@ mod tests cb.next_page(cb.get_write_ptr(), |_, _| {}); assert_eq!(cb.code_size(), 4); + // Write 4 bytes in the second page cb.write_bytes(&[0, 0, 0, 0]); assert_eq!(cb.code_size(), 8); + + // Rewrite 4 bytes in the first page + let old_write_pos = cb.get_write_pos(); + cb.set_pos(0); + cb.write_bytes(&[1, 1, 1, 1]); + + // Moving from an old page to the next page should not increase code_size + cb.next_page(cb.get_write_ptr(), |_, _| {}); + cb.set_pos(old_write_pos); + assert_eq!(cb.code_size(), 8); } } diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index 1007df9cf8ee6d..79af4f5858f1bf 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -184,6 +184,10 @@ fn emit_load_value(cb: &mut CodeBlock, rd: A64Opnd, value: u64) -> usize { } } +/// List of registers that can be used for stack temps. +/// These are caller-saved registers. +pub static TEMP_REGS: [Reg; 5] = [X1_REG, X9_REG, X10_REG, X14_REG, X15_REG]; + impl Assembler { // Special scratch registers for intermediate processing. @@ -192,10 +196,6 @@ impl Assembler const SCRATCH0: A64Opnd = A64Opnd::Reg(Assembler::SCRATCH_REG); const SCRATCH1: A64Opnd = A64Opnd::Reg(X17_REG); - /// List of registers that can be used for stack temps. - /// These are caller-saved registers. - pub const TEMP_REGS: [Reg; 5] = [X1_REG, X9_REG, X10_REG, X14_REG, X15_REG]; - /// Get the list of registers from which we will allocate on this platform /// These are caller-saved registers /// Note: we intentionally exclude C_RET_REG (X0) from this list @@ -1636,7 +1636,7 @@ mod tests { fn test_replace_mov_with_ldur() { let (mut asm, mut cb) = setup_asm(); - asm.mov(Opnd::Reg(Assembler::TEMP_REGS[0]), Opnd::mem(64, CFP, 8)); + asm.mov(Opnd::Reg(TEMP_REGS[0]), Opnd::mem(64, CFP, 8)); asm.compile_with_num_regs(&mut cb, 1); assert_disasm!(cb, "618240f8", {" @@ -1648,8 +1648,8 @@ mod tests { fn test_not_split_mov() { let (mut asm, mut cb) = setup_asm(); - asm.mov(Opnd::Reg(Assembler::TEMP_REGS[0]), Opnd::UImm(0xffff)); - asm.mov(Opnd::Reg(Assembler::TEMP_REGS[0]), Opnd::UImm(0x10000)); + asm.mov(Opnd::Reg(TEMP_REGS[0]), Opnd::UImm(0xffff)); + asm.mov(Opnd::Reg(TEMP_REGS[0]), Opnd::UImm(0x10000)); asm.compile_with_num_regs(&mut cb, 1); assert_disasm!(cb, "e1ff9fd2e10370b2", {" @@ -1663,7 +1663,7 @@ mod tests { let (mut asm, mut cb) = setup_asm(); let out = asm.csel_l(Qtrue.into(), Qfalse.into()); - asm.mov(Opnd::Reg(Assembler::TEMP_REGS[0]), out); + asm.mov(Opnd::Reg(TEMP_REGS[0]), out); asm.compile_with_num_regs(&mut cb, 2); assert_disasm!(cb, "8b0280d20c0080d261b18c9a", {" diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index a6803f7a633193..479a4df3dbbd82 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -1,26 +1,20 @@ #![allow(dead_code)] #![allow(unused_variables)] -#![allow(unused_imports)] use std::cell::Cell; use std::collections::HashMap; use std::fmt; use std::convert::From; -use std::io::Write; use std::mem::take; use crate::codegen::{gen_outlined_exit, gen_counted_exit}; use crate::cruby::{VALUE, SIZEOF_VALUE_I32}; use crate::virtualmem::{CodePtr}; -use crate::asm::{CodeBlock, uimm_num_bits, imm_num_bits, OutlinedCb}; -use crate::core::{Context, Type, TempMapping, RegTemps, MAX_REG_TEMPS, MAX_TEMP_TYPES}; +use crate::asm::{CodeBlock, OutlinedCb}; +use crate::core::{Context, RegTemps, MAX_REG_TEMPS}; use crate::options::*; use crate::stats::*; -#[cfg(target_arch = "x86_64")] -use crate::backend::x86_64::*; - -#[cfg(target_arch = "aarch64")] -use crate::backend::arm64::*; +use crate::backend::current::*; pub const EC: Opnd = _EC; pub const CFP: Opnd = _CFP; @@ -983,6 +977,9 @@ impl SideExitContext { } } +/// Initial capacity for asm.insns vector +const ASSEMBLER_INSNS_CAPACITY: usize = 256; + /// Object into which we assemble instructions to be /// optimized and lowered pub struct Assembler { @@ -1016,8 +1013,8 @@ impl Assembler pub fn new_with_label_names(label_names: Vec, side_exits: HashMap) -> Self { Self { - insns: Vec::default(), - live_ranges: Vec::default(), + insns: Vec::with_capacity(ASSEMBLER_INSNS_CAPACITY), + live_ranges: Vec::with_capacity(ASSEMBLER_INSNS_CAPACITY), label_names, ctx: Context::default(), side_exits, @@ -1027,10 +1024,9 @@ impl Assembler } /// Get the list of registers that can be used for stack temps. - pub fn get_temp_regs() -> Vec { + pub fn get_temp_regs() -> &'static [Reg] { let num_regs = get_option!(num_temp_regs); - let mut regs = Self::TEMP_REGS.to_vec(); - regs.drain(0..num_regs).collect() + &TEMP_REGS[0..num_regs] } /// Set a context for generating side exits @@ -1048,7 +1044,7 @@ impl Assembler /// Append an instruction onto the current list of instructions and update /// the live ranges of any instructions whose outputs are being used as /// operands to this instruction. - pub(super) fn push_insn(&mut self, insn: Insn) { + pub fn push_insn(&mut self, insn: Insn) { // Index of this instruction let insn_idx = self.insns.len(); @@ -1184,7 +1180,7 @@ impl Assembler // Spill live stack temps if self.ctx.get_reg_temps() != RegTemps::default() { - self.comment(&format!("spill_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), RegTemps::default().as_u8())); + asm_comment!(self, "spill_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), RegTemps::default().as_u8()); for stack_idx in 0..u8::min(MAX_REG_TEMPS, self.ctx.get_stack_size()) { if self.ctx.get_reg_temps().get(stack_idx) { let idx = self.ctx.get_stack_size() - 1 - stack_idx; @@ -1224,7 +1220,7 @@ impl Assembler /// Update which stack temps are in a register pub fn set_reg_temps(&mut self, reg_temps: RegTemps) { if self.ctx.get_reg_temps() != reg_temps { - self.comment(&format!("reg_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), reg_temps.as_u8())); + asm_comment!(self, "reg_temps: {:08b} -> {:08b}", self.ctx.get_reg_temps().as_u8(), reg_temps.as_u8()); self.ctx.set_reg_temps(reg_temps); self.verify_reg_temps(); } @@ -1565,7 +1561,7 @@ impl AssemblerDrainingIterator { Self { insns: asm.insns.into_iter().peekable(), index: 0, - indices: Vec::default() + indices: Vec::with_capacity(ASSEMBLER_INSNS_CAPACITY), } } @@ -1720,10 +1716,6 @@ impl Assembler { self.push_insn(Insn::Cmp { left, right }); } - pub fn comment(&mut self, text: &str) { - self.push_insn(Insn::Comment(text.to_string())); - } - #[must_use] pub fn cpop(&mut self) -> Opnd { let out = self.next_opnd_out(Opnd::DEFAULT_NUM_BITS); @@ -1999,6 +1991,17 @@ impl Assembler { } } +/// Macro to use format! for Insn::Comment, which skips a format! call +/// when disasm is not supported. +macro_rules! asm_comment { + ($asm:expr, $($fmt:tt)*) => { + if cfg!(feature = "disasm") { + $asm.push_insn(Insn::Comment(format!($($fmt)*))); + } + }; +} +pub(crate) use asm_comment; + #[cfg(test)] mod tests { use super::*; diff --git a/yjit/src/backend/mod.rs b/yjit/src/backend/mod.rs index 47946950946438..6921244c72ac63 100644 --- a/yjit/src/backend/mod.rs +++ b/yjit/src/backend/mod.rs @@ -4,5 +4,11 @@ pub mod x86_64; #[cfg(target_arch = "aarch64")] pub mod arm64; +#[cfg(target_arch = "x86_64")] +pub use x86_64 as current; + +#[cfg(target_arch = "aarch64")] +pub use arm64 as current; + pub mod ir; mod tests; diff --git a/yjit/src/backend/tests.rs b/yjit/src/backend/tests.rs index 8ba9f61d251e63..985e5a0e94d97c 100644 --- a/yjit/src/backend/tests.rs +++ b/yjit/src/backend/tests.rs @@ -87,7 +87,7 @@ fn test_mov_mem2mem() { let (mut asm, mut cb) = setup_asm(); - asm.comment("check that comments work too"); + asm_comment!(asm, "check that comments work too"); asm.mov(Opnd::mem(64, SP, 0), Opnd::mem(64, SP, 8)); asm.compile_with_num_regs(&mut cb, 1); diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 60d0e8bf8d9611..718e95188ebfb4 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -84,6 +84,9 @@ impl From<&Opnd> for X86Opnd { } } +/// List of registers that can be used for stack temps. +pub static TEMP_REGS: [Reg; 5] = [RSI_REG, RDI_REG, R8_REG, R9_REG, R10_REG]; + impl Assembler { // A special scratch register for intermediate processing. @@ -91,8 +94,6 @@ impl Assembler pub const SCRATCH_REG: Reg = R11_REG; const SCRATCH0: X86Opnd = X86Opnd::Reg(Assembler::SCRATCH_REG); - /// List of registers that can be used for stack temps. - pub const TEMP_REGS: [Reg; 5] = [RSI_REG, RDI_REG, R8_REG, R9_REG, R10_REG]; /// Get the list of registers from which we can allocate on this platform pub fn get_alloc_regs() -> Vec diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 69b1c52c9ca739..972933e855f4a4 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -1,4 +1,4 @@ -// We use the YARV bytecode constants which have a CRuby-style name +// We use the YARV bytecode constants which have a CRuby-style name #![allow(non_upper_case_globals)] use crate::asm::*; @@ -253,7 +253,7 @@ fn gen_counter_incr(asm: &mut Assembler, counter: Counter) { assert!(!DEFAULT_COUNTERS.contains(&counter), "gen_counter_incr incremented {:?}", counter); if get_option!(gen_stats) { - asm.comment(&format!("increment counter {}", counter.get_name())); + asm_comment!(asm, "increment counter {}", counter.get_name()); let ptr = get_counter_ptr(&counter.get_name()); let ptr_reg = asm.load(Opnd::const_ptr(ptr as *const u8)); let counter_opnd = Opnd::mem(64, ptr_reg, 0); @@ -272,7 +272,7 @@ fn jit_save_pc(jit: &JITState, asm: &mut Assembler) { pc.offset(cur_insn_len) }; - asm.comment("save PC to CFP"); + asm_comment!(asm, "save PC to CFP"); asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_PC), Opnd::const_ptr(ptr as *const u8)); } @@ -281,15 +281,19 @@ fn jit_save_pc(jit: &JITState, asm: &mut Assembler) { /// Note: this will change the current value of REG_SP, /// which could invalidate memory operands fn gen_save_sp(asm: &mut Assembler) { - asm.spill_temps(); - if asm.ctx.get_sp_offset() != 0 { - asm.comment("save SP to CFP"); - let stack_pointer = asm.ctx.sp_opnd(0); + gen_save_sp_with_offset(asm, 0); +} + +/// Save the current SP + offset on the CFP +fn gen_save_sp_with_offset(asm: &mut Assembler, offset: i8) { + if asm.ctx.get_sp_offset() != -offset { + asm_comment!(asm, "save SP to CFP"); + let stack_pointer = asm.ctx.sp_opnd((offset as i32 * SIZEOF_VALUE_I32) as isize); let sp_addr = asm.lea(stack_pointer); asm.mov(SP, sp_addr); let cfp_sp_opnd = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP); asm.mov(cfp_sp_opnd, SP); - asm.ctx.set_sp_offset(0); + asm.ctx.set_sp_offset(-offset); } } @@ -305,6 +309,9 @@ fn jit_prepare_routine_call( jit.record_boundary_patch_point = true; jit_save_pc(jit, asm); gen_save_sp(asm); + // After jit_prepare_routine_call(), we often pop operands before asm.ccall(). + // They should be spilled here to let GC mark them. + asm.spill_temps(); // In case the routine calls Ruby methods, it can set local variables // through Kernel#binding and other means. @@ -417,7 +424,7 @@ fn gen_stub_exit(ocb: &mut OutlinedCb) -> CodePtr { gen_counter_incr(&mut asm, Counter::exit_from_branch_stub); - asm.comment("exit from branch stub"); + asm_comment!(asm, "exit from branch stub"); asm.cpop_into(SP); asm.cpop_into(EC); asm.cpop_into(CFP); @@ -436,7 +443,7 @@ fn gen_exit(exit_pc: *mut VALUE, asm: &mut Assembler) { #[cfg(all(feature = "disasm", not(test)))] { let opcode = unsafe { rb_vm_insn_addr2opcode((*exit_pc).as_ptr()) }; - asm.comment(&format!("exit to interpreter on {}", insn_name(opcode as usize))); + asm_comment!(asm, "exit to interpreter on {}", insn_name(opcode as usize)); } // Spill stack temps before returning to the interpreter @@ -527,7 +534,7 @@ pub fn gen_counted_exit(side_exit: CodePtr, ocb: &mut OutlinedCb, counter: Optio let mut asm = Assembler::new(); // Load the pointer into a register - asm.comment(&format!("increment counter {}", counter.get_name())); + asm_comment!(asm, "increment counter {}", counter.get_name()); let ptr_reg = asm.load(Opnd::const_ptr(get_counter_ptr(&counter.get_name()) as *const u8)); let counter_opnd = Opnd::mem(64, ptr_reg, 0); @@ -571,7 +578,7 @@ fn gen_full_cfunc_return(ocb: &mut OutlinedCb) -> CodePtr { // 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_comment!(asm, "full cfunc return"); asm.ccall( rb_full_cfunc_return as *const u8, vec![EC, C_RET_OPND] @@ -608,7 +615,7 @@ fn gen_leave_exit(ocb: &mut OutlinedCb) -> CodePtr { // Every exit to the interpreter should be counted gen_counter_incr(&mut asm, Counter::leave_interp_return); - asm.comment("exit from leave"); + asm_comment!(asm, "exit from leave"); asm.cpop_into(SP); asm.cpop_into(EC); asm.cpop_into(CFP); @@ -634,12 +641,12 @@ fn gen_leave_exception(ocb: &mut OutlinedCb) -> CodePtr { // Every exit to the interpreter should be counted gen_counter_incr(&mut asm, Counter::leave_interp_return); - asm.comment("increment SP of the caller"); + asm_comment!(asm, "increment SP of the caller"); let sp = Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP); let new_sp = asm.add(sp, SIZEOF_VALUE.into()); asm.mov(sp, new_sp); - asm.comment("exit from exception"); + asm_comment!(asm, "exit from exception"); asm.cpop_into(SP); asm.cpop_into(EC); asm.cpop_into(CFP); @@ -673,7 +680,7 @@ pub fn gen_entry_chain_guard( let expected_pc = unsafe { rb_iseq_pc_at_idx(iseq, insn_idx.into()) }; let expected_pc_opnd = Opnd::const_ptr(expected_pc as *const u8); - asm.comment("guard expected PC"); + asm_comment!(asm, "guard expected PC"); asm.cmp(pc_opnd, expected_pc_opnd); asm.mark_entry_start(&entry); @@ -697,9 +704,9 @@ pub fn gen_entry_prologue( let mut asm = Assembler::new(); if get_option_ref!(dump_disasm).is_some() { - asm.comment(&format!("YJIT entry point: {}", iseq_get_location(iseq, 0))); + asm_comment!(asm, "YJIT entry point: {}", iseq_get_location(iseq, 0)); } else { - asm.comment("YJIT entry"); + asm_comment!(asm, "YJIT entry"); } asm.frame_setup(); @@ -780,7 +787,7 @@ fn gen_check_ints( ) { // Check for interrupts // see RUBY_VM_CHECK_INTS(ec) macro - asm.comment("RUBY_VM_CHECK_INTS(ec)"); + asm_comment!(asm, "RUBY_VM_CHECK_INTS(ec)"); // Not checking interrupt_mask since it's zero outside finalize_deferred_heap_pages, // signal_exec, or rb_postponed_job_flush. @@ -863,8 +870,8 @@ pub fn gen_single_block( if get_option_ref!(dump_disasm).is_some() { let blockid_idx = blockid.idx; let chain_depth = if asm.ctx.get_chain_depth() > 0 { format!("(chain_depth: {})", asm.ctx.get_chain_depth()) } else { "".to_string() }; - asm.comment(&format!("Block: {} {}", iseq_get_location(blockid.iseq, blockid_idx), chain_depth)); - asm.comment(&format!("reg_temps: {:08b}", asm.ctx.get_reg_temps().as_u8())); + asm_comment!(asm, "Block: {} {}", iseq_get_location(blockid.iseq, blockid_idx), chain_depth); + asm_comment!(asm, "reg_temps: {:08b}", asm.ctx.get_reg_temps().as_u8()); } // For each instruction to compile @@ -920,7 +927,7 @@ pub fn gen_single_block( let mut status = None; if let Some(gen_fn) = get_gen_fn(VALUE(opcode)) { // Add a comment for the name of the YARV instruction - asm.comment(&format!("Insn: {:04} {} (stack_size: {})", insn_idx, insn_name(opcode), asm.ctx.get_stack_size())); + asm_comment!(asm, "Insn: {:04} {} (stack_size: {})", insn_idx, insn_name(opcode), asm.ctx.get_stack_size()); // If requested, dump instructions for debugging if get_option!(dump_insns) { @@ -1260,7 +1267,7 @@ fn gen_newarray( let values_ptr = if n == 0 { Opnd::UImm(0) } else { - asm.comment("load pointer to array elements"); + asm_comment!(asm, "load pointer to array elements"); let offset_magnitude = (SIZEOF_VALUE as u32) * n; let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize)); asm.lea(values_opnd) @@ -1412,7 +1419,7 @@ fn guard_object_is_heap( return; } - asm.comment("guard object is heap"); + asm_comment!(asm, "guard object is heap"); // Test that the object is not an immediate asm.test(object, (RUBY_IMMEDIATE_MASK as u64).into()); @@ -1444,7 +1451,7 @@ fn guard_object_is_array( }; guard_object_is_heap(asm, object_reg, object_opnd, counter); - asm.comment("guard object is array"); + asm_comment!(asm, "guard object is array"); // Pull out the type mask let flags_opnd = Opnd::mem(VALUE_BITS, object_reg, RUBY_OFFSET_RBASIC_FLAGS); @@ -1476,7 +1483,7 @@ fn guard_object_is_string( }; guard_object_is_heap(asm, object_reg, object_opnd, counter); - asm.comment("guard object is string"); + asm_comment!(asm, "guard object is string"); // Pull out the type mask let flags_reg = asm.load(Opnd::mem(VALUE_BITS, object_reg, RUBY_OFFSET_RBASIC_FLAGS)); @@ -1500,7 +1507,7 @@ fn guard_object_is_not_ruby2_keyword_hash( object_opnd: Opnd, counter: Counter, ) { - asm.comment("guard object is not ruby2 keyword hash"); + asm_comment!(asm, "guard object is not ruby2 keyword hash"); let not_ruby2_keyword = asm.new_label("not_ruby2_keyword"); asm.test(object_opnd, (RUBY_IMMEDIATE_MASK as u64).into()); @@ -1600,7 +1607,7 @@ fn gen_expandarray( // Guard on the comptime/expected array length if comptime_len >= num { - asm.comment(&format!("guard array length >= {}", num)); + asm_comment!(asm, "guard array length >= {}", num); asm.cmp(array_len_opnd, num.into()); jit_chain_guard( JCC_JB, @@ -1612,7 +1619,7 @@ fn gen_expandarray( ); } else { - asm.comment(&format!("guard array length == {}", comptime_len)); + asm_comment!(asm, "guard array length == {}", comptime_len); asm.cmp(array_len_opnd, comptime_len.into()); jit_chain_guard( JCC_JNE, @@ -1640,7 +1647,7 @@ fn gen_expandarray( let offset = i32::try_from(i * (SIZEOF_VALUE as u32)).unwrap(); // Missing elements are Qnil - asm.comment(&format!("load array[{}]", i)); + asm_comment!(asm, "load array[{}]", i); let elem_opnd = if i < comptime_len { Opnd::mem(64, ary_opnd.unwrap(), offset) } else { Qnil.into() }; asm.mov(top, elem_opnd); } @@ -2145,7 +2152,7 @@ fn gen_get_ivar( if !receiver_t_object || uses_custom_allocator || comptime_receiver.shape_too_complex() || megamorphic { // General case. Call rb_ivar_get(). // VALUE rb_ivar_get(VALUE obj, ID id) - asm.comment("call rb_ivar_get()"); + asm_comment!(asm, "call rb_ivar_get()"); // The function could raise exceptions. jit_prepare_routine_call(jit, asm); @@ -2186,7 +2193,7 @@ fn gen_get_ivar( let shape_id_offset = unsafe { rb_shape_id_offset() }; let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset); - asm.comment("guard shape"); + asm_comment!(asm, "guard shape"); asm.cmp(shape_opnd, Opnd::UImm(expected_shape as u64)); jit_chain_guard( JCC_JNE, @@ -2291,7 +2298,7 @@ fn gen_write_iv( let ivar_opnd = Opnd::mem(64, recv, offs); // Write the IV - asm.comment("write IV"); + asm_comment!(asm, "write IV"); asm.mov(ivar_opnd, set_value); } else { // Compile time value is *not* embedded. @@ -2302,7 +2309,7 @@ fn gen_write_iv( // Write the ivar in to the extended table let ivar_opnd = Opnd::mem(64, tbl_opnd, (SIZEOF_VALUE * ivar_index) as i32); - asm.comment("write IV"); + asm_comment!(asm, "write IV"); asm.mov(ivar_opnd, set_value); } } @@ -2409,7 +2416,7 @@ fn gen_setinstancevariable( // 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 || uses_custom_allocator || shape_too_complex || new_shape_too_complex || megamorphic { - asm.comment("call rb_vm_setinstancevariable()"); + asm_comment!(asm, "call rb_vm_setinstancevariable()"); let ic = jit.get_arg(1).as_u64(); // type IVC @@ -2444,7 +2451,7 @@ fn gen_setinstancevariable( let shape_id_offset = unsafe { rb_shape_id_offset() }; let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset); - asm.comment("guard shape"); + asm_comment!(asm, "guard shape"); asm.cmp(shape_opnd, Opnd::UImm(expected_shape as u64)); jit_chain_guard( JCC_JNE, @@ -2466,7 +2473,7 @@ fn gen_setinstancevariable( if let Some((current_capacity, new_capacity)) = needs_extension { // Generate the C call so that runtime code will increase // the capacity and set the buffer. - asm.comment("call rb_ensure_iv_list_size"); + asm_comment!(asm, "call rb_ensure_iv_list_size"); // It allocates so can trigger GC, which takes the VM lock // so could yield to a different ractor. @@ -2486,7 +2493,7 @@ fn gen_setinstancevariable( write_val = asm.stack_pop(1); gen_write_iv(asm, comptime_receiver, recv, ivar_index, write_val, needs_extension.is_some()); - asm.comment("write shape"); + asm_comment!(asm, "write shape"); let shape_id_offset = unsafe { rb_shape_id_offset() }; let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset); @@ -2518,7 +2525,7 @@ fn gen_setinstancevariable( asm.cmp(write_val, Qnil.into()); asm.jbe(skip_wb); - asm.comment("write barrier"); + asm_comment!(asm, "write barrier"); asm.ccall( rb_gc_writebarrier as *const u8, vec![ @@ -2630,7 +2637,7 @@ fn gen_definedivar( let shape_id_offset = unsafe { rb_shape_id_offset() }; let shape_opnd = Opnd::mem(SHAPE_ID_NUM_BITS as u8, recv, shape_id_offset); - asm.comment("guard shape"); + asm_comment!(asm, "guard shape"); asm.cmp(shape_opnd, Opnd::UImm(shape_id as u64)); jit_chain_guard( JCC_JNE, @@ -2746,19 +2753,19 @@ fn guard_two_fixnums( let arg0_type = asm.ctx.get_opnd_type(arg0.into()); if arg0_type.is_heap() || arg1_type.is_heap() { - asm.comment("arg is heap object"); + asm_comment!(asm, "arg is heap object"); asm.jmp(Target::side_exit(counter)); return; } if arg0_type != Type::Fixnum && arg0_type.is_specific() { - asm.comment("arg0 not fixnum"); + asm_comment!(asm, "arg0 not fixnum"); asm.jmp(Target::side_exit(counter)); return; } if arg1_type != Type::Fixnum && arg1_type.is_specific() { - asm.comment("arg1 not fixnum"); + asm_comment!(asm, "arg1 not fixnum"); asm.jmp(Target::side_exit(counter)); return; } @@ -2770,7 +2777,7 @@ fn guard_two_fixnums( // If not fixnums at run-time, fall back if arg0_type != Type::Fixnum { - asm.comment("guard arg0 fixnum"); + asm_comment!(asm, "guard arg0 fixnum"); asm.test(arg0, Opnd::UImm(RUBY_FIXNUM_FLAG as u64)); jit_chain_guard( @@ -2783,7 +2790,7 @@ fn guard_two_fixnums( ); } if arg1_type != Type::Fixnum { - asm.comment("guard arg1 fixnum"); + asm_comment!(asm, "guard arg1 fixnum"); asm.test(arg1, Opnd::UImm(RUBY_FIXNUM_FLAG as u64)); jit_chain_guard( @@ -3996,7 +4003,7 @@ fn gen_throw( } let val = asm.ccall(rb_vm_throw as *mut u8, vec![EC, CFP, throw_state.into(), throwobj]); - asm.comment("exit from throw"); + asm_comment!(asm, "exit from throw"); asm.cpop_into(SP); asm.cpop_into(EC); asm.cpop_into(CFP); @@ -4060,7 +4067,7 @@ fn jit_guard_known_klass( assert!(!val_type.is_heap()); assert!(val_type.is_unknown()); - asm.comment("guard object is nil"); + asm_comment!(asm, "guard object is nil"); asm.cmp(obj_opnd, Qnil.into()); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); @@ -4069,7 +4076,7 @@ fn jit_guard_known_klass( assert!(!val_type.is_heap()); assert!(val_type.is_unknown()); - asm.comment("guard object is true"); + asm_comment!(asm, "guard object is true"); asm.cmp(obj_opnd, Qtrue.into()); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); @@ -4078,7 +4085,7 @@ fn jit_guard_known_klass( assert!(!val_type.is_heap()); assert!(val_type.is_unknown()); - asm.comment("guard object is false"); + asm_comment!(asm, "guard object is false"); assert!(Qfalse.as_i32() == 0); asm.test(obj_opnd, obj_opnd); jit_chain_guard(JCC_JNZ, jit, asm, ocb, max_chain_depth, counter); @@ -4089,7 +4096,7 @@ fn jit_guard_known_klass( // BIGNUM can be handled by the general else case below assert!(val_type.is_unknown()); - asm.comment("guard object is fixnum"); + asm_comment!(asm, "guard object is fixnum"); asm.test(obj_opnd, Opnd::Imm(RUBY_FIXNUM_FLAG as i64)); jit_chain_guard(JCC_JZ, jit, asm, ocb, max_chain_depth, counter); asm.ctx.upgrade_opnd_type(insn_opnd, Type::Fixnum); @@ -4100,7 +4107,7 @@ fn jit_guard_known_klass( if val_type != Type::ImmSymbol || !val_type.is_imm() { assert!(val_type.is_unknown()); - asm.comment("guard object is static symbol"); + asm_comment!(asm, "guard object is static symbol"); assert!(RUBY_SPECIAL_SHIFT == 8); asm.cmp(obj_opnd.with_num_bits(8).unwrap(), Opnd::UImm(RUBY_SYMBOL_FLAG as u64)); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); @@ -4112,7 +4119,7 @@ fn jit_guard_known_klass( assert!(val_type.is_unknown()); // We will guard flonum vs heap float as though they were separate classes - asm.comment("guard object is flonum"); + asm_comment!(asm, "guard object is flonum"); let flag_bits = asm.and(obj_opnd, Opnd::UImm(RUBY_FLONUM_MASK as u64)); asm.cmp(flag_bits, Opnd::UImm(RUBY_FLONUM_FLAG as u64)); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); @@ -4135,7 +4142,7 @@ fn jit_guard_known_klass( // this situation. // Also, guarding by identity is incorrect for IO objects because // IO#reopen can be used to change the class and singleton class of IO objects! - asm.comment("guard known object with singleton class"); + asm_comment!(asm, "guard known object with singleton class"); asm.cmp(obj_opnd, sample_instance.into()); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); } else if val_type == Type::CString && unsafe { known_klass == rb_cString } { @@ -4149,7 +4156,7 @@ fn jit_guard_known_klass( // Check that the receiver is a heap object // Note: if we get here, the class doesn't have immediate instances. if !val_type.is_heap() { - asm.comment("guard not immediate"); + asm_comment!(asm, "guard not immediate"); asm.test(obj_opnd, (RUBY_IMMEDIATE_MASK as u64).into()); jit_chain_guard(JCC_JNZ, jit, asm, ocb, max_chain_depth, counter); asm.cmp(obj_opnd, Qfalse.into()); @@ -4167,7 +4174,7 @@ fn jit_guard_known_klass( // Bail if receiver class is different from known_klass // TODO: jit_mov_gc_ptr keeps a strong reference, which leaks the class. - asm.comment("guard known class"); + asm_comment!(asm, "guard known class"); asm.cmp(klass_opnd, known_klass.into()); jit_chain_guard(JCC_JNE, jit, asm, ocb, max_chain_depth, counter); @@ -4223,14 +4230,14 @@ fn jit_rb_obj_not( match recv_opnd.known_truthy() { Some(false) => { - asm.comment("rb_obj_not(nil_or_false)"); + asm_comment!(asm, "rb_obj_not(nil_or_false)"); asm.stack_pop(1); let out_opnd = asm.stack_push(Type::True); asm.mov(out_opnd, Qtrue.into()); }, Some(true) => { // Note: recv_opnd != Type::Nil && recv_opnd != Type::False. - asm.comment("rb_obj_not(truthy)"); + asm_comment!(asm, "rb_obj_not(truthy)"); asm.stack_pop(1); let out_opnd = asm.stack_push(Type::False); asm.mov(out_opnd, Qfalse.into()); @@ -4254,7 +4261,7 @@ fn jit_rb_true( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("nil? == true"); + asm_comment!(asm, "nil? == true"); asm.stack_pop(1); let stack_ret = asm.stack_push(Type::True); asm.mov(stack_ret, Qtrue.into()); @@ -4272,7 +4279,7 @@ fn jit_rb_false( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("nil? == false"); + asm_comment!(asm, "nil? == false"); asm.stack_pop(1); let stack_ret = asm.stack_push(Type::False); asm.mov(stack_ret, Qfalse.into()); @@ -4316,7 +4323,7 @@ fn jit_rb_kernel_is_a( } let sample_is_a = unsafe { rb_obj_is_kind_of(sample_lhs, sample_rhs) == Qtrue }; - asm.comment("Kernel#is_a?"); + asm_comment!(asm, "Kernel#is_a?"); asm.cmp(asm.stack_opnd(0), sample_rhs.into()); asm.jne(Target::side_exit(Counter::guard_send_is_a_class_mismatch)); @@ -4375,7 +4382,7 @@ fn jit_rb_kernel_instance_of( let sample_instance_of = sample_lhs_real_class == sample_rhs; - asm.comment("Kernel#instance_of?"); + asm_comment!(asm, "Kernel#instance_of?"); asm.cmp(asm.stack_opnd(0), sample_rhs.into()); jit_chain_guard( JCC_JNE, @@ -4412,7 +4419,7 @@ fn jit_rb_mod_eqq( return false; } - asm.comment("Module#==="); + asm_comment!(asm, "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 @@ -4442,7 +4449,7 @@ fn jit_rb_obj_equal( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("equal?"); + asm_comment!(asm, "equal?"); let obj1 = asm.stack_pop(1); let obj2 = asm.stack_pop(1); @@ -4484,7 +4491,7 @@ fn jit_rb_int_equal( guard_two_fixnums(jit, asm, ocb); // Compare the arguments - asm.comment("rb_int_equal"); + asm_comment!(asm, "rb_int_equal"); let arg1 = asm.stack_pop(1); let arg0 = asm.stack_pop(1); asm.cmp(arg0, arg1); @@ -4495,34 +4502,6 @@ fn jit_rb_int_equal( true } -fn jit_rb_int_mul( - jit: &mut JITState, - asm: &mut Assembler, - ocb: &mut OutlinedCb, - _ci: *const rb_callinfo, - _cme: *const rb_callable_method_entry_t, - _block: Option, - _argc: i32, - _known_recv_class: *const VALUE, -) -> bool { - if asm.ctx.two_fixnums_on_stack(jit) != Some(true) { - return false; - } - guard_two_fixnums(jit, asm, ocb); - - // rb_fix_mul_fix may allocate memory for Bignum - jit_prepare_routine_call(jit, asm); - - asm.comment("Integer#*"); - let obj = asm.stack_pop(1); - let recv = asm.stack_pop(1); - let ret = asm.ccall(rb_fix_mul_fix as *const u8, vec![recv, obj]); - - let ret_opnd = asm.stack_push(Type::Unknown); - asm.mov(ret_opnd, ret); - true -} - fn jit_rb_int_div( jit: &mut JITState, asm: &mut Assembler, @@ -4541,7 +4520,7 @@ fn jit_rb_int_div( // rb_fix_div_fix may GC-allocate for Bignum jit_prepare_routine_call(jit, asm); - asm.comment("Integer#/"); + asm_comment!(asm, "Integer#/"); let obj = asm.stack_pop(1); let recv = asm.stack_pop(1); @@ -4626,7 +4605,7 @@ fn jit_rb_int_aref( } guard_two_fixnums(jit, asm, ocb); - asm.comment("Integer#[]"); + asm_comment!(asm, "Integer#[]"); let obj = asm.stack_pop(1); let recv = asm.stack_pop(1); @@ -4656,7 +4635,7 @@ fn jit_rb_str_uplus( // We allocate when we dup the string jit_prepare_routine_call(jit, asm); - asm.comment("Unary plus on string"); + asm_comment!(asm, "Unary plus on string"); let recv_opnd = asm.stack_pop(1); let recv_opnd = asm.load(recv_opnd); let flags_opnd = asm.load(Opnd::mem(64, recv_opnd, RUBY_OFFSET_RBASIC_FLAGS)); @@ -4691,11 +4670,11 @@ fn jit_rb_str_bytesize( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("String#bytesize"); + asm_comment!(asm, "String#bytesize"); let recv = asm.stack_pop(1); - asm.comment("get string length"); + asm_comment!(asm, "get string length"); let str_len_opnd = Opnd::mem( std::os::raw::c_long::BITS as u8, asm.load(recv), @@ -4723,7 +4702,7 @@ fn jit_rb_str_getbyte( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("String#getbyte"); + asm_comment!(asm, "String#getbyte"); extern "C" { fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE; } @@ -4756,7 +4735,7 @@ fn jit_rb_str_to_s( known_recv_class: *const VALUE, ) -> bool { if !known_recv_class.is_null() && unsafe { *known_recv_class == rb_cString } { - asm.comment("to_s on plain string"); + asm_comment!(asm, "to_s on plain string"); // The method returns the receiver, which is already on the stack. // No stack movement. return true; @@ -4777,7 +4756,7 @@ fn jit_rb_str_empty_p( ) -> bool { let recv_opnd = asm.stack_pop(1); - asm.comment("get string length"); + asm_comment!(asm, "get string length"); let str_len_opnd = Opnd::mem( std::os::raw::c_long::BITS as u8, asm.load(recv_opnd), @@ -4827,7 +4806,7 @@ fn jit_rb_str_concat( // 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"); + asm_comment!(asm, "<< on strings"); // Take receiver's object flags XOR arg's flags. If any // string-encoding flags are different between the two, @@ -4899,7 +4878,7 @@ fn jit_rb_ary_push( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("Array#<<"); + asm_comment!(asm, "Array#<<"); // rb_ary_push allocates memory for buffer extension jit_prepare_routine_call(jit, asm); @@ -5004,7 +4983,7 @@ fn jit_obj_respond_to( let _recv_opnd = asm.stack_pop(1); // This is necessary because we have no guarantee that sym_opnd is a constant - asm.comment("guard known mid"); + asm_comment!(asm, "guard known mid"); asm.cmp(sym_opnd, mid_sym.into()); jit_chain_guard( JCC_JNE, @@ -5030,7 +5009,7 @@ fn jit_rb_f_block_given_p( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("block_given?"); + asm_comment!(asm, "block_given?"); // Same as rb_vm_frame_block_handler let ep_opnd = gen_get_lep(jit, asm); @@ -5059,7 +5038,7 @@ fn jit_thread_s_current( _argc: i32, _known_recv_class: *const VALUE, ) -> bool { - asm.comment("Thread.current"); + asm_comment!(asm, "Thread.current"); asm.stack_pop(1); // ec->thread_ptr @@ -5161,7 +5140,7 @@ fn gen_push_frame( ) { let sp = frame.sp; - asm.comment("push cme, specval, frame type"); + asm_comment!(asm, "push cme, specval, frame type"); // Write method entry at sp[-3] // sp[-3] = me; @@ -5194,9 +5173,6 @@ fn gen_push_frame( let block_handler = asm.load( Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL) ); - - asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_BLOCK_CODE), block_handler); - block_handler } BlockHandler::AlreadySet => 0.into(), // unused @@ -5211,7 +5187,7 @@ fn gen_push_frame( } }; if let SpecVal::BlockHandler(Some(BlockHandler::AlreadySet)) = frame.specval { - asm.comment("specval should have been set"); + asm_comment!(asm, "specval should have been set"); } else { asm.store(Opnd::mem(64, sp, SIZEOF_VALUE_I32 * -2), specval); } @@ -5234,7 +5210,7 @@ fn gen_push_frame( // .ep = , // .block_code = 0, // }; - asm.comment("push callee control frame"); + asm_comment!(asm, "push callee control frame"); // For an iseq call PC may be None, in which case we will not set PC and will allow jitted code // to set it as necessary. @@ -5251,10 +5227,10 @@ fn gen_push_frame( asm.mov(cfp_opnd(RUBY_OFFSET_CFP_SELF), frame.recv); asm.mov(cfp_opnd(RUBY_OFFSET_CFP_BLOCK_CODE), 0.into()); - // Spill stack temps to let the callee use them (must be done before changing SP) - asm.spill_temps(); - if set_sp_cfp { + // Spill stack temps to let the callee use them (must be done before changing the SP register) + asm.spill_temps(); + // Saving SP before calculating ep avoids a dependency on a register // However this must be done after referencing frame.recv, which may be SP-relative asm.mov(SP, sp); @@ -5264,11 +5240,11 @@ fn gen_push_frame( let new_cfp = asm.lea(cfp_opnd(0)); if set_sp_cfp { - asm.comment("switch to new CFP"); + asm_comment!(asm, "switch to new CFP"); asm.mov(CFP, new_cfp); asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP); } else { - asm.comment("set ec->cfp"); + asm_comment!(asm, "set ec->cfp"); asm.store(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), new_cfp); } } @@ -5360,7 +5336,7 @@ fn gen_send_cfunc( // 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_comment!(asm, "stack overflow check"); let stack_limit = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE * 4 + 2 * RUBY_SIZEOF_CONTROL_FRAME) as isize)); asm.cmp(CFP, stack_limit); asm.jbe(Target::side_exit(Counter::guard_send_se_cf_overflow)); @@ -5485,7 +5461,7 @@ fn gen_send_cfunc( if !kw_arg.is_null() { // Build a hash from all kwargs passed - asm.comment("build_kwhash"); + asm_comment!(asm, "build_kwhash"); let imemo_ci = VALUE(ci as usize); assert_ne!(0, unsafe { rb_IMEMO_TYPE_P(imemo_ci, imemo_callinfo) }, "we assume all callinfos with kwargs are on the GC heap"); @@ -5497,22 +5473,17 @@ fn gen_send_cfunc( asm.mov(stack_opnd, kwargs); } - // Copy SP because REG_SP will get overwritten - let sp = asm.lea(asm.ctx.sp_opnd(0)); - - // Pop the C function arguments from the stack (in the caller) - asm.stack_pop((argc + 1).try_into().unwrap()); - // Write interpreter SP into CFP. - // Needed in case the callee yields to the block. - gen_save_sp(asm); + // We don't pop arguments yet to use registers for passing them, but we + // have to set cfp->sp below them for full_cfunc_return() invalidation. + gen_save_sp_with_offset(asm, -(argc + 1) as i8); // Non-variadic method let args = if cfunc_argc >= 0 { // 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).map(|i| - Opnd::mem(64, sp, -(argc + 1 - i) * SIZEOF_VALUE_I32) + asm.stack_opnd(argc - i) ).collect() } // Variadic method @@ -5521,8 +5492,8 @@ fn gen_send_cfunc( // rb_f_puts(int argc, VALUE *argv, VALUE recv) vec![ Opnd::Imm(passed_argc.into()), - asm.lea(Opnd::mem(64, sp, -(argc) * SIZEOF_VALUE_I32)), - Opnd::mem(64, sp, -(argc + 1) * SIZEOF_VALUE_I32), + asm.lea(asm.ctx.sp_opnd((-argc * SIZEOF_VALUE_I32) as isize)), + asm.stack_opnd(argc), ] } else { @@ -5533,8 +5504,9 @@ fn gen_send_cfunc( // 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_comment!(asm, "call C function"); let ret = asm.ccall(unsafe { get_mct_func(cfunc) }.cast(), args); + asm.stack_pop((argc + 1).try_into().unwrap()); // Pop arguments after ccall to use registers for passing them. // Record code position for TracePoint patching. See full_cfunc_return(). record_global_inval_patch(asm, CodegenGlobals::get_outline_full_cfunc_return_pos()); @@ -5564,7 +5536,7 @@ fn gen_send_cfunc( // Generate RARRAY_LEN. For array_opnd, use Opnd::Reg to reduce memory access, // and use Opnd::Mem to save registers. fn get_array_len(asm: &mut Assembler, array_opnd: Opnd) -> Opnd { - asm.comment("get array length for embedded or heap"); + asm_comment!(asm, "get array length for embedded or heap"); // Pull out the embed flag to check if it's an embedded array. let array_reg = match array_opnd { @@ -5597,7 +5569,7 @@ fn get_array_len(asm: &mut Assembler, array_opnd: Opnd) -> Opnd { // Generate RARRAY_CONST_PTR (part of RARRAY_AREF) fn get_array_ptr(asm: &mut Assembler, array_reg: Opnd) -> Opnd { - asm.comment("get array pointer for embedded or heap"); + asm_comment!(asm, "get array pointer for embedded or heap"); let flags_opnd = Opnd::mem(VALUE_BITS, array_reg, RUBY_OFFSET_RBASIC_FLAGS); asm.test(flags_opnd, (RARRAY_EMBED_FLAG as u64).into()); @@ -5616,11 +5588,11 @@ fn get_array_ptr(asm: &mut Assembler, array_reg: Opnd) -> Opnd { /// Pushes arguments from an array to the stack. Differs from push splat because /// the array can have items left over. fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) { - asm.comment("move_rest_args_to_stack"); + asm_comment!(asm, "move_rest_args_to_stack"); let array_len_opnd = get_array_len(asm, array); - asm.comment("Side exit if length is less than required"); + asm_comment!(asm, "Side exit if length is less than required"); asm.cmp(array_len_opnd, num_args.into()); asm.jl(Target::side_exit(Counter::guard_send_iseq_has_rest_and_splat_not_equal)); @@ -5629,7 +5601,7 @@ fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) { return; } - asm.comment("Push arguments from array"); + asm_comment!(asm, "Push arguments from array"); // Load the address of the embedded array // (struct RArray *)(obj)->as.ary @@ -5659,7 +5631,7 @@ fn move_rest_args_to_stack(array: Opnd, num_args: u32, asm: &mut Assembler) { /// It optimistically compiles to a static size that is the exact number of arguments /// needed for the function. fn push_splat_args(required_args: u32, asm: &mut Assembler) { - asm.comment("push_splat_args"); + asm_comment!(asm, "push_splat_args"); let array_opnd = asm.stack_opnd(0); let array_reg = asm.load(array_opnd); @@ -5671,7 +5643,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { Counter::guard_send_splat_not_array, ); - asm.comment("Get array length for embedded or heap"); + asm_comment!(asm, "Get array length for embedded or heap"); // Pull out the embed flag to check if it's an embedded array. let flags_opnd = Opnd::mem(VALUE_BITS, array_reg, RUBY_OFFSET_RBASIC_FLAGS); @@ -5695,11 +5667,11 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { ); let array_len_opnd = asm.csel_nz(emb_len_opnd, array_len_opnd); - asm.comment("Guard for expected splat length"); + asm_comment!(asm, "Guard for expected splat length"); asm.cmp(array_len_opnd, required_args.into()); asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal)); - asm.comment("Check last argument is not ruby2keyword hash"); + asm_comment!(asm, "Check last argument is not ruby2keyword hash"); // Need to repeat this here to deal with register allocation let array_reg = asm.load(asm.stack_opnd(0)); @@ -5714,7 +5686,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { Counter::guard_send_splatarray_last_ruby_2_keywords, ); - asm.comment("Push arguments from array"); + asm_comment!(asm, "Push arguments from array"); let array_opnd = asm.stack_pop(1); if required_args > 0 { @@ -5741,7 +5713,7 @@ fn push_splat_args(required_args: u32, asm: &mut Assembler) { asm.mov(top, Opnd::mem(64, ary_opnd, i as i32 * SIZEOF_VALUE_I32)); } - asm.comment("end push_each"); + asm_comment!(asm, "end push_each"); } } @@ -5998,7 +5970,7 @@ fn gen_send_iseq( // change and we don't change that dynmically so we side exit. // On a normal splat without rest and option args this is handled // elsewhere depending on the case - asm.comment("Side exit if length doesn't not equal compile time length"); + asm_comment!(asm, "Side exit if length doesn't not equal compile time length"); let array_len_opnd = get_array_len(asm, asm.stack_opnd(if block_arg { 1 } else { 0 })); asm.cmp(array_len_opnd, array_length.into()); asm.jne(Target::side_exit(Counter::guard_send_splatarray_length_not_equal)); @@ -6054,7 +6026,7 @@ fn gen_send_iseq( // rest param handling later. Also, since there are C calls that // come later, we can't hold this value in a register and place it // near the end when we push a new control frame. - asm.comment("guard block arg is a proc"); + asm_comment!(asm, "guard block arg is a proc"); // Simple predicate, no need for jit_prepare_routine_call(). let is_proc = asm.ccall(rb_obj_is_proc as _, vec![asm.stack_opnd(0)]); asm.cmp(is_proc, Qfalse.into()); @@ -6086,7 +6058,7 @@ fn gen_send_iseq( if let (None, Some(builtin_info), true, false) = (block, builtin_func, builtin_attrs & BUILTIN_ATTR_LEAF != 0, opt_send_call) { let builtin_argc = unsafe { (*builtin_info).argc }; if builtin_argc + 1 < (C_ARG_OPNDS.len() as i32) { - asm.comment("inlined leaf builtin"); + asm_comment!(asm, "inlined leaf builtin"); // Skip this if it doesn't trigger GC if builtin_attrs & BUILTIN_ATTR_NO_GC == 0 { @@ -6121,7 +6093,7 @@ fn gen_send_iseq( // 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"); + asm_comment!(asm, "stack overflow check"); let stack_max: i32 = unsafe { get_iseq_body_stack_max(iseq) }.try_into().unwrap(); let locals_offs = SIZEOF_VALUE_I32 * (num_locals + stack_max) + 2 * (RUBY_SIZEOF_CONTROL_FRAME as i32); @@ -6159,11 +6131,12 @@ fn gen_send_iseq( let non_rest_arg_count = argc - 1; // We start by dupping the array because someone else might have // a reference to it. This also normalizes to an ::Array instance. - let array = asm.stack_pop(1); + let array = asm.stack_opnd(0); let array = asm.ccall( rb_ary_dup as *const u8, vec![array], ); + asm.stack_pop(1); // Pop array after ccall to use a register for passing it. // This is the end stack state of all `non_rest_arg_count` situations below argc = required_num + opts_filled; @@ -6175,12 +6148,12 @@ fn gen_send_iseq( .try_into().unwrap(); // diff is >0 so no need to worry about null pointer - asm.comment("load pointer to array elements"); + asm_comment!(asm, "load pointer to array elements"); let offset_magnitude = SIZEOF_VALUE as u32 * diff; let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize)); let values_ptr = asm.lea(values_opnd); - asm.comment("prepend stack values to rest array"); + asm_comment!(asm, "prepend stack values to rest array"); let array = asm.ccall( rb_ary_unshift_m as *const u8, vec![Opnd::UImm(diff as u64), values_ptr, array], @@ -6191,7 +6164,7 @@ fn gen_send_iseq( } else if non_rest_arg_count < required_num + opt_num { // If we have fewer arguments than required, we need to take some // from the array and move them to the stack. - asm.comment("take items from splat array"); + asm_comment!(asm, "take items from splat array"); let diff: u32 = (required_num - non_rest_arg_count + opts_filled) .try_into().unwrap(); @@ -6205,13 +6178,13 @@ fn gen_send_iseq( sliced } else { // The arguments are equal so we can just push to the stack - asm.comment("same length for splat array and rest param"); + asm_comment!(asm, "same length for splat array and rest param"); assert!(non_rest_arg_count == required_num + opt_num); array } } else { - asm.comment("rest parameter without splat"); + asm_comment!(asm, "rest parameter without splat"); assert!(argc >= required_num); let n = (argc - required_num - opts_filled) as u32; @@ -6220,7 +6193,7 @@ fn gen_send_iseq( let values_ptr = if n == 0 { Opnd::UImm(0) } else { - asm.comment("load pointer to array elements"); + asm_comment!(asm, "load pointer to array elements"); let offset_magnitude = SIZEOF_VALUE as u32 * n; let values_opnd = asm.ctx.sp_opnd(-(offset_magnitude as isize)); asm.lea(values_opnd) @@ -6285,7 +6258,7 @@ fn gen_send_iseq( // keyword parameters. let keyword = unsafe { get_iseq_body_param_keyword(iseq) }; - asm.comment("keyword args"); + asm_comment!(asm, "keyword args"); // This is the list of keyword arguments that the callee specified // in its initial declaration. @@ -6420,7 +6393,7 @@ fn gen_send_iseq( let arg0_reg = asm.load(arg0_opnd); let array_opnd = get_array_ptr(asm, arg0_reg); - asm.comment("push splat arg0 onto the stack"); + asm_comment!(asm, "push splat arg0 onto the stack"); asm.stack_pop(argc.try_into().unwrap()); for i in 0..lead_num { let stack_opnd = asm.stack_push(Type::Unknown); @@ -6434,7 +6407,7 @@ fn gen_send_iseq( return; } - asm.comment(comment); + asm_comment!(asm, "{}", comment); for i in fill_range { let value_slot = asm.ctx.sp_opnd(i * SIZEOF_VALUE as isize); asm.store(value_slot, Qnil.into()); @@ -6480,7 +6453,7 @@ fn gen_send_iseq( let sp_offset = (argc as isize) + if captured_self { 0 } else { 1 }; // Store the updated SP on the current frame (pop arguments and receiver) - asm.comment("store caller sp"); + asm_comment!(asm, "store caller sp"); let caller_sp = asm.lea(asm.ctx.sp_opnd((SIZEOF_VALUE as isize) * -sp_offset)); asm.store(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_SP), caller_sp); @@ -6796,7 +6769,7 @@ fn gen_struct_aref( // true of the converse. let embedded = unsafe { FL_TEST_RAW(comptime_recv, VALUE(RSTRUCT_EMBED_LEN_MASK)) }; - asm.comment("struct aref"); + asm_comment!(asm, "struct aref"); let recv = asm.stack_pop(1); let recv = asm.load(recv); @@ -6842,7 +6815,7 @@ fn gen_struct_aset( assert!(unsafe { RB_TYPE_P(comptime_recv, RUBY_T_STRUCT) }); assert!((off as i64) < unsafe { RSTRUCT_LEN(comptime_recv) }); - asm.comment("struct aset"); + asm_comment!(asm, "struct aset"); let val = asm.stack_pop(1); let recv = asm.stack_pop(1); @@ -6938,7 +6911,7 @@ fn gen_send_general( let method_name = unsafe { cstr_to_rust_string(rb_id2name(mid)) }; match (class_name, method_name) { (Some(class_name), Some(method_name)) => { - asm.comment(&format!("call to {}#{}", class_name, method_name)) + asm_comment!(asm, "call to {}#{}", class_name, method_name); } _ => {} } @@ -7204,7 +7177,7 @@ fn gen_send_general( let symbol_id_opnd = asm.ccall(rb_get_symbol_id as *const u8, vec![name_opnd]); - asm.comment("chain_guard_send"); + asm_comment!(asm, "chain_guard_send"); asm.cmp(symbol_id_opnd, mid.into()); jit_chain_guard( JCC_JNE, @@ -7361,7 +7334,7 @@ fn gen_send_general( /// /// We do this for our compiletime context and the actual stack fn handle_opt_send_shift_stack(asm: &mut Assembler, argc: i32) { - asm.comment("shift_stack"); + asm_comment!(asm, "shift_stack"); for j in (0..argc).rev() { let opnd = asm.stack_opnd(j); let opnd2 = asm.stack_opnd(j + 1); @@ -7473,13 +7446,13 @@ fn gen_invokeblock_specialized( gen_counter_incr(asm, Counter::invokeblock_none); None } else if comptime_handler.0 & 0x3 == 0x1 { // VM_BH_ISEQ_BLOCK_P - asm.comment("get local EP"); + asm_comment!(asm, "get local EP"); let ep_opnd = gen_get_lep(jit, asm); let block_handler_opnd = asm.load( Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL) ); - asm.comment("guard block_handler type"); + asm_comment!(asm, "guard block_handler type"); let tag_opnd = asm.and(block_handler_opnd, 0x3.into()); // block_handler is a tagged pointer asm.cmp(tag_opnd, 0x1.into()); // VM_BH_ISEQ_BLOCK_P jit_chain_guard( @@ -7494,10 +7467,10 @@ fn gen_invokeblock_specialized( let comptime_captured = unsafe { ((comptime_handler.0 & !0x3) as *const rb_captured_block).as_ref().unwrap() }; let comptime_iseq = unsafe { *comptime_captured.code.iseq.as_ref() }; - asm.comment("guard known ISEQ"); + asm_comment!(asm, "guard known ISEQ"); let captured_opnd = asm.and(block_handler_opnd, Opnd::Imm(!0x3)); let iseq_opnd = asm.load(Opnd::mem(64, captured_opnd, SIZEOF_VALUE_I32 * 2)); - asm.cmp(iseq_opnd, (comptime_iseq as usize).into()); + asm.cmp(iseq_opnd, VALUE::from(comptime_iseq).into()); jit_chain_guard( JCC_JNE, jit, @@ -7532,13 +7505,13 @@ fn gen_invokeblock_specialized( return None; } - asm.comment("get local EP"); + asm_comment!(asm, "get local EP"); let ep_opnd = gen_get_lep(jit, asm); let block_handler_opnd = asm.load( Opnd::mem(64, ep_opnd, SIZEOF_VALUE_I32 * VM_ENV_DATA_INDEX_SPECVAL) ); - asm.comment("guard block_handler type"); + asm_comment!(asm, "guard block_handler type"); let tag_opnd = asm.and(block_handler_opnd, 0x3.into()); // block_handler is a tagged pointer asm.cmp(tag_opnd, 0x3.into()); // VM_BH_IFUNC_P jit_chain_guard( @@ -7556,7 +7529,7 @@ fn gen_invokeblock_specialized( extern "C" { fn rb_vm_yield_with_cfunc(ec: EcPtr, captured: *const rb_captured_block, argc: c_int, argv: *const VALUE) -> VALUE; } - asm.comment("call ifunc"); + asm_comment!(asm, "call ifunc"); let captured_opnd = asm.and(block_handler_opnd, Opnd::Imm(!0x3)); let argv = asm.lea(asm.ctx.sp_opnd((-argc * SIZEOF_VALUE_I32) as isize)); let ret = asm.ccall( @@ -7696,7 +7669,7 @@ fn gen_invokesuper_specialized( return None; } - asm.comment("guard known me"); + asm_comment!(asm, "guard known me"); let lep_opnd = gen_get_lep(jit, asm); let ep_me_opnd = Opnd::mem( 64, @@ -7752,7 +7725,7 @@ fn gen_leave( // Pop the current frame (ec->cfp++) // Note: the return PC is already in the previous CFP - asm.comment("pop stack frame"); + asm_comment!(asm, "pop stack frame"); let incr_cfp = asm.add(CFP, RUBY_SIZEOF_CONTROL_FRAME.into()); asm.mov(CFP, incr_cfp); asm.mov(Opnd::mem(64, EC, RUBY_OFFSET_EC_CFP), CFP); @@ -7964,25 +7937,25 @@ fn gen_getspecial( jit_prepare_routine_call(jit, asm); // call rb_backref_get() - asm.comment("rb_backref_get"); + asm_comment!(asm, "rb_backref_get"); let backref = asm.ccall(rb_backref_get as *const u8, vec![]); let rt_u8: u8 = (rtype >> 1).try_into().unwrap(); let val = match rt_u8.into() { '&' => { - asm.comment("rb_reg_last_match"); + asm_comment!(asm, "rb_reg_last_match"); asm.ccall(rb_reg_last_match as *const u8, vec![backref]) } '`' => { - asm.comment("rb_reg_match_pre"); + asm_comment!(asm, "rb_reg_match_pre"); asm.ccall(rb_reg_match_pre as *const u8, vec![backref]) } '\'' => { - asm.comment("rb_reg_match_post"); + asm_comment!(asm, "rb_reg_match_post"); asm.ccall(rb_reg_match_post as *const u8, vec![backref]) } '+' => { - asm.comment("rb_reg_match_last"); + asm_comment!(asm, "rb_reg_match_last"); asm.ccall(rb_reg_match_last as *const u8, vec![backref]) } _ => panic!("invalid back-ref"), @@ -7999,11 +7972,11 @@ fn gen_getspecial( jit_prepare_routine_call(jit, asm); // call rb_backref_get() - asm.comment("rb_backref_get"); + asm_comment!(asm, "rb_backref_get"); let backref = asm.ccall(rb_backref_get as *const u8, vec![]); // rb_reg_nth_match((int)(type >> 1), backref); - asm.comment("rb_reg_nth_match"); + asm_comment!(asm, "rb_reg_nth_match"); let val = asm.ccall( rb_reg_nth_match as *const u8, vec![ @@ -8776,7 +8749,6 @@ impl CodegenGlobals { self.yjit_reg_method(rb_cInteger, "==", jit_rb_int_equal); self.yjit_reg_method(rb_cInteger, "===", jit_rb_int_equal); - self.yjit_reg_method(rb_cInteger, "*", jit_rb_int_mul); self.yjit_reg_method(rb_cInteger, "/", jit_rb_int_div); self.yjit_reg_method(rb_cInteger, "<<", jit_rb_int_lshift); self.yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref); diff --git a/yjit/src/core.rs b/yjit/src/core.rs index 805b7dd68599ce..acea71179e0f3f 100644 --- a/yjit/src/core.rs +++ b/yjit/src/core.rs @@ -550,7 +550,7 @@ impl BranchGenFn { asm.jb(target0) } BranchGenFn::JITReturn => { - asm.comment("update cfp->jit_return"); + asm_comment!(asm, "update cfp->jit_return"); asm.mov(Opnd::mem(64, CFP, RUBY_OFFSET_CFP_JIT_RETURN), Opnd::const_ptr(target0.unwrap_code_ptr().raw_ptr())); } } @@ -2213,7 +2213,7 @@ pub fn gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exception: bool) -> Option< // Change the entry's jump target from an entry stub to a next entry pub fn regenerate_entry(cb: &mut CodeBlock, entryref: &EntryRef, next_entry: CodePtr) { let mut asm = Assembler::new(); - asm.comment("regenerate_entry"); + asm_comment!(asm, "regenerate_entry"); // gen_entry_guard generates cmp + jne. We're rewriting only jne. asm.jne(next_entry.into()); @@ -2248,7 +2248,7 @@ c_callable! { /// See [gen_call_entry_stub_hit]. fn entry_stub_hit(entry_ptr: *const c_void, ec: EcPtr) -> *const u8 { with_vm_lock(src_loc!(), || { - match entry_stub_hit_body(entry_ptr, ec) { + match with_compile_time(|| { entry_stub_hit_body(entry_ptr, ec) }) { Some(addr) => addr, // Failed to service the stub by generating a new block so now we // need to exit to the interpreter at the stubbed location. @@ -2322,7 +2322,7 @@ pub fn gen_entry_stub(entry_address: usize, ocb: &mut OutlinedCb) -> Option CodePtr { let mut asm = Assembler::new(); // See gen_entry_guard for how it's used. - asm.comment("entry_stub_hit() trampoline"); + asm_comment!(asm, "entry_stub_hit() trampoline"); let jump_addr = asm.ccall(entry_stub_hit as *mut u8, vec![C_ARG_OPNDS[0], EC]); // Jump to the address returned by the entry_stub_hit() call @@ -2370,7 +2370,7 @@ fn regenerate_branch(cb: &mut CodeBlock, branch: &Branch) { // Generate the branch let mut asm = Assembler::new(); - asm.comment("regenerate_branch"); + asm_comment!(asm, "regenerate_branch"); branch.gen_fn.call( &mut asm, Target::CodePtr(branch.get_target_address(0).unwrap()), @@ -2441,7 +2441,7 @@ c_callable! { ec: EcPtr, ) -> *const u8 { with_vm_lock(src_loc!(), || { - branch_stub_hit_body(branch_ptr, target_idx, ec) + with_compile_time(|| { branch_stub_hit_body(branch_ptr, target_idx, ec) }) }) } } @@ -2482,9 +2482,6 @@ fn branch_stub_hit_body(branch_ptr: *const c_void, target_idx: u32, ec: EcPtr) - (target.get_blockid(), target.get_ctx()) }; - let cb = CodegenGlobals::get_inline_cb(); - let ocb = CodegenGlobals::get_outlined_cb(); - let (cfp, original_interp_sp) = unsafe { let cfp = get_ec_cfp(ec); let original_interp_sp = get_cfp_sp(cfp); @@ -2506,9 +2503,18 @@ fn branch_stub_hit_body(branch_ptr: *const c_void, target_idx: u32, ec: EcPtr) - // So we do it here instead. rb_set_cfp_sp(cfp, reconned_sp); + // Bail if we're about to run out of native stack space. + // We've just reconstructed interpreter state. + if rb_ec_stack_check(ec as _) != 0 { + return CodegenGlobals::get_stub_exit_code().raw_ptr(); + } + (cfp, original_interp_sp) }; + let cb = CodegenGlobals::get_inline_cb(); + let ocb = CodegenGlobals::get_outlined_cb(); + // Try to find an existing compiled version of this block let mut block = find_block_version(target_blockid, &target_ctx); let mut branch_modified = false; @@ -2617,7 +2623,7 @@ fn gen_branch_stub( let mut asm = Assembler::new(); asm.ctx = ctx.clone(); asm.set_reg_temps(ctx.reg_temps); - asm.comment("branch stub hit"); + asm_comment!(asm, "branch stub hit"); // Save caller-saved registers before C_ARG_OPNDS get clobbered. // Spill all registers for consistency with the trampoline. @@ -2662,7 +2668,7 @@ pub fn gen_branch_stub_hit_trampoline(ocb: &mut OutlinedCb) -> CodePtr { // is the unchanging part. // Since this trampoline is static, it allows code GC inside // branch_stub_hit() to free stubs without problems. - asm.comment("branch_stub_hit() trampoline"); + asm_comment!(asm, "branch_stub_hit() trampoline"); let jump_addr = asm.ccall( branch_stub_hit as *mut u8, vec![ @@ -2688,7 +2694,7 @@ pub fn gen_branch_stub_hit_trampoline(ocb: &mut OutlinedCb) -> CodePtr { /// Return registers to be pushed and popped on branch_stub_hit. /// The return value may include an extra register for x86 alignment. fn caller_saved_temp_regs() -> Vec { - let mut regs = Assembler::get_temp_regs(); + let mut regs = Assembler::get_temp_regs().to_vec(); if regs.len() % 2 == 1 { regs.push(*regs.last().unwrap()); // x86 alignment } @@ -2787,7 +2793,7 @@ pub fn gen_direct_jump(jit: &mut JITState, ctx: &Context, target0: BlockId, asm: let block_addr = block.start_addr; // Call the branch generation function - asm.comment("gen_direct_jmp: existing block"); + asm_comment!(asm, "gen_direct_jmp: existing block"); asm.mark_branch_start(&branch); branch.gen_fn.call(asm, Target::CodePtr(block_addr), None); asm.mark_branch_end(&branch); @@ -2795,7 +2801,7 @@ pub fn gen_direct_jump(jit: &mut JITState, ctx: &Context, target0: BlockId, asm: BranchTarget::Block(blockref) } else { // The branch is effectively empty (a noop) - asm.comment("gen_direct_jmp: fallthrough"); + asm_comment!(asm, "gen_direct_jmp: fallthrough"); asm.mark_branch_start(&branch); asm.mark_branch_end(&branch); branch.gen_fn.set_shape(BranchShape::Next0); @@ -2841,7 +2847,7 @@ pub fn defer_compilation( let target0_address = branch.set_target(0, blockid, &next_ctx, ocb); // Call the branch generation function - asm.comment("defer_compilation"); + asm_comment!(asm, "defer_compilation"); asm.mark_branch_start(&branch); if let Some(dst_addr) = target0_address { branch.gen_fn.call(asm, Target::CodePtr(dst_addr), None); diff --git a/yjit/src/cruby_bindings.inc.rs b/yjit/src/cruby_bindings.inc.rs index ccf5b530d6732e..3e2961aa7263e9 100644 --- a/yjit/src/cruby_bindings.inc.rs +++ b/yjit/src/cruby_bindings.inc.rs @@ -1173,6 +1173,7 @@ extern "C" { ) -> *const rb_callable_method_entry_t; pub fn rb_obj_info(obj: VALUE) -> *const ::std::os::raw::c_char; pub fn rb_class_allocate_instance(klass: VALUE) -> VALUE; + pub fn rb_ec_stack_check(ec: *mut rb_execution_context_struct) -> ::std::os::raw::c_int; pub fn rb_shape_id_offset() -> i32; pub fn rb_shape_get_shape_by_id(shape_id: shape_id_t) -> *mut rb_shape_t; pub fn rb_shape_get_shape_id(obj: VALUE) -> shape_id_t; diff --git a/yjit/src/options.rs b/yjit/src/options.rs index cbed2718195b0a..44254d15572bfb 100644 --- a/yjit/src/options.rs +++ b/yjit/src/options.rs @@ -1,5 +1,5 @@ use std::ffi::CStr; -use crate::backend::ir::Assembler; +use crate::backend::current::TEMP_REGS; // Command-line options #[derive(Clone, PartialEq, Eq, Debug)] @@ -156,7 +156,7 @@ pub fn parse_option(str_ptr: *const std::os::raw::c_char) -> Option<()> { ("temp-regs", _) => match opt_val.parse() { Ok(n) => { - assert!(n <= Assembler::TEMP_REGS.len(), "--yjit-temp-regs must be <= {}", Assembler::TEMP_REGS.len()); + assert!(n <= TEMP_REGS.len(), "--yjit-temp-regs must be <= {}", TEMP_REGS.len()); unsafe { OPTIONS.num_temp_regs = n } } Err(_) => { diff --git a/yjit/src/stats.rs b/yjit/src/stats.rs index a4f95db6ae15cb..7eae0cba21e295 100644 --- a/yjit/src/stats.rs +++ b/yjit/src/stats.rs @@ -3,6 +3,10 @@ #![allow(dead_code)] // Counters are only used with the stats features +use std::alloc::{GlobalAlloc, Layout, System}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::time::Instant; + use crate::codegen::CodegenGlobals; use crate::core::Context; use crate::core::for_each_iseq_payload; @@ -10,13 +14,42 @@ use crate::cruby::*; use crate::options::*; use crate::yjit::yjit_enabled_p; -// stats_alloc is a middleware to instrument global allocations in Rust. -#[cfg(feature="stats")] +/// A middleware to count Rust-allocated bytes as yjit_alloc_size. #[global_allocator] -static GLOBAL_ALLOCATOR: &stats_alloc::StatsAlloc = &stats_alloc::INSTRUMENTED_SYSTEM; +static GLOBAL_ALLOCATOR: StatsAlloc = StatsAlloc { alloc_size: AtomicUsize::new(0) }; + +pub struct StatsAlloc { + alloc_size: AtomicUsize, +} + +unsafe impl GlobalAlloc for StatsAlloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + self.alloc_size.fetch_add(layout.size(), Ordering::SeqCst); + System.alloc(layout) + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + self.alloc_size.fetch_sub(layout.size(), Ordering::SeqCst); + System.dealloc(ptr, layout) + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + self.alloc_size.fetch_add(layout.size(), Ordering::SeqCst); + System.alloc_zeroed(layout) + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + if new_size > layout.size() { + self.alloc_size.fetch_add(new_size - layout.size(), Ordering::SeqCst); + } else if new_size < layout.size() { + self.alloc_size.fetch_sub(layout.size() - new_size, Ordering::SeqCst); + } + System.realloc(ptr, layout, new_size) + } +} // YJIT exit counts for each instruction type -const VM_INSTRUCTION_SIZE_USIZE:usize = VM_INSTRUCTION_SIZE as usize; +const VM_INSTRUCTION_SIZE_USIZE: usize = VM_INSTRUCTION_SIZE as usize; static mut EXIT_OP_COUNT: [u64; VM_INSTRUCTION_SIZE_USIZE] = [0; VM_INSTRUCTION_SIZE_USIZE]; /// Global state needed for collecting backtraces of exits @@ -165,13 +198,14 @@ macro_rules! make_counters { /// The list of counters that are available without --yjit-stats. /// They are incremented only by `incr_counter!` and don't use `gen_counter_incr`. -pub const DEFAULT_COUNTERS: [Counter; 6] = [ +pub const DEFAULT_COUNTERS: [Counter; 7] = [ Counter::code_gc_count, Counter::compiled_iseq_entry, Counter::compiled_iseq_count, Counter::compiled_blockid_count, Counter::compiled_block_count, Counter::compiled_branch_count, + Counter::compile_time_ns, ]; /// Macro to increase a counter by name and count @@ -411,6 +445,7 @@ make_counters! { compiled_blockid_count, compiled_block_count, compiled_branch_count, + compile_time_ns, compilation_failure, block_next_count, defer_count, @@ -588,8 +623,7 @@ fn rb_yjit_gen_stats_dict(context: bool) -> VALUE { hash_aset_usize!(hash, "code_region_size", cb.mapped_region_size()); // Rust global allocations in bytes - #[cfg(feature="stats")] - hash_aset_usize!(hash, "yjit_alloc_size", global_allocation_size()); + hash_aset_usize!(hash, "yjit_alloc_size", GLOBAL_ALLOCATOR.alloc_size.load(Ordering::SeqCst)); // `context` is true at RubyVM::YJIT._print_stats for --yjit-stats. It's false by default // for RubyVM::YJIT.runtime_stats because counting all Contexts could be expensive. @@ -833,9 +867,11 @@ pub extern "C" fn rb_yjit_count_side_exit_op(exit_pc: *const VALUE) -> *const VA return exit_pc; } -// Get the size of global allocations in Rust. -#[cfg(feature="stats")] -fn global_allocation_size() -> usize { - let stats = GLOBAL_ALLOCATOR.stats(); - stats.bytes_allocated.saturating_sub(stats.bytes_deallocated) +/// Measure the time taken by func() and add that to yjit_compile_time. +pub fn with_compile_time(func: F) -> R where F: FnOnce() -> R { + let start = Instant::now(); + let ret = func(); + let nanos = Instant::now().duration_since(start).as_nanos(); + incr_counter_by!(compile_time_ns, nanos); + ret } diff --git a/yjit/src/yjit.rs b/yjit/src/yjit.rs index 7f4cbbe18d017f..2aed3c6a4b75b1 100644 --- a/yjit/src/yjit.rs +++ b/yjit/src/yjit.rs @@ -5,6 +5,7 @@ use crate::invariants::*; use crate::options::*; use crate::stats::YjitExitLocations; use crate::stats::incr_counter; +use crate::stats::with_compile_time; use std::os::raw; use std::sync::atomic::{AtomicBool, Ordering}; @@ -113,6 +114,11 @@ fn rb_bug_panic_hook() { /// See [jit_compile_exception] for details. #[no_mangle] pub extern "C" fn rb_yjit_iseq_gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exception: bool) -> *const u8 { + // Don't compile when there is insufficient native stack space + if unsafe { rb_ec_stack_check(ec as _) } != 0 { + return std::ptr::null(); + } + // Reject ISEQs with very large temp stacks, // this will allow us to use u8/i8 values to track stack_size and sp_offset let stack_max = unsafe { rb_get_iseq_body_stack_max(iseq) }; @@ -130,7 +136,7 @@ pub extern "C" fn rb_yjit_iseq_gen_entry_point(iseq: IseqPtr, ec: EcPtr, jit_exc return std::ptr::null(); } - let maybe_code_ptr = gen_entry_point(iseq, ec, jit_exception); + let maybe_code_ptr = with_compile_time(|| { gen_entry_point(iseq, ec, jit_exception) }); match maybe_code_ptr { Some(ptr) => ptr.raw_ptr(),