Skip to content

Commit 87d73e1

Browse files
committed
Add prism parser support
Resolves #385 Related Prism bug: ruby/prism#3540 (merged) `test/corpus/literal/before/34.rb` contains expressions rejected by Prism (and regexp-related bug, see #385 (comment)): ```bash $ ASDF_RUBY_VERSION=3.4.2 ruby --parser prism test/corpus/literal/before/34.rb test/corpus/literal/before/34.rb:1: syntax errors found (SyntaxError) > 1 | retry | ^~~~~ Invalid retry without rescue > 2 | in {"#{"a"}": 1} then | ^~ unexpected 'in', ignoring it | ^~~~ unexpected 'then', ignoring it | ^~~~ unexpected 'then', expecting end-of-input 3 | true 4 | /\c*a/ 5 | /\c*a\c*/ 6 | /\c*\c*\c*/ > 7 | (break foo) || a | ^~~~~~~~~ Invalid break | ^~~~~~~~~ unexpected void value expression > 8 | (return foo) || a | ^~~~~~~~~~ unexpected void value expression > 9 | a = b || break | ^~~~~ Invalid break > 10 | a = b || next | ^~~~ Invalid next > 11 | a || (break foo) | ^~~~~~~~~ Invalid break > 12 | b or break | ^~~~~ Invalid break > 13 | b or next | ^~~~ Invalid next > 14 | break or b | ^~~~~ Invalid break | ^~~~~ unexpected void value expression > 15 | next or b | ^~~~ Invalid next | ^~~~ unexpected void value expression > 16 | return or a | ^~~~~~ unexpected void value expression ```
1 parent 05b9468 commit 87d73e1

31 files changed

+576
-353
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
strategy:
2020
fail-fast: false
2121
matrix:
22-
ruby: [ruby-3.2, ruby-3.3]
22+
ruby: [ruby-3.2, ruby-3.3, ruby-3.4]
2323
os: [ubuntu-latest]
2424
steps:
2525
- uses: actions/checkout@v4
@@ -35,7 +35,7 @@ jobs:
3535
strategy:
3636
fail-fast: false
3737
matrix:
38-
ruby: [ruby-3.2, ruby-3.3]
38+
ruby: [ruby-3.2, ruby-3.3, ruby-3.4]
3939
os: [ubuntu-latest]
4040
steps:
4141
- uses: actions/checkout@v4
@@ -53,7 +53,7 @@ jobs:
5353
strategy:
5454
fail-fast: false
5555
matrix:
56-
ruby: [ruby-3.2, ruby-3.3]
56+
ruby: [ruby-3.2, ruby-3.3, ruby-3.4]
5757
os: [ubuntu-latest]
5858
steps:
5959
- uses: actions/checkout@v4
@@ -69,7 +69,7 @@ jobs:
6969
strategy:
7070
fail-fast: false
7171
matrix:
72-
ruby: [ruby-3.2, ruby-3.3]
72+
ruby: [ruby-3.2, ruby-3.3, ruby-3.4]
7373
os: [ubuntu-latest]
7474
steps:
7575
- uses: actions/checkout@v4
@@ -85,7 +85,7 @@ jobs:
8585
strategy:
8686
fail-fast: false
8787
matrix:
88-
ruby: [ruby-3.2, ruby-3.3]
88+
ruby: [ruby-3.2, ruby-3.3, ruby-3.4]
8989
os: [ubuntu-latest]
9090
steps:
9191
- uses: actions/checkout@v4

.rspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--color
22
--format progress
3-
--warnings
3+
# --warnings
44
--order random
55
--require spec_helper

