Skip to content

Commit c2fdde5

Browse files
authored
Merge pull request #39 from ruby-syntax-tree/multiple-ruby-versions
Handle multiple Ruby versions
2 parents eafdb48 + 5c6615e commit c2fdde5

File tree

16 files changed

+195
-64
lines changed

16 files changed

+195
-64
lines changed

.github/workflows/main.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ on:
44
- pull_request_target
55
jobs:
66
ci:
7+
strategy:
8+
fail-fast: false
9+
matrix:
10+
ruby:
11+
- '2.7'
12+
- '3.0'
13+
- '3.1'
14+
- head
715
name: CI
816
runs-on: ubuntu-latest
917
env:
@@ -13,7 +21,7 @@ jobs:
1321
- uses: ruby/setup-ruby@v1
1422
with:
1523
bundler-cache: true
16-
ruby-version: '3.1'
24+
ruby-version: ${{ matrix.ruby }}
1725
- name: Test
1826
run: bundle exec rake test
1927
automerge:

Gemfile.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ GEM
2626

2727
PLATFORMS
2828
arm64-darwin-21
29+
ruby
2930
x86_64-darwin-19
3031
x86_64-darwin-21
3132
x86_64-linux

lib/syntax_tree/node.rb

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,6 +2233,9 @@ class BodyStmt < Node
22332233
# [nil | Rescue] the optional rescue chain attached to the begin clause
22342234
attr_reader :rescue_clause
22352235

2236+
# [nil | Kw] the optional else keyword
2237+
attr_reader :else_keyword
2238+
22362239
# [nil | Statements] the optional set of statements inside the else clause
22372240
attr_reader :else_clause
22382241

@@ -2245,13 +2248,15 @@ class BodyStmt < Node
22452248
def initialize(
22462249
statements:,
22472250
rescue_clause:,
2251+
else_keyword:,
22482252
else_clause:,
22492253
ensure_clause:,
22502254
location:,
22512255
comments: []
22522256
)
22532257
@statements = statements
22542258
@rescue_clause = rescue_clause
2259+
@else_keyword = else_keyword
22552260
@else_clause = else_clause
22562261
@ensure_clause = ensure_clause
22572262
@location = location
@@ -2294,7 +2299,7 @@ def accept(visitor)
22942299
end
22952300

22962301
def child_nodes
2297-
[statements, rescue_clause, else_clause, ensure_clause]
2302+
[statements, rescue_clause, else_keyword, else_clause, ensure_clause]
22982303
end
22992304

23002305
alias deconstruct child_nodes
@@ -2324,10 +2329,13 @@ def format(q)
23242329
if else_clause
23252330
q.nest(-2) do
23262331
q.breakable(force: true)
2327-
q.text("else")
2332+
q.format(else_keyword)
2333+
end
2334+
2335+
unless else_clause.empty?
2336+
q.breakable(force: true)
2337+
q.format(else_clause)
23282338
end
2329-
q.breakable(force: true)
2330-
q.format(else_clause)
23312339
end
23322340

23332341
if ensure_clause
@@ -3295,9 +3303,10 @@ def to_json(*opts)
32953303
private
32963304

32973305
def align?(node)
3298-
if node.arguments in Args[parts: [Def | Defs | DefEndless]]
3306+
case node.arguments
3307+
in Args[parts: [Def | Defs | DefEndless]]
32993308
false
3300-
elsif node.arguments in Args[parts: [Command => command]]
3309+
in Args[parts: [Command => command]]
33013310
align?(command)
33023311
else
33033312
true
@@ -4710,13 +4719,17 @@ def quotes(q)
47104719
# end
47114720
#
47124721
class Else < Node
4722+
# [Kw] the else keyword
4723+
attr_reader :keyword
4724+
47134725
# [Statements] the expressions to be executed
47144726
attr_reader :statements
47154727

47164728
# [Array[ Comment | EmbDoc ]] the comments attached to this node
47174729
attr_reader :comments
47184730

4719-
def initialize(statements:, location:, comments: [])
4731+
def initialize(keyword:, statements:, location:, comments: [])
4732+
@keyword = keyword
47204733
@statements = statements
47214734
@location = location
47224735
@comments = comments
@@ -4727,18 +4740,23 @@ def accept(visitor)
47274740
end
47284741

47294742
def child_nodes
4730-
[statements]
4743+
[keyword, statements]
47314744
end
47324745

47334746
alias deconstruct child_nodes
47344747

47354748
def deconstruct_keys(keys)
4736-
{ statements: statements, location: location, comments: comments }
4749+
{
4750+
keyword: keyword,
4751+
statements: statements,
4752+
location: location,
4753+
comments: comments
4754+
}
47374755
end
47384756

47394757
def format(q)
47404758
q.group do
4741-
q.text("else")
4759+
q.format(keyword)
47424760

