syntax_tree 5.3.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +12 -1
- data/CHANGELOG.md +64 -1
- data/Gemfile.lock +2 -2
- data/README.md +28 -9
- data/Rakefile +12 -8
- data/bin/console +1 -0
- data/bin/whitequark +79 -0
- data/doc/changing_structure.md +16 -0
- data/lib/syntax_tree/basic_visitor.rb +44 -5
- data/lib/syntax_tree/cli.rb +2 -2
- data/lib/syntax_tree/dsl.rb +23 -11
- data/lib/syntax_tree/{visitor/field_visitor.rb → field_visitor.rb} +54 -55
- data/lib/syntax_tree/formatter.rb +1 -1
- data/lib/syntax_tree/index.rb +56 -54
- data/lib/syntax_tree/json_visitor.rb +55 -0
- data/lib/syntax_tree/language_server.rb +157 -2
- data/lib/syntax_tree/match_visitor.rb +120 -0
- data/lib/syntax_tree/mermaid.rb +177 -0
- data/lib/syntax_tree/mermaid_visitor.rb +69 -0
- data/lib/syntax_tree/{visitor/mutation_visitor.rb → mutation_visitor.rb} +27 -27
- data/lib/syntax_tree/node.rb +198 -107
- data/lib/syntax_tree/parser.rb +322 -118
- data/lib/syntax_tree/pretty_print_visitor.rb +83 -0
- data/lib/syntax_tree/reflection.rb +241 -0
- data/lib/syntax_tree/translation/parser.rb +3019 -0
- data/lib/syntax_tree/translation/rubocop_ast.rb +21 -0
- data/lib/syntax_tree/translation.rb +28 -0
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree/with_scope.rb +244 -0
- data/lib/syntax_tree/yarv/basic_block.rb +53 -0
- data/lib/syntax_tree/yarv/calldata.rb +91 -0
- data/lib/syntax_tree/yarv/compiler.rb +110 -100
- data/lib/syntax_tree/yarv/control_flow_graph.rb +257 -0
- data/lib/syntax_tree/yarv/data_flow_graph.rb +338 -0
- data/lib/syntax_tree/yarv/decompiler.rb +1 -1
- data/lib/syntax_tree/yarv/disassembler.rb +104 -80
- data/lib/syntax_tree/yarv/instruction_sequence.rb +43 -18
- data/lib/syntax_tree/yarv/instructions.rb +203 -649
- data/lib/syntax_tree/yarv/legacy.rb +12 -24
- data/lib/syntax_tree/yarv/sea_of_nodes.rb +534 -0
- data/lib/syntax_tree/yarv.rb +18 -0
- data/lib/syntax_tree.rb +88 -56
- data/tasks/sorbet.rake +277 -0
- data/tasks/whitequark.rake +87 -0
- metadata +23 -11
- data/.gitmodules +0 -9
- data/lib/syntax_tree/language_server/inlay_hints.rb +0 -159
- data/lib/syntax_tree/visitor/environment.rb +0 -84
- data/lib/syntax_tree/visitor/json_visitor.rb +0 -55
- data/lib/syntax_tree/visitor/match_visitor.rb +0 -122
- data/lib/syntax_tree/visitor/pretty_print_visitor.rb +0 -85
- data/lib/syntax_tree/visitor/with_environment.rb +0 -140
data/lib/syntax_tree/node.rb
CHANGED
@@ -126,18 +126,28 @@ module SyntaxTree
|
|
126
126
|
raise NotImplementedError
|
127
127
|
end
|
128
128
|
|
129
|
+
def start_char
|
130
|
+
location.start_char
|
131
|
+
end
|
132
|
+
|
133
|
+
def end_char
|
134
|
+
location.end_char
|
135
|
+
end
|
136
|
+
|
129
137
|
def pretty_print(q)
|
130
|
-
|
131
|
-
visitor.visit(self)
|
138
|
+
accept(PrettyPrintVisitor.new(q))
|
132
139
|
end
|
133
140
|
|
134
141
|
def to_json(*opts)
|
135
|
-
|
136
|
-
|
142
|
+
accept(JSONVisitor.new).to_json(*opts)
|
143
|
+
end
|
144
|
+
|
145
|
+
def to_mermaid
|
146
|
+
accept(MermaidVisitor.new)
|
137
147
|
end
|
138
148
|
|
139
149
|
def construct_keys
|
140
|
-
PrettierPrint.format(+"") { |q|
|
150
|
+
PrettierPrint.format(+"") { |q| accept(MatchVisitor.new(q)) }
|
141
151
|
end
|
142
152
|
end
|
143
153
|
|
@@ -555,7 +565,7 @@ module SyntaxTree
|
|
555
565
|
# collection[]
|
556
566
|
#
|
557
567
|
class ARef < Node
|
558
|
-
# [
|
568
|
+
# [Node] the value being indexed
|
559
569
|
attr_reader :collection
|
560
570
|
|
561
571
|
# [nil | Args] the value being passed within the brackets
|
@@ -633,7 +643,7 @@ module SyntaxTree
|
|
633
643
|
# collection[index] = value
|
634
644
|
#
|
635
645
|
class ARefField < Node
|
636
|
-
# [
|
646
|
+
# [Node] the value being indexed
|
637
647
|
attr_reader :collection
|
638
648
|
|
639
649
|
# [nil | Args] the value being passed within the brackets
|
@@ -808,7 +818,7 @@ module SyntaxTree
|
|
808
818
|
# method(first, second, third)
|
809
819
|
#
|
810
820
|
class Args < Node
|
811
|
-
# [Array[
|
821
|
+
# [Array[ Node ]] the arguments that this node wraps
|
812
822
|
attr_reader :parts
|
813
823
|
|
814
824
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -874,7 +884,7 @@ module SyntaxTree
|
|
874
884
|
# method(&expression)
|
875
885
|
#
|
876
886
|
class ArgBlock < Node
|
877
|
-
# [nil |
|
887
|
+
# [nil | Node] the expression being turned into a block
|
878
888
|
attr_reader :value
|
879
889
|
|
880
890
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -926,7 +936,7 @@ module SyntaxTree
|
|
926
936
|
# method(*arguments)
|
927
937
|
#
|
928
938
|
class ArgStar < Node
|
929
|
-
# [nil |
|
939
|
+
# [nil | Node] the expression being splatted
|
930
940
|
attr_reader :value
|
931
941
|
|
932
942
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -1129,7 +1139,8 @@ module SyntaxTree
|
|
1129
1139
|
end
|
1130
1140
|
end
|
1131
1141
|
|
1132
|
-
# [LBracket
|
1142
|
+
# [nil | LBracket | QSymbolsBeg | QWordsBeg | SymbolsBeg | WordsBeg] the
|
1143
|
+
# bracket that opens this array
|
1133
1144
|
attr_reader :lbracket
|
1134
1145
|
|
1135
1146
|
# [nil | Args] the contents of the array
|
@@ -1287,7 +1298,7 @@ module SyntaxTree
|
|
1287
1298
|
# [nil | VarRef] the optional constant wrapper
|
1288
1299
|
attr_reader :constant
|
1289
1300
|
|
1290
|
-
# [Array[
|
1301
|
+
# [Array[ Node ]] the regular positional arguments that this array
|
1291
1302
|
# pattern is matching against
|
1292
1303
|
attr_reader :requireds
|
1293
1304
|
|
@@ -1295,7 +1306,7 @@ module SyntaxTree
|
|
1295
1306
|
# positional arguments
|
1296
1307
|
attr_reader :rest
|
1297
1308
|
|
1298
|
-
# [Array[
|
1309
|
+
# [Array[ Node ]] the list of positional arguments occurring after the
|
1299
1310
|
# optional star if there is one
|
1300
1311
|
attr_reader :posts
|
1301
1312
|
|
@@ -1405,7 +1416,7 @@ module SyntaxTree
|
|
1405
1416
|
# to assign the result of the expression to
|
1406
1417
|
attr_reader :target
|
1407
1418
|
|
1408
|
-
# [
|
1419
|
+
# [Node] the expression to be assigned
|
1409
1420
|
attr_reader :value
|
1410
1421
|
|
1411
1422
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -1480,10 +1491,10 @@ module SyntaxTree
|
|
1480
1491
|
#
|
1481
1492
|
# In the above example, the would be two Assoc nodes.
|
1482
1493
|
class Assoc < Node
|
1483
|
-
# [
|
1494
|
+
# [Node] the key of this pair
|
1484
1495
|
attr_reader :key
|
1485
1496
|
|
1486
|
-
# [
|
1497
|
+
# [nil | Node] the value of this pair
|
1487
1498
|
attr_reader :value
|
1488
1499
|
|
1489
1500
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -1537,7 +1548,7 @@ module SyntaxTree
|
|
1537
1548
|
private
|
1538
1549
|
|
1539
1550
|
def format_contents(q)
|
1540
|
-
q.parent.format_key(q, key)
|
1551
|
+
(q.parent || HashKeyFormatter::Identity.new).format_key(q, key)
|
1541
1552
|
return unless value
|
1542
1553
|
|
1543
1554
|
if key.comments.empty? && AssignFormatting.skip_indent?(value)
|
@@ -1558,7 +1569,7 @@ module SyntaxTree
|
|
1558
1569
|
# { **pairs }
|
1559
1570
|
#
|
1560
1571
|
class AssocSplat < Node
|
1561
|
-
# [nil |
|
1572
|
+
# [nil | Node] the expression that is being splatted
|
1562
1573
|
attr_reader :value
|
1563
1574
|
|
1564
1575
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -1754,6 +1765,20 @@ module SyntaxTree
|
|
1754
1765
|
end
|
1755
1766
|
end
|
1756
1767
|
|
1768
|
+
# When formatting a single assoc node without the context of the parent
|
1769
|
+
# hash, this formatter is used. It uses whatever is present in the node,
|
1770
|
+
# because there is nothing to be consistent with.
|
1771
|
+
class Identity
|
1772
|
+
def format_key(q, key)
|
1773
|
+
if key.is_a?(Label)
|
1774
|
+
q.format(key)
|
1775
|
+
else
|
1776
|
+
q.format(key)
|
1777
|
+
q.text(" =>")
|
1778
|
+
end
|
1779
|
+
end
|
1780
|
+
end
|
1781
|
+
|
1757
1782
|
def self.for(container)
|
1758
1783
|
labels =
|
1759
1784
|
container.assocs.all? do |assoc|
|
@@ -1908,7 +1933,7 @@ module SyntaxTree
|
|
1908
1933
|
# end
|
1909
1934
|
#
|
1910
1935
|
class PinnedBegin < Node
|
1911
|
-
# [
|
1936
|
+
# [Node] the expression being pinned
|
1912
1937
|
attr_reader :statement
|
1913
1938
|
|
1914
1939
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -1989,13 +2014,13 @@ module SyntaxTree
|
|
1989
2014
|
}
|
1990
2015
|
end
|
1991
2016
|
|
1992
|
-
# [
|
2017
|
+
# [Node] the left-hand side of the expression
|
1993
2018
|
attr_reader :left
|
1994
2019
|
|
1995
2020
|
# [Symbol] the operator used between the two expressions
|
1996
2021
|
attr_reader :operator
|
1997
2022
|
|
1998
|
-
# [
|
2023
|
+
# [Node] the right-hand side of the expression
|
1999
2024
|
attr_reader :right
|
2000
2025
|
|
2001
2026
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -2149,6 +2174,14 @@ module SyntaxTree
|
|
2149
2174
|
other.is_a?(BlockVar) && params === other.params &&
|
2150
2175
|
ArrayMatch.call(locals, other.locals)
|
2151
2176
|
end
|
2177
|
+
|
2178
|
+
# When a single required parameter is declared for a block, it gets
|
2179
|
+
# automatically expanded if the values being yielded into it are an array.
|
2180
|
+
def arg0?
|
2181
|
+
params.requireds.length == 1 && params.optionals.empty? &&
|
2182
|
+
params.rest.nil? && params.posts.empty? && params.keywords.empty? &&
|
2183
|
+
params.keyword_rest.nil? && params.block.nil?
|
2184
|
+
end
|
2152
2185
|
end
|
2153
2186
|
|
2154
2187
|
# BlockArg represents declaring a block parameter on a method definition.
|
@@ -2242,7 +2275,7 @@ module SyntaxTree
|
|
2242
2275
|
@comments = []
|
2243
2276
|
end
|
2244
2277
|
|
2245
|
-
def bind(start_char, start_column, end_char, end_column)
|
2278
|
+
def bind(parser, start_char, start_column, end_char, end_column)
|
2246
2279
|
@location =
|
2247
2280
|
Location.new(
|
2248
2281
|
start_line: location.start_line,
|
@@ -2256,6 +2289,7 @@ module SyntaxTree
|
|
2256
2289
|
# Here we're going to determine the bounds for the statements
|
2257
2290
|
consequent = rescue_clause || else_clause || ensure_clause
|
2258
2291
|
statements.bind(
|
2292
|
+
parser,
|
2259
2293
|
start_char,
|
2260
2294
|
start_column,
|
2261
2295
|
consequent ? consequent.location.start_char : end_char,
|
@@ -2646,7 +2680,7 @@ module SyntaxTree
|
|
2646
2680
|
# Of course there are a lot of caveats to that, including trailing operators
|
2647
2681
|
# when necessary, where comments are places, how blocks are aligned, etc.
|
2648
2682
|
class CallChainFormatter
|
2649
|
-
# [
|
2683
|
+
# [CallNode | MethodAddBlock] the top of the call chain
|
2650
2684
|
attr_reader :node
|
2651
2685
|
|
2652
2686
|
def initialize(node)
|
@@ -2867,7 +2901,7 @@ module SyntaxTree
|
|
2867
2901
|
# receiver.message
|
2868
2902
|
#
|
2869
2903
|
class CallNode < Node
|
2870
|
-
# [nil |
|
2904
|
+
# [nil | Node] the receiver of the method call
|
2871
2905
|
attr_reader :receiver
|
2872
2906
|
|
2873
2907
|
# [nil | :"::" | Op | Period] the operator being used to send the message
|
@@ -3043,7 +3077,7 @@ module SyntaxTree
|
|
3043
3077
|
# [Kw] the keyword that opens this expression
|
3044
3078
|
attr_reader :keyword
|
3045
3079
|
|
3046
|
-
# [nil |
|
3080
|
+
# [nil | Node] optional value being switched on
|
3047
3081
|
attr_reader :value
|
3048
3082
|
|
3049
3083
|
# [In | When] the next clause in the chain
|
@@ -3122,14 +3156,14 @@ module SyntaxTree
|
|
3122
3156
|
# value => pattern
|
3123
3157
|
#
|
3124
3158
|
class RAssign < Node
|
3125
|
-
# [
|
3159
|
+
# [Node] the left-hand expression
|
3126
3160
|
attr_reader :value
|
3127
3161
|
|
3128
3162
|
# [Kw | Op] the operator being used to match against the pattern, which is
|
3129
3163
|
# either => or in
|
3130
3164
|
attr_reader :operator
|
3131
3165
|
|
3132
|
-
# [
|
3166
|
+
# [Node] the pattern on the right-hand side of the expression
|
3133
3167
|
attr_reader :pattern
|
3134
3168
|
|
3135
3169
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -3240,7 +3274,7 @@ module SyntaxTree
|
|
3240
3274
|
# defined
|
3241
3275
|
attr_reader :constant
|
3242
3276
|
|
3243
|
-
# [nil |
|
3277
|
+
# [nil | Node] the optional superclass declaration
|
3244
3278
|
attr_reader :superclass
|
3245
3279
|
|
3246
3280
|
# [BodyStmt] the expressions to execute within the context of the class
|
@@ -3378,7 +3412,7 @@ module SyntaxTree
|
|
3378
3412
|
# [Args] the arguments being sent with the message
|
3379
3413
|
attr_reader :arguments
|
3380
3414
|
|
3381
|
-
# [nil |
|
3415
|
+
# [nil | BlockNode] the optional block being passed to the method
|
3382
3416
|
attr_reader :block
|
3383
3417
|
|
3384
3418
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -3484,19 +3518,19 @@ module SyntaxTree
|
|
3484
3518
|
# object.method argument
|
3485
3519
|
#
|
3486
3520
|
class CommandCall < Node
|
3487
|
-
# [
|
3521
|
+
# [nil | Node] the receiver of the message
|
3488
3522
|
attr_reader :receiver
|
3489
3523
|
|
3490
|
-
# [:"::" | Op | Period] the operator used to send the message
|
3524
|
+
# [nil | :"::" | Op | Period] the operator used to send the message
|
3491
3525
|
attr_reader :operator
|
3492
3526
|
|
3493
|
-
# [Const | Ident | Op] the message being send
|
3527
|
+
# [:call | Const | Ident | Op] the message being send
|
3494
3528
|
attr_reader :message
|
3495
3529
|
|
3496
|
-
# [nil | Args] the arguments going along with the message
|
3530
|
+
# [nil | Args | ArgParen] the arguments going along with the message
|
3497
3531
|
attr_reader :arguments
|
3498
3532
|
|
3499
|
-
# [nil |
|
3533
|
+
# [nil | BlockNode] the block associated with this method call
|
3500
3534
|
attr_reader :block
|
3501
3535
|
|
3502
3536
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -3782,7 +3816,7 @@ module SyntaxTree
|
|
3782
3816
|
# object::Const = value
|
3783
3817
|
#
|
3784
3818
|
class ConstPathField < Node
|
3785
|
-
# [
|
3819
|
+
# [Node] the source of the constant
|
3786
3820
|
attr_reader :parent
|
3787
3821
|
|
3788
3822
|
# [Const] the constant itself
|
@@ -3846,7 +3880,7 @@ module SyntaxTree
|
|
3846
3880
|
# object::Const
|
3847
3881
|
#
|
3848
3882
|
class ConstPathRef < Node
|
3849
|
-
# [
|
3883
|
+
# [Node] the source of the constant
|
3850
3884
|
attr_reader :parent
|
3851
3885
|
|
3852
3886
|
# [Const] the constant itself
|
@@ -4015,7 +4049,7 @@ module SyntaxTree
|
|
4015
4049
|
# def object.method(param) result end
|
4016
4050
|
#
|
4017
4051
|
class DefNode < Node
|
4018
|
-
# [nil |
|
4052
|
+
# [nil | Node] the target where the method is being defined
|
4019
4053
|
attr_reader :target
|
4020
4054
|
|
4021
4055
|
# [nil | Op | Period] the operator being used to declare the method
|
@@ -4027,7 +4061,7 @@ module SyntaxTree
|
|
4027
4061
|
# [nil | Params | Paren] the parameter declaration for the method
|
4028
4062
|
attr_reader :params
|
4029
4063
|
|
4030
|
-
# [BodyStmt |
|
4064
|
+
# [BodyStmt | Node] the expressions to be executed by the method
|
4031
4065
|
attr_reader :bodystmt
|
4032
4066
|
|
4033
4067
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -4090,7 +4124,8 @@ module SyntaxTree
|
|
4090
4124
|
def format(q)
|
4091
4125
|
q.group do
|
4092
4126
|
q.group do
|
4093
|
-
q.text("def
|
4127
|
+
q.text("def")
|
4128
|
+
q.text(" ") if target || name.comments.empty?
|
4094
4129
|
|
4095
4130
|
if target
|
4096
4131
|
q.format(target)
|
@@ -4160,7 +4195,7 @@ module SyntaxTree
|
|
4160
4195
|
# defined?(variable)
|
4161
4196
|
#
|
4162
4197
|
class Defined < Node
|
4163
|
-
# [
|
4198
|
+
# [Node] the value being sent to the keyword
|
4164
4199
|
attr_reader :value
|
4165
4200
|
|
4166
4201
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -4317,7 +4352,7 @@ module SyntaxTree
|
|
4317
4352
|
# are no parentheses around the arguments to that command, so we need to
|
4318
4353
|
# break the block.
|
4319
4354
|
case q.parent
|
4320
|
-
when Command, CommandCall
|
4355
|
+
when nil, Command, CommandCall
|
4321
4356
|
q.break_parent
|
4322
4357
|
format_break(q, break_opening, break_closing)
|
4323
4358
|
return
|
@@ -4371,7 +4406,7 @@ module SyntaxTree
|
|
4371
4406
|
# If we're a sibling of a control-flow keyword, then we're going to have to
|
4372
4407
|
# use the do..end bounds.
|
4373
4408
|
def forced_do_end_bounds?(q)
|
4374
|
-
case q.parent
|
4409
|
+
case q.parent&.call
|
4375
4410
|
when Break, Next, ReturnNode, Super
|
4376
4411
|
true
|
4377
4412
|
else
|
@@ -4451,13 +4486,13 @@ module SyntaxTree
|
|
4451
4486
|
#
|
4452
4487
|
# One of the sides of the expression may be nil, but not both.
|
4453
4488
|
class RangeNode < Node
|
4454
|
-
# [nil |
|
4489
|
+
# [nil | Node] the left side of the expression
|
4455
4490
|
attr_reader :left
|
4456
4491
|
|
4457
4492
|
# [Op] the operator used for this range
|
4458
4493
|
attr_reader :operator
|
4459
4494
|
|
4460
|
-
# [nil |
|
4495
|
+
# [nil | Node] the right side of the expression
|
4461
4496
|
attr_reader :right
|
4462
4497
|
|
4463
4498
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -4578,7 +4613,7 @@ module SyntaxTree
|
|
4578
4613
|
# dynamic symbol
|
4579
4614
|
attr_reader :parts
|
4580
4615
|
|
4581
|
-
# [String] the quote used to delimit the dynamic symbol
|
4616
|
+
# [nil | String] the quote used to delimit the dynamic symbol
|
4582
4617
|
attr_reader :quote
|
4583
4618
|
|
4584
4619
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -4776,7 +4811,7 @@ module SyntaxTree
|
|
4776
4811
|
# end
|
4777
4812
|
#
|
4778
4813
|
class Elsif < Node
|
4779
|
-
# [
|
4814
|
+
# [Node] the expression to be checked
|
4780
4815
|
attr_reader :predicate
|
4781
4816
|
|
4782
4817
|
# [Statements] the expressions to be executed
|
@@ -4872,6 +4907,25 @@ module SyntaxTree
|
|
4872
4907
|
def initialize(value:, location:)
|
4873
4908
|
@value = value
|
4874
4909
|
@location = location
|
4910
|
+
|
4911
|
+
@leading = false
|
4912
|
+
@trailing = false
|
4913
|
+
end
|
4914
|
+
|
4915
|
+
def leading!
|
4916
|
+
@leading = true
|
4917
|
+
end
|
4918
|
+
|
4919
|
+
def leading?
|
4920
|
+
@leading
|
4921
|
+
end
|
4922
|
+
|
4923
|
+
def trailing!
|
4924
|
+
@trailing = true
|
4925
|
+
end
|
4926
|
+
|
4927
|
+
def trailing?
|
4928
|
+
@trailing
|
4875
4929
|
end
|
4876
4930
|
|
4877
4931
|
def inline?
|
@@ -4908,7 +4962,13 @@ module SyntaxTree
|
|
4908
4962
|
end
|
4909
4963
|
|
4910
4964
|
def format(q)
|
4911
|
-
q.
|
4965
|
+
if (q.parent.is_a?(DefNode) && q.parent.endless?) ||
|
4966
|
+
q.parent.is_a?(Statements)
|
4967
|
+
q.trim
|
4968
|
+
else
|
4969
|
+
q.breakable_return
|
4970
|
+
end
|
4971
|
+
|
4912
4972
|
q.text(value)
|
4913
4973
|
end
|
4914
4974
|
|
@@ -5177,7 +5237,7 @@ module SyntaxTree
|
|
5177
5237
|
# object.variable = value
|
5178
5238
|
#
|
5179
5239
|
class Field < Node
|
5180
|
-
# [
|
5240
|
+
# [Node] the parent object that owns the field being assigned
|
5181
5241
|
attr_reader :parent
|
5182
5242
|
|
5183
5243
|
# [:"::" | Op | Period] the operator being used for the assignment
|
@@ -5303,13 +5363,13 @@ module SyntaxTree
|
|
5303
5363
|
# end
|
5304
5364
|
#
|
5305
5365
|
class FndPtn < Node
|
5306
|
-
# [nil |
|
5366
|
+
# [nil | Node] the optional constant wrapper
|
5307
5367
|
attr_reader :constant
|
5308
5368
|
|
5309
5369
|
# [VarField] the splat on the left-hand side
|
5310
5370
|
attr_reader :left
|
5311
5371
|
|
5312
|
-
# [Array[
|
5372
|
+
# [Array[ Node ]] the list of positional expressions in the pattern that
|
5313
5373
|
# are being matched
|
5314
5374
|
attr_reader :values
|
5315
5375
|
|
@@ -5405,7 +5465,7 @@ module SyntaxTree
|
|
5405
5465
|
# pull values out of the object being enumerated
|
5406
5466
|
attr_reader :index
|
5407
5467
|
|
5408
|
-
# [
|
5468
|
+
# [Node] the object being enumerated in the loop
|
5409
5469
|
attr_reader :collection
|
5410
5470
|
|
5411
5471
|
# [Statements] the statements to be executed
|
@@ -5884,7 +5944,7 @@ module SyntaxTree
|
|
5884
5944
|
# [Label] the keyword being used
|
5885
5945
|
attr_reader :key
|
5886
5946
|
|
5887
|
-
# [
|
5947
|
+
# [Node] the optional value for the keyword
|
5888
5948
|
attr_reader :value
|
5889
5949
|
|
5890
5950
|
def initialize(key, value)
|
@@ -5897,7 +5957,7 @@ module SyntaxTree
|
|
5897
5957
|
end
|
5898
5958
|
|
5899
5959
|
def format(q)
|
5900
|
-
|
5960
|
+
HashKeyFormatter::Labels.new.format_key(q, key)
|
5901
5961
|
|
5902
5962
|
if value
|
5903
5963
|
q.text(" ")
|
@@ -5925,11 +5985,11 @@ module SyntaxTree
|
|
5925
5985
|
end
|
5926
5986
|
end
|
5927
5987
|
|
5928
|
-
# [nil |
|
5988
|
+
# [nil | Node] the optional constant wrapper
|
5929
5989
|
attr_reader :constant
|
5930
5990
|
|
5931
|
-
# [Array[ [Label,
|
5932
|
-
# that should be matched against in the pattern
|
5991
|
+
# [Array[ [DynaSymbol | Label, nil | Node] ]] the set of tuples
|
5992
|
+
# representing the keywords that should be matched against in the pattern
|
5933
5993
|
attr_reader :keywords
|
5934
5994
|
|
5935
5995
|
# [nil | VarField] an optional parameter to gather up all remaining keywords
|
@@ -6354,7 +6414,7 @@ module SyntaxTree
|
|
6354
6414
|
# end
|
6355
6415
|
#
|
6356
6416
|
class IfNode < Node
|
6357
|
-
# [
|
6417
|
+
# [Node] the expression to be checked
|
6358
6418
|
attr_reader :predicate
|
6359
6419
|
|
6360
6420
|
# [Statements] the expressions to be executed
|
@@ -6427,13 +6487,13 @@ module SyntaxTree
|
|
6427
6487
|
# predicate ? truthy : falsy
|
6428
6488
|
#
|
6429
6489
|
class IfOp < Node
|
6430
|
-
# [
|
6490
|
+
# [Node] the expression to be checked
|
6431
6491
|
attr_reader :predicate
|
6432
6492
|
|
6433
|
-
# [
|
6493
|
+
# [Node] the expression to be executed if the predicate is truthy
|
6434
6494
|
attr_reader :truthy
|
6435
6495
|
|
6436
|
-
# [
|
6496
|
+
# [Node] the expression to be executed if the predicate is falsy
|
6437
6497
|
attr_reader :falsy
|
6438
6498
|
|
6439
6499
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -6617,7 +6677,7 @@ module SyntaxTree
|
|
6617
6677
|
# end
|
6618
6678
|
#
|
6619
6679
|
class In < Node
|
6620
|
-
# [
|
6680
|
+
# [Node] the pattern to check against
|
6621
6681
|
attr_reader :pattern
|
6622
6682
|
|
6623
6683
|
# [Statements] the expressions to execute if the pattern matched
|
@@ -7400,7 +7460,7 @@ module SyntaxTree
|
|
7400
7460
|
# [MLHS | MLHSParen] the target of the multiple assignment
|
7401
7461
|
attr_reader :target
|
7402
7462
|
|
7403
|
-
# [
|
7463
|
+
# [Node] the value being assigned
|
7404
7464
|
attr_reader :value
|
7405
7465
|
|
7406
7466
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -7460,10 +7520,10 @@ module SyntaxTree
|
|
7460
7520
|
# method {}
|
7461
7521
|
#
|
7462
7522
|
class MethodAddBlock < Node
|
7463
|
-
# [
|
7523
|
+
# [ARef | CallNode | Command | CommandCall | Super | ZSuper] the method call
|
7464
7524
|
attr_reader :call
|
7465
7525
|
|
7466
|
-
# [
|
7526
|
+
# [BlockNode] the block being sent with the method call
|
7467
7527
|
attr_reader :block
|
7468
7528
|
|
7469
7529
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -7535,8 +7595,12 @@ module SyntaxTree
|
|
7535
7595
|
# first, second, third = value
|
7536
7596
|
#
|
7537
7597
|
class MLHS < Node
|
7538
|
-
#
|
7539
|
-
#
|
7598
|
+
# [
|
7599
|
+
# Array[
|
7600
|
+
# ARefField | ArgStar | ConstPathField | Field | Ident | MLHSParen |
|
7601
|
+
# TopConstField | VarField
|
7602
|
+
# ]
|
7603
|
+
# ] the parts of the left-hand side of a multiple assignment
|
7540
7604
|
attr_reader :parts
|
7541
7605
|
|
7542
7606
|
# [boolean] whether or not there is a trailing comma at the end of this
|
@@ -7762,7 +7826,7 @@ module SyntaxTree
|
|
7762
7826
|
# values = first, second, third
|
7763
7827
|
#
|
7764
7828
|
class MRHS < Node
|
7765
|
-
# Array[
|
7829
|
+
# [Array[Node]] the parts that are being assigned
|
7766
7830
|
attr_reader :parts
|
7767
7831
|
|
7768
7832
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -7938,7 +8002,7 @@ module SyntaxTree
|
|
7938
8002
|
# [Op] the operator being used for the assignment
|
7939
8003
|
attr_reader :operator
|
7940
8004
|
|
7941
|
-
# [
|
8005
|
+
# [Node] the expression to be assigned
|
7942
8006
|
attr_reader :value
|
7943
8007
|
|
7944
8008
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -8095,7 +8159,7 @@ module SyntaxTree
|
|
8095
8159
|
# [Ident] the name of the parameter
|
8096
8160
|
attr_reader :name
|
8097
8161
|
|
8098
|
-
# [
|
8162
|
+
# [Node] the value of the parameter
|
8099
8163
|
attr_reader :value
|
8100
8164
|
|
8101
8165
|
def initialize(name, value)
|
@@ -8120,7 +8184,7 @@ module SyntaxTree
|
|
8120
8184
|
# [Ident] the name of the parameter
|
8121
8185
|
attr_reader :name
|
8122
8186
|
|
8123
|
-
# [nil |
|
8187
|
+
# [nil | Node] the value of the parameter
|
8124
8188
|
attr_reader :value
|
8125
8189
|
|
8126
8190
|
def initialize(name, value)
|
@@ -8161,10 +8225,10 @@ module SyntaxTree
|
|
8161
8225
|
end
|
8162
8226
|
end
|
8163
8227
|
|
8164
|
-
# [Array[ Ident ]] any required parameters
|
8228
|
+
# [Array[ Ident | MLHSParen ]] any required parameters
|
8165
8229
|
attr_reader :requireds
|
8166
8230
|
|
8167
|
-
# [Array[ [ Ident,
|
8231
|
+
# [Array[ [ Ident, Node ] ]] any optional parameters and their default
|
8168
8232
|
# values
|
8169
8233
|
attr_reader :optionals
|
8170
8234
|
|
@@ -8176,11 +8240,12 @@ module SyntaxTree
|
|
8176
8240
|
# parameter
|
8177
8241
|
attr_reader :posts
|
8178
8242
|
|
8179
|
-
# [Array[ [
|
8243
|
+
# [Array[ [ Label, nil | Node ] ]] any keyword parameters and their
|
8180
8244
|
# optional default values
|
8181
8245
|
attr_reader :keywords
|
8182
8246
|
|
8183
|
-
# [nil | :nil | KwRestParam] the optional keyword rest
|
8247
|
+
# [nil | :nil | ArgsForward | KwRestParam] the optional keyword rest
|
8248
|
+
# parameter
|
8184
8249
|
attr_reader :keyword_rest
|
8185
8250
|
|
8186
8251
|
# [nil | BlockArg] the optional block parameter
|
@@ -8369,7 +8434,7 @@ module SyntaxTree
|
|
8369
8434
|
# [LParen] the left parenthesis that opened this statement
|
8370
8435
|
attr_reader :lparen
|
8371
8436
|
|
8372
|
-
# [nil |
|
8437
|
+
# [nil | Node] the expression inside the parentheses
|
8373
8438
|
attr_reader :contents
|
8374
8439
|
|
8375
8440
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -9218,7 +9283,7 @@ module SyntaxTree
|
|
9218
9283
|
# end
|
9219
9284
|
#
|
9220
9285
|
class RescueEx < Node
|
9221
|
-
# [
|
9286
|
+
# [nil | Node] the list of exceptions being rescued
|
9222
9287
|
attr_reader :exceptions
|
9223
9288
|
|
9224
9289
|
# [nil | Field | VarField] the expression being used to capture the raised
|
@@ -9296,7 +9361,7 @@ module SyntaxTree
|
|
9296
9361
|
# [Kw] the rescue keyword
|
9297
9362
|
attr_reader :keyword
|
9298
9363
|
|
9299
|
-
# [RescueEx] the exceptions being rescued
|
9364
|
+
# [nil | RescueEx] the exceptions being rescued
|
9300
9365
|
attr_reader :exception
|
9301
9366
|
|
9302
9367
|
# [Statements] the expressions to evaluate when an error is rescued
|
@@ -9416,10 +9481,10 @@ module SyntaxTree
|
|
9416
9481
|
# expression rescue value
|
9417
9482
|
#
|
9418
9483
|
class RescueMod < Node
|
9419
|
-
# [
|
9484
|
+
# [Node] the expression to execute
|
9420
9485
|
attr_reader :statement
|
9421
9486
|
|
9422
|
-
# [
|
9487
|
+
# [Node] the value to use if the executed expression raises an error
|
9423
9488
|
attr_reader :value
|
9424
9489
|
|
9425
9490
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -9678,7 +9743,7 @@ module SyntaxTree
|
|
9678
9743
|
# end
|
9679
9744
|
#
|
9680
9745
|
class SClass < Node
|
9681
|
-
# [
|
9746
|
+
# [Node] the target of the singleton class to enter
|
9682
9747
|
attr_reader :target
|
9683
9748
|
|
9684
9749
|
# [BodyStmt] the expressions to be executed
|
@@ -9752,23 +9817,19 @@ module SyntaxTree
|
|
9752
9817
|
# propagate that onto void_stmt nodes inside the stmts in order to make sure
|
9753
9818
|
# all comments get printed appropriately.
|
9754
9819
|
class Statements < Node
|
9755
|
-
# [
|
9756
|
-
attr_reader :parser
|
9757
|
-
|
9758
|
-
# [Array[ untyped ]] the list of expressions contained within this node
|
9820
|
+
# [Array[ Node ]] the list of expressions contained within this node
|
9759
9821
|
attr_reader :body
|
9760
9822
|
|
9761
9823
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
9762
9824
|
attr_reader :comments
|
9763
9825
|
|
9764
|
-
def initialize(
|
9765
|
-
@parser = parser
|
9826
|
+
def initialize(body:, location:)
|
9766
9827
|
@body = body
|
9767
9828
|
@location = location
|
9768
9829
|
@comments = []
|
9769
9830
|
end
|
9770
9831
|
|
9771
|
-
def bind(start_char, start_column, end_char, end_column)
|
9832
|
+
def bind(parser, start_char, start_column, end_char, end_column)
|
9772
9833
|
@location =
|
9773
9834
|
Location.new(
|
9774
9835
|
start_line: location.start_line,
|
@@ -9794,7 +9855,7 @@ module SyntaxTree
|
|
9794
9855
|
body[0] = VoidStmt.new(location: location)
|
9795
9856
|
end
|
9796
9857
|
|
9797
|
-
attach_comments(start_char, end_char)
|
9858
|
+
attach_comments(parser, start_char, end_char)
|
9798
9859
|
end
|
9799
9860
|
|
9800
9861
|
def bind_end(end_char, end_column)
|
@@ -9826,7 +9887,6 @@ module SyntaxTree
|
|
9826
9887
|
def copy(body: nil, location: nil)
|
9827
9888
|
node =
|
9828
9889
|
Statements.new(
|
9829
|
-
parser,
|
9830
9890
|
body: body || self.body,
|
9831
9891
|
location: location || self.location
|
9832
9892
|
)
|
@@ -9838,7 +9898,7 @@ module SyntaxTree
|
|
9838
9898
|
alias deconstruct child_nodes
|
9839
9899
|
|
9840
9900
|
def deconstruct_keys(_keys)
|
9841
|
-
{
|
9901
|
+
{ body: body, location: location, comments: comments }
|
9842
9902
|
end
|
9843
9903
|
|
9844
9904
|
def format(q)
|
@@ -9898,7 +9958,7 @@ module SyntaxTree
|
|
9898
9958
|
# As efficiently as possible, gather up all of the comments that have been
|
9899
9959
|
# found while this statements list was being parsed and add them into the
|
9900
9960
|
# body.
|
9901
|
-
def attach_comments(start_char, end_char)
|
9961
|
+
def attach_comments(parser, start_char, end_char)
|
9902
9962
|
parser_comments = parser.comments
|
9903
9963
|
|
9904
9964
|
comment_index = 0
|
@@ -9945,9 +10005,13 @@ module SyntaxTree
|
|
9945
10005
|
# string
|
9946
10006
|
attr_reader :parts
|
9947
10007
|
|
10008
|
+
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
10009
|
+
attr_reader :comments
|
10010
|
+
|
9948
10011
|
def initialize(parts:, location:)
|
9949
10012
|
@parts = parts
|
9950
10013
|
@location = location
|
10014
|
+
@comments = []
|
9951
10015
|
end
|
9952
10016
|
|
9953
10017
|
def accept(visitor)
|
@@ -9974,6 +10038,33 @@ module SyntaxTree
|
|
9974
10038
|
def ===(other)
|
9975
10039
|
other.is_a?(StringContent) && ArrayMatch.call(parts, other.parts)
|
9976
10040
|
end
|
10041
|
+
|
10042
|
+
def format(q)
|
10043
|
+
q.text(q.quote)
|
10044
|
+
q.group do
|
10045
|
+
parts.each do |part|
|
10046
|
+
if part.is_a?(TStringContent)
|
10047
|
+
value = Quotes.normalize(part.value, q.quote)
|
10048
|
+
first = true
|
10049
|
+
|
10050
|
+
value.each_line(chomp: true) do |line|
|
10051
|
+
if first
|
10052
|
+
first = false
|
10053
|
+
else
|
10054
|
+
q.breakable_return
|
10055
|
+
end
|
10056
|
+
|
10057
|
+
q.text(line)
|
10058
|
+
end
|
10059
|
+
|
10060
|
+
q.breakable_return if value.end_with?("\n")
|
10061
|
+
else
|
10062
|
+
q.format(part)
|
10063
|
+
end
|
10064
|
+
end
|
10065
|
+
end
|
10066
|
+
q.text(q.quote)
|
10067
|
+
end
|
9977
10068
|
end
|
9978
10069
|
|
9979
10070
|
# StringConcat represents concatenating two strings together using a backward
|
@@ -9983,7 +10074,8 @@ module SyntaxTree
|
|
9983
10074
|
# "second"
|
9984
10075
|
#
|
9985
10076
|
class StringConcat < Node
|
9986
|
-
# [StringConcat | StringLiteral] the left side of the
|
10077
|
+
# [Heredoc | StringConcat | StringLiteral] the left side of the
|
10078
|
+
# concatenation
|
9987
10079
|
attr_reader :left
|
9988
10080
|
|
9989
10081
|
# [StringLiteral] the right side of the concatenation
|
@@ -10180,7 +10272,7 @@ module SyntaxTree
|
|
10180
10272
|
# string literal
|
10181
10273
|
attr_reader :parts
|
10182
10274
|
|
10183
|
-
# [String] which quote was used by the string literal
|
10275
|
+
# [nil | String] which quote was used by the string literal
|
10184
10276
|
attr_reader :quote
|
10185
10277
|
|
10186
10278
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -10425,8 +10517,8 @@ module SyntaxTree
|
|
10425
10517
|
# :symbol
|
10426
10518
|
#
|
10427
10519
|
class SymbolLiteral < Node
|
10428
|
-
# [Backtick | Const | CVar | GVar | Ident | IVar | Kw | Op
|
10429
|
-
# symbol
|
10520
|
+
# [Backtick | Const | CVar | GVar | Ident | IVar | Kw | Op | TStringContent]
|
10521
|
+
# the value of the symbol
|
10430
10522
|
attr_reader :value
|
10431
10523
|
|
10432
10524
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -10465,6 +10557,7 @@ module SyntaxTree
|
|
10465
10557
|
|
10466
10558
|
def format(q)
|
10467
10559
|
q.text(":")
|
10560
|
+
q.text("\\") if value.comments.any?
|
10468
10561
|
q.format(value)
|
10469
10562
|
end
|
10470
10563
|
|
@@ -10934,7 +11027,7 @@ module SyntaxTree
|
|
10934
11027
|
# not value
|
10935
11028
|
#
|
10936
11029
|
class Not < Node
|
10937
|
-
# [nil |
|
11030
|
+
# [nil | Node] the statement on which to operate
|
10938
11031
|
attr_reader :statement
|
10939
11032
|
|
10940
11033
|
# [boolean] whether or not parentheses were used
|
@@ -11021,7 +11114,7 @@ module SyntaxTree
|
|
11021
11114
|
# [String] the operator being used
|
11022
11115
|
attr_reader :operator
|
11023
11116
|
|
11024
|
-
# [
|
11117
|
+
# [Node] the statement on which to operate
|
11025
11118
|
attr_reader :statement
|
11026
11119
|
|
11027
11120
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -11165,7 +11258,7 @@ module SyntaxTree
|
|
11165
11258
|
# end
|
11166
11259
|
#
|
11167
11260
|
class UnlessNode < Node
|
11168
|
-
# [
|
11261
|
+
# [Node] the expression to be checked
|
11169
11262
|
attr_reader :predicate
|
11170
11263
|
|
11171
11264
|
# [Statements] the expressions to be executed
|
@@ -11311,7 +11404,7 @@ module SyntaxTree
|
|
11311
11404
|
# end
|
11312
11405
|
#
|
11313
11406
|
class UntilNode < Node
|
11314
|
-
# [
|
11407
|
+
# [Node] the expression to be checked
|
11315
11408
|
attr_reader :predicate
|
11316
11409
|
|
11317
11410
|
# [Statements] the expressions to be executed
|
@@ -11379,7 +11472,7 @@ module SyntaxTree
|
|
11379
11472
|
#
|
11380
11473
|
# In the example above, the VarField node represents the +variable+ token.
|
11381
11474
|
class VarField < Node
|
11382
|
-
# [nil | Const | CVar | GVar | Ident | IVar] the target of this node
|
11475
|
+
# [nil | :nil | Const | CVar | GVar | Ident | IVar] the target of this node
|
11383
11476
|
attr_reader :value
|
11384
11477
|
|
11385
11478
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -11490,8 +11583,9 @@ module SyntaxTree
|
|
11490
11583
|
#
|
11491
11584
|
# To be clear, this method should just not exist. It's not good. It's a
|
11492
11585
|
# place of shame. But it's necessary for now, so I'm keeping it.
|
11493
|
-
def pin(parent)
|
11494
|
-
replace =
|
11586
|
+
def pin(parent, pin)
|
11587
|
+
replace =
|
11588
|
+
PinnedVarRef.new(value: value, location: pin.location.to(location))
|
11495
11589
|
|
11496
11590
|
parent
|
11497
11591
|
.deconstruct_keys([])
|
@@ -11517,7 +11611,7 @@ module SyntaxTree
|
|
11517
11611
|
# This can be a plain local variable like the example above. It can also be a
|
11518
11612
|
# a class variable, a global variable, or an instance variable.
|
11519
11613
|
class PinnedVarRef < Node
|
11520
|
-
# [
|
11614
|
+
# [Const | CVar | GVar | Ident | IVar] the value of this node
|
11521
11615
|
attr_reader :value
|
11522
11616
|
|
11523
11617
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
@@ -11631,9 +11725,6 @@ module SyntaxTree
|
|
11631
11725
|
# ;;
|
11632
11726
|
#
|
11633
11727
|
class VoidStmt < Node
|
11634
|
-
# [Location] the location of this node
|
11635
|
-
attr_reader :location
|
11636
|
-
|
11637
11728
|
# [Array[ Comment | EmbDoc ]] the comments attached to this node
|
11638
11729
|
attr_reader :comments
|
11639
11730
|
|
@@ -11794,7 +11885,7 @@ module SyntaxTree
|
|
11794
11885
|
# end
|
11795
11886
|
#
|
11796
11887
|
class WhileNode < Node
|
11797
|
-
# [
|
11888
|
+
# [Node] the expression to be checked
|
11798
11889
|
attr_reader :predicate
|
11799
11890
|
|
11800
11891
|
# [Statements] the expressions to be executed
|