syntax_tree 2.2.0 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +20 -1
- data/.rubocop.yml +80 -0
- data/CHANGELOG.md +47 -1
- data/Gemfile +2 -0
- data/Gemfile.lock +26 -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 +14 -6
- 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 +1042 -326
- data/lib/syntax_tree/parser.rb +444 -111
- data/lib/syntax_tree/prettyprint.rb +53 -38
- 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 +8 -4
data/lib/syntax_tree/node.rb
CHANGED
@@ -3,9 +3,21 @@
|
|
3
3
|
module SyntaxTree
|
4
4
|
# Represents the location of a node in the tree from the source code.
|
5
5
|
class Location
|
6
|
-
attr_reader :start_line,
|
6
|
+
attr_reader :start_line,
|
7
|
+
:start_char,
|
8
|
+
:start_column,
|
9
|
+
:end_line,
|
10
|
+
:end_char,
|
11
|
+
:end_column
|
7
12
|
|
8
|
-
def initialize(
|
13
|
+
def initialize(
|
14
|
+
start_line:,
|
15
|
+
start_char:,
|
16
|
+
start_column:,
|
17
|
+
end_line:,
|
18
|
+
end_char:,
|
19
|
+
end_column:
|
20
|
+
)
|
9
21
|
@start_line = start_line
|
10
22
|
@start_char = start_char
|
11
23
|
@start_column = start_column
|
@@ -39,7 +51,7 @@ module SyntaxTree
|
|
39
51
|
[start_line, start_char, start_column, end_line, end_char, end_column]
|
40
52
|
end
|
41
53
|
|
42
|
-
def deconstruct_keys(
|
54
|
+
def deconstruct_keys(_keys)
|
43
55
|
{
|
44
56
|
start_line: start_line,
|
45
57
|
start_char: start_char,
|
@@ -62,7 +74,14 @@ module SyntaxTree
|
|
62
74
|
end
|
63
75
|
|
64
76
|
def self.fixed(line:, char:, column:)
|
65
|
-
new(
|
77
|
+
new(
|
78
|
+
start_line: line,
|
79
|
+
start_char: char,
|
80
|
+
start_column: column,
|
81
|
+
end_line: line,
|
82
|
+
end_char: char,
|
83
|
+
end_column: column
|
84
|
+
)
|
66
85
|
end
|
67
86
|
end
|
68
87
|
|
@@ -102,6 +121,10 @@ module SyntaxTree
|
|
102
121
|
visitor = Visitor::JSONVisitor.new
|
103
122
|
visitor.visit(self).to_json(*opts)
|
104
123
|
end
|
124
|
+
|
125
|
+
def construct_keys
|
126
|
+
PP.format(+"") { |q| Visitor::MatchVisitor.new(q).visit(self) }
|
127
|
+
end
|
105
128
|
end
|
106
129
|
|
107
130
|
# BEGINBlock represents the use of the +BEGIN+ keyword, which hooks into the
|
@@ -140,7 +163,7 @@ module SyntaxTree
|
|
140
163
|
|
141
164
|
alias deconstruct child_nodes
|
142
165
|
|
143
|
-
def deconstruct_keys(
|
166
|
+
def deconstruct_keys(_keys)
|
144
167
|
{
|
145
168
|
lbrace: lbrace,
|
146
169
|
statements: statements,
|
@@ -192,7 +215,7 @@ module SyntaxTree
|
|
192
215
|
|
193
216
|
alias deconstruct child_nodes
|
194
217
|
|
195
|
-
def deconstruct_keys(
|
218
|
+
def deconstruct_keys(_keys)
|
196
219
|
{ value: value, location: location, comments: comments }
|
197
220
|
end
|
198
221
|
|
@@ -243,7 +266,7 @@ module SyntaxTree
|
|
243
266
|
|
244
267
|
alias deconstruct child_nodes
|
245
268
|
|
246
|
-
def deconstruct_keys(
|
269
|
+
def deconstruct_keys(_keys)
|
247
270
|
{
|
248
271
|
lbrace: lbrace,
|
249
272
|
statements: statements,
|
@@ -298,7 +321,7 @@ module SyntaxTree
|
|
298
321
|
|
299
322
|
alias deconstruct child_nodes
|
300
323
|
|
301
|
-
def deconstruct_keys(
|
324
|
+
def deconstruct_keys(_keys)
|
302
325
|
{ value: value, location: location, comments: comments }
|
303
326
|
end
|
304
327
|
|
@@ -323,6 +346,8 @@ module SyntaxTree
|
|
323
346
|
# symbols (note that this includes dynamic symbols like
|
324
347
|
# :"left-#{middle}-right").
|
325
348
|
class Alias < Node
|
349
|
+
# Formats an argument to the alias keyword. For symbol literals it uses the
|
350
|
+
# value of the symbol directly to look like bare words.
|
326
351
|
class AliasArgumentFormatter
|
327
352
|
# [DynaSymbol | SymbolLiteral] the argument being passed to alias
|
328
353
|
attr_reader :argument
|
@@ -374,7 +399,7 @@ module SyntaxTree
|
|
374
399
|
|
375
400
|
alias deconstruct child_nodes
|
376
401
|
|
377
|
-
def deconstruct_keys(
|
402
|
+
def deconstruct_keys(_keys)
|
378
403
|
{ left: left, right: right, location: location, comments: comments }
|
379
404
|
end
|
380
405
|
|
@@ -435,7 +460,7 @@ module SyntaxTree
|
|
435
460
|
|
436
461
|
alias deconstruct child_nodes
|
437
462
|
|
438
|
-
def deconstruct_keys(
|
463
|
+
def deconstruct_keys(_keys)
|
439
464
|
{
|
440
465
|
collection: collection,
|
441
466
|
index: index,
|
@@ -496,7 +521,7 @@ module SyntaxTree
|
|
496
521
|
|
497
522
|
alias deconstruct child_nodes
|
498
523
|
|
499
|
-
def deconstruct_keys(
|
524
|
+
def deconstruct_keys(_keys)
|
500
525
|
{
|
501
526
|
collection: collection,
|
502
527
|
index: index,
|
@@ -558,7 +583,7 @@ module SyntaxTree
|
|
558
583
|
|
559
584
|
alias deconstruct child_nodes
|
560
585
|
|
561
|
-
def deconstruct_keys(
|
586
|
+
def deconstruct_keys(_keys)
|
562
587
|
{ arguments: arguments, location: location, comments: comments }
|
563
588
|
end
|
564
589
|
|
@@ -606,7 +631,7 @@ module SyntaxTree
|
|
606
631
|
|
607
632
|
alias deconstruct child_nodes
|
608
633
|
|
609
|
-
def deconstruct_keys(
|
634
|
+
def deconstruct_keys(_keys)
|
610
635
|
{ parts: parts, location: location, comments: comments }
|
611
636
|
end
|
612
637
|
|
@@ -642,7 +667,7 @@ module SyntaxTree
|
|
642
667
|
|
643
668
|
alias deconstruct child_nodes
|
644
669
|
|
645
|
-
def deconstruct_keys(
|
670
|
+
def deconstruct_keys(_keys)
|
646
671
|
{ value: value, location: location, comments: comments }
|
647
672
|
end
|
648
673
|
|
@@ -679,7 +704,7 @@ module SyntaxTree
|
|
679
704
|
|
680
705
|
alias deconstruct child_nodes
|
681
706
|
|
682
|
-
def deconstruct_keys(
|
707
|
+
def deconstruct_keys(_keys)
|
683
708
|
{ value: value, location: location, comments: comments }
|
684
709
|
end
|
685
710
|
|
@@ -729,7 +754,7 @@ module SyntaxTree
|
|
729
754
|
|
730
755
|
alias deconstruct child_nodes
|
731
756
|
|
732
|
-
def deconstruct_keys(
|
757
|
+
def deconstruct_keys(_keys)
|
733
758
|
{ value: value, location: location, comments: comments }
|
734
759
|
end
|
735
760
|
|
@@ -745,6 +770,7 @@ module SyntaxTree
|
|
745
770
|
# [one, two, three]
|
746
771
|
#
|
747
772
|
class ArrayLiteral < Node
|
773
|
+
# Formats an array of multiple simple string literals into the %w syntax.
|
748
774
|
class QWordsFormatter
|
749
775
|
# [Args] the contents of the array
|
750
776
|
attr_reader :contents
|
@@ -761,7 +787,7 @@ module SyntaxTree
|
|
761
787
|
if part.is_a?(StringLiteral)
|
762
788
|
q.format(part.parts.first)
|
763
789
|
else
|
764
|
-
q.text(part.value[1
|
790
|
+
q.text(part.value[1..])
|
765
791
|
end
|
766
792
|
end
|
767
793
|
end
|
@@ -770,6 +796,7 @@ module SyntaxTree
|
|
770
796
|
end
|
771
797
|
end
|
772
798
|
|
799
|
+
# Formats an array of multiple simple symbol literals into the %i syntax.
|
773
800
|
class QSymbolsFormatter
|
774
801
|
# [Args] the contents of the array
|
775
802
|
attr_reader :contents
|
@@ -791,6 +818,28 @@ module SyntaxTree
|
|
791
818
|
end
|
792
819
|
end
|
793
820
|
|
821
|
+
# Formats an array that contains only a list of variable references. To make
|
822
|
+
# things simpler, if there are a bunch, we format them all using the "fill"
|
823
|
+
# algorithm as opposed to breaking them into a ton of lines. For example,
|
824
|
+
#
|
825
|
+
# [foo, bar, baz]
|
826
|
+
#
|
827
|
+
# instead of becoming:
|
828
|
+
#
|
829
|
+
# [
|
830
|
+
# foo,
|
831
|
+
# bar,
|
832
|
+
# baz
|
833
|
+
# ]
|
834
|
+
#
|
835
|
+
# would instead become:
|
836
|
+
#
|
837
|
+
# [
|
838
|
+
# foo, bar,
|
839
|
+
# baz
|
840
|
+
# ]
|
841
|
+
#
|
842
|
+
# provided the line length was hit between `bar` and `baz`.
|
794
843
|
class VarRefsFormatter
|
795
844
|
# [Args] the contents of the array
|
796
845
|
attr_reader :contents
|
@@ -816,6 +865,32 @@ module SyntaxTree
|
|
816
865
|
end
|
817
866
|
end
|
818
867
|
|
868
|
+
# This is a special formatter used if the array literal contains no values
|
869
|
+
# but _does_ contain comments. In this case we do some special formatting to
|
870
|
+
# make sure the comments gets indented properly.
|
871
|
+
class EmptyWithCommentsFormatter
|
872
|
+
# [LBracket] the opening bracket
|
873
|
+
attr_reader :lbracket
|
874
|
+
|
875
|
+
def initialize(lbracket)
|
876
|
+
@lbracket = lbracket
|
877
|
+
end
|
878
|
+
|
879
|
+
def format(q)
|
880
|
+
q.group do
|
881
|
+
q.text("[")
|
882
|
+
q.indent do
|
883
|
+
lbracket.comments.each do |comment|
|
884
|
+
q.breakable(force: true)
|
885
|
+
comment.format(q)
|
886
|
+
end
|
887
|
+
end
|
888
|
+
q.breakable(force: true)
|
889
|
+
q.text("]")
|
890
|
+
end
|
891
|
+
end
|
892
|
+
end
|
893
|
+
|
819
894
|
# [LBracket] the bracket that opens this array
|
820
895
|
attr_reader :lbracket
|
821
896
|
|
@@ -842,7 +917,7 @@ module SyntaxTree
|
|
842
917
|
|
843
918
|
alias deconstruct child_nodes
|
844
919
|
|
845
|
-
def deconstruct_keys(
|
920
|
+
def deconstruct_keys(_keys)
|
846
921
|
{
|
847
922
|
lbracket: lbracket,
|
848
923
|
contents: contents,
|
@@ -867,6 +942,11 @@ module SyntaxTree
|
|
867
942
|
return
|
868
943
|
end
|
869
944
|
|
945
|
+
if empty_with_comments?
|
946
|
+
EmptyWithCommentsFormatter.new(lbracket).format(q)
|
947
|
+
return
|
948
|
+
end
|
949
|
+
|
870
950
|
q.group do
|
871
951
|
q.format(lbracket)
|
872
952
|
|
@@ -919,6 +999,13 @@ module SyntaxTree
|
|
919
999
|
q.maxwidth * 2
|
920
1000
|
)
|
921
1001
|
end
|
1002
|
+
|
1003
|
+
# If we have an empty array that contains only comments, then we're going
|
1004
|
+
# to do some special printing to ensure they get indented correctly.
|
1005
|
+
def empty_with_comments?
|
1006
|
+
contents.nil? && lbracket.comments.any? &&
|
1007
|
+
lbracket.comments.none?(&:inline?)
|
1008
|
+
end
|
922
1009
|
end
|
923
1010
|
|
924
1011
|
# AryPtn represents matching against an array pattern using the Ruby 2.7+
|
@@ -939,6 +1026,7 @@ module SyntaxTree
|
|
939
1026
|
# and an optional array of positional matches that occur after the splat.
|
940
1027
|
# All of the in clauses above would create an AryPtn node.
|
941
1028
|
class AryPtn < Node
|
1029
|
+
# Formats the optional splat of an array pattern.
|
942
1030
|
class RestFormatter
|
943
1031
|
# [VarField] the identifier that represents the remaining positionals
|
944
1032
|
attr_reader :value
|
@@ -1001,7 +1089,7 @@ module SyntaxTree
|
|
1001
1089
|
|
1002
1090
|
alias deconstruct child_nodes
|
1003
1091
|
|
1004
|
-
def deconstruct_keys(
|
1092
|
+
def deconstruct_keys(_keys)
|
1005
1093
|
{
|
1006
1094
|
constant: constant,
|
1007
1095
|
requireds: requireds,
|
@@ -1033,6 +1121,8 @@ module SyntaxTree
|
|
1033
1121
|
q.text("[")
|
1034
1122
|
q.seplist(parts) { |part| q.format(part) }
|
1035
1123
|
q.text("]")
|
1124
|
+
elsif parts.empty?
|
1125
|
+
q.text("[]")
|
1036
1126
|
else
|
1037
1127
|
q.group { q.seplist(parts) { |part| q.format(part) } }
|
1038
1128
|
end
|
@@ -1042,17 +1132,17 @@ module SyntaxTree
|
|
1042
1132
|
# Determins if the following value should be indented or not.
|
1043
1133
|
module AssignFormatting
|
1044
1134
|
def self.skip_indent?(value)
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1135
|
+
case value
|
1136
|
+
in ArrayLiteral | HashLiteral | Heredoc | Lambda | QSymbols | QWords |
|
1137
|
+
Symbols | Words
|
1138
|
+
true
|
1139
|
+
in Call[receiver:]
|
1140
|
+
skip_indent?(receiver)
|
1141
|
+
in DynaSymbol[quote:]
|
1142
|
+
quote.start_with?("%s")
|
1143
|
+
else
|
1144
|
+
false
|
1145
|
+
end
|
1056
1146
|
end
|
1057
1147
|
end
|
1058
1148
|
|
@@ -1090,7 +1180,7 @@ module SyntaxTree
|
|
1090
1180
|
|
1091
1181
|
alias deconstruct child_nodes
|
1092
1182
|
|
1093
|
-
def deconstruct_keys(
|
1183
|
+
def deconstruct_keys(_keys)
|
1094
1184
|
{ target: target, value: value, location: location, comments: comments }
|
1095
1185
|
end
|
1096
1186
|
|
@@ -1152,12 +1242,12 @@ module SyntaxTree
|
|
1152
1242
|
|
1153
1243
|
alias deconstruct child_nodes
|
1154
1244
|
|
1155
|
-
def deconstruct_keys(
|
1245
|
+
def deconstruct_keys(_keys)
|
1156
1246
|
{ key: key, value: value, location: location, comments: comments }
|
1157
1247
|
end
|
1158
1248
|
|
1159
1249
|
def format(q)
|
1160
|
-
if value
|
1250
|
+
if value.is_a?(HashLiteral)
|
1161
1251
|
format_contents(q)
|
1162
1252
|
else
|
1163
1253
|
q.group { format_contents(q) }
|
@@ -1210,7 +1300,7 @@ module SyntaxTree
|
|
1210
1300
|
|
1211
1301
|
alias deconstruct child_nodes
|
1212
1302
|
|
1213
|
-
def deconstruct_keys(
|
1303
|
+
def deconstruct_keys(_keys)
|
1214
1304
|
{ value: value, location: location, comments: comments }
|
1215
1305
|
end
|
1216
1306
|
|
@@ -1248,7 +1338,7 @@ module SyntaxTree
|
|
1248
1338
|
|
1249
1339
|
alias deconstruct child_nodes
|
1250
1340
|
|
1251
|
-
def deconstruct_keys(
|
1341
|
+
def deconstruct_keys(_keys)
|
1252
1342
|
{ value: value, location: location, comments: comments }
|
1253
1343
|
end
|
1254
1344
|
|
@@ -1283,7 +1373,7 @@ module SyntaxTree
|
|
1283
1373
|
|
1284
1374
|
alias deconstruct child_nodes
|
1285
1375
|
|
1286
|
-
def deconstruct_keys(
|
1376
|
+
def deconstruct_keys(_keys)
|
1287
1377
|
{ value: value, location: location, comments: comments }
|
1288
1378
|
end
|
1289
1379
|
|
@@ -1296,21 +1386,28 @@ module SyntaxTree
|
|
1296
1386
|
# hash or bare hash. It first determines if every key in the hash can use
|
1297
1387
|
# labels. If it can, it uses labels. Otherwise it uses hash rockets.
|
1298
1388
|
module HashKeyFormatter
|
1389
|
+
# Formats the keys of a hash literal using labels.
|
1299
1390
|
class Labels
|
1391
|
+
LABEL = /^[@$_A-Za-z]([_A-Za-z0-9]*)?([!_=?A-Za-z0-9])?$/
|
1392
|
+
|
1300
1393
|
def format_key(q, key)
|
1301
1394
|
case key
|
1302
|
-
|
1395
|
+
in Label
|
1303
1396
|
q.format(key)
|
1304
|
-
|
1397
|
+
in SymbolLiteral
|
1305
1398
|
q.format(key.value)
|
1306
1399
|
q.text(":")
|
1307
|
-
|
1400
|
+
in DynaSymbol[parts: [TStringContent[value: LABEL] => part]]
|
1401
|
+
q.format(part)
|
1402
|
+
q.text(":")
|
1403
|
+
in DynaSymbol
|
1308
1404
|
q.format(key)
|
1309
1405
|
q.text(":")
|
1310
1406
|
end
|
1311
1407
|
end
|
1312
1408
|
end
|
1313
1409
|
|
1410
|
+
# Formats the keys of a hash literal using hash rockets.
|
1314
1411
|
class Rockets
|
1315
1412
|
def format_key(q, key)
|
1316
1413
|
case key
|
@@ -1384,7 +1481,7 @@ module SyntaxTree
|
|
1384
1481
|
|
1385
1482
|
alias deconstruct child_nodes
|
1386
1483
|
|
1387
|
-
def deconstruct_keys(
|
1484
|
+
def deconstruct_keys(_keys)
|
1388
1485
|
{ assocs: assocs, location: location, comments: comments }
|
1389
1486
|
end
|
1390
1487
|
|
@@ -1426,7 +1523,7 @@ module SyntaxTree
|
|
1426
1523
|
|
1427
1524
|
alias deconstruct child_nodes
|
1428
1525
|
|
1429
|
-
def deconstruct_keys(
|
1526
|
+
def deconstruct_keys(_keys)
|
1430
1527
|
{ bodystmt: bodystmt, location: location, comments: comments }
|
1431
1528
|
end
|
1432
1529
|
|
@@ -1474,7 +1571,7 @@ module SyntaxTree
|
|
1474
1571
|
|
1475
1572
|
alias deconstruct child_nodes
|
1476
1573
|
|
1477
|
-
def deconstruct_keys(
|
1574
|
+
def deconstruct_keys(_keys)
|
1478
1575
|
{ statement: statement, location: location, comments: comments }
|
1479
1576
|
end
|
1480
1577
|
|
@@ -1534,7 +1631,7 @@ module SyntaxTree
|
|
1534
1631
|
|
1535
1632
|
alias deconstruct child_nodes
|
1536
1633
|
|
1537
|
-
def deconstruct_keys(
|
1634
|
+
def deconstruct_keys(_keys)
|
1538
1635
|
{
|
1539
1636
|
left: left,
|
1540
1637
|
operator: operator,
|
@@ -1552,12 +1649,12 @@ module SyntaxTree
|
|
1552
1649
|
q.text(" ") unless power
|
1553
1650
|
|
1554
1651
|
if operator == :<<
|
1555
|
-
q.text(operator)
|
1652
|
+
q.text(operator.to_s)
|
1556
1653
|
q.text(" ")
|
1557
1654
|
q.format(right)
|
1558
1655
|
else
|
1559
1656
|
q.group do
|
1560
|
-
q.text(operator)
|
1657
|
+
q.text(operator.to_s)
|
1561
1658
|
|
1562
1659
|
q.indent do
|
1563
1660
|
q.breakable(power ? "" : " ")
|
@@ -1649,7 +1746,7 @@ module SyntaxTree
|
|
1649
1746
|
|
1650
1747
|
alias deconstruct child_nodes
|
1651
1748
|
|
1652
|
-
def deconstruct_keys(
|
1749
|
+
def deconstruct_keys(_keys)
|
1653
1750
|
{ params: params, locals: locals, location: location, comments: comments }
|
1654
1751
|
end
|
1655
1752
|
|
@@ -1693,7 +1790,7 @@ module SyntaxTree
|
|
1693
1790
|
|
1694
1791
|
alias deconstruct child_nodes
|
1695
1792
|
|
1696
|
-
def deconstruct_keys(
|
1793
|
+
def deconstruct_keys(_keys)
|
1697
1794
|
{ name: name, location: location, comments: comments }
|
1698
1795
|
end
|
1699
1796
|
|
@@ -1789,7 +1886,7 @@ module SyntaxTree
|
|
1789
1886
|
|
1790
1887
|
alias deconstruct child_nodes
|
1791
1888
|
|
1792
|
-
def deconstruct_keys(
|
1889
|
+
def deconstruct_keys(_keys)
|
1793
1890
|
{
|
1794
1891
|
statements: statements,
|
1795
1892
|
rescue_clause: rescue_clause,
|
@@ -1835,6 +1932,7 @@ module SyntaxTree
|
|
1835
1932
|
|
1836
1933
|
# Responsible for formatting either a BraceBlock or a DoBlock.
|
1837
1934
|
class BlockFormatter
|
1935
|
+
# Formats the opening brace or keyword of a block.
|
1838
1936
|
class BlockOpenFormatter
|
1839
1937
|
# [String] the actual output that should be printed
|
1840
1938
|
attr_reader :text
|
@@ -1900,9 +1998,9 @@ module SyntaxTree
|
|
1900
1998
|
end
|
1901
1999
|
|
1902
2000
|
q.group do
|
1903
|
-
q
|
1904
|
-
|
1905
|
-
|
2001
|
+
q
|
2002
|
+
.if_break { format_break(q, break_opening, break_closing) }
|
2003
|
+
.if_flat { format_flat(q, flat_opening, flat_closing) }
|
1906
2004
|
end
|
1907
2005
|
end
|
1908
2006
|
|
@@ -2027,7 +2125,7 @@ module SyntaxTree
|
|
2027
2125
|
|
2028
2126
|
alias deconstruct child_nodes
|
2029
2127
|
|
2030
|
-
def deconstruct_keys(
|
2128
|
+
def deconstruct_keys(_keys)
|
2031
2129
|
{
|
2032
2130
|
lbrace: lbrace,
|
2033
2131
|
block_var: block_var,
|
@@ -2042,12 +2140,12 @@ module SyntaxTree
|
|
2042
2140
|
end
|
2043
2141
|
end
|
2044
2142
|
|
2045
|
-
# Formats either a Break or
|
2143
|
+
# Formats either a Break, Next, or Return node.
|
2046
2144
|
class FlowControlFormatter
|
2047
2145
|
# [String] the keyword to print
|
2048
2146
|
attr_reader :keyword
|
2049
2147
|
|
2050
|
-
# [Break | Next] the node being formatted
|
2148
|
+
# [Break | Next | Return] the node being formatted
|
2051
2149
|
attr_reader :node
|
2052
2150
|
|
2053
2151
|
def initialize(keyword, node)
|
@@ -2056,32 +2154,123 @@ module SyntaxTree
|
|
2056
2154
|
end
|
2057
2155
|
|
2058
2156
|
def format(q)
|
2059
|
-
arguments = node.arguments
|
2060
|
-
|
2061
2157
|
q.group do
|
2062
2158
|
q.text(keyword)
|
2063
2159
|
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2160
|
+
case node.arguments.parts
|
2161
|
+
in []
|
2162
|
+
# Here there are no arguments at all, so we're not going to print
|
2163
|
+
# anything. This would be like if we had:
|
2164
|
+
#
|
2165
|
+
# break
|
2166
|
+
#
|
2167
|
+
in [Paren[
|
2168
|
+
contents: {
|
2169
|
+
body: [ArrayLiteral[contents: { parts: [_, _, *] }] => array]
|
2170
|
+
}
|
2171
|
+
]]
|
2172
|
+
# Here we have a single argument that is a set of parentheses wrapping
|
2173
|
+
# an array literal that has at least 2 elements. We're going to print
|
2174
|
+
# the contents of the array directly. This would be like if we had:
|
2175
|
+
#
|
2176
|
+
# break([1, 2, 3])
|
2177
|
+
#
|
2178
|
+
# which we will print as:
|
2179
|
+
#
|
2180
|
+
# break 1, 2, 3
|
2181
|
+
#
|
2182
|
+
q.text(" ")
|
2183
|
+
format_array_contents(q, array)
|
2184
|
+
in [Paren[contents: { body: [ArrayLiteral => statement] }]]
|
2185
|
+
# Here we have a single argument that is a set of parentheses wrapping
|
2186
|
+
# an array literal that has 0 or 1 elements. We're going to skip the
|
2187
|
+
# parentheses but print the array itself. This would be like if we
|
2188
|
+
# had:
|
2189
|
+
#
|
2190
|
+
# break([1])
|
2191
|
+
#
|
2192
|
+
# which we will print as:
|
2193
|
+
#
|
2194
|
+
# break [1]
|
2195
|
+
#
|
2196
|
+
q.text(" ")
|
2197
|
+
q.format(statement)
|
2198
|
+
in [Paren[contents: { body: [statement] }]] if skip_parens?(statement)
|
2199
|
+
# Here we have a single argument that is a set of parentheses that
|
2200
|
+
# themselves contain a single statement. That statement is a simple
|
2201
|
+
# value that we can skip the parentheses for. This would be like if we
|
2202
|
+
# had:
|
2203
|
+
#
|
2204
|
+
# break(1)
|
2205
|
+
#
|
2206
|
+
# which we will print as:
|
2207
|
+
#
|
2208
|
+
# break 1
|
2209
|
+
#
|
2210
|
+
q.text(" ")
|
2211
|
+
q.format(statement)
|
2212
|
+
in [Paren => part]
|
2213
|
+
# Here we have a single argument that is a set of parentheses. We're
|
2214
|
+
# going to print the parentheses themselves as if they were the set of
|
2215
|
+
# arguments. This would be like if we had:
|
2216
|
+
#
|
2217
|
+
# break(foo.bar)
|
2218
|
+
#
|
2219
|
+
q.format(part)
|
2220
|
+
in [ArrayLiteral[contents: { parts: [_, _, *] }] => array]
|
2221
|
+
# Here there is a single argument that is an array literal with at
|
2222
|
+
# least two elements. We skip directly into the array literal's
|
2223
|
+
# elements in order to print the contents. This would be like if we
|
2224
|
+
# had:
|
2225
|
+
#
|
2226
|
+
# break [1, 2, 3]
|
2227
|
+
#
|
2228
|
+
# which we will print as:
|
2229
|
+
#
|
2230
|
+
# break 1, 2, 3
|
2231
|
+
#
|
2232
|
+
q.text(" ")
|
2233
|
+
format_array_contents(q, array)
|
2234
|
+
in [ArrayLiteral => part]
|
2235
|
+
# Here there is a single argument that is an array literal with 0 or 1
|
2236
|
+
# elements. In this case we're going to print the array as it is
|
2237
|
+
# because skipping the brackets would change the remaining. This would
|
2238
|
+
# be like if we had:
|
2239
|
+
#
|
2240
|
+
# break []
|
2241
|
+
# break [1]
|
2242
|
+
#
|
2243
|
+
q.text(" ")
|
2244
|
+
q.format(part)
|
2245
|
+
in [_]
|
2246
|
+
# Here there is a single argument that hasn't matched one of our
|
2247
|
+
# previous cases. We're going to print the argument as it is. This
|
2248
|
+
# would be like if we had:
|
2249
|
+
#
|
2250
|
+
# break foo
|
2251
|
+
#
|
2252
|
+
format_arguments(q, "(", ")")
|
2253
|
+
else
|
2254
|
+
# If there are multiple arguments, format them all. If the line is
|
2255
|
+
# going to break into multiple, then use brackets to start and end the
|
2256
|
+
# expression.
|
2257
|
+
format_arguments(q, " [", "]")
|
2079
2258
|
end
|
2080
2259
|
end
|
2081
2260
|
end
|
2082
2261
|
|
2083
2262
|
private
|
2084
2263
|
|
2264
|
+
def format_array_contents(q, array)
|
2265
|
+
q.if_break { q.text("[") }
|
2266
|
+
q.indent do
|
2267
|
+
q.breakable("")
|
2268
|
+
q.format(array.contents)
|
2269
|
+
end
|
2270
|
+
q.breakable("")
|
2271
|
+
q.if_break { q.text("]") }
|
2272
|
+
end
|
2273
|
+
|
2085
2274
|
def format_arguments(q, opening, closing)
|
2086
2275
|
q.if_break { q.text(opening) }
|
2087
2276
|
q.indent do
|
@@ -2091,6 +2280,17 @@ module SyntaxTree
|
|
2091
2280
|
q.breakable("")
|
2092
2281
|
q.if_break { q.text(closing) }
|
2093
2282
|
end
|
2283
|
+
|
2284
|
+
def skip_parens?(node)
|
2285
|
+
case node
|
2286
|
+
in FloatLiteral | Imaginary | Int | RationalLiteral
|
2287
|
+
true
|
2288
|
+
in VarRef[value: Const | CVar | GVar | IVar | Kw]
|
2289
|
+
true
|
2290
|
+
else
|
2291
|
+
false
|
2292
|
+
end
|
2293
|
+
end
|
2094
2294
|
end
|
2095
2295
|
|
2096
2296
|
# Break represents using the +break+ keyword.
|
@@ -2124,7 +2324,7 @@ module SyntaxTree
|
|
2124
2324
|
|
2125
2325
|
alias deconstruct child_nodes
|
2126
2326
|
|
2127
|
-
def deconstruct_keys(
|
2327
|
+
def deconstruct_keys(_keys)
|
2128
2328
|
{ arguments: arguments, location: location, comments: comments }
|
2129
2329
|
end
|
2130
2330
|
|
@@ -2156,6 +2356,211 @@ module SyntaxTree
|
|
2156
2356
|
end
|
2157
2357
|
end
|
2158
2358
|
|
2359
|
+
# This is probably the most complicated formatter in this file. It's
|
2360
|
+
# responsible for formatting chains of method calls, with or without arguments
|
2361
|
+
# or blocks. In general, we want to go from something like
|
2362
|
+
#
|
2363
|
+
# foo.bar.baz
|
2364
|
+
#
|
2365
|
+
# to
|
2366
|
+
#
|
2367
|
+
# foo
|
2368
|
+
# .bar
|
2369
|
+
# .baz
|
2370
|
+
#
|
2371
|
+
# Of course there are a lot of caveats to that, including trailing operators
|
2372
|
+
# when necessary, where comments are places, how blocks are aligned, etc.
|
2373
|
+
class CallChainFormatter
|
2374
|
+
# [Call | MethodAddBlock] the top of the call chain
|
2375
|
+
attr_reader :node
|
2376
|
+
|
2377
|
+
def initialize(node)
|
2378
|
+
@node = node
|
2379
|
+
end
|
2380
|
+
|
2381
|
+
def format(q)
|
2382
|
+
children = [node]
|
2383
|
+
threshold = 3
|
2384
|
+
|
2385
|
+
# First, walk down the chain until we get to the point where we're not
|
2386
|
+
# longer at a chainable node.
|
2387
|
+
loop do
|
2388
|
+
case children.last
|
2389
|
+
in Call[receiver: Call]
|
2390
|
+
children << children.last.receiver
|
2391
|
+
in Call[receiver: MethodAddBlock[call: Call]]
|
2392
|
+
children << children.last.receiver
|
2393
|
+
in MethodAddBlock[call: Call]
|
2394
|
+
children << children.last.call
|
2395
|
+
else
|
2396
|
+
break
|
2397
|
+
end
|
2398
|
+
end
|
2399
|
+
|
2400
|
+
# Here, we have very specialized behavior where if we're within a sig
|
2401
|
+
# block, then we're going to assume we're creating a Sorbet type
|
2402
|
+
# signature. In that case, we really want the threshold to be lowered so
|
2403
|
+
# that we create method chains off of any two method calls within the
|
2404
|
+
# block. For more details, see
|
2405
|
+
# https://github.com/prettier/plugin-ruby/issues/863.
|
2406
|
+
parents = q.parents.take(4)
|
2407
|
+
if (parent = parents[2])
|
2408
|
+
# If we're at a do_block, then we want to go one more level up. This is
|
2409
|
+
# because do blocks have BodyStmt nodes instead of just Statements
|
2410
|
+
# nodes.
|
2411
|
+
parent = parents[3] if parent.is_a?(DoBlock)
|
2412
|
+
|
2413
|
+
case parent
|
2414
|
+
in MethodAddBlock[call: FCall[value: { value: "sig" }]]
|
2415
|
+
threshold = 2
|
2416
|
+
else
|
2417
|
+
end
|
2418
|
+
end
|
2419
|
+
|
2420
|
+
if children.length >= threshold
|
2421
|
+
q.group do
|
2422
|
+
q
|
2423
|
+
.if_break { format_chain(q, children) }
|
2424
|
+
.if_flat { node.format_contents(q) }
|
2425
|
+
end
|
2426
|
+
else
|
2427
|
+
node.format_contents(q)
|
2428
|
+
end
|
2429
|
+
end
|
2430
|
+
|
2431
|
+
def format_chain(q, children)
|
2432
|
+
# We're going to have some specialized behavior for if it's an entire
|
2433
|
+
# chain of calls without arguments except for the last one. This is common
|
2434
|
+
# enough in Ruby source code that it's worth the extra complexity here.
|
2435
|
+
empty_except_last =
|
2436
|
+
children
|
2437
|
+
.drop(1)
|
2438
|
+
.all? { |child| child.is_a?(Call) && child.arguments.nil? }
|
2439
|
+
|
2440
|
+
# Here, we're going to add all of the children onto the stack of the
|
2441
|
+
# formatter so it's as if we had descending normally into them. This is
|
2442
|
+
# necessary so they can check their parents as normal.
|
2443
|
+
q.stack.concat(children)
|
2444
|
+
q.format(children.last.receiver)
|
2445
|
+
|
2446
|
+
q.group do
|
2447
|
+
if attach_directly?(children.last)
|
2448
|
+
format_child(q, children.pop)
|
2449
|
+
q.stack.pop
|
2450
|
+
end
|
2451
|
+
|
2452
|
+
q.indent do
|
2453
|
+
# We track another variable that checks if you need to move the
|
2454
|
+
# operator to the previous line in case there are trailing comments
|
2455
|
+
# and a trailing operator.
|
2456
|
+
skip_operator = false
|
2457
|
+
|
2458
|
+
while (child = children.pop)
|
2459
|
+
case child
|
2460
|
+
in Call[
|
2461
|
+
receiver: Call[message: { value: "where" }],
|
2462
|
+
message: { value: "not" }
|
2463
|
+
]
|
2464
|
+
# This is very specialized behavior wherein we group
|
2465
|
+
# .where.not calls together because it looks better. For more
|
2466
|
+
# information, see
|
2467
|
+
# https://github.com/prettier/plugin-ruby/issues/862.
|
2468
|
+
in Call
|
2469
|
+
# If we're at a Call node and not a MethodAddBlock node in the
|
2470
|
+
# chain then we're going to add a newline so it indents properly.
|
2471
|
+
q.breakable("")
|
2472
|
+
else
|
2473
|
+
end
|
2474
|
+
|
2475
|
+
format_child(
|
2476
|
+
q,
|
2477
|
+
child,
|
2478
|
+
skip_comments: children.empty?,
|
2479
|
+
skip_operator: skip_operator,
|
2480
|
+
skip_attached: empty_except_last && children.empty?
|
2481
|
+
)
|
2482
|
+
|
2483
|
+
# If the parent call node has a comment on the message then we need
|
2484
|
+
# to print the operator trailing in order to keep it working.
|
2485
|
+
case children.last
|
2486
|
+
in Call[message: { comments: [_, *] }, operator:]
|
2487
|
+
q.format(CallOperatorFormatter.new(operator))
|
2488
|
+
skip_operator = true
|
2489
|
+
else
|
2490
|
+
skip_operator = false
|
2491
|
+
end
|
2492
|
+
|
2493
|
+
# Pop off the formatter's stack so that it aligns with what would
|
2494
|
+
# have happened if we had been formatting normally.
|
2495
|
+
q.stack.pop
|
2496
|
+
end
|
2497
|
+
end
|
2498
|
+
end
|
2499
|
+
|
2500
|
+
if empty_except_last
|
2501
|
+
case node
|
2502
|
+
in Call
|
2503
|
+
node.format_arguments(q)
|
2504
|
+
in MethodAddBlock[block:]
|
2505
|
+
q.format(block)
|
2506
|
+
end
|
2507
|
+
end
|
2508
|
+
end
|
2509
|
+
|
2510
|
+
def self.chained?(node)
|
2511
|
+
case node
|
2512
|
+
in Call | MethodAddBlock[call: Call]
|
2513
|
+
true
|
2514
|
+
else
|
2515
|
+
false
|
2516
|
+
end
|
2517
|
+
end
|
2518
|
+
|
2519
|
+
private
|
2520
|
+
|
2521
|
+
# For certain nodes, we want to attach directly to the end and don't
|
2522
|
+
# want to indent the first call. So we'll pop off the first children and
|
2523
|
+
# format it separately here.
|
2524
|
+
def attach_directly?(node)
|
2525
|
+
[ArrayLiteral, HashLiteral, Heredoc, If, Unless, XStringLiteral].include?(
|
2526
|
+
node.receiver.class
|
2527
|
+
)
|
2528
|
+
end
|
2529
|
+
|
2530
|
+
def format_child(
|
2531
|
+
q,
|
2532
|
+
child,
|
2533
|
+
skip_comments: false,
|
2534
|
+
skip_operator: false,
|
2535
|
+
skip_attached: false
|
2536
|
+
)
|
2537
|
+
# First, format the actual contents of the child.
|
2538
|
+
case child
|
2539
|
+
in Call
|
2540
|
+
q.group do
|
2541
|
+
unless skip_operator
|
2542
|
+
q.format(CallOperatorFormatter.new(child.operator))
|
2543
|
+
end
|
2544
|
+
q.format(child.message) if child.message != :call
|
2545
|
+
child.format_arguments(q) unless skip_attached
|
2546
|
+
end
|
2547
|
+
in MethodAddBlock
|
2548
|
+
q.format(child.block) unless skip_attached
|
2549
|
+
end
|
2550
|
+
|
2551
|
+
# If there are any comments on this node then we need to explicitly print
|
2552
|
+
# them out here since we're bypassing the normal comment printing.
|
2553
|
+
if child.comments.any? && !skip_comments
|
2554
|
+
child.comments.each do |comment|
|
2555
|
+
comment.inline? ? q.text(" ") : q.breakable
|
2556
|
+
comment.format(q)
|
2557
|
+
end
|
2558
|
+
|
2559
|
+
q.break_parent
|
2560
|
+
end
|
2561
|
+
end
|
2562
|
+
end
|
2563
|
+
|
2159
2564
|
# Call represents a method call.
|
2160
2565
|
#
|
2161
2566
|
# receiver.message
|
@@ -2207,7 +2612,7 @@ module SyntaxTree
|
|
2207
2612
|
|
2208
2613
|
alias deconstruct child_nodes
|
2209
2614
|
|
2210
|
-
def deconstruct_keys(
|
2615
|
+
def deconstruct_keys(_keys)
|
2211
2616
|
{
|
2212
2617
|
receiver: receiver,
|
2213
2618
|
operator: operator,
|
@@ -2219,6 +2624,34 @@ module SyntaxTree
|
|
2219
2624
|
end
|
2220
2625
|
|
2221
2626
|
def format(q)
|
2627
|
+
# If we're at the top of a call chain, then we're going to do some
|
2628
|
+
# specialized printing in case we can print it nicely. We _only_ do this
|
2629
|
+
# at the top of the chain to avoid weird recursion issues.
|
2630
|
+
if !CallChainFormatter.chained?(q.parent) &&
|
2631
|
+
CallChainFormatter.chained?(receiver)
|
2632
|
+
q.group do
|
2633
|
+
q
|
2634
|
+
.if_break { CallChainFormatter.new(self).format(q) }
|
2635
|
+
.if_flat { format_contents(q) }
|
2636
|
+
end
|
2637
|
+
else
|
2638
|
+
format_contents(q)
|
2639
|
+
end
|
2640
|
+
end
|
2641
|
+
|
2642
|
+
def format_arguments(q)
|
2643
|
+
case arguments
|
2644
|
+
in ArgParen
|
2645
|
+
q.format(arguments)
|
2646
|
+
in Args
|
2647
|
+
q.text(" ")
|
2648
|
+
q.format(arguments)
|
2649
|
+
else
|
2650
|
+
# Do nothing if there are no arguments.
|
2651
|
+
end
|
2652
|
+
end
|
2653
|
+
|
2654
|
+
def format_contents(q)
|
2222
2655
|
call_operator = CallOperatorFormatter.new(operator)
|
2223
2656
|
|
2224
2657
|
q.group do
|
@@ -2241,7 +2674,7 @@ module SyntaxTree
|
|
2241
2674
|
q.format(message) if message != :call
|
2242
2675
|
end
|
2243
2676
|
|
2244
|
-
q
|
2677
|
+
format_arguments(q)
|
2245
2678
|
end
|
2246
2679
|
end
|
2247
2680
|
end
|
@@ -2289,7 +2722,7 @@ module SyntaxTree
|
|
2289
2722
|
|
2290
2723
|
alias deconstruct child_nodes
|
2291
2724
|
|
2292
|
-
def deconstruct_keys(
|
2725
|
+
def deconstruct_keys(_keys)
|
2293
2726
|
{
|
2294
2727
|
keyword: keyword,
|
2295
2728
|
value: value,
|
@@ -2354,7 +2787,7 @@ module SyntaxTree
|
|
2354
2787
|
|
2355
2788
|
alias deconstruct child_nodes
|
2356
2789
|
|
2357
|
-
def deconstruct_keys(
|
2790
|
+
def deconstruct_keys(_keys)
|
2358
2791
|
{
|
2359
2792
|
value: value,
|
2360
2793
|
operator: operator,
|
@@ -2443,7 +2876,7 @@ module SyntaxTree
|
|
2443
2876
|
|
2444
2877
|
alias deconstruct child_nodes
|
2445
2878
|
|
2446
|
-
def deconstruct_keys(
|
2879
|
+
def deconstruct_keys(_keys)
|
2447
2880
|
{
|
2448
2881
|
constant: constant,
|
2449
2882
|
superclass: superclass,
|
@@ -2507,8 +2940,8 @@ module SyntaxTree
|
|
2507
2940
|
end
|
2508
2941
|
|
2509
2942
|
alias deconstruct child_nodes
|
2510
|
-
|
2511
|
-
def deconstruct_keys(
|
2943
|
+
|
2944
|
+
def deconstruct_keys(_keys)
|
2512
2945
|
{ value: value, location: location }
|
2513
2946
|
end
|
2514
2947
|
end
|
@@ -2546,7 +2979,7 @@ module SyntaxTree
|
|
2546
2979
|
|
2547
2980
|
alias deconstruct child_nodes
|
2548
2981
|
|
2549
|
-
def deconstruct_keys(
|
2982
|
+
def deconstruct_keys(_keys)
|
2550
2983
|
{
|
2551
2984
|
message: message,
|
2552
2985
|
arguments: arguments,
|
@@ -2558,26 +2991,25 @@ module SyntaxTree
|
|
2558
2991
|
def format(q)
|
2559
2992
|
q.group do
|
2560
2993
|
q.format(message)
|
2561
|
-
q.
|
2562
|
-
|
2563
|
-
if align?(self)
|
2564
|
-
q.nest(message.value.length + 1) { q.format(arguments) }
|
2565
|
-
else
|
2566
|
-
q.format(arguments)
|
2567
|
-
end
|
2994
|
+
align(q, self) { q.format(arguments) }
|
2568
2995
|
end
|
2569
2996
|
end
|
2570
2997
|
|
2571
2998
|
private
|
2572
2999
|
|
2573
|
-
def align
|
3000
|
+
def align(q, node, &block)
|
2574
3001
|
case node.arguments
|
2575
3002
|
in Args[parts: [Def | Defs | DefEndless]]
|
2576
|
-
|
3003
|
+
q.text(" ")
|
3004
|
+
yield
|
3005
|
+
in Args[parts: [IfOp]]
|
3006
|
+
q.if_flat { q.text(" ") }
|
3007
|
+
yield
|
2577
3008
|
in Args[parts: [Command => command]]
|
2578
|
-
align
|
3009
|
+
align(q, command, &block)
|
2579
3010
|
else
|
2580
|
-
|
3011
|
+
q.text(" ")
|
3012
|
+
q.nest(message.value.length + 1) { yield }
|
2581
3013
|
end
|
2582
3014
|
end
|
2583
3015
|
end
|
@@ -2629,7 +3061,7 @@ module SyntaxTree
|
|
2629
3061
|
|
2630
3062
|
alias deconstruct child_nodes
|
2631
3063
|
|
2632
|
-
def deconstruct_keys(
|
3064
|
+
def deconstruct_keys(_keys)
|
2633
3065
|
{
|
2634
3066
|
receiver: receiver,
|
2635
3067
|
operator: operator,
|
@@ -2649,9 +3081,15 @@ module SyntaxTree
|
|
2649
3081
|
q.format(message)
|
2650
3082
|
end
|
2651
3083
|
|
2652
|
-
|
3084
|
+
case arguments
|
3085
|
+
in Args[parts: [IfOp]]
|
3086
|
+
q.if_flat { q.text(" ") }
|
3087
|
+
q.format(arguments)
|
3088
|
+
in Args
|
2653
3089
|
q.text(" ")
|
2654
3090
|
q.nest(argument_alignment(q, doc)) { q.format(arguments) }
|
3091
|
+
else
|
3092
|
+
# If there are no arguments, print nothing.
|
2655
3093
|
end
|
2656
3094
|
end
|
2657
3095
|
end
|
@@ -2745,7 +3183,7 @@ module SyntaxTree
|
|
2745
3183
|
end
|
2746
3184
|
|
2747
3185
|
def ignore?
|
2748
|
-
value[1
|
3186
|
+
value[1..].strip == "stree-ignore"
|
2749
3187
|
end
|
2750
3188
|
|
2751
3189
|
def comments
|
@@ -2762,7 +3200,7 @@ module SyntaxTree
|
|
2762
3200
|
|
2763
3201
|
alias deconstruct child_nodes
|
2764
3202
|
|
2765
|
-
def deconstruct_keys(
|
3203
|
+
def deconstruct_keys(_keys)
|
2766
3204
|
{ value: value, inline: inline, location: location }
|
2767
3205
|
end
|
2768
3206
|
|
@@ -2808,7 +3246,7 @@ module SyntaxTree
|
|
2808
3246
|
|
2809
3247
|
alias deconstruct child_nodes
|
2810
3248
|
|
2811
|
-
def deconstruct_keys(
|
3249
|
+
def deconstruct_keys(_keys)
|
2812
3250
|
{ value: value, location: location, comments: comments }
|
2813
3251
|
end
|
2814
3252
|
|
@@ -2850,7 +3288,7 @@ module SyntaxTree
|
|
2850
3288
|
|
2851
3289
|
alias deconstruct child_nodes
|
2852
3290
|
|
2853
|
-
def deconstruct_keys(
|
3291
|
+
def deconstruct_keys(_keys)
|
2854
3292
|
{
|
2855
3293
|
parent: parent,
|
2856
3294
|
constant: constant,
|
@@ -2897,7 +3335,7 @@ module SyntaxTree
|
|
2897
3335
|
|
2898
3336
|
alias deconstruct child_nodes
|
2899
3337
|
|
2900
|
-
def deconstruct_keys(
|
3338
|
+
def deconstruct_keys(_keys)
|
2901
3339
|
{
|
2902
3340
|
parent: parent,
|
2903
3341
|
constant: constant,
|
@@ -2942,7 +3380,7 @@ module SyntaxTree
|
|
2942
3380
|
|
2943
3381
|
alias deconstruct child_nodes
|
2944
3382
|
|
2945
|
-
def deconstruct_keys(
|
3383
|
+
def deconstruct_keys(_keys)
|
2946
3384
|
{ constant: constant, location: location, comments: comments }
|
2947
3385
|
end
|
2948
3386
|
|
@@ -2978,7 +3416,7 @@ module SyntaxTree
|
|
2978
3416
|
|
2979
3417
|
alias deconstruct child_nodes
|
2980
3418
|
|
2981
|
-
def deconstruct_keys(
|
3419
|
+
def deconstruct_keys(_keys)
|
2982
3420
|
{ value: value, location: location, comments: comments }
|
2983
3421
|
end
|
2984
3422
|
|
@@ -3022,7 +3460,7 @@ module SyntaxTree
|
|
3022
3460
|
|
3023
3461
|
alias deconstruct child_nodes
|
3024
3462
|
|
3025
|
-
def deconstruct_keys(
|
3463
|
+
def deconstruct_keys(_keys)
|
3026
3464
|
{
|
3027
3465
|
name: name,
|
3028
3466
|
params: params,
|
@@ -3037,7 +3475,10 @@ module SyntaxTree
|
|
3037
3475
|
q.group do
|
3038
3476
|
q.text("def ")
|
3039
3477
|
q.format(name)
|
3040
|
-
|
3478
|
+
|
3479
|
+
if !params.is_a?(Params) || !params.empty? || params.comments.any?
|
3480
|
+
q.format(params)
|
3481
|
+
end
|
3041
3482
|
end
|
3042
3483
|
|
3043
3484
|
unless bodystmt.empty?
|
@@ -3104,7 +3545,7 @@ module SyntaxTree
|
|
3104
3545
|
|
3105
3546
|
alias deconstruct child_nodes
|
3106
3547
|
|
3107
|
-
def deconstruct_keys(
|
3548
|
+
def deconstruct_keys(_keys)
|
3108
3549
|
{
|
3109
3550
|
target: target,
|
3110
3551
|
operator: operator,
|
@@ -3172,7 +3613,7 @@ module SyntaxTree
|
|
3172
3613
|
|
3173
3614
|
alias deconstruct child_nodes
|
3174
3615
|
|
3175
|
-
def deconstruct_keys(
|
3616
|
+
def deconstruct_keys(_keys)
|
3176
3617
|
{ value: value, location: location, comments: comments }
|
3177
3618
|
end
|
3178
3619
|
|
@@ -3238,7 +3679,7 @@ module SyntaxTree
|
|
3238
3679
|
|
3239
3680
|
alias deconstruct child_nodes
|
3240
3681
|
|
3241
|
-
def deconstruct_keys(
|
3682
|
+
def deconstruct_keys(_keys)
|
3242
3683
|
{
|
3243
3684
|
target: target,
|
3244
3685
|
operator: operator,
|
@@ -3257,7 +3698,10 @@ module SyntaxTree
|
|
3257
3698
|
q.format(target)
|
3258
3699
|
q.format(CallOperatorFormatter.new(operator), stackable: false)
|
3259
3700
|
q.format(name)
|
3260
|
-
|
3701
|
+
|
3702
|
+
if !params.is_a?(Params) || !params.empty? || params.comments.any?
|
3703
|
+
q.format(params)
|
3704
|
+
end
|
3261
3705
|
end
|
3262
3706
|
|
3263
3707
|
unless bodystmt.empty?
|
@@ -3310,7 +3754,7 @@ module SyntaxTree
|
|
3310
3754
|
|
3311
3755
|
alias deconstruct child_nodes
|
3312
3756
|
|
3313
|
-
def deconstruct_keys(
|
3757
|
+
def deconstruct_keys(_keys)
|
3314
3758
|
{
|
3315
3759
|
keyword: keyword,
|
3316
3760
|
block_var: block_var,
|
@@ -3390,7 +3834,7 @@ module SyntaxTree
|
|
3390
3834
|
|
3391
3835
|
alias deconstruct child_nodes
|
3392
3836
|
|
3393
|
-
def deconstruct_keys(
|
3837
|
+
def deconstruct_keys(_keys)
|
3394
3838
|
{ left: left, right: right, location: location, comments: comments }
|
3395
3839
|
end
|
3396
3840
|
|
@@ -3438,7 +3882,7 @@ module SyntaxTree
|
|
3438
3882
|
|
3439
3883
|
alias deconstruct child_nodes
|
3440
3884
|
|
3441
|
-
def deconstruct_keys(
|
3885
|
+
def deconstruct_keys(_keys)
|
3442
3886
|
{ left: left, right: right, location: location, comments: comments }
|
3443
3887
|
end
|
3444
3888
|
|
@@ -3460,7 +3904,7 @@ module SyntaxTree
|
|
3460
3904
|
# quotes, then single quotes would deactivate it.)
|
3461
3905
|
def self.locked?(node)
|
3462
3906
|
node.parts.any? do |part|
|
3463
|
-
part.is_a?(TStringContent) && part.value.match?(
|
3907
|
+
part.is_a?(TStringContent) && part.value.match?(/\\|#[@${]/)
|
3464
3908
|
end
|
3465
3909
|
end
|
3466
3910
|
|
@@ -3525,7 +3969,7 @@ module SyntaxTree
|
|
3525
3969
|
|
3526
3970
|
alias deconstruct child_nodes
|
3527
3971
|
|
3528
|
-
def deconstruct_keys(
|
3972
|
+
def deconstruct_keys(_keys)
|
3529
3973
|
{ parts: parts, quote: quote, location: location, comments: comments }
|
3530
3974
|
end
|
3531
3975
|
|
@@ -3566,9 +4010,14 @@ module SyntaxTree
|
|
3566
4010
|
matching = Quotes.matching(quote[2])
|
3567
4011
|
pattern = /[\n#{Regexp.escape(matching)}'"]/
|
3568
4012
|
|
3569
|
-
|
3570
|
-
|
3571
|
-
|
4013
|
+
# This check is to ensure we don't find a matching quote inside of the
|
4014
|
+
# symbol that would be confusing.
|
4015
|
+
matched =
|
4016
|
+
parts.any? do |part|
|
4017
|
+
part.is_a?(TStringContent) && part.value.match?(pattern)
|
4018
|
+
end
|
4019
|
+
|
4020
|
+
if matched
|
3572
4021
|
[quote, matching]
|
3573
4022
|
elsif Quotes.locked?(self)
|
3574
4023
|
["#{":" unless hash_key}'", "'"]
|
@@ -3577,7 +4026,7 @@ module SyntaxTree
|
|
3577
4026
|
end
|
3578
4027
|
elsif Quotes.locked?(self)
|
3579
4028
|
if quote.start_with?(":")
|
3580
|
-
[hash_key ? quote[1
|
4029
|
+
[hash_key ? quote[1..] : quote, quote[1..]]
|
3581
4030
|
else
|
3582
4031
|
[hash_key ? quote : ":#{quote}", quote]
|
3583
4032
|
end
|
@@ -3620,7 +4069,7 @@ module SyntaxTree
|
|
3620
4069
|
|
3621
4070
|
alias deconstruct child_nodes
|
3622
4071
|
|
3623
|
-
def deconstruct_keys(
|
4072
|
+
def deconstruct_keys(_keys)
|
3624
4073
|
{
|
3625
4074
|
keyword: keyword,
|
3626
4075
|
statements: statements,
|
@@ -3686,7 +4135,7 @@ module SyntaxTree
|
|
3686
4135
|
|
3687
4136
|
alias deconstruct child_nodes
|
3688
4137
|
|
3689
|
-
def deconstruct_keys(
|
4138
|
+
def deconstruct_keys(_keys)
|
3690
4139
|
{
|
3691
4140
|
predicate: predicate,
|
3692
4141
|
statements: statements,
|
@@ -3758,7 +4207,7 @@ module SyntaxTree
|
|
3758
4207
|
|
3759
4208
|
alias deconstruct child_nodes
|
3760
4209
|
|
3761
|
-
def deconstruct_keys(
|
4210
|
+
def deconstruct_keys(_keys)
|
3762
4211
|
{ value: value, location: location }
|
3763
4212
|
end
|
3764
4213
|
|
@@ -3792,8 +4241,8 @@ module SyntaxTree
|
|
3792
4241
|
end
|
3793
4242
|
|
3794
4243
|
alias deconstruct child_nodes
|
3795
|
-
|
3796
|
-
def deconstruct_keys(
|
4244
|
+
|
4245
|
+
def deconstruct_keys(_keys)
|
3797
4246
|
{ value: value, location: location }
|
3798
4247
|
end
|
3799
4248
|
end
|
@@ -3822,8 +4271,8 @@ module SyntaxTree
|
|
3822
4271
|
end
|
3823
4272
|
|
3824
4273
|
alias deconstruct child_nodes
|
3825
|
-
|
3826
|
-
def deconstruct_keys(
|
4274
|
+
|
4275
|
+
def deconstruct_keys(_keys)
|
3827
4276
|
{ value: value, location: location }
|
3828
4277
|
end
|
3829
4278
|
end
|
@@ -3854,8 +4303,8 @@ module SyntaxTree
|
|
3854
4303
|
end
|
3855
4304
|
|
3856
4305
|
alias deconstruct child_nodes
|
3857
|
-
|
3858
|
-
def deconstruct_keys(
|
4306
|
+
|
4307
|
+
def deconstruct_keys(_keys)
|
3859
4308
|
{ value: value, location: location }
|
3860
4309
|
end
|
3861
4310
|
end
|
@@ -3894,7 +4343,7 @@ module SyntaxTree
|
|
3894
4343
|
|
3895
4344
|
alias deconstruct child_nodes
|
3896
4345
|
|
3897
|
-
def deconstruct_keys(
|
4346
|
+
def deconstruct_keys(_keys)
|
3898
4347
|
{
|
3899
4348
|
keyword: keyword,
|
3900
4349
|
statements: statements,
|
@@ -3948,7 +4397,7 @@ module SyntaxTree
|
|
3948
4397
|
|
3949
4398
|
alias deconstruct child_nodes
|
3950
4399
|
|
3951
|
-
def deconstruct_keys(
|
4400
|
+
def deconstruct_keys(_keys)
|
3952
4401
|
{ value: value, location: location, comments: comments }
|
3953
4402
|
end
|
3954
4403
|
|
@@ -3991,7 +4440,7 @@ module SyntaxTree
|
|
3991
4440
|
|
3992
4441
|
alias deconstruct child_nodes
|
3993
4442
|
|
3994
|
-
def deconstruct_keys(
|
4443
|
+
def deconstruct_keys(_keys)
|
3995
4444
|
{
|
3996
4445
|
value: value,
|
3997
4446
|
arguments: arguments,
|
@@ -4002,7 +4451,16 @@ module SyntaxTree
|
|
4002
4451
|
|
4003
4452
|
def format(q)
|
4004
4453
|
q.format(value)
|
4005
|
-
|
4454
|
+
|
4455
|
+
if arguments.is_a?(ArgParen) && arguments.arguments.nil? &&
|
4456
|
+
!value.is_a?(Const)
|
4457
|
+
# If you're using an explicit set of parentheses on something that looks
|
4458
|
+
# like a constant, then we need to match that in order to maintain valid
|
4459
|
+
# Ruby. For example, you could do something like Foo(), on which we
|
4460
|
+
# would need to keep the parentheses to make it look like a method call.
|
4461
|
+
else
|
4462
|
+
q.format(arguments)
|
4463
|
+
end
|
4006
4464
|
end
|
4007
4465
|
end
|
4008
4466
|
|
@@ -4042,7 +4500,7 @@ module SyntaxTree
|
|
4042
4500
|
|
4043
4501
|
alias deconstruct child_nodes
|
4044
4502
|
|
4045
|
-
def deconstruct_keys(
|
4503
|
+
def deconstruct_keys(_keys)
|
4046
4504
|
{
|
4047
4505
|
parent: parent,
|
4048
4506
|
operator: operator,
|
@@ -4088,7 +4546,7 @@ module SyntaxTree
|
|
4088
4546
|
|
4089
4547
|
alias deconstruct child_nodes
|
4090
4548
|
|
4091
|
-
def deconstruct_keys(
|
4549
|
+
def deconstruct_keys(_keys)
|
4092
4550
|
{ value: value, location: location, comments: comments }
|
4093
4551
|
end
|
4094
4552
|
|
@@ -4140,7 +4598,7 @@ module SyntaxTree
|
|
4140
4598
|
|
4141
4599
|
alias deconstruct child_nodes
|
4142
4600
|
|
4143
|
-
def deconstruct_keys(
|
4601
|
+
def deconstruct_keys(_keys)
|
4144
4602
|
{
|
4145
4603
|
constant: constant,
|
4146
4604
|
left: left,
|
@@ -4204,7 +4662,7 @@ module SyntaxTree
|
|
4204
4662
|
|
4205
4663
|
alias deconstruct child_nodes
|
4206
4664
|
|
4207
|
-
def deconstruct_keys(
|
4665
|
+
def deconstruct_keys(_keys)
|
4208
4666
|
{
|
4209
4667
|
index: index,
|
4210
4668
|
collection: collection,
|
@@ -4261,7 +4719,7 @@ module SyntaxTree
|
|
4261
4719
|
|
4262
4720
|
alias deconstruct child_nodes
|
4263
4721
|
|
4264
|
-
def deconstruct_keys(
|
4722
|
+
def deconstruct_keys(_keys)
|
4265
4723
|
{ value: value, location: location, comments: comments }
|
4266
4724
|
end
|
4267
4725
|
|
@@ -4275,6 +4733,32 @@ module SyntaxTree
|
|
4275
4733
|
# { key => value }
|
4276
4734
|
#
|
4277
4735
|
class HashLiteral < Node
|
4736
|
+
# This is a special formatter used if the hash literal contains no values
|
4737
|
+
# but _does_ contain comments. In this case we do some special formatting to
|
4738
|
+
# make sure the comments gets indented properly.
|
4739
|
+
class EmptyWithCommentsFormatter
|
4740
|
+
# [LBrace] the opening brace
|
4741
|
+
attr_reader :lbrace
|
4742
|
+
|
4743
|
+
def initialize(lbrace)
|
4744
|
+
@lbrace = lbrace
|
4745
|
+
end
|
4746
|
+
|
4747
|
+
def format(q)
|
4748
|
+
q.group do
|
4749
|
+
q.text("{")
|
4750
|
+
q.indent do
|
4751
|
+
lbrace.comments.each do |comment|
|
4752
|
+
q.breakable(force: true)
|
4753
|
+
comment.format(q)
|
4754
|
+
end
|
4755
|
+
end
|
4756
|
+
q.breakable(force: true)
|
4757
|
+
q.text("}")
|
4758
|
+
end
|
4759
|
+
end
|
4760
|
+
end
|
4761
|
+
|
4278
4762
|
# [LBrace] the left brace that opens this hash
|
4279
4763
|
attr_reader :lbrace
|
4280
4764
|
|
@@ -4301,7 +4785,7 @@ module SyntaxTree
|
|
4301
4785
|
|
4302
4786
|
alias deconstruct child_nodes
|
4303
4787
|
|
4304
|
-
def deconstruct_keys(
|
4788
|
+
def deconstruct_keys(_keys)
|
4305
4789
|
{ lbrace: lbrace, assocs: assocs, location: location, comments: comments }
|
4306
4790
|
end
|
4307
4791
|
|
@@ -4319,7 +4803,18 @@ module SyntaxTree
|
|
4319
4803
|
|
4320
4804
|
private
|
4321
4805
|
|
4322
|
-
|
4806
|
+
# If we have an empty hash that contains only comments, then we're going
|
4807
|
+
# to do some special printing to ensure they get indented correctly.
|
4808
|
+
def empty_with_comments?
|
4809
|
+
assocs.empty? && lbrace.comments.any? && lbrace.comments.none?(&:inline?)
|
4810
|
+
end
|
4811
|
+
|
4812
|
+
def format_contents(q)
|
4813
|
+
if empty_with_comments?
|
4814
|
+
EmptyWithCommentsFormatter.new(lbrace).format(q)
|
4815
|
+
return
|
4816
|
+
end
|
4817
|
+
|
4323
4818
|
q.format(lbrace)
|
4324
4819
|
|
4325
4820
|
if assocs.empty?
|
@@ -4359,7 +4854,14 @@ module SyntaxTree
|
|
4359
4854
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
4360
4855
|
attr_reader :comments
|
4361
4856
|
|
4362
|
-
def initialize(
|
4857
|
+
def initialize(
|
4858
|
+
beginning:,
|
4859
|
+
ending: nil,
|
4860
|
+
dedent: 0,
|
4861
|
+
parts: [],
|
4862
|
+
location:,
|
4863
|
+
comments: []
|
4864
|
+
)
|
4363
4865
|
@beginning = beginning
|
4364
4866
|
@ending = ending
|
4365
4867
|
@dedent = dedent
|
@@ -4378,7 +4880,7 @@ module SyntaxTree
|
|
4378
4880
|
|
4379
4881
|
alias deconstruct child_nodes
|
4380
4882
|
|
4381
|
-
def deconstruct_keys(
|
4883
|
+
def deconstruct_keys(_keys)
|
4382
4884
|
{
|
4383
4885
|
beginning: beginning,
|
4384
4886
|
location: location,
|
@@ -4393,8 +4895,12 @@ module SyntaxTree
|
|
4393
4895
|
# prettyprint module. It's when you want to force a newline, but don't
|
4394
4896
|
# want to force the break parent.
|
4395
4897
|
breakable = -> do
|
4396
|
-
q.target <<
|
4397
|
-
|
4898
|
+
q.target << PrettyPrint::Breakable.new(
|
4899
|
+
" ",
|
4900
|
+
1,
|
4901
|
+
indent: false,
|
4902
|
+
force: true
|
4903
|
+
)
|
4398
4904
|
end
|
4399
4905
|
|
4400
4906
|
q.group do
|
@@ -4450,7 +4956,7 @@ module SyntaxTree
|
|
4450
4956
|
|
4451
4957
|
alias deconstruct child_nodes
|
4452
4958
|
|
4453
|
-
def deconstruct_keys(
|
4959
|
+
def deconstruct_keys(_keys)
|
4454
4960
|
{ value: value, location: location, comments: comments }
|
4455
4961
|
end
|
4456
4962
|
|
@@ -4467,6 +4973,7 @@ module SyntaxTree
|
|
4467
4973
|
# end
|
4468
4974
|
#
|
4469
4975
|
class HshPtn < Node
|
4976
|
+
# Formats a key-value pair in a hash pattern. The value is optional.
|
4470
4977
|
class KeywordFormatter
|
4471
4978
|
# [Label] the keyword being used
|
4472
4979
|
attr_reader :key
|
@@ -4493,6 +5000,7 @@ module SyntaxTree
|
|
4493
5000
|
end
|
4494
5001
|
end
|
4495
5002
|
|
5003
|
+
# Formats the optional double-splat from the pattern.
|
4496
5004
|
class KeywordRestFormatter
|
4497
5005
|
# [VarField] the parameter that matches the remaining keywords
|
4498
5006
|
attr_reader :keyword_rest
|
@@ -4542,7 +5050,7 @@ module SyntaxTree
|
|
4542
5050
|
|
4543
5051
|
alias deconstruct child_nodes
|
4544
5052
|
|
4545
|
-
def deconstruct_keys(
|
5053
|
+
def deconstruct_keys(_keys)
|
4546
5054
|
{
|
4547
5055
|
constant: constant,
|
4548
5056
|
keywords: keywords,
|
@@ -4565,27 +5073,52 @@ module SyntaxTree
|
|
4565
5073
|
q.text(" then") if !constant && keyword_rest && keyword_rest.value.nil?
|
4566
5074
|
end
|
4567
5075
|
|
5076
|
+
# If there is a constant, we're going to format to have the constant name
|
5077
|
+
# first and then use brackets.
|
4568
5078
|
if constant
|
4569
|
-
q.
|
4570
|
-
|
5079
|
+
q.group do
|
5080
|
+
q.format(constant)
|
5081
|
+
q.text("[")
|
5082
|
+
q.indent do
|
5083
|
+
q.breakable("")
|
5084
|
+
contents.call
|
5085
|
+
end
|
5086
|
+
q.breakable("")
|
5087
|
+
q.text("]")
|
5088
|
+
end
|
4571
5089
|
return
|
4572
5090
|
end
|
4573
5091
|
|
5092
|
+
# If there's nothing at all, then we're going to use empty braces.
|
4574
5093
|
if parts.empty?
|
4575
5094
|
q.text("{}")
|
4576
|
-
|
4577
|
-
|
4578
|
-
|
4579
|
-
|
4580
|
-
|
5095
|
+
return
|
5096
|
+
end
|
5097
|
+
|
5098
|
+
# If there's only one pair, then we'll just print the contents provided
|
5099
|
+
# we're not inside another pattern.
|
5100
|
+
if !PATTERNS.include?(q.parent.class) && parts.size == 1
|
4581
5101
|
contents.call
|
5102
|
+
return
|
5103
|
+
end
|
5104
|
+
|
5105
|
+
# Otherwise, we're going to always use braces to make it clear it's a hash
|
5106
|
+
# pattern.
|
5107
|
+
q.group do
|
5108
|
+
q.text("{")
|
5109
|
+
q.indent do
|
5110
|
+
q.breakable
|
5111
|
+
contents.call
|
5112
|
+
end
|
5113
|
+
q.breakable
|
5114
|
+
q.text("}")
|
4582
5115
|
end
|
4583
5116
|
end
|
4584
5117
|
end
|
4585
5118
|
|
4586
5119
|
# The list of nodes that represent patterns inside of pattern matching so that
|
4587
5120
|
# when a pattern is being printed it knows if it's nested.
|
4588
|
-
PATTERNS = [AryPtn, Binary, FndPtn, HshPtn, RAssign]
|
5121
|
+
PATTERNS = [AryPtn, Binary, FndPtn, HshPtn, RAssign].freeze
|
4589
5122
|
|
4590
5123
|
# Ident represents an identifier anywhere in code. It can represent a very
|
4591
5124
|
# large number of things, depending on where it is in the syntax tree.
|
@@ -4615,7 +5148,7 @@ module SyntaxTree
|
|
4615
5148
|
|
4616
5149
|
alias deconstruct child_nodes
|
4617
5150
|
|
4618
|
-
def deconstruct_keys(
|
5151
|
+
def deconstruct_keys(_keys)
|
4619
5152
|
{ value: value, location: location, comments: comments }
|
4620
5153
|
end
|
4621
5154
|
|
@@ -4632,7 +5165,7 @@ module SyntaxTree
|
|
4632
5165
|
def self.call(parent)
|
4633
5166
|
queue = [parent]
|
4634
5167
|
|
4635
|
-
while node = queue.shift
|
5168
|
+
while (node = queue.shift)
|
4636
5169
|
return true if [Assign, MAssign, OpAssign].include?(node.class)
|
4637
5170
|
queue += node.child_nodes
|
4638
5171
|
end
|
@@ -4641,6 +5174,65 @@ module SyntaxTree
|
|
4641
5174
|
end
|
4642
5175
|
end
|
4643
5176
|
|
5177
|
+
# In order for an `if` or `unless` expression to be shortened to a ternary,
|
5178
|
+
# there has to be one and only one consequent clause which is an Else. Both
|
5179
|
+
# the body of the main node and the body of the Else node must have only one
|
5180
|
+
# statement, and that statement must not be on the denied list of potential
|
5181
|
+
# statements.
|
5182
|
+
module Ternaryable
|
5183
|
+
class << self
|
5184
|
+
def call(q, node)
|
5185
|
+
case q.parents.take(2)[1]
|
5186
|
+
in Paren[contents: Statements[body: [node]]]
|
5187
|
+
# If this is a conditional inside of a parentheses as the only
|
5188
|
+
# content, then we don't want to transform it into a ternary.
|
5189
|
+
# Presumably the user wanted it to be an explicit conditional because
|
5190
|
+
# there are parentheses around it. So we'll just leave it in place.
|
5191
|
+
false
|
5192
|
+
else
|
5193
|
+
# Otherwise, we're going to check the conditional for certain cases.
|
5194
|
+
case node
|
5195
|
+
in predicate: Assign | Command | CommandCall | MAssign | OpAssign
|
5196
|
+
false
|
5197
|
+
in {
|
5198
|
+
statements: { body: [truthy] },
|
5199
|
+
consequent: Else[statements: { body: [falsy] }]
|
5200
|
+
}
|
5201
|
+
ternaryable?(truthy) && ternaryable?(falsy)
|
5202
|
+
else
|
5203
|
+
false
|
5204
|
+
end
|
5205
|
+
end
|
5206
|
+
end
|
5207
|
+
|
5208
|
+
private
|
5209
|
+
|
5210
|
+
# Certain expressions cannot be reduced to a ternary without adding
|
5211
|
+
# parentheses around them. In this case we say they cannot be ternaried
|
5212
|
+
# and default instead to breaking them into multiple lines.
|
5213
|
+
def ternaryable?(statement)
|
5214
|
+
# This is a list of nodes that should not be allowed to be a part of a
|
5215
|
+
# ternary clause.
|
5216
|
+
no_ternary = [
|
5217
|
+
Alias, Assign, Break, Command, CommandCall, Heredoc, If, IfMod, IfOp,
|
5218
|
+
Lambda, MAssign, Next, OpAssign, RescueMod, Return, Return0, Super,
|
5219
|
+
Undef, Unless, UnlessMod, Until, UntilMod, VarAlias, VoidStmt, While,
|
5220
|
+
WhileMod, Yield, Yield0, ZSuper
|
5221
|
+
]
|
5222
|
+
|
5223
|
+
# Here we're going to check that the only statement inside the
|
5224
|
+
# statements node is no a part of our denied list of nodes that can be
|
5225
|
+
# ternaries.
|
5226
|
+
#
|
5227
|
+
# If the user is using one of the lower precedence "and" or "or"
|
5228
|
+
# operators, then we can't use a ternary expression as it would break
|
5229
|
+
# the flow control.
|
5230
|
+
!no_ternary.include?(statement.class) &&
|
5231
|
+
!(statement.is_a?(Binary) && %i[and or].include?(statement.operator))
|
5232
|
+
end
|
5233
|
+
end
|
5234
|
+
end
|
5235
|
+
|
4644
5236
|
# Formats an If or Unless node.
|
4645
5237
|
class ConditionalFormatter
|
4646
5238
|
# [String] the keyword associated with this conditional
|
@@ -4655,6 +5247,13 @@ module SyntaxTree
|
|
4655
5247
|
end
|
4656
5248
|
|
4657
5249
|
def format(q)
|
5250
|
+
# If we can transform this node into a ternary, then we're going to print
|
5251
|
+
# a special version that uses the ternary operator if it fits on one line.
|
5252
|
+
if Ternaryable.call(q, node)
|
5253
|
+
format_ternary(q)
|
5254
|
+
return
|
5255
|
+
end
|
5256
|
+
|
4658
5257
|
# If the predicate of the conditional contains an assignment (in which
|
4659
5258
|
# case we can't know for certain that that assignment doesn't impact the
|
4660
5259
|
# statements inside the conditional) then we can't use the modifier form
|
@@ -4664,17 +5263,19 @@ module SyntaxTree
|
|
4664
5263
|
return
|
4665
5264
|
end
|
4666
5265
|
|
4667
|
-
if node.consequent || node.statements.empty?
|
5266
|
+
if node.consequent || node.statements.empty? || contains_conditional?
|
4668
5267
|
q.group { format_break(q, force: true) }
|
4669
5268
|
else
|
4670
5269
|
q.group do
|
4671
|
-
q
|
4672
|
-
|
4673
|
-
|
4674
|
-
|
4675
|
-
|
5270
|
+
q
|
5271
|
+
.if_break { format_break(q, force: false) }
|
5272
|
+
.if_flat do
|
5273
|
+
Parentheses.flat(q) do
|
5274
|
+
q.format(node.statements)
|
5275
|
+
q.text(" #{keyword} ")
|
5276
|
+
q.format(node.predicate)
|
5277
|
+
end
|
4676
5278
|
end
|
4677
|
-
end
|
4678
5279
|
end
|
4679
5280
|
end
|
4680
5281
|
end
|
@@ -4700,6 +5301,61 @@ module SyntaxTree
|
|
4700
5301
|
q.breakable(force: force)
|
4701
5302
|
q.text("end")
|
4702
5303
|
end
|
5304
|
+
|
5305
|
+
def format_ternary(q)
|
5306
|
+
q.group do
|
5307
|
+
q
|
5308
|
+
.if_break do
|
5309
|
+
q.text("#{keyword} ")
|
5310
|
+
q.nest(keyword.length + 1) { q.format(node.predicate) }
|
5311
|
+
|
5312
|
+
q.indent do
|
5313
|
+
q.breakable
|
5314
|
+
q.format(node.statements)
|
5315
|
+
end
|
5316
|
+
|
5317
|
+
q.breakable
|
5318
|
+
q.group do
|
5319
|
+
q.format(node.consequent.keyword)
|
5320
|
+
q.indent do
|
5321
|
+
# This is a very special case of breakable where we want to
|
5322
|
+
# force it into the output but we _don't_ want to explicitly
|
5323
|
+
# break the parent. If a break-parent shows up in the tree, then
|
5324
|
+
# it's going to force it all the way up to the tree, which is
|
5325
|
+
# going to negate the ternary. Maybe this should be an option in
|
5326
|
+
# prettyprint? As in force: :no_break_parent or something.
|
5327
|
+
q.target << PrettyPrint::Breakable.new(" ", 1, force: true)
|
5328
|
+
q.format(node.consequent.statements)
|
5329
|
+
end
|
5330
|
+
end
|
5331
|
+
|
5332
|
+
q.breakable
|
5333
|
+
q.text("end")
|
5334
|
+
end
|
5335
|
+
.if_flat do
|
5336
|
+
Parentheses.flat(q) do
|
5337
|
+
q.format(node.predicate)
|
5338
|
+
q.text(" ? ")
|
5339
|
+
|
5340
|
+
statements = [node.statements, node.consequent.statements]
|
5341
|
+
statements.reverse! if keyword == "unless"
|
5342
|
+
|
5343
|
+
q.format(statements[0])
|
5344
|
+
q.text(" : ")
|
5345
|
+
q.format(statements[1])
|
5346
|
+
end
|
5347
|
+
end
|
5348
|
+
end
|
5349
|
+
end
|
5350
|
+
|
5351
|
+
def contains_conditional?
|
5352
|
+
case node
|
5353
|
+
in statements: { body: [If | IfMod | IfOp | Unless | UnlessMod] }
|
5354
|
+
true
|
5355
|
+
else
|
5356
|
+
false
|
5357
|
+
end
|
5358
|
+
end
|
4703
5359
|
end
|
4704
5360
|
|
4705
5361
|
# If represents the first clause in an +if+ chain.
|
@@ -4744,7 +5400,7 @@ module SyntaxTree
|
|
4744
5400
|
|
4745
5401
|
alias deconstruct child_nodes
|
4746
5402
|
|
4747
|
-
def deconstruct_keys(
|
5403
|
+
def deconstruct_keys(_keys)
|
4748
5404
|
{
|
4749
5405
|
predicate: predicate,
|
4750
5406
|
statements: statements,
|
@@ -4794,7 +5450,7 @@ module SyntaxTree
|
|
4794
5450
|
|
4795
5451
|
alias deconstruct child_nodes
|
4796
5452
|
|
4797
|
-
def deconstruct_keys(
|
5453
|
+
def deconstruct_keys(_keys)
|
4798
5454
|
{
|
4799
5455
|
predicate: predicate,
|
4800
5456
|
truthy: truthy,
|
@@ -4812,7 +5468,8 @@ module SyntaxTree
|
|
4812
5468
|
Yield0, ZSuper
|
4813
5469
|
]
|
4814
5470
|
|
4815
|
-
if
|
5471
|
+
if q.parent.is_a?(Paren) || force_flat.include?(truthy.class) ||
|
5472
|
+
force_flat.include?(falsy.class)
|
4816
5473
|
q.group { format_flat(q) }
|
4817
5474
|
return
|
4818
5475
|
end
|
@@ -4932,7 +5589,7 @@ module SyntaxTree
|
|
4932
5589
|
|
4933
5590
|
alias deconstruct child_nodes
|
4934
5591
|
|
4935
|
-
def deconstruct_keys(
|
5592
|
+
def deconstruct_keys(_keys)
|
4936
5593
|
{
|
4937
5594
|
statement: statement,
|
4938
5595
|
predicate: predicate,
|
@@ -4973,7 +5630,7 @@ module SyntaxTree
|
|
4973
5630
|
|
4974
5631
|
alias deconstruct child_nodes
|
4975
5632
|
|
4976
|
-
def deconstruct_keys(
|
5633
|
+
def deconstruct_keys(_keys)
|
4977
5634
|
{ value: value, location: location, comments: comments }
|
4978
5635
|
end
|
4979
5636
|
|
@@ -5020,7 +5677,7 @@ module SyntaxTree
|
|
5020
5677
|
|
5021
5678
|
alias deconstruct child_nodes
|
5022
5679
|
|
5023
|
-
def deconstruct_keys(
|
5680
|
+
def deconstruct_keys(_keys)
|
5024
5681
|
{
|
5025
5682
|
pattern: pattern,
|
5026
5683
|
statements: statements,
|
@@ -5079,7 +5736,7 @@ module SyntaxTree
|
|
5079
5736
|
|
5080
5737
|
alias deconstruct child_nodes
|
5081
5738
|
|
5082
|
-
def deconstruct_keys(
|
5739
|
+
def deconstruct_keys(_keys)
|
5083
5740
|
{ value: value, location: location, comments: comments }
|
5084
5741
|
end
|
5085
5742
|
|
@@ -5089,7 +5746,7 @@ module SyntaxTree
|
|
5089
5746
|
# the values, then we're going to insert them every 3 characters
|
5090
5747
|
# starting from the right.
|
5091
5748
|
index = (value.length + 2) % 3
|
5092
|
-
q.text(" #{value}"[index
|
5749
|
+
q.text(" #{value}"[index..].scan(/.../).join("_").strip)
|
5093
5750
|
else
|
5094
5751
|
q.text(value)
|
5095
5752
|
end
|
@@ -5123,7 +5780,7 @@ module SyntaxTree
|
|
5123
5780
|
|
5124
5781
|
alias deconstruct child_nodes
|
5125
5782
|
|
5126
|
-
def deconstruct_keys(
|
5783
|
+
def deconstruct_keys(_keys)
|
5127
5784
|
{ value: value, location: location, comments: comments }
|
5128
5785
|
end
|
5129
5786
|
|
@@ -5168,7 +5825,7 @@ module SyntaxTree
|
|
5168
5825
|
|
5169
5826
|
alias deconstruct child_nodes
|
5170
5827
|
|
5171
|
-
def deconstruct_keys(
|
5828
|
+
def deconstruct_keys(_keys)
|
5172
5829
|
{ value: value, location: location, comments: comments }
|
5173
5830
|
end
|
5174
5831
|
|
@@ -5205,7 +5862,7 @@ module SyntaxTree
|
|
5205
5862
|
|
5206
5863
|
alias deconstruct child_nodes
|
5207
5864
|
|
5208
|
-
def deconstruct_keys(
|
5865
|
+
def deconstruct_keys(_keys)
|
5209
5866
|
{ name: name, location: location, comments: comments }
|
5210
5867
|
end
|
5211
5868
|
|
@@ -5251,7 +5908,7 @@ module SyntaxTree
|
|
5251
5908
|
|
5252
5909
|
alias deconstruct child_nodes
|
5253
5910
|
|
5254
|
-
def deconstruct_keys(
|
5911
|
+
def deconstruct_keys(_keys)
|
5255
5912
|
{ value: value, location: location, comments: comments }
|
5256
5913
|
end
|
5257
5914
|
|
@@ -5285,8 +5942,8 @@ module SyntaxTree
|
|
5285
5942
|
end
|
5286
5943
|
|
5287
5944
|
alias deconstruct child_nodes
|
5288
|
-
|
5289
|
-
def deconstruct_keys(
|
5945
|
+
|
5946
|
+
def deconstruct_keys(_keys)
|
5290
5947
|
{ value: value, location: location }
|
5291
5948
|
end
|
5292
5949
|
end
|
@@ -5322,7 +5979,7 @@ module SyntaxTree
|
|
5322
5979
|
|
5323
5980
|
alias deconstruct child_nodes
|
5324
5981
|
|
5325
|
-
def deconstruct_keys(
|
5982
|
+
def deconstruct_keys(_keys)
|
5326
5983
|
{
|
5327
5984
|
params: params,
|
5328
5985
|
statements: statements,
|
@@ -5344,25 +6001,27 @@ module SyntaxTree
|
|
5344
6001
|
end
|
5345
6002
|
|
5346
6003
|
q.text(" ")
|
5347
|
-
q
|
5348
|
-
|
5349
|
-
|
5350
|
-
|
6004
|
+
q
|
6005
|
+
.if_break do
|
6006
|
+
force_parens =
|
6007
|
+
q.parents.any? do |node|
|
6008
|
+
node.is_a?(Command) || node.is_a?(CommandCall)
|
6009
|
+
end
|
6010
|
+
|
6011
|
+
q.text(force_parens ? "{" : "do")
|
6012
|
+
q.indent do
|
6013
|
+
q.breakable
|
6014
|
+
q.format(statements)
|
5351
6015
|
end
|
5352
6016
|
|
5353
|
-
q.text(force_parens ? "{" : "do")
|
5354
|
-
q.indent do
|
5355
6017
|
q.breakable
|
6018
|
+
q.text(force_parens ? "}" : "end")
|
6019
|
+
end
|
6020
|
+
.if_flat do
|
6021
|
+
q.text("{ ")
|
5356
6022
|
q.format(statements)
|
6023
|
+
q.text(" }")
|
5357
6024
|
end
|
5358
|
-
|
5359
|
-
q.breakable
|
5360
|
-
q.text(force_parens ? "}" : "end")
|
5361
|
-
end.if_flat do
|
5362
|
-
q.text("{ ")
|
5363
|
-
q.format(statements)
|
5364
|
-
q.text(" }")
|
5365
|
-
end
|
5366
6025
|
end
|
5367
6026
|
end
|
5368
6027
|
end
|
@@ -5391,7 +6050,7 @@ module SyntaxTree
|
|
5391
6050
|
|
5392
6051
|
alias deconstruct child_nodes
|
5393
6052
|
|
5394
|
-
def deconstruct_keys(
|
6053
|
+
def deconstruct_keys(_keys)
|
5395
6054
|
{ value: value, location: location, comments: comments }
|
5396
6055
|
end
|
5397
6056
|
|
@@ -5424,7 +6083,7 @@ module SyntaxTree
|
|
5424
6083
|
|
5425
6084
|
alias deconstruct child_nodes
|
5426
6085
|
|
5427
|
-
def deconstruct_keys(
|
6086
|
+
def deconstruct_keys(_keys)
|
5428
6087
|
{ value: value, location: location, comments: comments }
|
5429
6088
|
end
|
5430
6089
|
|
@@ -5457,7 +6116,7 @@ module SyntaxTree
|
|
5457
6116
|
|
5458
6117
|
alias deconstruct child_nodes
|
5459
6118
|
|
5460
|
-
def deconstruct_keys(
|
6119
|
+
def deconstruct_keys(_keys)
|
5461
6120
|
{ value: value, location: location, comments: comments }
|
5462
6121
|
end
|
5463
6122
|
|
@@ -5507,7 +6166,7 @@ module SyntaxTree
|
|
5507
6166
|
|
5508
6167
|
alias deconstruct child_nodes
|
5509
6168
|
|
5510
|
-
def deconstruct_keys(
|
6169
|
+
def deconstruct_keys(_keys)
|
5511
6170
|
{ target: target, value: value, location: location, comments: comments }
|
5512
6171
|
end
|
5513
6172
|
|
@@ -5554,11 +6213,27 @@ module SyntaxTree
|
|
5554
6213
|
|
5555
6214
|
alias deconstruct child_nodes
|
5556
6215
|
|
5557
|
-
def deconstruct_keys(
|
6216
|
+
def deconstruct_keys(_keys)
|
5558
6217
|
{ call: call, block: block, location: location, comments: comments }
|
5559
6218
|
end
|
5560
6219
|
|
5561
6220
|
def format(q)
|
6221
|
+
# If we're at the top of a call chain, then we're going to do some
|
6222
|
+
# specialized printing in case we can print it nicely. We _only_ do this
|
6223
|
+
# at the top of the chain to avoid weird recursion issues.
|
6224
|
+
if !CallChainFormatter.chained?(q.parent) &&
|
6225
|
+
CallChainFormatter.chained?(call)
|
6226
|
+
q.group do
|
6227
|
+
q
|
6228
|
+
.if_break { CallChainFormatter.new(self).format(q) }
|
6229
|
+
.if_flat { format_contents(q) }
|
6230
|
+
end
|
6231
|
+
else
|
6232
|
+
format_contents(q)
|
6233
|
+
end
|
6234
|
+
end
|
6235
|
+
|
6236
|
+
def format_contents(q)
|
5562
6237
|
q.format(call)
|
5563
6238
|
q.format(block)
|
5564
6239
|
end
|
@@ -5599,7 +6274,7 @@ module SyntaxTree
|
|
5599
6274
|
|
5600
6275
|
alias deconstruct child_nodes
|
5601
6276
|
|
5602
|
-
def deconstruct_keys(
|
6277
|
+
def deconstruct_keys(_keys)
|
5603
6278
|
{ parts: parts, location: location, comma: comma, comments: comments }
|
5604
6279
|
end
|
5605
6280
|
|
@@ -5643,7 +6318,7 @@ module SyntaxTree
|
|
5643
6318
|
|
5644
6319
|
alias deconstruct child_nodes
|
5645
6320
|
|
5646
|
-
def deconstruct_keys(
|
6321
|
+
def deconstruct_keys(_keys)
|
5647
6322
|
{ contents: contents, location: location, comments: comments }
|
5648
6323
|
end
|
5649
6324
|
|
@@ -5699,7 +6374,7 @@ module SyntaxTree
|
|
5699
6374
|
|
5700
6375
|
alias deconstruct child_nodes
|
5701
6376
|
|
5702
|
-
def deconstruct_keys(
|
6377
|
+
def deconstruct_keys(_keys)
|
5703
6378
|
{
|
5704
6379
|
constant: constant,
|
5705
6380
|
bodystmt: bodystmt,
|
@@ -5766,7 +6441,7 @@ module SyntaxTree
|
|
5766
6441
|
|
5767
6442
|
alias deconstruct child_nodes
|
5768
6443
|
|
5769
|
-
def deconstruct_keys(
|
6444
|
+
def deconstruct_keys(_keys)
|
5770
6445
|
{ parts: parts, location: location, comments: comments }
|
5771
6446
|
end
|
5772
6447
|
|
@@ -5815,7 +6490,7 @@ module SyntaxTree
|
|
5815
6490
|
|
5816
6491
|
alias deconstruct child_nodes
|
5817
6492
|
|
5818
|
-
def deconstruct_keys(
|
6493
|
+
def deconstruct_keys(_keys)
|
5819
6494
|
{ arguments: arguments, location: location, comments: comments }
|
5820
6495
|
end
|
5821
6496
|
|
@@ -5852,7 +6527,7 @@ module SyntaxTree
|
|
5852
6527
|
|
5853
6528
|
alias deconstruct child_nodes
|
5854
6529
|
|
5855
|
-
def deconstruct_keys(
|
6530
|
+
def deconstruct_keys(_keys)
|
5856
6531
|
{ value: value, location: location, comments: comments }
|
5857
6532
|
end
|
5858
6533
|
|
@@ -5898,7 +6573,7 @@ module SyntaxTree
|
|
5898
6573
|
|
5899
6574
|
alias deconstruct child_nodes
|
5900
6575
|
|
5901
|
-
def deconstruct_keys(
|
6576
|
+
def deconstruct_keys(_keys)
|
5902
6577
|
{
|
5903
6578
|
target: target,
|
5904
6579
|
operator: operator,
|
@@ -5966,7 +6641,16 @@ module SyntaxTree
|
|
5966
6641
|
# This approach maintains the nice conciseness of the inline version, while
|
5967
6642
|
# keeping the correct semantic meaning.
|
5968
6643
|
module Parentheses
|
5969
|
-
NODES = [
|
6644
|
+
NODES = [
|
6645
|
+
Args,
|
6646
|
+
Assign,
|
6647
|
+
Assoc,
|
6648
|
+
Binary,
|
6649
|
+
Call,
|
6650
|
+
Defined,
|
6651
|
+
MAssign,
|
6652
|
+
OpAssign
|
6653
|
+
].freeze
|
5970
6654
|
|
5971
6655
|
def self.flat(q)
|
5972
6656
|
return yield unless NODES.include?(q.parent.class)
|
@@ -5998,6 +6682,8 @@ module SyntaxTree
|
|
5998
6682
|
# def method(param) end
|
5999
6683
|
#
|
6000
6684
|
class Params < Node
|
6685
|
+
# Formats the optional position of the parameters. This includes the label,
|
6686
|
+
# as well as the default value.
|
6001
6687
|
class OptionalFormatter
|
6002
6688
|
# [Ident] the name of the parameter
|
6003
6689
|
attr_reader :name
|
@@ -6021,6 +6707,8 @@ module SyntaxTree
|
|
6021
6707
|
end
|
6022
6708
|
end
|
6023
6709
|
|
6710
|
+
# Formats the keyword position of the parameters. This includes the label,
|
6711
|
+
# as well as an optional default value.
|
6024
6712
|
class KeywordFormatter
|
6025
6713
|
# [Ident] the name of the parameter
|
6026
6714
|
attr_reader :name
|
@@ -6047,6 +6735,8 @@ module SyntaxTree
|
|
6047
6735
|
end
|
6048
6736
|
end
|
6049
6737
|
|
6738
|
+
# Formats the keyword_rest position of the parameters. This can be the **nil
|
6739
|
+
# syntax, the ... syntax, or the ** syntax.
|
6050
6740
|
class KeywordRestFormatter
|
6051
6741
|
# [:nil | ArgsForward | KwRestParam] the value of the parameter
|
6052
6742
|
attr_reader :value
|
@@ -6060,11 +6750,7 @@ module SyntaxTree
|
|
6060
6750
|
end
|
6061
6751
|
|
6062
6752
|
def format(q)
|
6063
|
-
|
6064
|
-
q.text("**nil")
|
6065
|
-
else
|
6066
|
-
q.format(value)
|
6067
|
-
end
|
6753
|
+
value == :nil ? q.text("**nil") : q.format(value)
|
6068
6754
|
end
|
6069
6755
|
end
|
6070
6756
|
|
@@ -6145,7 +6831,7 @@ module SyntaxTree
|
|
6145
6831
|
|
6146
6832
|
alias deconstruct child_nodes
|
6147
6833
|
|
6148
|
-
def deconstruct_keys(
|
6834
|
+
def deconstruct_keys(_keys)
|
6149
6835
|
{
|
6150
6836
|
location: location,
|
6151
6837
|
requireds: requireds,
|
@@ -6166,21 +6852,22 @@ module SyntaxTree
|
|
6166
6852
|
]
|
6167
6853
|
|
6168
6854
|
parts << rest if rest && !rest.is_a?(ExcessedComma)
|
6169
|
-
parts +=
|
6170
|
-
|
6171
|
-
|
6172
|
-
|
6173
|
-
]
|
6855
|
+
parts += [
|
6856
|
+
*posts,
|
6857
|
+
*keywords.map { |(name, value)| KeywordFormatter.new(name, value) }
|
6858
|
+
]
|
6174
6859
|
|
6175
6860
|
parts << KeywordRestFormatter.new(keyword_rest) if keyword_rest
|
6176
6861
|
parts << block if block
|
6177
6862
|
|
6178
6863
|
contents = -> do
|
6179
6864
|
q.seplist(parts) { |part| q.format(part) }
|
6180
|
-
q.format(rest) if rest
|
6865
|
+
q.format(rest) if rest.is_a?(ExcessedComma)
|
6181
6866
|
end
|
6182
6867
|
|
6183
|
-
if [Def, Defs, DefEndless].include?(q.parent.class)
|
6868
|
+
if ![Def, Defs, DefEndless].include?(q.parent.class) || parts.empty?
|
6869
|
+
q.nest(0, &contents)
|
6870
|
+
else
|
6184
6871
|
q.group(0, "(", ")") do
|
6185
6872
|
q.indent do
|
6186
6873
|
q.breakable("")
|
@@ -6188,8 +6875,6 @@ module SyntaxTree
|
|
6188
6875
|
end
|
6189
6876
|
q.breakable("")
|
6190
6877
|
end
|
6191
|
-
else
|
6192
|
-
q.nest(0, &contents)
|
6193
6878
|
end
|
6194
6879
|
end
|
6195
6880
|
end
|
@@ -6227,7 +6912,7 @@ module SyntaxTree
|
|
6227
6912
|
|
6228
6913
|
alias deconstruct child_nodes
|
6229
6914
|
|
6230
|
-
def deconstruct_keys(
|
6915
|
+
def deconstruct_keys(_keys)
|
6231
6916
|
{
|
6232
6917
|
lparen: lparen,
|
6233
6918
|
contents: contents,
|
@@ -6278,7 +6963,7 @@ module SyntaxTree
|
|
6278
6963
|
|
6279
6964
|
alias deconstruct child_nodes
|
6280
6965
|
|
6281
|
-
def deconstruct_keys(
|
6966
|
+
def deconstruct_keys(_keys)
|
6282
6967
|
{ value: value, location: location, comments: comments }
|
6283
6968
|
end
|
6284
6969
|
|
@@ -6311,7 +6996,7 @@ module SyntaxTree
|
|
6311
6996
|
|
6312
6997
|
alias deconstruct child_nodes
|
6313
6998
|
|
6314
|
-
def deconstruct_keys(
|
6999
|
+
def deconstruct_keys(_keys)
|
6315
7000
|
{ statements: statements, location: location, comments: comments }
|
6316
7001
|
end
|
6317
7002
|
|
@@ -6356,7 +7041,7 @@ module SyntaxTree
|
|
6356
7041
|
|
6357
7042
|
alias deconstruct child_nodes
|
6358
7043
|
|
6359
|
-
def deconstruct_keys(
|
7044
|
+
def deconstruct_keys(_keys)
|
6360
7045
|
{
|
6361
7046
|
beginning: beginning,
|
6362
7047
|
elements: elements,
|
@@ -6410,18 +7095,9 @@ module SyntaxTree
|
|
6410
7095
|
end
|
6411
7096
|
|
6412
7097
|
alias deconstruct child_nodes
|
6413
|
-
|
6414
|
-
def deconstruct_keys(keys)
|
6415
|
-
{ value: value, location: location }
|
6416
|
-
end
|
6417
|
-
|
6418
|
-
def pretty_print(q)
|
6419
|
-
q.group(2, "(", ")") do
|
6420
|
-
q.text("qsymbols_beg")
|
6421
7098
|
|
6422
|
-
|
6423
|
-
|
6424
|
-
end
|
7099
|
+
def deconstruct_keys(_keys)
|
7100
|
+
{ value: value, location: location }
|
6425
7101
|
end
|
6426
7102
|
end
|
6427
7103
|
|
@@ -6456,7 +7132,7 @@ module SyntaxTree
|
|
6456
7132
|
|
6457
7133
|
alias deconstruct child_nodes
|
6458
7134
|
|
6459
|
-
def deconstruct_keys(
|
7135
|
+
def deconstruct_keys(_keys)
|
6460
7136
|
{
|
6461
7137
|
beginning: beginning,
|
6462
7138
|
elements: elements,
|
@@ -6510,8 +7186,8 @@ module SyntaxTree
|
|
6510
7186
|
end
|
6511
7187
|
|
6512
7188
|
alias deconstruct child_nodes
|
6513
|
-
|
6514
|
-
def deconstruct_keys(
|
7189
|
+
|
7190
|
+
def deconstruct_keys(_keys)
|
6515
7191
|
{ value: value, location: location }
|
6516
7192
|
end
|
6517
7193
|
end
|
@@ -6543,7 +7219,7 @@ module SyntaxTree
|
|
6543
7219
|
|
6544
7220
|
alias deconstruct child_nodes
|
6545
7221
|
|
6546
|
-
def deconstruct_keys(
|
7222
|
+
def deconstruct_keys(_keys)
|
6547
7223
|
{ value: value, location: location, comments: comments }
|
6548
7224
|
end
|
6549
7225
|
|
@@ -6571,8 +7247,8 @@ module SyntaxTree
|
|
6571
7247
|
end
|
6572
7248
|
|
6573
7249
|
alias deconstruct child_nodes
|
6574
|
-
|
6575
|
-
def deconstruct_keys(
|
7250
|
+
|
7251
|
+
def deconstruct_keys(_keys)
|
6576
7252
|
{ value: value, location: location }
|
6577
7253
|
end
|
6578
7254
|
end
|
@@ -6596,8 +7272,8 @@ module SyntaxTree
|
|
6596
7272
|
end
|
6597
7273
|
|
6598
7274
|
alias deconstruct child_nodes
|
6599
|
-
|
6600
|
-
def deconstruct_keys(
|
7275
|
+
|
7276
|
+
def deconstruct_keys(_keys)
|
6601
7277
|
{ value: value, location: location }
|
6602
7278
|
end
|
6603
7279
|
end
|
@@ -6629,7 +7305,7 @@ module SyntaxTree
|
|
6629
7305
|
|
6630
7306
|
alias deconstruct child_nodes
|
6631
7307
|
|
6632
|
-
def deconstruct_keys(
|
7308
|
+
def deconstruct_keys(_keys)
|
6633
7309
|
{ value: value, location: location, comments: comments }
|
6634
7310
|
end
|
6635
7311
|
|
@@ -6667,8 +7343,8 @@ module SyntaxTree
|
|
6667
7343
|
end
|
6668
7344
|
|
6669
7345
|
alias deconstruct child_nodes
|
6670
|
-
|
6671
|
-
def deconstruct_keys(
|
7346
|
+
|
7347
|
+
def deconstruct_keys(_keys)
|
6672
7348
|
{ beginning: beginning, parts: parts, location: location }
|
6673
7349
|
end
|
6674
7350
|
end
|
@@ -6700,8 +7376,8 @@ module SyntaxTree
|
|
6700
7376
|
end
|
6701
7377
|
|
6702
7378
|
alias deconstruct child_nodes
|
6703
|
-
|
6704
|
-
def deconstruct_keys(
|
7379
|
+
|
7380
|
+
def deconstruct_keys(_keys)
|
6705
7381
|
{ value: value, location: location }
|
6706
7382
|
end
|
6707
7383
|
end
|
@@ -6734,8 +7410,8 @@ module SyntaxTree
|
|
6734
7410
|
end
|
6735
7411
|
|
6736
7412
|
alias deconstruct child_nodes
|
6737
|
-
|
6738
|
-
def deconstruct_keys(
|
7413
|
+
|
7414
|
+
def deconstruct_keys(_keys)
|
6739
7415
|
{ value: value, location: location }
|
6740
7416
|
end
|
6741
7417
|
end
|
@@ -6776,10 +7452,11 @@ module SyntaxTree
|
|
6776
7452
|
|
6777
7453
|
alias deconstruct child_nodes
|
6778
7454
|
|
6779
|
-
def deconstruct_keys(
|
7455
|
+
def deconstruct_keys(_keys)
|
6780
7456
|
{
|
6781
7457
|
beginning: beginning,
|
6782
7458
|
ending: ending,
|
7459
|
+
options: options,
|
6783
7460
|
parts: parts,
|
6784
7461
|
location: location,
|
6785
7462
|
comments: comments
|
@@ -6787,7 +7464,7 @@ module SyntaxTree
|
|
6787
7464
|
end
|
6788
7465
|
|
6789
7466
|
def format(q)
|
6790
|
-
braces = ambiguous?(q) || include?(%r{
|
7467
|
+
braces = ambiguous?(q) || include?(%r{/})
|
6791
7468
|
|
6792
7469
|
if braces && include?(/[{}]/)
|
6793
7470
|
q.group do
|
@@ -6814,18 +7491,22 @@ module SyntaxTree
|
|
6814
7491
|
end
|
6815
7492
|
|
6816
7493
|
q.text("}")
|
6817
|
-
q.text(
|
7494
|
+
q.text(options)
|
6818
7495
|
end
|
6819
7496
|
else
|
6820
7497
|
q.group do
|
6821
7498
|
q.text("/")
|
6822
7499
|
q.format_each(parts)
|
6823
7500
|
q.text("/")
|
6824
|
-
q.text(
|
7501
|
+
q.text(options)
|
6825
7502
|
end
|
6826
7503
|
end
|
6827
7504
|
end
|
6828
7505
|
|
7506
|
+
def options
|
7507
|
+
ending[1..]
|
7508
|
+
end
|
7509
|
+
|
6829
7510
|
private
|
6830
7511
|
|
6831
7512
|
def include?(pattern)
|
@@ -6881,7 +7562,7 @@ module SyntaxTree
|
|
6881
7562
|
|
6882
7563
|
alias deconstruct child_nodes
|
6883
7564
|
|
6884
|
-
def deconstruct_keys(
|
7565
|
+
def deconstruct_keys(_keys)
|
6885
7566
|
{
|
6886
7567
|
exceptions: exceptions,
|
6887
7568
|
variable: variable,
|
@@ -6956,7 +7637,10 @@ module SyntaxTree
|
|
6956
7637
|
|
6957
7638
|
if consequent
|
6958
7639
|
consequent.bind_end(end_char, end_column)
|
6959
|
-
statements.bind_end(
|
7640
|
+
statements.bind_end(
|
7641
|
+
consequent.location.start_char,
|
7642
|
+
consequent.location.start_column
|
7643
|
+
)
|
6960
7644
|
else
|
6961
7645
|
statements.bind_end(end_char, end_column)
|
6962
7646
|
end
|
@@ -6972,7 +7656,7 @@ module SyntaxTree
|
|
6972
7656
|
|
6973
7657
|
alias deconstruct child_nodes
|
6974
7658
|
|
6975
|
-
def deconstruct_keys(
|
7659
|
+
def deconstruct_keys(_keys)
|
6976
7660
|
{
|
6977
7661
|
keyword: keyword,
|
6978
7662
|
exception: exception,
|
@@ -7039,7 +7723,7 @@ module SyntaxTree
|
|
7039
7723
|
|
7040
7724
|
alias deconstruct child_nodes
|
7041
7725
|
|
7042
|
-
def deconstruct_keys(
|
7726
|
+
def deconstruct_keys(_keys)
|
7043
7727
|
{
|
7044
7728
|
statement: statement,
|
7045
7729
|
value: value,
|
@@ -7093,7 +7777,7 @@ module SyntaxTree
|
|
7093
7777
|
|
7094
7778
|
alias deconstruct child_nodes
|
7095
7779
|
|
7096
|
-
def deconstruct_keys(
|
7780
|
+
def deconstruct_keys(_keys)
|
7097
7781
|
{ name: name, location: location, comments: comments }
|
7098
7782
|
end
|
7099
7783
|
|
@@ -7130,7 +7814,7 @@ module SyntaxTree
|
|
7130
7814
|
|
7131
7815
|
alias deconstruct child_nodes
|
7132
7816
|
|
7133
|
-
def deconstruct_keys(
|
7817
|
+
def deconstruct_keys(_keys)
|
7134
7818
|
{ value: value, location: location, comments: comments }
|
7135
7819
|
end
|
7136
7820
|
|
@@ -7166,7 +7850,7 @@ module SyntaxTree
|
|
7166
7850
|
|
7167
7851
|
alias deconstruct child_nodes
|
7168
7852
|
|
7169
|
-
def deconstruct_keys(
|
7853
|
+
def deconstruct_keys(_keys)
|
7170
7854
|
{ arguments: arguments, location: location, comments: comments }
|
7171
7855
|
end
|
7172
7856
|
|
@@ -7202,7 +7886,7 @@ module SyntaxTree
|
|
7202
7886
|
|
7203
7887
|
alias deconstruct child_nodes
|
7204
7888
|
|
7205
|
-
def deconstruct_keys(
|
7889
|
+
def deconstruct_keys(_keys)
|
7206
7890
|
{ value: value, location: location, comments: comments }
|
7207
7891
|
end
|
7208
7892
|
|
@@ -7220,7 +7904,7 @@ module SyntaxTree
|
|
7220
7904
|
@value = value
|
7221
7905
|
@location = location
|
7222
7906
|
end
|
7223
|
-
|
7907
|
+
|
7224
7908
|
def accept(visitor)
|
7225
7909
|
visitor.visit_rparen(self)
|
7226
7910
|
end
|
@@ -7230,8 +7914,8 @@ module SyntaxTree
|
|
7230
7914
|
end
|
7231
7915
|
|
7232
7916
|
alias deconstruct child_nodes
|
7233
|
-
|
7234
|
-
def deconstruct_keys(
|
7917
|
+
|
7918
|
+
def deconstruct_keys(_keys)
|
7235
7919
|
{ value: value, location: location }
|
7236
7920
|
end
|
7237
7921
|
end
|
@@ -7270,7 +7954,7 @@ module SyntaxTree
|
|
7270
7954
|
|
7271
7955
|
alias deconstruct child_nodes
|
7272
7956
|
|
7273
|
-
def deconstruct_keys(
|
7957
|
+
def deconstruct_keys(_keys)
|
7274
7958
|
{
|
7275
7959
|
target: target,
|
7276
7960
|
bodystmt: bodystmt,
|
@@ -7372,7 +8056,7 @@ module SyntaxTree
|
|
7372
8056
|
|
7373
8057
|
alias deconstruct child_nodes
|
7374
8058
|
|
7375
|
-
def deconstruct_keys(
|
8059
|
+
def deconstruct_keys(_keys)
|
7376
8060
|
{ parser: parser, body: body, location: location, comments: comments }
|
7377
8061
|
end
|
7378
8062
|
|
@@ -7444,8 +8128,6 @@ module SyntaxTree
|
|
7444
8128
|
|
7445
8129
|
if !comment.inline? && (start_char <= location.start_char) &&
|
7446
8130
|
(end_char >= location.end_char) && !comment.ignore?
|
7447
|
-
parser_comments.delete_at(comment_index)
|
7448
|
-
|
7449
8131
|
while (node = body[body_index]) &&
|
7450
8132
|
(
|
7451
8133
|
node.is_a?(VoidStmt) ||
|
@@ -7454,7 +8136,17 @@ module SyntaxTree
|
|
7454
8136
|
body_index += 1
|
7455
8137
|
end
|
7456
8138
|
|
7457
|
-
|
8139
|
+
if body_index != 0 &&
|
8140
|
+
body[body_index - 1].location.start_char < location.start_char &&
|
8141
|
+
body[body_index - 1].location.end_char > location.start_char
|
8142
|
+
# The previous node entirely encapsules the comment, so we don't
|
8143
|
+
# want to attach it here since it will get attached normally. This
|
8144
|
+
# is mostly in the case of hash and array literals.
|
8145
|
+
comment_index += 1
|
8146
|
+
else
|
8147
|
+
parser_comments.delete_at(comment_index)
|
8148
|
+
body.insert(body_index, comment)
|
8149
|
+
end
|
7458
8150
|
else
|
7459
8151
|
comment_index += 1
|
7460
8152
|
end
|
@@ -7485,8 +8177,8 @@ module SyntaxTree
|
|
7485
8177
|
end
|
7486
8178
|
|
7487
8179
|
alias deconstruct child_nodes
|
7488
|
-
|
7489
|
-
def deconstruct_keys(
|
8180
|
+
|
8181
|
+
def deconstruct_keys(_keys)
|
7490
8182
|
{ parts: parts, location: location }
|
7491
8183
|
end
|
7492
8184
|
end
|
@@ -7524,14 +8216,14 @@ module SyntaxTree
|
|
7524
8216
|
|
7525
8217
|
alias deconstruct child_nodes
|
7526
8218
|
|
7527
|
-
def deconstruct_keys(
|
8219
|
+
def deconstruct_keys(_keys)
|
7528
8220
|
{ left: left, right: right, location: location, comments: comments }
|
7529
8221
|
end
|
7530
8222
|
|
7531
8223
|
def format(q)
|
7532
8224
|
q.group do
|
7533
8225
|
q.format(left)
|
7534
|
-
q.text(
|
8226
|
+
q.text(" \\")
|
7535
8227
|
q.indent do
|
7536
8228
|
q.breakable(force: true)
|
7537
8229
|
q.format(right)
|
@@ -7569,7 +8261,7 @@ module SyntaxTree
|
|
7569
8261
|
|
7570
8262
|
alias deconstruct child_nodes
|
7571
8263
|
|
7572
|
-
def deconstruct_keys(
|
8264
|
+
def deconstruct_keys(_keys)
|
7573
8265
|
{ variable: variable, location: location, comments: comments }
|
7574
8266
|
end
|
7575
8267
|
|
@@ -7609,7 +8301,7 @@ module SyntaxTree
|
|
7609
8301
|
|
7610
8302
|
alias deconstruct child_nodes
|
7611
8303
|
|
7612
|
-
def deconstruct_keys(
|
8304
|
+
def deconstruct_keys(_keys)
|
7613
8305
|
{ statements: statements, location: location, comments: comments }
|
7614
8306
|
end
|
7615
8307
|
|
@@ -7667,7 +8359,7 @@ module SyntaxTree
|
|
7667
8359
|
|
7668
8360
|
alias deconstruct child_nodes
|
7669
8361
|
|
7670
|
-
def deconstruct_keys(
|
8362
|
+
def deconstruct_keys(_keys)
|
7671
8363
|
{ parts: parts, quote: quote, location: location, comments: comments }
|
7672
8364
|
end
|
7673
8365
|
|
@@ -7730,7 +8422,7 @@ module SyntaxTree
|
|
7730
8422
|
|
7731
8423
|
alias deconstruct child_nodes
|
7732
8424
|
|
7733
|
-
def deconstruct_keys(
|
8425
|
+
def deconstruct_keys(_keys)
|
7734
8426
|
{ arguments: arguments, location: location, comments: comments }
|
7735
8427
|
end
|
7736
8428
|
|
@@ -7782,8 +8474,8 @@ module SyntaxTree
|
|
7782
8474
|
end
|
7783
8475
|
|
7784
8476
|
alias deconstruct child_nodes
|
7785
|
-
|
7786
|
-
def deconstruct_keys(
|
8477
|
+
|
8478
|
+
def deconstruct_keys(_keys)
|
7787
8479
|
{ value: value, location: location }
|
7788
8480
|
end
|
7789
8481
|
end
|
@@ -7812,8 +8504,8 @@ module SyntaxTree
|
|
7812
8504
|
end
|
7813
8505
|
|
7814
8506
|
alias deconstruct child_nodes
|
7815
|
-
|
7816
|
-
def deconstruct_keys(
|
8507
|
+
|
8508
|
+
def deconstruct_keys(_keys)
|
7817
8509
|
{ value: value, location: location }
|
7818
8510
|
end
|
7819
8511
|
end
|
@@ -7847,7 +8539,7 @@ module SyntaxTree
|
|
7847
8539
|
|
7848
8540
|
alias deconstruct child_nodes
|
7849
8541
|
|
7850
|
-
def deconstruct_keys(
|
8542
|
+
def deconstruct_keys(_keys)
|
7851
8543
|
{ value: value, location: location, comments: comments }
|
7852
8544
|
end
|
7853
8545
|
|
@@ -7888,7 +8580,7 @@ module SyntaxTree
|
|
7888
8580
|
|
7889
8581
|
alias deconstruct child_nodes
|
7890
8582
|
|
7891
|
-
def deconstruct_keys(
|
8583
|
+
def deconstruct_keys(_keys)
|
7892
8584
|
{
|
7893
8585
|
beginning: beginning,
|
7894
8586
|
elements: elements,
|
@@ -7943,8 +8635,8 @@ module SyntaxTree
|
|
7943
8635
|
end
|
7944
8636
|
|
7945
8637
|
alias deconstruct child_nodes
|
7946
|
-
|
7947
|
-
def deconstruct_keys(
|
8638
|
+
|
8639
|
+
def deconstruct_keys(_keys)
|
7948
8640
|
{ value: value, location: location }
|
7949
8641
|
end
|
7950
8642
|
end
|
@@ -7972,8 +8664,8 @@ module SyntaxTree
|
|
7972
8664
|
end
|
7973
8665
|
|
7974
8666
|
alias deconstruct child_nodes
|
7975
|
-
|
7976
|
-
def deconstruct_keys(
|
8667
|
+
|
8668
|
+
def deconstruct_keys(_keys)
|
7977
8669
|
{ value: value, location: location }
|
7978
8670
|
end
|
7979
8671
|
end
|
@@ -8002,8 +8694,8 @@ module SyntaxTree
|
|
8002
8694
|
end
|
8003
8695
|
|
8004
8696
|
alias deconstruct child_nodes
|
8005
|
-
|
8006
|
-
def deconstruct_keys(
|
8697
|
+
|
8698
|
+
def deconstruct_keys(_keys)
|
8007
8699
|
{ value: value, location: location }
|
8008
8700
|
end
|
8009
8701
|
end
|
@@ -8037,7 +8729,7 @@ module SyntaxTree
|
|
8037
8729
|
|
8038
8730
|
alias deconstruct child_nodes
|
8039
8731
|
|
8040
|
-
def deconstruct_keys(
|
8732
|
+
def deconstruct_keys(_keys)
|
8041
8733
|
{ constant: constant, location: location, comments: comments }
|
8042
8734
|
end
|
8043
8735
|
|
@@ -8075,7 +8767,7 @@ module SyntaxTree
|
|
8075
8767
|
|
8076
8768
|
alias deconstruct child_nodes
|
8077
8769
|
|
8078
|
-
def deconstruct_keys(
|
8770
|
+
def deconstruct_keys(_keys)
|
8079
8771
|
{ constant: constant, location: location, comments: comments }
|
8080
8772
|
end
|
8081
8773
|
|
@@ -8113,8 +8805,8 @@ module SyntaxTree
|
|
8113
8805
|
end
|
8114
8806
|
|
8115
8807
|
alias deconstruct child_nodes
|
8116
|
-
|
8117
|
-
def deconstruct_keys(
|
8808
|
+
|
8809
|
+
def deconstruct_keys(_keys)
|
8118
8810
|
{ value: value, location: location }
|
8119
8811
|
end
|
8120
8812
|
end
|
@@ -8154,7 +8846,7 @@ module SyntaxTree
|
|
8154
8846
|
|
8155
8847
|
alias deconstruct child_nodes
|
8156
8848
|
|
8157
|
-
def deconstruct_keys(
|
8849
|
+
def deconstruct_keys(_keys)
|
8158
8850
|
{ value: value, location: location, comments: comments }
|
8159
8851
|
end
|
8160
8852
|
|
@@ -8191,8 +8883,8 @@ module SyntaxTree
|
|
8191
8883
|
end
|
8192
8884
|
|
8193
8885
|
alias deconstruct child_nodes
|
8194
|
-
|
8195
|
-
def deconstruct_keys(
|
8886
|
+
|
8887
|
+
def deconstruct_keys(_keys)
|
8196
8888
|
{ value: value, location: location }
|
8197
8889
|
end
|
8198
8890
|
end
|
@@ -8228,7 +8920,7 @@ module SyntaxTree
|
|
8228
8920
|
|
8229
8921
|
alias deconstruct child_nodes
|
8230
8922
|
|
8231
|
-
def deconstruct_keys(
|
8923
|
+
def deconstruct_keys(_keys)
|
8232
8924
|
{
|
8233
8925
|
statement: statement,
|
8234
8926
|
parentheses: parentheses,
|
@@ -8238,9 +8930,28 @@ module SyntaxTree
|
|
8238
8930
|
end
|
8239
8931
|
|
8240
8932
|
def format(q)
|
8241
|
-
q.
|
8933
|
+
parent = q.parents.take(2)[1]
|
8934
|
+
ternary =
|
8935
|
+
(parent.is_a?(If) || parent.is_a?(Unless)) &&
|
8936
|
+
Ternaryable.call(q, parent)
|
8937
|
+
|
8938
|
+
q.text("not")
|
8939
|
+
|
8940
|
+
if parentheses
|
8941
|
+
q.text("(")
|
8942
|
+
elsif ternary
|
8943
|
+
q.if_break { q.text(" ") }.if_flat { q.text("(") }
|
8944
|
+
else
|
8945
|
+
q.text(" ")
|
8946
|
+
end
|
8947
|
+
|
8242
8948
|
q.format(statement) if statement
|
8243
|
-
|
8949
|
+
|
8950
|
+
if parentheses
|
8951
|
+
q.text(")")
|
8952
|
+
elsif ternary
|
8953
|
+
q.if_flat { q.text(")") }
|
8954
|
+
end
|
8244
8955
|
end
|
8245
8956
|
end
|
8246
8957
|
|
@@ -8276,7 +8987,7 @@ module SyntaxTree
|
|
8276
8987
|
|
8277
8988
|
alias deconstruct child_nodes
|
8278
8989
|
|
8279
|
-
def deconstruct_keys(
|
8990
|
+
def deconstruct_keys(_keys)
|
8280
8991
|
{
|
8281
8992
|
operator: operator,
|
8282
8993
|
statement: statement,
|
@@ -8296,6 +9007,9 @@ module SyntaxTree
|
|
8296
9007
|
# undef method
|
8297
9008
|
#
|
8298
9009
|
class Undef < Node
|
9010
|
+
# Undef accepts a variable number of arguments that can be either DynaSymbol
|
9011
|
+
# or SymbolLiteral objects. For SymbolLiteral objects we descend directly
|
9012
|
+
# into the value in order to have it come out as bare words.
|
8299
9013
|
class UndefArgumentFormatter
|
8300
9014
|
# [DynaSymbol | SymbolLiteral] the symbol to undefine
|
8301
9015
|
attr_reader :node
|
@@ -8339,7 +9053,7 @@ module SyntaxTree
|
|
8339
9053
|
|
8340
9054
|
alias deconstruct child_nodes
|
8341
9055
|
|
8342
|
-
def deconstruct_keys(
|
9056
|
+
def deconstruct_keys(_keys)
|
8343
9057
|
{ symbols: symbols, location: location, comments: comments }
|
8344
9058
|
end
|
8345
9059
|
|
@@ -8398,7 +9112,7 @@ module SyntaxTree
|
|
8398
9112
|
|
8399
9113
|
alias deconstruct child_nodes
|
8400
9114
|
|
8401
|
-
def deconstruct_keys(
|
9115
|
+
def deconstruct_keys(_keys)
|
8402
9116
|
{
|
8403
9117
|
predicate: predicate,
|
8404
9118
|
statements: statements,
|
@@ -8444,7 +9158,7 @@ module SyntaxTree
|
|
8444
9158
|
|
8445
9159
|
alias deconstruct child_nodes
|
8446
9160
|
|
8447
|
-
def deconstruct_keys(
|
9161
|
+
def deconstruct_keys(_keys)
|
8448
9162
|
{
|
8449
9163
|
statement: statement,
|
8450
9164
|
predicate: predicate,
|
@@ -8483,13 +9197,15 @@ module SyntaxTree
|
|
8483
9197
|
end
|
8484
9198
|
|
8485
9199
|
q.group do
|
8486
|
-
q
|
8487
|
-
|
8488
|
-
|
8489
|
-
|
8490
|
-
|
9200
|
+
q
|
9201
|
+
.if_break { format_break(q) }
|
9202
|
+
.if_flat do
|
9203
|
+
Parentheses.flat(q) do
|
9204
|
+
q.format(statements)
|
9205
|
+
q.text(" #{keyword} ")
|
9206
|
+
q.format(node.predicate)
|
9207
|
+
end
|
8491
9208
|
end
|
8492
|
-
end
|
8493
9209
|
end
|
8494
9210
|
end
|
8495
9211
|
|
@@ -8539,7 +9255,7 @@ module SyntaxTree
|
|
8539
9255
|
|
8540
9256
|
alias deconstruct child_nodes
|
8541
9257
|
|
8542
|
-
def deconstruct_keys(
|
9258
|
+
def deconstruct_keys(_keys)
|
8543
9259
|
{
|
8544
9260
|
predicate: predicate,
|
8545
9261
|
statements: statements,
|
@@ -8595,7 +9311,7 @@ module SyntaxTree
|
|
8595
9311
|
|
8596
9312
|
alias deconstruct child_nodes
|
8597
9313
|
|
8598
|
-
def deconstruct_keys(
|
9314
|
+
def deconstruct_keys(_keys)
|
8599
9315
|
{
|
8600
9316
|
statement: statement,
|
8601
9317
|
predicate: predicate,
|
@@ -8661,7 +9377,7 @@ module SyntaxTree
|
|
8661
9377
|
|
8662
9378
|
alias deconstruct child_nodes
|
8663
9379
|
|
8664
|
-
def deconstruct_keys(
|
9380
|
+
def deconstruct_keys(_keys)
|
8665
9381
|
{ left: left, right: right, location: location, comments: comments }
|
8666
9382
|
end
|
8667
9383
|
|
@@ -8704,7 +9420,7 @@ module SyntaxTree
|
|
8704
9420
|
|
8705
9421
|
alias deconstruct child_nodes
|
8706
9422
|
|
8707
|
-
def deconstruct_keys(
|
9423
|
+
def deconstruct_keys(_keys)
|
8708
9424
|
{ value: value, location: location, comments: comments }
|
8709
9425
|
end
|
8710
9426
|
|
@@ -8748,7 +9464,7 @@ module SyntaxTree
|
|
8748
9464
|
|
8749
9465
|
alias deconstruct child_nodes
|
8750
9466
|
|
8751
|
-
def deconstruct_keys(
|
9467
|
+
def deconstruct_keys(_keys)
|
8752
9468
|
{ value: value, location: location, comments: comments }
|
8753
9469
|
end
|
8754
9470
|
|
@@ -8789,7 +9505,7 @@ module SyntaxTree
|
|
8789
9505
|
|
8790
9506
|
alias deconstruct child_nodes
|
8791
9507
|
|
8792
|
-
def deconstruct_keys(
|
9508
|
+
def deconstruct_keys(_keys)
|
8793
9509
|
{ value: value, location: location, comments: comments }
|
8794
9510
|
end
|
8795
9511
|
|
@@ -8829,7 +9545,7 @@ module SyntaxTree
|
|
8829
9545
|
|
8830
9546
|
alias deconstruct child_nodes
|
8831
9547
|
|
8832
|
-
def deconstruct_keys(
|
9548
|
+
def deconstruct_keys(_keys)
|
8833
9549
|
{ value: value, location: location, comments: comments }
|
8834
9550
|
end
|
8835
9551
|
|
@@ -8864,7 +9580,7 @@ module SyntaxTree
|
|
8864
9580
|
|
8865
9581
|
alias deconstruct child_nodes
|
8866
9582
|
|
8867
|
-
def deconstruct_keys(
|
9583
|
+
def deconstruct_keys(_keys)
|
8868
9584
|
{ location: location, comments: comments }
|
8869
9585
|
end
|
8870
9586
|
|
@@ -8915,7 +9631,7 @@ module SyntaxTree
|
|
8915
9631
|
|
8916
9632
|
alias deconstruct child_nodes
|
8917
9633
|
|
8918
|
-
def deconstruct_keys(
|
9634
|
+
def deconstruct_keys(_keys)
|
8919
9635
|
{
|
8920
9636
|
arguments: arguments,
|
8921
9637
|
statements: statements,
|
@@ -8996,7 +9712,7 @@ module SyntaxTree
|
|
8996
9712
|
|
8997
9713
|
alias deconstruct child_nodes
|
8998
9714
|
|
8999
|
-
def deconstruct_keys(
|
9715
|
+
def deconstruct_keys(_keys)
|
9000
9716
|
{
|
9001
9717
|
predicate: predicate,
|
9002
9718
|
statements: statements,
|
@@ -9052,7 +9768,7 @@ module SyntaxTree
|
|
9052
9768
|
|
9053
9769
|
alias deconstruct child_nodes
|
9054
9770
|
|
9055
|
-
def deconstruct_keys(
|
9771
|
+
def deconstruct_keys(_keys)
|
9056
9772
|
{
|
9057
9773
|
statement: statement,
|
9058
9774
|
predicate: predicate,
|
@@ -9121,7 +9837,7 @@ module SyntaxTree
|
|
9121
9837
|
|
9122
9838
|
alias deconstruct child_nodes
|
9123
9839
|
|
9124
|
-
def deconstruct_keys(
|
9840
|
+
def deconstruct_keys(_keys)
|
9125
9841
|
{ parts: parts, location: location, comments: comments }
|
9126
9842
|
end
|
9127
9843
|
|
@@ -9161,7 +9877,7 @@ module SyntaxTree
|
|
9161
9877
|
|
9162
9878
|
alias deconstruct child_nodes
|
9163
9879
|
|
9164
|
-
def deconstruct_keys(
|
9880
|
+
def deconstruct_keys(_keys)
|
9165
9881
|
{
|
9166
9882
|
beginning: beginning,
|
9167
9883
|
elements: elements,
|
@@ -9216,8 +9932,8 @@ module SyntaxTree
|
|
9216
9932
|
end
|
9217
9933
|
|
9218
9934
|
alias deconstruct child_nodes
|
9219
|
-
|
9220
|
-
def deconstruct_keys(
|
9935
|
+
|
9936
|
+
def deconstruct_keys(_keys)
|
9221
9937
|
{ value: value, location: location }
|
9222
9938
|
end
|
9223
9939
|
end
|
@@ -9245,8 +9961,8 @@ module SyntaxTree
|
|
9245
9961
|
end
|
9246
9962
|
|
9247
9963
|
alias deconstruct child_nodes
|
9248
|
-
|
9249
|
-
def deconstruct_keys(
|
9964
|
+
|
9965
|
+
def deconstruct_keys(_keys)
|
9250
9966
|
{ parts: parts, location: location }
|
9251
9967
|
end
|
9252
9968
|
end
|
@@ -9279,7 +9995,7 @@ module SyntaxTree
|
|
9279
9995
|
|
9280
9996
|
alias deconstruct child_nodes
|
9281
9997
|
|
9282
|
-
def deconstruct_keys(
|
9998
|
+
def deconstruct_keys(_keys)
|
9283
9999
|
{ parts: parts, location: location, comments: comments }
|
9284
10000
|
end
|
9285
10001
|
|
@@ -9317,7 +10033,7 @@ module SyntaxTree
|
|
9317
10033
|
|
9318
10034
|
alias deconstruct child_nodes
|
9319
10035
|
|
9320
|
-
def deconstruct_keys(
|
10036
|
+
def deconstruct_keys(_keys)
|
9321
10037
|
{ arguments: arguments, location: location, comments: comments }
|
9322
10038
|
end
|
9323
10039
|
|
@@ -9367,7 +10083,7 @@ module SyntaxTree
|
|
9367
10083
|
|
9368
10084
|
alias deconstruct child_nodes
|
9369
10085
|
|
9370
|
-
def deconstruct_keys(
|
10086
|
+
def deconstruct_keys(_keys)
|
9371
10087
|
{ value: value, location: location, comments: comments }
|
9372
10088
|
end
|
9373
10089
|
|
@@ -9403,7 +10119,7 @@ module SyntaxTree
|
|
9403
10119
|
|
9404
10120
|
alias deconstruct child_nodes
|
9405
10121
|
|
9406
|
-
def deconstruct_keys(
|
10122
|
+
def deconstruct_keys(_keys)
|
9407
10123
|
{ value: value, location: location, comments: comments }
|
9408
10124
|
end
|
9409
10125
|
|