Skip to content

Commit b4d2ae5

Browse files
authored
Merge pull request #387 from viralpraxis/add-prism-support
Add `prism` parser support
2 parents 9946c0c + 1e4963e commit b4d2ae5

File tree

22 files changed

+524
-343
lines changed

22 files changed

+524
-343
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

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.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ 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/

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: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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+
'def a(...); "foo#{b(...)}"; end',
30+
'`
31+
foo\
32+
b\nar
33+
`',
34+
].freeze
35+
36+
PRISM_NO_ROUND_TRIP = (PRISM_INVALID + PRISM_TODO).to_set.freeze
37+
38+
private_constant :PRISM_INVALID, :PRISM_TODO
39+
40+
class << self
41+
def prepare
42+
FileUtils.rm_rf("#{PARSER_PATH}/test/prism/fixtures-tmp")
43+
Dir.mkdir("#{PARSER_PATH}/test/prism/fixtures-tmp")
44+
45+
Dir.glob("#{PARSER_PATH}/test/prism/fixtures/**/*.txt")
46+
.then(&method(:select_fixtures))
47+
.each do |path|
48+
examples = File.read(path).split(/(?<=\n\n)/).then(&method(:reject_no_round_trip_examples))
49+
output_path = path.gsub('prism/fixtures', 'prism/fixtures-tmp')
50+
dirname = File.dirname(output_path)
51+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
52+
File.write(output_path, examples.join("\n\n"))
53+
end
54+
end
55+
56+
def target_glob
57+
"#{PARSER_PATH}/test/prism/fixtures-tmp/**/*.txt"
58+
end
59+
60+
def excludes
61+
%w[
62+
spanning_heredoc
63+
heredocs_with_fake_newlines
64+
heredocs_nested
65+
].to_set { |file| "#{PARSER_PATH}/test/prism/fixtures-tmp/#{file}.txt" }
66+
end
67+
68+
private
69+
70+
def select_fixtures(paths)
71+
paths.reject { _1.include?('fixtures/unparser/') }
72+
end
73+
74+
def reject_no_round_trip_examples(examples)
75+
examples.reject do |example|
76+
PRISM_NO_ROUND_TRIP.any? { |snippet| example.include?(snippet) }
77+
end
78+
end
79+
end
80+
end
81+
82+
unless PrismParser::PARSER_PATH.exist?
83+
Kernel.system(
84+
*%W[
85+
git
86+
clone
87+
https://github.com/#{PrismParser::PARSER}
88+
#{PrismParser::PARSER_PATH}
89+
],
90+
exception: true
91+
)
92+
end
93+
94+
Dir.chdir(PrismParser::PARSER_PATH) do
95+
Kernel.system(
96+
*%W[
97+
git
98+
checkout
99+
v#{PrismParser::PARSER_VERSION}
100+
],
101+
exception: true
102+
)
103+
Kernel.system(*%w[git clean --force -d -X], exception: true)
104+
end
105+
106+
ignores_cli_option = PrismParser.excludes.flat_map { |file| ['--ignore', file] }
107+
108+
PrismParser.prepare
109+
exit Unparser::CLI.run([PrismParser.target_glob, *ignores_cli_option])

0 commit comments

Comments
 (0)