syntax_tree 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +20 -1
- data/.rubocop.yml +80 -0
- data/CHANGELOG.md +19 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +22 -1
- data/README.md +113 -0
- data/Rakefile +27 -5
- data/config/rubocop.yml +64 -0
- data/lib/syntax_tree/cli.rb +63 -27
- data/lib/syntax_tree/formatter.rb +6 -5
- data/lib/syntax_tree/language_server/inlay_hints.rb +87 -38
- data/lib/syntax_tree/language_server.rb +50 -14
- data/lib/syntax_tree/node.rb +494 -305
- data/lib/syntax_tree/parser.rb +439 -110
- data/lib/syntax_tree/prettyprint.rb +28 -25
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree/visitor/field_visitor.rb +1115 -0
- data/lib/syntax_tree/visitor/json_visitor.rb +25 -1305
- data/lib/syntax_tree/visitor/match_visitor.rb +122 -0
- data/lib/syntax_tree/visitor/pretty_print_visitor.rb +35 -1163
- data/lib/syntax_tree/visitor.rb +6 -1
- data/lib/syntax_tree.rb +19 -1
- data/syntax_tree.gemspec +21 -19
- metadata +7 -3
data/lib/syntax_tree/parser.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SyntaxTree
|
4
|
+
# Parser is a subclass of the Ripper library that subscribes to the stream of
|
5
|
+
# tokens and nodes coming from the parser and builds up a syntax tree.
|
4
6
|
class Parser < Ripper
|
5
7
|
# A special parser error so that we can get nice syntax displays on the
|
6
8
|
# error message when prettier prints out the results.
|
@@ -40,9 +42,11 @@ module SyntaxTree
|
|
40
42
|
@start = start
|
41
43
|
@indices = []
|
42
44
|
|
43
|
-
line
|
44
|
-
|
45
|
-
|
45
|
+
line
|
46
|
+
.each_char
|
47
|
+
.with_index(start) do |char, index|
|
48
|
+
char.bytesize.times { @indices << index }
|
49
|
+
end
|
46
50
|
end
|
47
51
|
|
48
52
|
# Technically it's possible for the column index to be a negative value if
|
@@ -130,10 +134,10 @@ module SyntaxTree
|
|
130
134
|
last_index = 0
|
131
135
|
|
132
136
|
@source.lines.each do |line|
|
133
|
-
if line.size == line.bytesize
|
134
|
-
|
137
|
+
@line_counts << if line.size == line.bytesize
|
138
|
+
SingleByteString.new(last_index)
|
135
139
|
else
|
136
|
-
|
140
|
+
MultiByteString.new(last_index, line)
|
137
141
|
end
|
138
142
|
|
139
143
|
last_index += line.size
|
@@ -239,7 +243,7 @@ module SyntaxTree
|
|
239
243
|
# By finding the next non-space character, we can make sure that the bounds
|
240
244
|
# of the statement list are correct.
|
241
245
|
def find_next_statement_start(position)
|
242
|
-
remaining = source[position
|
246
|
+
remaining = source[position..]
|
243
247
|
|
244
248
|
if remaining.sub(/\A +/, "")[0] == "#"
|
245
249
|
return position + remaining.index("\n")
|
@@ -264,7 +268,7 @@ module SyntaxTree
|
|
264
268
|
start_char,
|
265
269
|
start_char - line_counts[lbrace.location.start_line - 1].start,
|
266
270
|
rbrace.location.start_char,
|
267
|
-
rbrace.location.start_column
|
271
|
+
rbrace.location.start_column
|
268
272
|
)
|
269
273
|
|
270
274
|
keyword = find_token(Kw, "BEGIN")
|
@@ -281,7 +285,13 @@ module SyntaxTree
|
|
281
285
|
def on_CHAR(value)
|
282
286
|
CHAR.new(
|
283
287
|
value: value,
|
284
|
-
location:
|
288
|
+
location:
|
289
|
+
Location.token(
|
290
|
+
line: lineno,
|
291
|
+
char: char_pos,
|
292
|
+
column: current_column,
|
293
|
+
size: value.size
|
294
|
+
)
|
285
295
|
)
|
286
296
|
end
|
287
297
|
|
@@ -313,8 +323,14 @@ module SyntaxTree
|
|
313
323
|
def on___end__(value)
|
314
324
|
@__end__ =
|
315
325
|
EndContent.new(
|
316
|
-
value: source[(char_pos + value.length)
|
317
|
-
location:
|
326
|
+
value: source[(char_pos + value.length)..],
|
327
|
+
location:
|
328
|
+
Location.token(
|
329
|
+
line: lineno,
|
330
|
+
char: char_pos,
|
331
|
+
column: current_column,
|
332
|
+
size: value.size
|
333
|
+
)
|
318
334
|
)
|
319
335
|
end
|
320
336
|
|
@@ -423,7 +439,8 @@ module SyntaxTree
|
|
423
439
|
# If there are any arguments and the operator we found from the list is
|
424
440
|
# not after them, then we're going to return the arguments as-is because
|
425
441
|
# we're looking at an & that occurs before the arguments are done.
|
426
|
-
if arguments.parts.any? &&
|
442
|
+
if arguments.parts.any? &&
|
443
|
+
operator.location.start_char < arguments.location.end_char
|
427
444
|
return arguments
|
428
445
|
end
|
429
446
|
|
@@ -478,7 +495,11 @@ module SyntaxTree
|
|
478
495
|
# :call-seq:
|
479
496
|
# on_args_new: () -> Args
|
480
497
|
def on_args_new
|
481
|
-
Args.new(
|
498
|
+
Args.new(
|
499
|
+
parts: [],
|
500
|
+
location:
|
501
|
+
Location.fixed(line: lineno, column: current_column, char: char_pos)
|
502
|
+
)
|
482
503
|
end
|
483
504
|
|
484
505
|
# :call-seq:
|
@@ -529,7 +550,7 @@ module SyntaxTree
|
|
529
550
|
|
530
551
|
# If there's the optional then keyword, then we'll delete that and use it
|
531
552
|
# as the end bounds of the location.
|
532
|
-
if token = find_token(Kw, "then", consume: false)
|
553
|
+
if (token = find_token(Kw, "then", consume: false))
|
533
554
|
tokens.delete(token)
|
534
555
|
location = location.to(token.location)
|
535
556
|
end
|
@@ -538,10 +559,10 @@ module SyntaxTree
|
|
538
559
|
# here because it currently doesn't have anything to use for its precise
|
539
560
|
# location. If we hit a comma, then we've gone too far.
|
540
561
|
if rest.is_a?(VarField) && rest.value.nil?
|
541
|
-
tokens.rindex do |
|
542
|
-
case
|
562
|
+
tokens.rindex do |rtoken|
|
563
|
+
case rtoken
|
543
564
|
in Op[value: "*"]
|
544
|
-
rest = VarField.new(value: nil, location:
|
565
|
+
rest = VarField.new(value: nil, location: rtoken.location)
|
545
566
|
break
|
546
567
|
in Comma
|
547
568
|
break
|
@@ -561,7 +582,13 @@ module SyntaxTree
|
|
561
582
|
|
562
583
|
# :call-seq:
|
563
584
|
# on_assign: (
|
564
|
-
# (
|
585
|
+
# (
|
586
|
+
# ARefField |
|
587
|
+
# ConstPathField |
|
588
|
+
# Field |
|
589
|
+
# TopConstField |
|
590
|
+
# VarField
|
591
|
+
# ) target,
|
565
592
|
# untyped value
|
566
593
|
# ) -> Assign
|
567
594
|
def on_assign(target, value)
|
@@ -586,7 +613,10 @@ module SyntaxTree
|
|
586
613
|
def on_assoc_splat(value)
|
587
614
|
operator = find_token(Op, "**")
|
588
615
|
|
589
|
-
AssocSplat.new(
|
616
|
+
AssocSplat.new(
|
617
|
+
value: value,
|
618
|
+
location: operator.location.to(value.location)
|
619
|
+
)
|
590
620
|
end
|
591
621
|
|
592
622
|
# def on_assoclist_from_args(assocs)
|
@@ -598,7 +628,13 @@ module SyntaxTree
|
|
598
628
|
def on_backref(value)
|
599
629
|
Backref.new(
|
600
630
|
value: value,
|
601
|
-
location:
|
631
|
+
location:
|
632
|
+
Location.token(
|
633
|
+
line: lineno,
|
634
|
+
char: char_pos,
|
635
|
+
column: current_column,
|
636
|
+
size: value.size
|
637
|
+
)
|
602
638
|
)
|
603
639
|
end
|
604
640
|
|
@@ -608,7 +644,13 @@ module SyntaxTree
|
|
608
644
|
node =
|
609
645
|
Backtick.new(
|
610
646
|
value: value,
|
611
|
-
location:
|
647
|
+
location:
|
648
|
+
Location.token(
|
649
|
+
line: lineno,
|
650
|
+
char: char_pos,
|
651
|
+
column: current_column,
|
652
|
+
size: value.size
|
653
|
+
)
|
612
654
|
)
|
613
655
|
|
614
656
|
tokens << node
|
@@ -616,7 +658,9 @@ module SyntaxTree
|
|
616
658
|
end
|
617
659
|
|
618
660
|
# :call-seq:
|
619
|
-
# on_bare_assoc_hash: (
|
661
|
+
# on_bare_assoc_hash: (
|
662
|
+
# Array[AssocNew | AssocSplat] assocs
|
663
|
+
# ) -> BareAssocHash
|
620
664
|
def on_bare_assoc_hash(assocs)
|
621
665
|
BareAssocHash.new(
|
622
666
|
assocs: assocs,
|
@@ -641,7 +685,7 @@ module SyntaxTree
|
|
641
685
|
keyword = find_token(Kw, "begin")
|
642
686
|
end_location =
|
643
687
|
if bodystmt.rescue_clause || bodystmt.ensure_clause ||
|
644
|
-
|
688
|
+
bodystmt.else_clause
|
645
689
|
bodystmt.location
|
646
690
|
else
|
647
691
|
find_token(Kw, "end").location
|
@@ -660,7 +704,11 @@ module SyntaxTree
|
|
660
704
|
end
|
661
705
|
|
662
706
|
# :call-seq:
|
663
|
-
# on_binary: (
|
707
|
+
# on_binary: (
|
708
|
+
# untyped left,
|
709
|
+
# (Op | Symbol) operator,
|
710
|
+
# untyped right
|
711
|
+
# ) -> Binary
|
664
712
|
def on_binary(left, operator, right)
|
665
713
|
if operator.is_a?(Symbol)
|
666
714
|
# Here, we're going to search backward for the token that's between the
|
@@ -737,7 +785,8 @@ module SyntaxTree
|
|
737
785
|
else_keyword: else_clause && find_token(Kw, "else"),
|
738
786
|
else_clause: else_clause,
|
739
787
|
ensure_clause: ensure_clause,
|
740
|
-
location:
|
788
|
+
location:
|
789
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
741
790
|
)
|
742
791
|
end
|
743
792
|
|
@@ -764,7 +813,10 @@ module SyntaxTree
|
|
764
813
|
start_line: lbrace.location.start_line,
|
765
814
|
start_char: lbrace.location.start_char,
|
766
815
|
start_column: lbrace.location.start_column,
|
767
|
-
end_line: [
|
816
|
+
end_line: [
|
817
|
+
rbrace.location.end_line,
|
818
|
+
statements.location.end_line
|
819
|
+
].max,
|
768
820
|
end_char: rbrace.location.end_char,
|
769
821
|
end_column: rbrace.location.end_column
|
770
822
|
)
|
@@ -816,7 +868,7 @@ module SyntaxTree
|
|
816
868
|
# :call-seq:
|
817
869
|
# on_case: (untyped value, untyped consequent) -> Case | RAssign
|
818
870
|
def on_case(value, consequent)
|
819
|
-
if keyword = find_token(Kw, "case", consume: false)
|
871
|
+
if (keyword = find_token(Kw, "case", consume: false))
|
820
872
|
tokens.delete(keyword)
|
821
873
|
|
822
874
|
Case.new(
|
@@ -870,7 +922,13 @@ module SyntaxTree
|
|
870
922
|
node =
|
871
923
|
Comma.new(
|
872
924
|
value: value,
|
873
|
-
location:
|
925
|
+
location:
|
926
|
+
Location.token(
|
927
|
+
line: lineno,
|
928
|
+
char: char_pos,
|
929
|
+
column: current_column,
|
930
|
+
size: value.size
|
931
|
+
)
|
874
932
|
)
|
875
933
|
|
876
934
|
tokens << node
|
@@ -915,7 +973,12 @@ module SyntaxTree
|
|
915
973
|
value: value.chomp,
|
916
974
|
inline: value.strip != lines[line - 1].strip,
|
917
975
|
location:
|
918
|
-
Location.token(
|
976
|
+
Location.token(
|
977
|
+
line: line,
|
978
|
+
char: char_pos,
|
979
|
+
column: current_column,
|
980
|
+
size: value.size - 1
|
981
|
+
)
|
919
982
|
)
|
920
983
|
|
921
984
|
@comments << comment
|
@@ -927,7 +990,13 @@ module SyntaxTree
|
|
927
990
|
def on_const(value)
|
928
991
|
Const.new(
|
929
992
|
value: value,
|
930
|
-
location:
|
993
|
+
location:
|
994
|
+
Location.token(
|
995
|
+
line: lineno,
|
996
|
+
char: char_pos,
|
997
|
+
column: current_column,
|
998
|
+
size: value.size
|
999
|
+
)
|
931
1000
|
)
|
932
1001
|
end
|
933
1002
|
|
@@ -962,7 +1031,13 @@ module SyntaxTree
|
|
962
1031
|
def on_cvar(value)
|
963
1032
|
CVar.new(
|
964
1033
|
value: value,
|
965
|
-
location:
|
1034
|
+
location:
|
1035
|
+
Location.token(
|
1036
|
+
line: lineno,
|
1037
|
+
char: char_pos,
|
1038
|
+
column: current_column,
|
1039
|
+
size: value.size
|
1040
|
+
)
|
966
1041
|
)
|
967
1042
|
end
|
968
1043
|
|
@@ -1047,7 +1122,10 @@ module SyntaxTree
|
|
1047
1122
|
ending = find_token(RParen)
|
1048
1123
|
end
|
1049
1124
|
|
1050
|
-
Defined.new(
|
1125
|
+
Defined.new(
|
1126
|
+
value: value,
|
1127
|
+
location: beginning.location.to(ending.location)
|
1128
|
+
)
|
1051
1129
|
end
|
1052
1130
|
|
1053
1131
|
# :call-seq:
|
@@ -1268,7 +1346,8 @@ module SyntaxTree
|
|
1268
1346
|
@embdoc =
|
1269
1347
|
EmbDoc.new(
|
1270
1348
|
value: value,
|
1271
|
-
location:
|
1349
|
+
location:
|
1350
|
+
Location.fixed(line: lineno, column: current_column, char: char_pos)
|
1272
1351
|
)
|
1273
1352
|
end
|
1274
1353
|
|
@@ -1302,7 +1381,13 @@ module SyntaxTree
|
|
1302
1381
|
node =
|
1303
1382
|
EmbExprBeg.new(
|
1304
1383
|
value: value,
|
1305
|
-
location:
|
1384
|
+
location:
|
1385
|
+
Location.token(
|
1386
|
+
line: lineno,
|
1387
|
+
char: char_pos,
|
1388
|
+
column: current_column,
|
1389
|
+
size: value.size
|
1390
|
+
)
|
1306
1391
|
)
|
1307
1392
|
|
1308
1393
|
tokens << node
|
@@ -1315,7 +1400,13 @@ module SyntaxTree
|
|
1315
1400
|
node =
|
1316
1401
|
EmbExprEnd.new(
|
1317
1402
|
value: value,
|
1318
|
-
location:
|
1403
|
+
location:
|
1404
|
+
Location.token(
|
1405
|
+
line: lineno,
|
1406
|
+
char: char_pos,
|
1407
|
+
column: current_column,
|
1408
|
+
size: value.size
|
1409
|
+
)
|
1319
1410
|
)
|
1320
1411
|
|
1321
1412
|
tokens << node
|
@@ -1328,7 +1419,13 @@ module SyntaxTree
|
|
1328
1419
|
node =
|
1329
1420
|
EmbVar.new(
|
1330
1421
|
value: value,
|
1331
|
-
location:
|
1422
|
+
location:
|
1423
|
+
Location.token(
|
1424
|
+
line: lineno,
|
1425
|
+
char: char_pos,
|
1426
|
+
column: current_column,
|
1427
|
+
size: value.size
|
1428
|
+
)
|
1332
1429
|
)
|
1333
1430
|
|
1334
1431
|
tokens << node
|
@@ -1395,7 +1492,13 @@ module SyntaxTree
|
|
1395
1492
|
def on_float(value)
|
1396
1493
|
FloatLiteral.new(
|
1397
1494
|
value: value,
|
1398
|
-
location:
|
1495
|
+
location:
|
1496
|
+
Location.token(
|
1497
|
+
line: lineno,
|
1498
|
+
char: char_pos,
|
1499
|
+
column: current_column,
|
1500
|
+
size: value.size
|
1501
|
+
)
|
1399
1502
|
)
|
1400
1503
|
end
|
1401
1504
|
|
@@ -1413,8 +1516,7 @@ module SyntaxTree
|
|
1413
1516
|
# the location of the node.
|
1414
1517
|
opening =
|
1415
1518
|
find_token(LBracket, consume: false) ||
|
1416
|
-
|
1417
|
-
left
|
1519
|
+
find_token(LParen, consume: false) || left
|
1418
1520
|
|
1419
1521
|
# The closing is based on the opening, which is either the matched
|
1420
1522
|
# punctuation or the right splat.
|
@@ -1453,8 +1555,9 @@ module SyntaxTree
|
|
1453
1555
|
# Consume the do keyword if it exists so that it doesn't get confused for
|
1454
1556
|
# some other block
|
1455
1557
|
keyword = find_token(Kw, "do", consume: false)
|
1456
|
-
if keyword &&
|
1457
|
-
|
1558
|
+
if keyword &&
|
1559
|
+
keyword.location.start_char > collection.location.end_char &&
|
1560
|
+
keyword.location.end_char < ending.location.start_char
|
1458
1561
|
tokens.delete(keyword)
|
1459
1562
|
end
|
1460
1563
|
|
@@ -1483,7 +1586,13 @@ module SyntaxTree
|
|
1483
1586
|
def on_gvar(value)
|
1484
1587
|
GVar.new(
|
1485
1588
|
value: value,
|
1486
|
-
location:
|
1589
|
+
location:
|
1590
|
+
Location.token(
|
1591
|
+
line: lineno,
|
1592
|
+
char: char_pos,
|
1593
|
+
column: current_column,
|
1594
|
+
size: value.size
|
1595
|
+
)
|
1487
1596
|
)
|
1488
1597
|
end
|
1489
1598
|
|
@@ -1504,7 +1613,12 @@ module SyntaxTree
|
|
1504
1613
|
# on_heredoc_beg: (String value) -> HeredocBeg
|
1505
1614
|
def on_heredoc_beg(value)
|
1506
1615
|
location =
|
1507
|
-
Location.token(
|
1616
|
+
Location.token(
|
1617
|
+
line: lineno,
|
1618
|
+
char: char_pos,
|
1619
|
+
column: current_column,
|
1620
|
+
size: value.size + 1
|
1621
|
+
)
|
1508
1622
|
|
1509
1623
|
# Here we're going to artificially create an extra node type so that if
|
1510
1624
|
# there are comments after the declaration of a heredoc, they get printed.
|
@@ -1545,7 +1659,7 @@ module SyntaxTree
|
|
1545
1659
|
start_column: heredoc.location.start_column,
|
1546
1660
|
end_line: lineno,
|
1547
1661
|
end_char: char_pos,
|
1548
|
-
end_column: current_column
|
1662
|
+
end_column: current_column
|
1549
1663
|
)
|
1550
1664
|
)
|
1551
1665
|
end
|
@@ -1563,24 +1677,32 @@ module SyntaxTree
|
|
1563
1677
|
keyword_rest = VarField.new(value: nil, location: token.location)
|
1564
1678
|
end
|
1565
1679
|
|
1680
|
+
parts = [constant, *keywords&.flatten(1), keyword_rest].compact
|
1681
|
+
|
1682
|
+
# If there's no constant, there may be braces, so we're going to look for
|
1683
|
+
# those to get our bounds.
|
1684
|
+
unless constant
|
1685
|
+
lbrace = find_token(LBrace, consume: false)
|
1686
|
+
rbrace = find_token(RBrace, consume: false)
|
1687
|
+
|
1688
|
+
if lbrace && rbrace
|
1689
|
+
parts = [lbrace, *parts, rbrace]
|
1690
|
+
tokens.delete(lbrace)
|
1691
|
+
tokens.delete(rbrace)
|
1692
|
+
end
|
1693
|
+
end
|
1694
|
+
|
1566
1695
|
# Delete the optional then keyword
|
1567
|
-
if token = find_token(Kw, "then", consume: false)
|
1696
|
+
if (token = find_token(Kw, "then", consume: false))
|
1697
|
+
parts << token
|
1568
1698
|
tokens.delete(token)
|
1569
1699
|
end
|
1570
1700
|
|
1571
|
-
parts = [constant, *keywords&.flatten(1), keyword_rest].compact
|
1572
|
-
location =
|
1573
|
-
if parts.any?
|
1574
|
-
parts[0].location.to(parts[-1].location)
|
1575
|
-
else
|
1576
|
-
find_token(LBrace).location.to(find_token(RBrace).location)
|
1577
|
-
end
|
1578
|
-
|
1579
1701
|
HshPtn.new(
|
1580
1702
|
constant: constant,
|
1581
1703
|
keywords: keywords || [],
|
1582
1704
|
keyword_rest: keyword_rest,
|
1583
|
-
location: location
|
1705
|
+
location: parts[0].location.to(parts[-1].location)
|
1584
1706
|
)
|
1585
1707
|
end
|
1586
1708
|
|
@@ -1589,7 +1711,13 @@ module SyntaxTree
|
|
1589
1711
|
def on_ident(value)
|
1590
1712
|
Ident.new(
|
1591
1713
|
value: value,
|
1592
|
-
location:
|
1714
|
+
location:
|
1715
|
+
Location.token(
|
1716
|
+
line: lineno,
|
1717
|
+
char: char_pos,
|
1718
|
+
column: current_column,
|
1719
|
+
size: value.size
|
1720
|
+
)
|
1593
1721
|
)
|
1594
1722
|
end
|
1595
1723
|
|
@@ -1654,7 +1782,13 @@ module SyntaxTree
|
|
1654
1782
|
def on_imaginary(value)
|
1655
1783
|
Imaginary.new(
|
1656
1784
|
value: value,
|
1657
|
-
location:
|
1785
|
+
location:
|
1786
|
+
Location.token(
|
1787
|
+
line: lineno,
|
1788
|
+
char: char_pos,
|
1789
|
+
column: current_column,
|
1790
|
+
size: value.size
|
1791
|
+
)
|
1658
1792
|
)
|
1659
1793
|
end
|
1660
1794
|
|
@@ -1673,7 +1807,7 @@ module SyntaxTree
|
|
1673
1807
|
ending = consequent || find_token(Kw, "end")
|
1674
1808
|
|
1675
1809
|
statements_start = pattern
|
1676
|
-
if token = find_token(Kw, "then", consume: false)
|
1810
|
+
if (token = find_token(Kw, "then", consume: false))
|
1677
1811
|
tokens.delete(token)
|
1678
1812
|
statements_start = token
|
1679
1813
|
end
|
@@ -1681,7 +1815,8 @@ module SyntaxTree
|
|
1681
1815
|
start_char = find_next_statement_start(statements_start.location.end_char)
|
1682
1816
|
statements.bind(
|
1683
1817
|
start_char,
|
1684
|
-
start_char -
|
1818
|
+
start_char -
|
1819
|
+
line_counts[statements_start.location.start_line - 1].start,
|
1685
1820
|
ending.location.start_char,
|
1686
1821
|
ending.location.start_column
|
1687
1822
|
)
|
@@ -1699,7 +1834,13 @@ module SyntaxTree
|
|
1699
1834
|
def on_int(value)
|
1700
1835
|
Int.new(
|
1701
1836
|
value: value,
|
1702
|
-
location:
|
1837
|
+
location:
|
1838
|
+
Location.token(
|
1839
|
+
line: lineno,
|
1840
|
+
char: char_pos,
|
1841
|
+
column: current_column,
|
1842
|
+
size: value.size
|
1843
|
+
)
|
1703
1844
|
)
|
1704
1845
|
end
|
1705
1846
|
|
@@ -1708,7 +1849,13 @@ module SyntaxTree
|
|
1708
1849
|
def on_ivar(value)
|
1709
1850
|
IVar.new(
|
1710
1851
|
value: value,
|
1711
|
-
location:
|
1852
|
+
location:
|
1853
|
+
Location.token(
|
1854
|
+
line: lineno,
|
1855
|
+
char: char_pos,
|
1856
|
+
column: current_column,
|
1857
|
+
size: value.size
|
1858
|
+
)
|
1712
1859
|
)
|
1713
1860
|
end
|
1714
1861
|
|
@@ -1718,7 +1865,13 @@ module SyntaxTree
|
|
1718
1865
|
node =
|
1719
1866
|
Kw.new(
|
1720
1867
|
value: value,
|
1721
|
-
location:
|
1868
|
+
location:
|
1869
|
+
Location.token(
|
1870
|
+
line: lineno,
|
1871
|
+
char: char_pos,
|
1872
|
+
column: current_column,
|
1873
|
+
size: value.size
|
1874
|
+
)
|
1722
1875
|
)
|
1723
1876
|
|
1724
1877
|
tokens << node
|
@@ -1739,7 +1892,13 @@ module SyntaxTree
|
|
1739
1892
|
def on_label(value)
|
1740
1893
|
Label.new(
|
1741
1894
|
value: value,
|
1742
|
-
location:
|
1895
|
+
location:
|
1896
|
+
Location.token(
|
1897
|
+
line: lineno,
|
1898
|
+
char: char_pos,
|
1899
|
+
column: current_column,
|
1900
|
+
size: value.size
|
1901
|
+
)
|
1743
1902
|
)
|
1744
1903
|
end
|
1745
1904
|
|
@@ -1749,7 +1908,13 @@ module SyntaxTree
|
|
1749
1908
|
node =
|
1750
1909
|
LabelEnd.new(
|
1751
1910
|
value: value,
|
1752
|
-
location:
|
1911
|
+
location:
|
1912
|
+
Location.token(
|
1913
|
+
line: lineno,
|
1914
|
+
char: char_pos,
|
1915
|
+
column: current_column,
|
1916
|
+
size: value.size
|
1917
|
+
)
|
1753
1918
|
)
|
1754
1919
|
|
1755
1920
|
tokens << node
|
@@ -1763,11 +1928,13 @@ module SyntaxTree
|
|
1763
1928
|
# ) -> Lambda
|
1764
1929
|
def on_lambda(params, statements)
|
1765
1930
|
beginning = find_token(TLambda)
|
1766
|
-
|
1767
|
-
|
1931
|
+
braces =
|
1932
|
+
tokens.any? do |token|
|
1768
1933
|
token.is_a?(TLamBeg) &&
|
1769
1934
|
token.location.start_char > beginning.location.start_char
|
1770
|
-
|
1935
|
+
end
|
1936
|
+
|
1937
|
+
if braces
|
1771
1938
|
opening = find_token(TLamBeg)
|
1772
1939
|
closing = find_token(RBrace)
|
1773
1940
|
else
|
@@ -1795,7 +1962,13 @@ module SyntaxTree
|
|
1795
1962
|
node =
|
1796
1963
|
LBrace.new(
|
1797
1964
|
value: value,
|
1798
|
-
location:
|
1965
|
+
location:
|
1966
|
+
Location.token(
|
1967
|
+
line: lineno,
|
1968
|
+
char: char_pos,
|
1969
|
+
column: current_column,
|
1970
|
+
size: value.size
|
1971
|
+
)
|
1799
1972
|
)
|
1800
1973
|
|
1801
1974
|
tokens << node
|
@@ -1808,7 +1981,13 @@ module SyntaxTree
|
|
1808
1981
|
node =
|
1809
1982
|
LBracket.new(
|
1810
1983
|
value: value,
|
1811
|
-
location:
|
1984
|
+
location:
|
1985
|
+
Location.token(
|
1986
|
+
line: lineno,
|
1987
|
+
char: char_pos,
|
1988
|
+
column: current_column,
|
1989
|
+
size: value.size
|
1990
|
+
)
|
1812
1991
|
)
|
1813
1992
|
|
1814
1993
|
tokens << node
|
@@ -1821,7 +2000,13 @@ module SyntaxTree
|
|
1821
2000
|
node =
|
1822
2001
|
LParen.new(
|
1823
2002
|
value: value,
|
1824
|
-
location:
|
2003
|
+
location:
|
2004
|
+
Location.token(
|
2005
|
+
line: lineno,
|
2006
|
+
char: char_pos,
|
2007
|
+
column: current_column,
|
2008
|
+
size: value.size
|
2009
|
+
)
|
1825
2010
|
)
|
1826
2011
|
|
1827
2012
|
tokens << node
|
@@ -1920,7 +2105,11 @@ module SyntaxTree
|
|
1920
2105
|
# :call-seq:
|
1921
2106
|
# on_mlhs_new: () -> MLHS
|
1922
2107
|
def on_mlhs_new
|
1923
|
-
MLHS.new(
|
2108
|
+
MLHS.new(
|
2109
|
+
parts: [],
|
2110
|
+
location:
|
2111
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2112
|
+
)
|
1924
2113
|
end
|
1925
2114
|
|
1926
2115
|
# :call-seq:
|
@@ -1965,18 +2154,18 @@ module SyntaxTree
|
|
1965
2154
|
# :call-seq:
|
1966
2155
|
# on_mrhs_new: () -> MRHS
|
1967
2156
|
def on_mrhs_new
|
1968
|
-
MRHS.new(
|
2157
|
+
MRHS.new(
|
2158
|
+
parts: [],
|
2159
|
+
location:
|
2160
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2161
|
+
)
|
1969
2162
|
end
|
1970
2163
|
|
1971
2164
|
# :call-seq:
|
1972
2165
|
# on_mrhs_add: (MRHS mrhs, untyped part) -> MRHS
|
1973
2166
|
def on_mrhs_add(mrhs, part)
|
1974
2167
|
location =
|
1975
|
-
|
1976
|
-
mrhs.location
|
1977
|
-
else
|
1978
|
-
mrhs.location.to(part.location)
|
1979
|
-
end
|
2168
|
+
(mrhs.parts.empty? ? mrhs.location : mrhs.location.to(part.location))
|
1980
2169
|
|
1981
2170
|
MRHS.new(parts: mrhs.parts << part, location: location)
|
1982
2171
|
end
|
@@ -2034,7 +2223,13 @@ module SyntaxTree
|
|
2034
2223
|
node =
|
2035
2224
|
Op.new(
|
2036
2225
|
value: value,
|
2037
|
-
location:
|
2226
|
+
location:
|
2227
|
+
Location.token(
|
2228
|
+
line: lineno,
|
2229
|
+
char: char_pos,
|
2230
|
+
column: current_column,
|
2231
|
+
size: value.size
|
2232
|
+
)
|
2038
2233
|
)
|
2039
2234
|
|
2040
2235
|
tokens << node
|
@@ -2043,7 +2238,13 @@ module SyntaxTree
|
|
2043
2238
|
|
2044
2239
|
# :call-seq:
|
2045
2240
|
# on_opassign: (
|
2046
|
-
# (
|
2241
|
+
# (
|
2242
|
+
# ARefField |
|
2243
|
+
# ConstPathField |
|
2244
|
+
# Field |
|
2245
|
+
# TopConstField |
|
2246
|
+
# VarField
|
2247
|
+
# ) target,
|
2047
2248
|
# Op operator,
|
2048
2249
|
# untyped value
|
2049
2250
|
# ) -> OpAssign
|
@@ -2118,14 +2319,15 @@ module SyntaxTree
|
|
2118
2319
|
lparen = find_token(LParen)
|
2119
2320
|
rparen = find_token(RParen)
|
2120
2321
|
|
2121
|
-
if contents
|
2322
|
+
if contents.is_a?(Params)
|
2122
2323
|
location = contents.location
|
2123
2324
|
start_char = find_next_statement_start(lparen.location.end_char)
|
2124
2325
|
location =
|
2125
2326
|
Location.new(
|
2126
2327
|
start_line: location.start_line,
|
2127
2328
|
start_char: start_char,
|
2128
|
-
start_column:
|
2329
|
+
start_column:
|
2330
|
+
start_char - line_counts[lparen.location.start_line - 1].start,
|
2129
2331
|
end_line: location.end_line,
|
2130
2332
|
end_char: rparen.location.start_char,
|
2131
2333
|
end_column: rparen.location.start_column
|
@@ -2166,7 +2368,13 @@ module SyntaxTree
|
|
2166
2368
|
def on_period(value)
|
2167
2369
|
Period.new(
|
2168
2370
|
value: value,
|
2169
|
-
location:
|
2371
|
+
location:
|
2372
|
+
Location.token(
|
2373
|
+
line: lineno,
|
2374
|
+
char: char_pos,
|
2375
|
+
column: current_column,
|
2376
|
+
size: value.size
|
2377
|
+
)
|
2170
2378
|
)
|
2171
2379
|
end
|
2172
2380
|
|
@@ -2298,7 +2506,13 @@ module SyntaxTree
|
|
2298
2506
|
node =
|
2299
2507
|
QSymbolsBeg.new(
|
2300
2508
|
value: value,
|
2301
|
-
location:
|
2509
|
+
location:
|
2510
|
+
Location.token(
|
2511
|
+
line: lineno,
|
2512
|
+
char: char_pos,
|
2513
|
+
column: current_column,
|
2514
|
+
size: value.size
|
2515
|
+
)
|
2302
2516
|
)
|
2303
2517
|
|
2304
2518
|
tokens << node
|
@@ -2333,7 +2547,13 @@ module SyntaxTree
|
|
2333
2547
|
node =
|
2334
2548
|
QWordsBeg.new(
|
2335
2549
|
value: value,
|
2336
|
-
location:
|
2550
|
+
location:
|
2551
|
+
Location.token(
|
2552
|
+
line: lineno,
|
2553
|
+
char: char_pos,
|
2554
|
+
column: current_column,
|
2555
|
+
size: value.size
|
2556
|
+
)
|
2337
2557
|
)
|
2338
2558
|
|
2339
2559
|
tokens << node
|
@@ -2345,7 +2565,11 @@ module SyntaxTree
|
|
2345
2565
|
def on_qwords_new
|
2346
2566
|
beginning = find_token(QWordsBeg)
|
2347
2567
|
|
2348
|
-
QWords.new(
|
2568
|
+
QWords.new(
|
2569
|
+
beginning: beginning,
|
2570
|
+
elements: [],
|
2571
|
+
location: beginning.location
|
2572
|
+
)
|
2349
2573
|
end
|
2350
2574
|
|
2351
2575
|
# :call-seq:
|
@@ -2353,7 +2577,13 @@ module SyntaxTree
|
|
2353
2577
|
def on_rational(value)
|
2354
2578
|
RationalLiteral.new(
|
2355
2579
|
value: value,
|
2356
|
-
location:
|
2580
|
+
location:
|
2581
|
+
Location.token(
|
2582
|
+
line: lineno,
|
2583
|
+
char: char_pos,
|
2584
|
+
column: current_column,
|
2585
|
+
size: value.size
|
2586
|
+
)
|
2357
2587
|
)
|
2358
2588
|
end
|
2359
2589
|
|
@@ -2363,7 +2593,13 @@ module SyntaxTree
|
|
2363
2593
|
node =
|
2364
2594
|
RBrace.new(
|
2365
2595
|
value: value,
|
2366
|
-
location:
|
2596
|
+
location:
|
2597
|
+
Location.token(
|
2598
|
+
line: lineno,
|
2599
|
+
char: char_pos,
|
2600
|
+
column: current_column,
|
2601
|
+
size: value.size
|
2602
|
+
)
|
2367
2603
|
)
|
2368
2604
|
|
2369
2605
|
tokens << node
|
@@ -2376,7 +2612,13 @@ module SyntaxTree
|
|
2376
2612
|
node =
|
2377
2613
|
RBracket.new(
|
2378
2614
|
value: value,
|
2379
|
-
location:
|
2615
|
+
location:
|
2616
|
+
Location.token(
|
2617
|
+
line: lineno,
|
2618
|
+
char: char_pos,
|
2619
|
+
column: current_column,
|
2620
|
+
size: value.size
|
2621
|
+
)
|
2380
2622
|
)
|
2381
2623
|
|
2382
2624
|
tokens << node
|
@@ -2410,7 +2652,13 @@ module SyntaxTree
|
|
2410
2652
|
node =
|
2411
2653
|
RegexpBeg.new(
|
2412
2654
|
value: value,
|
2413
|
-
location:
|
2655
|
+
location:
|
2656
|
+
Location.token(
|
2657
|
+
line: lineno,
|
2658
|
+
char: char_pos,
|
2659
|
+
column: current_column,
|
2660
|
+
size: value.size
|
2661
|
+
)
|
2414
2662
|
)
|
2415
2663
|
|
2416
2664
|
tokens << node
|
@@ -2422,7 +2670,13 @@ module SyntaxTree
|
|
2422
2670
|
def on_regexp_end(value)
|
2423
2671
|
RegexpEnd.new(
|
2424
2672
|
value: value,
|
2425
|
-
location:
|
2673
|
+
location:
|
2674
|
+
Location.token(
|
2675
|
+
line: lineno,
|
2676
|
+
char: char_pos,
|
2677
|
+
column: current_column,
|
2678
|
+
size: value.size
|
2679
|
+
)
|
2426
2680
|
)
|
2427
2681
|
end
|
2428
2682
|
|
@@ -2563,7 +2817,13 @@ module SyntaxTree
|
|
2563
2817
|
node =
|
2564
2818
|
RParen.new(
|
2565
2819
|
value: value,
|
2566
|
-
location:
|
2820
|
+
location:
|
2821
|
+
Location.token(
|
2822
|
+
line: lineno,
|
2823
|
+
char: char_pos,
|
2824
|
+
column: current_column,
|
2825
|
+
size: value.size
|
2826
|
+
)
|
2567
2827
|
)
|
2568
2828
|
|
2569
2829
|
tokens << node
|
@@ -2611,7 +2871,11 @@ module SyntaxTree
|
|
2611
2871
|
statements.location.to(statement.location)
|
2612
2872
|
end
|
2613
2873
|
|
2614
|
-
Statements.new(
|
2874
|
+
Statements.new(
|
2875
|
+
self,
|
2876
|
+
body: statements.body << statement,
|
2877
|
+
location: location
|
2878
|
+
)
|
2615
2879
|
end
|
2616
2880
|
|
2617
2881
|
# :call-seq:
|
@@ -2620,7 +2884,8 @@ module SyntaxTree
|
|
2620
2884
|
Statements.new(
|
2621
2885
|
self,
|
2622
2886
|
body: [],
|
2623
|
-
location:
|
2887
|
+
location:
|
2888
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2624
2889
|
)
|
2625
2890
|
end
|
2626
2891
|
|
@@ -2654,7 +2919,8 @@ module SyntaxTree
|
|
2654
2919
|
def on_string_content
|
2655
2920
|
StringContent.new(
|
2656
2921
|
parts: [],
|
2657
|
-
location:
|
2922
|
+
location:
|
2923
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2658
2924
|
)
|
2659
2925
|
end
|
2660
2926
|
|
@@ -2703,7 +2969,7 @@ module SyntaxTree
|
|
2703
2969
|
def on_string_literal(string)
|
2704
2970
|
heredoc = @heredocs[-1]
|
2705
2971
|
|
2706
|
-
if heredoc
|
2972
|
+
if heredoc&.ending
|
2707
2973
|
heredoc = @heredocs.pop
|
2708
2974
|
|
2709
2975
|
Heredoc.new(
|
@@ -2756,7 +3022,13 @@ module SyntaxTree
|
|
2756
3022
|
node =
|
2757
3023
|
SymBeg.new(
|
2758
3024
|
value: value,
|
2759
|
-
location:
|
3025
|
+
location:
|
3026
|
+
Location.token(
|
3027
|
+
line: lineno,
|
3028
|
+
char: char_pos,
|
3029
|
+
column: current_column,
|
3030
|
+
size: value.size
|
3031
|
+
)
|
2760
3032
|
)
|
2761
3033
|
|
2762
3034
|
tokens << node
|
@@ -2810,7 +3082,13 @@ module SyntaxTree
|
|
2810
3082
|
node =
|
2811
3083
|
SymbolsBeg.new(
|
2812
3084
|
value: value,
|
2813
|
-
location:
|
3085
|
+
location:
|
3086
|
+
Location.token(
|
3087
|
+
line: lineno,
|
3088
|
+
char: char_pos,
|
3089
|
+
column: current_column,
|
3090
|
+
size: value.size
|
3091
|
+
)
|
2814
3092
|
)
|
2815
3093
|
|
2816
3094
|
tokens << node
|
@@ -2835,7 +3113,13 @@ module SyntaxTree
|
|
2835
3113
|
node =
|
2836
3114
|
TLambda.new(
|
2837
3115
|
value: value,
|
2838
|
-
location:
|
3116
|
+
location:
|
3117
|
+
Location.token(
|
3118
|
+
line: lineno,
|
3119
|
+
char: char_pos,
|
3120
|
+
column: current_column,
|
3121
|
+
size: value.size
|
3122
|
+
)
|
2839
3123
|
)
|
2840
3124
|
|
2841
3125
|
tokens << node
|
@@ -2848,7 +3132,13 @@ module SyntaxTree
|
|
2848
3132
|
node =
|
2849
3133
|
TLamBeg.new(
|
2850
3134
|
value: value,
|
2851
|
-
location:
|
3135
|
+
location:
|
3136
|
+
Location.token(
|
3137
|
+
line: lineno,
|
3138
|
+
char: char_pos,
|
3139
|
+
column: current_column,
|
3140
|
+
size: value.size
|
3141
|
+
)
|
2852
3142
|
)
|
2853
3143
|
|
2854
3144
|
tokens << node
|
@@ -2883,7 +3173,13 @@ module SyntaxTree
|
|
2883
3173
|
node =
|
2884
3174
|
TStringBeg.new(
|
2885
3175
|
value: value,
|
2886
|
-
location:
|
3176
|
+
location:
|
3177
|
+
Location.token(
|
3178
|
+
line: lineno,
|
3179
|
+
char: char_pos,
|
3180
|
+
column: current_column,
|
3181
|
+
size: value.size
|
3182
|
+
)
|
2887
3183
|
)
|
2888
3184
|
|
2889
3185
|
tokens << node
|
@@ -2895,7 +3191,13 @@ module SyntaxTree
|
|
2895
3191
|
def on_tstring_content(value)
|
2896
3192
|
TStringContent.new(
|
2897
3193
|
value: value,
|
2898
|
-
location:
|
3194
|
+
location:
|
3195
|
+
Location.token(
|
3196
|
+
line: lineno,
|
3197
|
+
char: char_pos,
|
3198
|
+
column: current_column,
|
3199
|
+
size: value.size
|
3200
|
+
)
|
2899
3201
|
)
|
2900
3202
|
end
|
2901
3203
|
|
@@ -2905,7 +3207,13 @@ module SyntaxTree
|
|
2905
3207
|
node =
|
2906
3208
|
TStringEnd.new(
|
2907
3209
|
value: value,
|
2908
|
-
location:
|
3210
|
+
location:
|
3211
|
+
Location.token(
|
3212
|
+
line: lineno,
|
3213
|
+
char: char_pos,
|
3214
|
+
column: current_column,
|
3215
|
+
size: value.size
|
3216
|
+
)
|
2909
3217
|
)
|
2910
3218
|
|
2911
3219
|
tokens << node
|
@@ -3014,7 +3322,7 @@ module SyntaxTree
|
|
3014
3322
|
# some other block
|
3015
3323
|
keyword = find_token(Kw, "do", consume: false)
|
3016
3324
|
if keyword && keyword.location.start_char > predicate.location.end_char &&
|
3017
|
-
|
3325
|
+
keyword.location.end_char < ending.location.start_char
|
3018
3326
|
tokens.delete(keyword)
|
3019
3327
|
end
|
3020
3328
|
|
@@ -3081,7 +3389,10 @@ module SyntaxTree
|
|
3081
3389
|
|
3082
3390
|
if pin && pin.location.start_char == value.location.start_char - 1
|
3083
3391
|
tokens.delete(pin)
|
3084
|
-
PinnedVarRef.new(
|
3392
|
+
PinnedVarRef.new(
|
3393
|
+
value: value,
|
3394
|
+
location: pin.location.to(value.location)
|
3395
|
+
)
|
3085
3396
|
else
|
3086
3397
|
VarRef.new(value: value, location: value.location)
|
3087
3398
|
end
|
@@ -3096,7 +3407,10 @@ module SyntaxTree
|
|
3096
3407
|
# :call-seq:
|
3097
3408
|
# on_void_stmt: () -> VoidStmt
|
3098
3409
|
def on_void_stmt
|
3099
|
-
VoidStmt.new(
|
3410
|
+
VoidStmt.new(
|
3411
|
+
location:
|
3412
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
3413
|
+
)
|
3100
3414
|
end
|
3101
3415
|
|
3102
3416
|
# :call-seq:
|
@@ -3110,7 +3424,7 @@ module SyntaxTree
|
|
3110
3424
|
ending = consequent || find_token(Kw, "end")
|
3111
3425
|
|
3112
3426
|
statements_start = arguments
|
3113
|
-
if token = find_token(Kw, "then", consume: false)
|
3427
|
+
if (token = find_token(Kw, "then", consume: false))
|
3114
3428
|
tokens.delete(token)
|
3115
3429
|
statements_start = token
|
3116
3430
|
end
|
@@ -3119,7 +3433,8 @@ module SyntaxTree
|
|
3119
3433
|
|
3120
3434
|
statements.bind(
|
3121
3435
|
start_char,
|
3122
|
-
start_char -
|
3436
|
+
start_char -
|
3437
|
+
line_counts[statements_start.location.start_line - 1].start,
|
3123
3438
|
ending.location.start_char,
|
3124
3439
|
ending.location.start_column
|
3125
3440
|
)
|
@@ -3142,7 +3457,7 @@ module SyntaxTree
|
|
3142
3457
|
# some other block
|
3143
3458
|
keyword = find_token(Kw, "do", consume: false)
|
3144
3459
|
if keyword && keyword.location.start_char > predicate.location.end_char &&
|
3145
|
-
|
3460
|
+
keyword.location.end_char < ending.location.start_char
|
3146
3461
|
tokens.delete(keyword)
|
3147
3462
|
end
|
3148
3463
|
|
@@ -3188,7 +3503,11 @@ module SyntaxTree
|
|
3188
3503
|
# :call-seq:
|
3189
3504
|
# on_word_new: () -> Word
|
3190
3505
|
def on_word_new
|
3191
|
-
Word.new(
|
3506
|
+
Word.new(
|
3507
|
+
parts: [],
|
3508
|
+
location:
|
3509
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
3510
|
+
)
|
3192
3511
|
end
|
3193
3512
|
|
3194
3513
|
# :call-seq:
|
@@ -3207,7 +3526,13 @@ module SyntaxTree
|
|
3207
3526
|
node =
|
3208
3527
|
WordsBeg.new(
|
3209
3528
|
value: value,
|
3210
|
-
location:
|
3529
|
+
location:
|
3530
|
+
Location.token(
|
3531
|
+
line: lineno,
|
3532
|
+
char: char_pos,
|
3533
|
+
column: current_column,
|
3534
|
+
size: value.size
|
3535
|
+
)
|
3211
3536
|
)
|
3212
3537
|
|
3213
3538
|
tokens << node
|
@@ -3219,7 +3544,11 @@ module SyntaxTree
|
|
3219
3544
|
def on_words_new
|
3220
3545
|
beginning = find_token(WordsBeg)
|
3221
3546
|
|
3222
|
-
Words.new(
|
3547
|
+
Words.new(
|
3548
|
+
beginning: beginning,
|
3549
|
+
elements: [],
|
3550
|
+
location: beginning.location
|
3551
|
+
)
|
3223
3552
|
end
|
3224
3553
|
|
3225
3554
|
# def on_words_sep(value)
|