47434761
unless statements.empty?
47444762
q.indent do
@@ -8992,6 +9010,9 @@ def to_json(*opts)
89929010
# end
89939011
#
89949012
class Rescue < Node
9013+
# [Kw] the rescue keyword
9014+
attr_reader :keyword
9015+
89959016
# [RescueEx] the exceptions being rescued
89969017
attr_reader :exception
89979018

@@ -9005,12 +9026,14 @@ class Rescue < Node
90059026
attr_reader :comments
90069027

90079028
def initialize(
9029+
keyword:,
90089030
exception:,
90099031
statements:,
90109032
consequent:,
90119033
location:,
90129034
comments: []
90139035
)
9036+
@keyword = keyword
90149037
@exception = exception
90159038
@statements = statements
90169039
@consequent = consequent
@@ -9040,13 +9063,14 @@ def accept(visitor)
90409063
end
90419064

90429065
def child_nodes
9043-
[exception, statements, consequent]
9066+
[keyword, exception, statements, consequent]
90449067
end
90459068

90469069
alias deconstruct child_nodes
90479070

90489071
def deconstruct_keys(keys)
90499072
{
9073+
keyword: keyword,
90509074
exception: exception,
90519075
statements: statements,
90529076
consequent: consequent,
@@ -9057,10 +9081,10 @@ def deconstruct_keys(keys)
90579081

90589082
def format(q)
90599083
q.group do
9060-
q.text("rescue")
9084+
q.format(keyword)
90619085

90629086
if exception
9063-
q.nest("rescue ".length) { q.format(exception) }
9087+
q.nest(keyword.value.length + 1) { q.format(exception) }
90649088
else
90659089
q.text(" StandardError")
90669090
end

lib/syntax_tree/parser.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ def on_bodystmt(statements, rescue_clause, else_clause, ensure_clause)
682682
BodyStmt.new(
683683
statements: statements,
684684
rescue_clause: rescue_clause,
685+
else_keyword: else_clause && find_token(Kw, "else"),
685686
else_clause: else_clause,
686687
ensure_clause: ensure_clause,
687688
location: Location.fixed(line: lineno, char: char_pos)
@@ -1115,7 +1116,7 @@ def on_dyna_symbol(string_content)
11151116
# :call-seq:
11161117
# on_else: (Statements statements) -> Else
11171118
def on_else(statements)
1118-
beginning = find_token(Kw, "else")
1119+
keyword = find_token(Kw, "else")
11191120

11201121
# else can either end with an end keyword (in which case we'll want to
11211122
# consume that event) or it can end with an ensure keyword (in which case
@@ -1127,13 +1128,16 @@ def on_else(statements)
11271128

11281129
node = tokens[index]
11291130
ending = node.value == "end" ? tokens.delete_at(index) : node
1130-
# ending = node
11311131

1132-
statements.bind(beginning.location.end_char, ending.location.start_char)
1132+
statements.bind(
1133+
find_next_statement_start(keyword.location.end_char),
1134+
ending.location.start_char
1135+
)
11331136

11341137
Else.new(
1138+
keyword: keyword,
11351139
statements: statements,
1136-
location: beginning.location.to(ending.location)
1140+
location: keyword.location.to(ending.location)
11371141
)
11381142
end
11391143

@@ -2316,6 +2320,7 @@ def on_rescue(exceptions, variable, statements, consequent)
23162320
end
23172321

23182322
Rescue.new(
2323+
keyword: keyword,
23192324
exception: rescue_ex,
23202325
statements: statements,
23212326
consequent: consequent,

test/fixtures/begin.rb

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,3 @@
55
begin
66
expression
77
end
8-
%
9-
case value
10-
in ^(expression)
11-
end

test/fixtures/bodystmt.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,23 @@
3434
ensure
3535
foo
3636
end
37+
%
38+
begin
39+
else # else
40+
end
41+
%
42+
begin
43+
ensure # ensure
44+
end
45+
%
46+
begin
47+
rescue # rescue
48+
else # else
49+
ensure # ensure
50+
end
51+
-
52+
begin
53+
rescue StandardError # rescue
54+
else # else
55+
ensure # ensure
56+
end

test/fixtures/command.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,3 @@
2323
%
2424
meta3 meta2 meta1 def self.foo
2525
end
26-
%
27-
meta1 def foo = 1
28-
%
29-
meta2 meta1 def foo = 1
30-
%
31-
meta3 meta2 meta1 def foo = 1
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
%
2+
meta1 def foo = 1
3+
%
4+
meta2 meta1 def foo = 1
5+
%
6+
meta3 meta2 meta1 def foo = 1

test/fixtures/else.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@
1818
else
1919
bar
2020
end
21+
%
22+
if foo
23+
else # bar
24+
end

test/fixtures/pinned_begin.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
%
2+
case value
3+
in ^(expression)
4+
end

0 commit comments

Comments
 (0)