.tool-versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ruby 3.4.3

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
# Unreleased
2+
3+
[#387](https://github.com/mbj/unparser/pull/387)
4+
5+
* Add `prism` parser support for Ruby 3.4. ([viralpraxis](https://github.com/viralpraxis))
6+
17
# v0.7.0 2025-03-16
28

39
[#366](https://github.com/mbj/unparser/pull/366)

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
source 'https://rubygems.org'
44

5+
gem 'pry'
6+
57
gemspec

Gemfile.lock

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,24 @@ PATH
44
unparser (0.7.0)
55
diff-lcs (~> 1.6)
66
parser (>= 3.3.0)
7+
prism (>= 1.4)
78

89
GEM
910
remote: https://rubygems.org/
1011
specs:
1112
ast (2.4.3)
13+
coderay (1.1.3)
14+
date (3.4.1)
1215
diff-lcs (1.6.1)
16+
io-console (0.8.0)
17+
irb (1.15.2)
18+
pp (>= 0.6.0)
19+
rdoc (>= 4.0.0)
20+
reline (>= 0.4.2)
1321
json (2.10.2)
1422
language_server-protocol (3.17.0.4)
1523
lint_roller (1.1.0)
24+
method_source (1.1.0)
1625
mutant (0.13.1)
1726
diff-lcs (~> 1.3)
1827
parser (~> 3.3.0)
@@ -26,10 +35,23 @@ GEM
2635
parser (3.3.8.0)
2736
ast (~> 2.4.1)
2837
racc
38+
pp (0.6.2)
39+
prettyprint
40+
prettyprint (0.2.0)
2941
prism (1.4.0)
42+
pry (0.15.2)
43+
coderay (~> 1.1)
44+
method_source (~> 1.0)
45+
psych (5.2.3)
46+
date
47+
stringio
3048
racc (1.8.1)
3149
rainbow (3.1.1)
50+
rdoc (6.13.1)
51+
psych (>= 4.0.0)
3252
regexp_parser (2.10.0)
53+
reline (0.6.1)
54+
io-console (~> 0.5)
3355
rspec (3.13.0)
3456
rspec-core (~> 3.13.0)
3557
rspec-expectations (~> 3.13.0)
@@ -65,6 +87,7 @@ GEM
6587
rubocop (>= 1.72.1, < 2.0)
6688
ruby-progressbar (1.13.0)
6789
sorbet-runtime (0.5.12028)
90+
stringio (3.1.7)
6891
unicode-display_width (3.1.4)
6992
unicode-emoji (~> 4.0, >= 4.0.4)
7093
unicode-emoji (4.0.4)
@@ -74,8 +97,10 @@ PLATFORMS
7497
x86_64-linux
7598

7699
DEPENDENCIES
100+
irb
77101
mutant (~> 0.13.0)
78102
mutant-rspec (~> 0.13.0)
103+
pry
79104
rspec (~> 3.13)
80105
rspec-core (~> 3.13)
81106
rspec-its (~> 1.3.0)

bin/corpus

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module Unparser
2424
# rubocop:disable Metrics/AbcSize
2525
# rubocop:disable Metrics/MethodLength
2626
def verify
27-
puts("Verifiying: #{name}")
27+
puts("Verifying: #{name}")
2828
checkout
2929

3030
paths = Pathname.glob(Pathname.new(repo_path).join('**/*.rb'))

bin/parser-prism-round-trip-test

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require 'unparser'
5+
require 'prism'
6+
require 'fileutils'
7+
require 'pathname'
8+
9+
module PrismParser
10+
PARSER = 'ruby/prism'
11+
PARSER_VERSION = Prism::VERSION
12+
PARSER_PATH = Pathname('tmp/parser-prism')
13+
14+
PRISM_INVALID = Set[
15+
'def __ENCODING__.a',
16+
'def __FILE__.a',
17+
'def __LINE__.a',
18+
'\777',
19+
'ち\xE3\x81\xFF',
20+
'\x8E\x01',
21+
'a\xE9b',
22+
'a\247b',
23+
'\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99',
24+
'hello \u{fc}',
25+
'# encoding: sjis'
26+
].freeze
27+
28+
PRISM_TODO = Set[
29+
'0..',
30+
'def a(...); "foo#{b(...)}"; end',
31+
'(a,), = []',
32+
'foo = 1, 2 rescue nil',
33+
'`
34+
foo\
35+
b\nar
36+
`',
37+
].freeze
38+
39+
PRISM_NO_ROUND_TRIP = (PRISM_INVALID + PRISM_TODO).to_set.freeze
40+
41+
private_constant :PRISM_INVALID, :PRISM_TODO
42+
43+
class << self
44+
def prepare # rubocop:disable Metrics
45+
FileUtils.rm_rf("#{PARSER_PATH}/test/prism/fixtures-tmp")
46+
Dir.mkdir("#{PARSER_PATH}/test/prism/fixtures-tmp")
47+
Dir.glob("#{PARSER_PATH}/test/prism/fixtures/**/*.txt")
48+
.reject { _1.include?('unparser/') }
49+
.each do |path|
50+
examples = File.read(path).split(/(?<=\n\n)/).reject do |example|
51+
PRISM_NO_ROUND_TRIP.any? { |snippet| example.include?(snippet) }
52+
end
53+
path = Pathname(path).relative_path_from("#{PARSER_PATH}/test/prism/fixtures").to_s
54+
path = "#{PARSER_PATH}/test/prism/fixtures-tmp/#{path}"
55+
56+
dirname = File.dirname(path)
57+
unless File.directory?(dirname)
58+
FileUtils.mkdir_p(dirname)
59+
end
60+
File.write(path, examples.join("\n\n"))
61+
end
62+
end
63+
64+
def target_glob
65+
"#{PARSER_PATH}/test/prism/fixtures-tmp/**/*.txt"
66+
end
67+
68+
def excludes
69+
%w[
70+
spanning_heredoc
71+
heredocs_with_fake_newlines
72+
heredocs_nested
73+
].to_set { |file| "#{PARSER_PATH}/test/prism/fixtures-tmp/#{file}.txt" }
74+
end
75+
76+
end
77+
end
78+
79+
unless PrismParser::PARSER_PATH.exist?
80+
Kernel.system(
81+
*%W[
82+
git
83+
clone
84+
https://github.com/#{PrismParser::PARSER}
85+
#{PrismParser::PARSER_PATH}
86+
],
87+
exception: true
88+
)
89+
end
90+
91+
Dir.chdir(PrismParser::PARSER_PATH) do
92+
Kernel.system(
93+
*%W[
94+
git
95+
checkout
96+
v#{PrismParser::PARSER_VERSION}
97+
],
98+
exception: true
99+
)
100+
Kernel.system(*%w[git clean --force -d -X], exception: true)
101+
end
102+
103+
ignores_cli_option = PrismParser.excludes.flat_map { |file| ['--ignore', file] }
104+
105+
PrismParser.prepare
106+
exit Unparser::CLI.run([PrismParser.target_glob, *ignores_cli_option])

0 commit comments

Comments
 (0)