syntax_tree 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +20 -1
- data/.rubocop.yml +80 -0
- data/CHANGELOG.md +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
|
|