syntax_tree 2.0.0 → 2.1.1
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 +9 -1
- data/.gitignore +1 -0
- data/CHANGELOG.md +41 -6
- data/Gemfile.lock +5 -3
- data/README.md +290 -32
- data/lib/syntax_tree/cli.rb +46 -45
- data/lib/syntax_tree/language_server/inlay_hints.rb +0 -16
- data/lib/syntax_tree/node.rb +1021 -3618
- data/lib/syntax_tree/parser.rb +265 -130
- data/lib/syntax_tree/version.rb +1 -1
- data/lib/syntax_tree/visitor/json_visitor.rb +1335 -0
- data/lib/syntax_tree/visitor/pretty_print_visitor.rb +1213 -0
- data/lib/syntax_tree/visitor.rb +548 -0
- data/lib/syntax_tree.rb +15 -0
- metadata +5 -3
- data/bin/setup +0 -6
data/lib/syntax_tree/parser.rb
CHANGED
@@ -163,6 +163,13 @@ module SyntaxTree
|
|
163
163
|
line_counts[lineno - 1][column]
|
164
164
|
end
|
165
165
|
|
166
|
+
# This represents the current column we're in relative to the beginning of
|
167
|
+
# the current line.
|
168
|
+
def current_column
|
169
|
+
line = line_counts[lineno - 1]
|
170
|
+
line[column].to_i - line.start
|
171
|
+
end
|
172
|
+
|
166
173
|
# As we build up a list of tokens, we'll periodically need to go backwards
|
167
174
|
# and find the ones that we've already hit in order to determine the
|
168
175
|
# location information for nodes that use them. For example, if you have a
|
@@ -251,10 +258,13 @@ module SyntaxTree
|
|
251
258
|
def on_BEGIN(statements)
|
252
259
|
lbrace = find_token(LBrace)
|
253
260
|
rbrace = find_token(RBrace)
|
261
|
+
start_char = find_next_statement_start(lbrace.location.end_char)
|
254
262
|
|
255
263
|
statements.bind(
|
256
|
-
|
257
|
-
|
264
|
+
start_char,
|
265
|
+
start_char - line_counts[lbrace.location.start_line - 1].start,
|
266
|
+
rbrace.location.start_char,
|
267
|
+
rbrace.location.start_column,
|
258
268
|
)
|
259
269
|
|
260
270
|
keyword = find_token(Kw, "BEGIN")
|
@@ -271,7 +281,7 @@ module SyntaxTree
|
|
271
281
|
def on_CHAR(value)
|
272
282
|
CHAR.new(
|
273
283
|
value: value,
|
274
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
284
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
275
285
|
)
|
276
286
|
end
|
277
287
|
|
@@ -280,10 +290,13 @@ module SyntaxTree
|
|
280
290
|
def on_END(statements)
|
281
291
|
lbrace = find_token(LBrace)
|
282
292
|
rbrace = find_token(RBrace)
|
293
|
+
start_char = find_next_statement_start(lbrace.location.end_char)
|
283
294
|
|
284
295
|
statements.bind(
|
285
|
-
|
286
|
-
|
296
|
+
start_char,
|
297
|
+
start_char - line_counts[lbrace.location.start_line - 1].start,
|
298
|
+
rbrace.location.start_char,
|
299
|
+
rbrace.location.start_column
|
287
300
|
)
|
288
301
|
|
289
302
|
keyword = find_token(Kw, "END")
|
@@ -301,7 +314,7 @@ module SyntaxTree
|
|
301
314
|
@__end__ =
|
302
315
|
EndContent.new(
|
303
316
|
value: source[(char_pos + value.length)..-1],
|
304
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
317
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
305
318
|
)
|
306
319
|
end
|
307
320
|
|
@@ -401,12 +414,19 @@ module SyntaxTree
|
|
401
414
|
# (false | untyped) block
|
402
415
|
# ) -> Args
|
403
416
|
def on_args_add_block(arguments, block)
|
417
|
+
# First, see if there is an & operator that could potentially be
|
418
|
+
# associated with the block part of this args_add_block. If there is not,
|
419
|
+
# then just return the arguments.
|
404
420
|
operator = find_token(Op, "&", consume: false)
|
405
|
-
|
406
|
-
# If we can't find the & operator, then there's no block to add to the
|
407
|
-
# list, so we're just going to return the arguments as-is.
|
408
421
|
return arguments unless operator
|
409
422
|
|
423
|
+
# If there are any arguments and the operator we found from the list is
|
424
|
+
# not after them, then we're going to return the arguments as-is because
|
425
|
+
# we're looking at an & that occurs before the arguments are done.
|
426
|
+
if arguments.parts.any? && operator.location.start_char < arguments.location.end_char
|
427
|
+
return arguments
|
428
|
+
end
|
429
|
+
|
410
430
|
# Now we know we have an & operator, so we're going to delete it from the
|
411
431
|
# list of tokens to make sure it doesn't get confused with anything else.
|
412
432
|
tokens.delete(operator)
|
@@ -415,13 +435,6 @@ module SyntaxTree
|
|
415
435
|
location = operator.location
|
416
436
|
location = operator.location.to(block.location) if block
|
417
437
|
|
418
|
-
# If there are any arguments and the operator we found from the list is
|
419
|
-
# not after them, then we're going to return the arguments as-is because
|
420
|
-
# we're looking at an & that occurs before the arguments are done.
|
421
|
-
if arguments.parts.any? && location.start_char < arguments.location.end_char
|
422
|
-
return arguments
|
423
|
-
end
|
424
|
-
|
425
438
|
# Otherwise, we're looking at an actual block argument (with or without a
|
426
439
|
# block, which could be missing because it could be a bare & since 3.1.0).
|
427
440
|
arg_block = ArgBlock.new(value: block, location: location)
|
@@ -465,7 +478,7 @@ module SyntaxTree
|
|
465
478
|
# :call-seq:
|
466
479
|
# on_args_new: () -> Args
|
467
480
|
def on_args_new
|
468
|
-
Args.new(parts: [], location: Location.fixed(line: lineno, char: char_pos))
|
481
|
+
Args.new(parts: [], location: Location.fixed(line: lineno, column: current_column, char: char_pos))
|
469
482
|
end
|
470
483
|
|
471
484
|
# :call-seq:
|
@@ -551,7 +564,7 @@ module SyntaxTree
|
|
551
564
|
def on_backref(value)
|
552
565
|
Backref.new(
|
553
566
|
value: value,
|
554
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
567
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
555
568
|
)
|
556
569
|
end
|
557
570
|
|
@@ -561,7 +574,7 @@ module SyntaxTree
|
|
561
574
|
node =
|
562
575
|
Backtick.new(
|
563
576
|
value: value,
|
564
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
577
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
565
578
|
)
|
566
579
|
|
567
580
|
tokens << node
|
@@ -592,15 +605,20 @@ module SyntaxTree
|
|
592
605
|
PinnedBegin.new(statement: bodystmt, location: location)
|
593
606
|
else
|
594
607
|
keyword = find_token(Kw, "begin")
|
595
|
-
|
608
|
+
end_location =
|
596
609
|
if bodystmt.rescue_clause || bodystmt.ensure_clause ||
|
597
610
|
bodystmt.else_clause
|
598
|
-
bodystmt.location
|
611
|
+
bodystmt.location
|
599
612
|
else
|
600
|
-
find_token(Kw, "end").location
|
613
|
+
find_token(Kw, "end").location
|
601
614
|
end
|
602
615
|
|
603
|
-
bodystmt.bind(
|
616
|
+
bodystmt.bind(
|
617
|
+
keyword.location.end_char,
|
618
|
+
keyword.location.end_column,
|
619
|
+
end_location.end_char,
|
620
|
+
end_location.end_column
|
621
|
+
)
|
604
622
|
location = keyword.location.to(bodystmt.location)
|
605
623
|
|
606
624
|
Begin.new(bodystmt: bodystmt, location: location)
|
@@ -682,9 +700,10 @@ module SyntaxTree
|
|
682
700
|
BodyStmt.new(
|
683
701
|
statements: statements,
|
684
702
|
rescue_clause: rescue_clause,
|
703
|
+
else_keyword: else_clause && find_token(Kw, "else"),
|
685
704
|
else_clause: else_clause,
|
686
705
|
ensure_clause: ensure_clause,
|
687
|
-
location: Location.fixed(line: lineno, char: char_pos)
|
706
|
+
location: Location.fixed(line: lineno, char: char_pos, column: current_column)
|
688
707
|
)
|
689
708
|
end
|
690
709
|
|
@@ -696,18 +715,24 @@ module SyntaxTree
|
|
696
715
|
def on_brace_block(block_var, statements)
|
697
716
|
lbrace = find_token(LBrace)
|
698
717
|
rbrace = find_token(RBrace)
|
718
|
+
location = (block_var || lbrace).location
|
719
|
+
start_char = find_next_statement_start(location.end_char)
|
699
720
|
|
700
721
|
statements.bind(
|
701
|
-
|
702
|
-
|
722
|
+
start_char,
|
723
|
+
start_char - line_counts[location.start_line - 1].start,
|
724
|
+
rbrace.location.start_char,
|
725
|
+
rbrace.location.start_column
|
703
726
|
)
|
704
727
|
|
705
728
|
location =
|
706
729
|
Location.new(
|
707
730
|
start_line: lbrace.location.start_line,
|
708
731
|
start_char: lbrace.location.start_char,
|
732
|
+
start_column: lbrace.location.start_column,
|
709
733
|
end_line: [rbrace.location.end_line, statements.location.end_line].max,
|
710
|
-
end_char: rbrace.location.end_char
|
734
|
+
end_char: rbrace.location.end_char,
|
735
|
+
end_column: rbrace.location.end_column
|
711
736
|
)
|
712
737
|
|
713
738
|
BraceBlock.new(
|
@@ -736,8 +761,14 @@ module SyntaxTree
|
|
736
761
|
# (:call | Backtick | Const | Ident | Op) message
|
737
762
|
# ) -> Call
|
738
763
|
def on_call(receiver, operator, message)
|
739
|
-
ending =
|
740
|
-
|
764
|
+
ending =
|
765
|
+
if message != :call
|
766
|
+
message
|
767
|
+
elsif operator != :"::"
|
768
|
+
operator
|
769
|
+
else
|
770
|
+
receiver
|
771
|
+
end
|
741
772
|
|
742
773
|
Call.new(
|
743
774
|
receiver: receiver,
|
@@ -781,10 +812,14 @@ module SyntaxTree
|
|
781
812
|
def on_class(constant, superclass, bodystmt)
|
782
813
|
beginning = find_token(Kw, "class")
|
783
814
|
ending = find_token(Kw, "end")
|
815
|
+
location = (superclass || constant).location
|
816
|
+
start_char = find_next_statement_start(location.end_char)
|
784
817
|
|
785
818
|
bodystmt.bind(
|
786
|
-
|
787
|
-
|
819
|
+
start_char,
|
820
|
+
start_char - line_counts[location.start_line - 1].start,
|
821
|
+
ending.location.start_char,
|
822
|
+
ending.location.start_column
|
788
823
|
)
|
789
824
|
|
790
825
|
ClassDeclaration.new(
|
@@ -801,7 +836,7 @@ module SyntaxTree
|
|
801
836
|
node =
|
802
837
|
Comma.new(
|
803
838
|
value: value,
|
804
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
839
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
805
840
|
)
|
806
841
|
|
807
842
|
tokens << node
|
@@ -846,7 +881,7 @@ module SyntaxTree
|
|
846
881
|
value: value.chomp,
|
847
882
|
inline: value.strip != lines[line - 1].strip,
|
848
883
|
location:
|
849
|
-
Location.token(line: line, char: char_pos, size: value.size - 1)
|
884
|
+
Location.token(line: line, char: char_pos, column: current_column, size: value.size - 1)
|
850
885
|
)
|
851
886
|
|
852
887
|
@comments << comment
|
@@ -858,7 +893,7 @@ module SyntaxTree
|
|
858
893
|
def on_const(value)
|
859
894
|
Const.new(
|
860
895
|
value: value,
|
861
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
896
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
862
897
|
)
|
863
898
|
end
|
864
899
|
|
@@ -893,7 +928,7 @@ module SyntaxTree
|
|
893
928
|
def on_cvar(value)
|
894
929
|
CVar.new(
|
895
930
|
value: value,
|
896
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
931
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
897
932
|
)
|
898
933
|
end
|
899
934
|
|
@@ -917,12 +952,15 @@ module SyntaxTree
|
|
917
952
|
# location information
|
918
953
|
if params.is_a?(Params) && params.empty?
|
919
954
|
end_char = name.location.end_char
|
955
|
+
end_column = name.location.end_column
|
920
956
|
location =
|
921
957
|
Location.new(
|
922
958
|
start_line: params.location.start_line,
|
923
959
|
start_char: end_char,
|
960
|
+
start_column: end_column,
|
924
961
|
end_line: params.location.end_line,
|
925
|
-
end_char: end_char
|
962
|
+
end_char: end_char,
|
963
|
+
end_column: end_column
|
926
964
|
)
|
927
965
|
|
928
966
|
params = Params.new(location: location)
|
@@ -932,9 +970,13 @@ module SyntaxTree
|
|
932
970
|
|
933
971
|
if ending
|
934
972
|
tokens.delete(ending)
|
973
|
+
start_char = find_next_statement_start(params.location.end_char)
|
974
|
+
|
935
975
|
bodystmt.bind(
|
936
|
-
|
937
|
-
|
976
|
+
start_char,
|
977
|
+
start_char - line_counts[params.location.start_line - 1].start,
|
978
|
+
ending.location.start_char,
|
979
|
+
ending.location.start_column
|
938
980
|
)
|
939
981
|
|
940
982
|
Def.new(
|
@@ -992,12 +1034,15 @@ module SyntaxTree
|
|
992
1034
|
# location information
|
993
1035
|
if params.is_a?(Params) && params.empty?
|
994
1036
|
end_char = name.location.end_char
|
1037
|
+
end_column = name.location.end_column
|
995
1038
|
location =
|
996
1039
|
Location.new(
|
997
1040
|
start_line: params.location.start_line,
|
998
1041
|
start_char: end_char,
|
1042
|
+
start_column: end_column,
|
999
1043
|
end_line: params.location.end_line,
|
1000
|
-
end_char: end_char
|
1044
|
+
end_char: end_char,
|
1045
|
+
end_column: end_column
|
1001
1046
|
)
|
1002
1047
|
|
1003
1048
|
params = Params.new(location: location)
|
@@ -1008,9 +1053,13 @@ module SyntaxTree
|
|
1008
1053
|
|
1009
1054
|
if ending
|
1010
1055
|
tokens.delete(ending)
|
1056
|
+
start_char = find_next_statement_start(params.location.end_char)
|
1057
|
+
|
1011
1058
|
bodystmt.bind(
|
1012
|
-
|
1013
|
-
|
1059
|
+
start_char,
|
1060
|
+
start_char - line_counts[params.location.start_line - 1].start,
|
1061
|
+
ending.location.start_char,
|
1062
|
+
ending.location.start_column
|
1014
1063
|
)
|
1015
1064
|
|
1016
1065
|
Defs.new(
|
@@ -1042,10 +1091,14 @@ module SyntaxTree
|
|
1042
1091
|
def on_do_block(block_var, bodystmt)
|
1043
1092
|
beginning = find_token(Kw, "do")
|
1044
1093
|
ending = find_token(Kw, "end")
|
1094
|
+
location = (block_var || beginning).location
|
1095
|
+
start_char = find_next_statement_start(location.end_char)
|
1045
1096
|
|
1046
1097
|
bodystmt.bind(
|
1047
|
-
|
1048
|
-
|
1098
|
+
start_char,
|
1099
|
+
start_char - line_counts[location.start_line - 1].start,
|
1100
|
+
ending.location.start_char,
|
1101
|
+
ending.location.start_column
|
1049
1102
|
)
|
1050
1103
|
|
1051
1104
|
DoBlock.new(
|
@@ -1115,7 +1168,7 @@ module SyntaxTree
|
|
1115
1168
|
# :call-seq:
|
1116
1169
|
# on_else: (Statements statements) -> Else
|
1117
1170
|
def on_else(statements)
|
1118
|
-
|
1171
|
+
keyword = find_token(Kw, "else")
|
1119
1172
|
|
1120
1173
|
# else can either end with an end keyword (in which case we'll want to
|
1121
1174
|
# consume that event) or it can end with an ensure keyword (in which case
|
@@ -1127,13 +1180,19 @@ module SyntaxTree
|
|
1127
1180
|
|
1128
1181
|
node = tokens[index]
|
1129
1182
|
ending = node.value == "end" ? tokens.delete_at(index) : node
|
1130
|
-
|
1183
|
+
start_char = find_next_statement_start(keyword.location.end_char)
|
1131
1184
|
|
1132
|
-
statements.bind(
|
1185
|
+
statements.bind(
|
1186
|
+
start_char,
|
1187
|
+
start_char - line_counts[keyword.location.start_line - 1].start,
|
1188
|
+
ending.location.start_char,
|
1189
|
+
ending.location.start_column
|
1190
|
+
)
|
1133
1191
|
|
1134
1192
|
Else.new(
|
1193
|
+
keyword: keyword,
|
1135
1194
|
statements: statements,
|
1136
|
-
location:
|
1195
|
+
location: keyword.location.to(ending.location)
|
1137
1196
|
)
|
1138
1197
|
end
|
1139
1198
|
|
@@ -1147,7 +1206,12 @@ module SyntaxTree
|
|
1147
1206
|
beginning = find_token(Kw, "elsif")
|
1148
1207
|
ending = consequent || find_token(Kw, "end")
|
1149
1208
|
|
1150
|
-
statements.bind(
|
1209
|
+
statements.bind(
|
1210
|
+
predicate.location.end_char,
|
1211
|
+
predicate.location.end_column,
|
1212
|
+
ending.location.start_char,
|
1213
|
+
ending.location.start_column
|
1214
|
+
)
|
1151
1215
|
|
1152
1216
|
Elsif.new(
|
1153
1217
|
predicate: predicate,
|
@@ -1170,7 +1234,7 @@ module SyntaxTree
|
|
1170
1234
|
@embdoc =
|
1171
1235
|
EmbDoc.new(
|
1172
1236
|
value: value,
|
1173
|
-
location: Location.fixed(line: lineno, char: char_pos)
|
1237
|
+
location: Location.fixed(line: lineno, column: current_column, char: char_pos)
|
1174
1238
|
)
|
1175
1239
|
end
|
1176
1240
|
|
@@ -1185,8 +1249,10 @@ module SyntaxTree
|
|
1185
1249
|
Location.new(
|
1186
1250
|
start_line: location.start_line,
|
1187
1251
|
start_char: location.start_char,
|
1252
|
+
start_column: location.start_column,
|
1188
1253
|
end_line: lineno,
|
1189
|
-
end_char: char_pos + value.length - 1
|
1254
|
+
end_char: char_pos + value.length - 1,
|
1255
|
+
end_column: current_column + value.length - 1
|
1190
1256
|
)
|
1191
1257
|
)
|
1192
1258
|
|
@@ -1202,7 +1268,7 @@ module SyntaxTree
|
|
1202
1268
|
node =
|
1203
1269
|
EmbExprBeg.new(
|
1204
1270
|
value: value,
|
1205
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1271
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1206
1272
|
)
|
1207
1273
|
|
1208
1274
|
tokens << node
|
@@ -1215,7 +1281,7 @@ module SyntaxTree
|
|
1215
1281
|
node =
|
1216
1282
|
EmbExprEnd.new(
|
1217
1283
|
value: value,
|
1218
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1284
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1219
1285
|
)
|
1220
1286
|
|
1221
1287
|
tokens << node
|
@@ -1228,7 +1294,7 @@ module SyntaxTree
|
|
1228
1294
|
node =
|
1229
1295
|
EmbVar.new(
|
1230
1296
|
value: value,
|
1231
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1297
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1232
1298
|
)
|
1233
1299
|
|
1234
1300
|
tokens << node
|
@@ -1243,9 +1309,12 @@ module SyntaxTree
|
|
1243
1309
|
# We don't want to consume the :@kw event, because that would break
|
1244
1310
|
# def..ensure..end chains.
|
1245
1311
|
ending = find_token(Kw, "end", consume: false)
|
1312
|
+
start_char = find_next_statement_start(keyword.location.end_char)
|
1246
1313
|
statements.bind(
|
1247
|
-
|
1248
|
-
|
1314
|
+
start_char,
|
1315
|
+
start_char - line_counts[keyword.location.start_line - 1].start,
|
1316
|
+
ending.location.start_char,
|
1317
|
+
ending.location.start_column
|
1249
1318
|
)
|
1250
1319
|
|
1251
1320
|
Ensure.new(
|
@@ -1292,7 +1361,7 @@ module SyntaxTree
|
|
1292
1361
|
def on_float(value)
|
1293
1362
|
FloatLiteral.new(
|
1294
1363
|
value: value,
|
1295
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1364
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1296
1365
|
)
|
1297
1366
|
end
|
1298
1367
|
|
@@ -1337,7 +1406,9 @@ module SyntaxTree
|
|
1337
1406
|
|
1338
1407
|
statements.bind(
|
1339
1408
|
(keyword || collection).location.end_char,
|
1340
|
-
|
1409
|
+
(keyword || collection).location.end_column,
|
1410
|
+
ending.location.start_char,
|
1411
|
+
ending.location.start_column
|
1341
1412
|
)
|
1342
1413
|
|
1343
1414
|
if index.is_a?(MLHS)
|
@@ -1358,7 +1429,7 @@ module SyntaxTree
|
|
1358
1429
|
def on_gvar(value)
|
1359
1430
|
GVar.new(
|
1360
1431
|
value: value,
|
1361
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1432
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1362
1433
|
)
|
1363
1434
|
end
|
1364
1435
|
|
@@ -1379,7 +1450,7 @@ module SyntaxTree
|
|
1379
1450
|
# on_heredoc_beg: (String value) -> HeredocBeg
|
1380
1451
|
def on_heredoc_beg(value)
|
1381
1452
|
location =
|
1382
|
-
Location.token(line: lineno, char: char_pos, size: value.size + 1)
|
1453
|
+
Location.token(line: lineno, char: char_pos, column: current_column, size: value.size + 1)
|
1383
1454
|
|
1384
1455
|
# Here we're going to artificially create an extra node type so that if
|
1385
1456
|
# there are comments after the declaration of a heredoc, they get printed.
|
@@ -1415,8 +1486,10 @@ module SyntaxTree
|
|
1415
1486
|
Location.new(
|
1416
1487
|
start_line: heredoc.location.start_line,
|
1417
1488
|
start_char: heredoc.location.start_char,
|
1489
|
+
start_column: heredoc.location.start_column,
|
1418
1490
|
end_line: lineno,
|
1419
|
-
end_char: char_pos
|
1491
|
+
end_char: char_pos,
|
1492
|
+
end_column: current_column,
|
1420
1493
|
)
|
1421
1494
|
)
|
1422
1495
|
end
|
@@ -1428,13 +1501,19 @@ module SyntaxTree
|
|
1428
1501
|
# (nil | VarField) keyword_rest
|
1429
1502
|
# ) -> HshPtn
|
1430
1503
|
def on_hshptn(constant, keywords, keyword_rest)
|
1431
|
-
parts = [constant, keywords, keyword_rest].
|
1504
|
+
parts = [constant, *keywords&.flatten(1), keyword_rest].compact
|
1505
|
+
location =
|
1506
|
+
if parts.empty?
|
1507
|
+
find_token(LBrace).location.to(find_token(RBrace).location)
|
1508
|
+
else
|
1509
|
+
parts[0].location.to(parts[-1].location)
|
1510
|
+
end
|
1432
1511
|
|
1433
1512
|
HshPtn.new(
|
1434
1513
|
constant: constant,
|
1435
|
-
keywords: keywords,
|
1514
|
+
keywords: keywords || [],
|
1436
1515
|
keyword_rest: keyword_rest,
|
1437
|
-
location:
|
1516
|
+
location: location
|
1438
1517
|
)
|
1439
1518
|
end
|
1440
1519
|
|
@@ -1443,7 +1522,7 @@ module SyntaxTree
|
|
1443
1522
|
def on_ident(value)
|
1444
1523
|
Ident.new(
|
1445
1524
|
value: value,
|
1446
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1525
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1447
1526
|
)
|
1448
1527
|
end
|
1449
1528
|
|
@@ -1457,7 +1536,12 @@ module SyntaxTree
|
|
1457
1536
|
beginning = find_token(Kw, "if")
|
1458
1537
|
ending = consequent || find_token(Kw, "end")
|
1459
1538
|
|
1460
|
-
statements.bind(
|
1539
|
+
statements.bind(
|
1540
|
+
predicate.location.end_char,
|
1541
|
+
predicate.location.end_column,
|
1542
|
+
ending.location.start_char,
|
1543
|
+
ending.location.start_column
|
1544
|
+
)
|
1461
1545
|
|
1462
1546
|
If.new(
|
1463
1547
|
predicate: predicate,
|
@@ -1503,7 +1587,7 @@ module SyntaxTree
|
|
1503
1587
|
def on_imaginary(value)
|
1504
1588
|
Imaginary.new(
|
1505
1589
|
value: value,
|
1506
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1590
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1507
1591
|
)
|
1508
1592
|
end
|
1509
1593
|
|
@@ -1527,9 +1611,12 @@ module SyntaxTree
|
|
1527
1611
|
statements_start = token
|
1528
1612
|
end
|
1529
1613
|
|
1614
|
+
start_char = find_next_statement_start(statements_start.location.end_char)
|
1530
1615
|
statements.bind(
|
1531
|
-
|
1532
|
-
|
1616
|
+
start_char,
|
1617
|
+
start_char - line_counts[statements_start.location.start_line - 1].start,
|
1618
|
+
ending.location.start_char,
|
1619
|
+
ending.location.start_column
|
1533
1620
|
)
|
1534
1621
|
|
1535
1622
|
In.new(
|
@@ -1545,7 +1632,7 @@ module SyntaxTree
|
|
1545
1632
|
def on_int(value)
|
1546
1633
|
Int.new(
|
1547
1634
|
value: value,
|
1548
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1635
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1549
1636
|
)
|
1550
1637
|
end
|
1551
1638
|
|
@@ -1554,7 +1641,7 @@ module SyntaxTree
|
|
1554
1641
|
def on_ivar(value)
|
1555
1642
|
IVar.new(
|
1556
1643
|
value: value,
|
1557
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1644
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1558
1645
|
)
|
1559
1646
|
end
|
1560
1647
|
|
@@ -1564,7 +1651,7 @@ module SyntaxTree
|
|
1564
1651
|
node =
|
1565
1652
|
Kw.new(
|
1566
1653
|
value: value,
|
1567
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1654
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1568
1655
|
)
|
1569
1656
|
|
1570
1657
|
tokens << node
|
@@ -1585,7 +1672,7 @@ module SyntaxTree
|
|
1585
1672
|
def on_label(value)
|
1586
1673
|
Label.new(
|
1587
1674
|
value: value,
|
1588
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1675
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1589
1676
|
)
|
1590
1677
|
end
|
1591
1678
|
|
@@ -1595,7 +1682,7 @@ module SyntaxTree
|
|
1595
1682
|
node =
|
1596
1683
|
LabelEnd.new(
|
1597
1684
|
value: value,
|
1598
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1685
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1599
1686
|
)
|
1600
1687
|
|
1601
1688
|
tokens << node
|
@@ -1621,7 +1708,12 @@ module SyntaxTree
|
|
1621
1708
|
closing = find_token(Kw, "end")
|
1622
1709
|
end
|
1623
1710
|
|
1624
|
-
statements.bind(
|
1711
|
+
statements.bind(
|
1712
|
+
opening.location.end_char,
|
1713
|
+
opening.location.end_column,
|
1714
|
+
closing.location.start_char,
|
1715
|
+
closing.location.start_column
|
1716
|
+
)
|
1625
1717
|
|
1626
1718
|
Lambda.new(
|
1627
1719
|
params: params,
|
@@ -1636,7 +1728,7 @@ module SyntaxTree
|
|
1636
1728
|
node =
|
1637
1729
|
LBrace.new(
|
1638
1730
|
value: value,
|
1639
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1731
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1640
1732
|
)
|
1641
1733
|
|
1642
1734
|
tokens << node
|
@@ -1649,7 +1741,7 @@ module SyntaxTree
|
|
1649
1741
|
node =
|
1650
1742
|
LBracket.new(
|
1651
1743
|
value: value,
|
1652
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1744
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1653
1745
|
)
|
1654
1746
|
|
1655
1747
|
tokens << node
|
@@ -1662,7 +1754,7 @@ module SyntaxTree
|
|
1662
1754
|
node =
|
1663
1755
|
LParen.new(
|
1664
1756
|
value: value,
|
1665
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1757
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1666
1758
|
)
|
1667
1759
|
|
1668
1760
|
tokens << node
|
@@ -1761,7 +1853,7 @@ module SyntaxTree
|
|
1761
1853
|
# :call-seq:
|
1762
1854
|
# on_mlhs_new: () -> MLHS
|
1763
1855
|
def on_mlhs_new
|
1764
|
-
MLHS.new(parts: [], location: Location.fixed(line: lineno, char: char_pos))
|
1856
|
+
MLHS.new(parts: [], location: Location.fixed(line: lineno, char: char_pos, column: current_column))
|
1765
1857
|
end
|
1766
1858
|
|
1767
1859
|
# :call-seq:
|
@@ -1787,10 +1879,13 @@ module SyntaxTree
|
|
1787
1879
|
def on_module(constant, bodystmt)
|
1788
1880
|
beginning = find_token(Kw, "module")
|
1789
1881
|
ending = find_token(Kw, "end")
|
1882
|
+
start_char = find_next_statement_start(constant.location.end_char)
|
1790
1883
|
|
1791
1884
|
bodystmt.bind(
|
1792
|
-
|
1793
|
-
|
1885
|
+
start_char,
|
1886
|
+
start_char - line_counts[constant.location.start_line - 1].start,
|
1887
|
+
ending.location.start_char,
|
1888
|
+
ending.location.start_column
|
1794
1889
|
)
|
1795
1890
|
|
1796
1891
|
ModuleDeclaration.new(
|
@@ -1803,7 +1898,7 @@ module SyntaxTree
|
|
1803
1898
|
# :call-seq:
|
1804
1899
|
# on_mrhs_new: () -> MRHS
|
1805
1900
|
def on_mrhs_new
|
1806
|
-
MRHS.new(parts: [], location: Location.fixed(line: lineno, char: char_pos))
|
1901
|
+
MRHS.new(parts: [], location: Location.fixed(line: lineno, char: char_pos, column: current_column))
|
1807
1902
|
end
|
1808
1903
|
|
1809
1904
|
# :call-seq:
|
@@ -1872,7 +1967,7 @@ module SyntaxTree
|
|
1872
1967
|
node =
|
1873
1968
|
Op.new(
|
1874
1969
|
value: value,
|
1875
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
1970
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
1876
1971
|
)
|
1877
1972
|
|
1878
1973
|
tokens << node
|
@@ -1931,7 +2026,7 @@ module SyntaxTree
|
|
1931
2026
|
if parts.any?
|
1932
2027
|
parts[0].location.to(parts[-1].location)
|
1933
2028
|
else
|
1934
|
-
Location.fixed(line: lineno, char: char_pos)
|
2029
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
1935
2030
|
end
|
1936
2031
|
|
1937
2032
|
Params.new(
|
@@ -1954,12 +2049,15 @@ module SyntaxTree
|
|
1954
2049
|
|
1955
2050
|
if contents && contents.is_a?(Params)
|
1956
2051
|
location = contents.location
|
2052
|
+
start_char = find_next_statement_start(lparen.location.end_char)
|
1957
2053
|
location =
|
1958
2054
|
Location.new(
|
1959
2055
|
start_line: location.start_line,
|
1960
|
-
start_char:
|
2056
|
+
start_char: start_char,
|
2057
|
+
start_column: start_char - line_counts[lparen.location.start_line - 1].start,
|
1961
2058
|
end_line: location.end_line,
|
1962
|
-
end_char: rparen.location.start_char
|
2059
|
+
end_char: rparen.location.start_char,
|
2060
|
+
end_column: rparen.location.start_column
|
1963
2061
|
)
|
1964
2062
|
|
1965
2063
|
contents =
|
@@ -1997,23 +2095,26 @@ module SyntaxTree
|
|
1997
2095
|
def on_period(value)
|
1998
2096
|
Period.new(
|
1999
2097
|
value: value,
|
2000
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2098
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2001
2099
|
)
|
2002
2100
|
end
|
2003
2101
|
|
2004
2102
|
# :call-seq:
|
2005
2103
|
# on_program: (Statements statements) -> Program
|
2006
2104
|
def on_program(statements)
|
2105
|
+
last_column = source.length - line_counts[lines.length - 1].start
|
2007
2106
|
location =
|
2008
2107
|
Location.new(
|
2009
2108
|
start_line: 1,
|
2010
2109
|
start_char: 0,
|
2110
|
+
start_column: 0,
|
2011
2111
|
end_line: lines.length,
|
2012
|
-
end_char: source.length
|
2112
|
+
end_char: source.length,
|
2113
|
+
end_column: last_column
|
2013
2114
|
)
|
2014
2115
|
|
2015
2116
|
statements.body << @__end__ if @__end__
|
2016
|
-
statements.bind(0, source.length)
|
2117
|
+
statements.bind(0, 0, source.length, last_column)
|
2017
2118
|
|
2018
2119
|
program = Program.new(statements: statements, location: location)
|
2019
2120
|
attach_comments(program, @comments)
|
@@ -2126,7 +2227,7 @@ module SyntaxTree
|
|
2126
2227
|
node =
|
2127
2228
|
QSymbolsBeg.new(
|
2128
2229
|
value: value,
|
2129
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2230
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2130
2231
|
)
|
2131
2232
|
|
2132
2233
|
tokens << node
|
@@ -2161,7 +2262,7 @@ module SyntaxTree
|
|
2161
2262
|
node =
|
2162
2263
|
QWordsBeg.new(
|
2163
2264
|
value: value,
|
2164
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2265
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2165
2266
|
)
|
2166
2267
|
|
2167
2268
|
tokens << node
|
@@ -2181,7 +2282,7 @@ module SyntaxTree
|
|
2181
2282
|
def on_rational(value)
|
2182
2283
|
RationalLiteral.new(
|
2183
2284
|
value: value,
|
2184
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2285
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2185
2286
|
)
|
2186
2287
|
end
|
2187
2288
|
|
@@ -2191,7 +2292,7 @@ module SyntaxTree
|
|
2191
2292
|
node =
|
2192
2293
|
RBrace.new(
|
2193
2294
|
value: value,
|
2194
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2295
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2195
2296
|
)
|
2196
2297
|
|
2197
2298
|
tokens << node
|
@@ -2204,7 +2305,7 @@ module SyntaxTree
|
|
2204
2305
|
node =
|
2205
2306
|
RBracket.new(
|
2206
2307
|
value: value,
|
2207
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2308
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2208
2309
|
)
|
2209
2310
|
|
2210
2311
|
tokens << node
|
@@ -2238,7 +2339,7 @@ module SyntaxTree
|
|
2238
2339
|
node =
|
2239
2340
|
RegexpBeg.new(
|
2240
2341
|
value: value,
|
2241
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2342
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2242
2343
|
)
|
2243
2344
|
|
2244
2345
|
tokens << node
|
@@ -2250,7 +2351,7 @@ module SyntaxTree
|
|
2250
2351
|
def on_regexp_end(value)
|
2251
2352
|
RegexpEnd.new(
|
2252
2353
|
value: value,
|
2253
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2354
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2254
2355
|
)
|
2255
2356
|
end
|
2256
2357
|
|
@@ -2292,9 +2393,12 @@ module SyntaxTree
|
|
2292
2393
|
exceptions = exceptions[0] if exceptions.is_a?(Array)
|
2293
2394
|
|
2294
2395
|
last_node = variable || exceptions || keyword
|
2396
|
+
start_char = find_next_statement_start(last_node.location.end_char)
|
2295
2397
|
statements.bind(
|
2296
|
-
|
2297
|
-
|
2398
|
+
start_char,
|
2399
|
+
start_char - line_counts[last_node.location.start_line - 1].start,
|
2400
|
+
char_pos,
|
2401
|
+
current_column
|
2298
2402
|
)
|
2299
2403
|
|
2300
2404
|
# We add an additional inner node here that ripper doesn't provide so that
|
@@ -2309,13 +2413,16 @@ module SyntaxTree
|
|
2309
2413
|
Location.new(
|
2310
2414
|
start_line: keyword.location.start_line,
|
2311
2415
|
start_char: keyword.location.end_char + 1,
|
2416
|
+
start_column: keyword.location.end_column + 1,
|
2312
2417
|
end_line: last_node.location.end_line,
|
2313
|
-
end_char: last_node.location.end_char
|
2418
|
+
end_char: last_node.location.end_char,
|
2419
|
+
end_column: last_node.location.end_column
|
2314
2420
|
)
|
2315
2421
|
)
|
2316
2422
|
end
|
2317
2423
|
|
2318
2424
|
Rescue.new(
|
2425
|
+
keyword: keyword,
|
2319
2426
|
exception: rescue_ex,
|
2320
2427
|
statements: statements,
|
2321
2428
|
consequent: consequent,
|
@@ -2323,8 +2430,10 @@ module SyntaxTree
|
|
2323
2430
|
Location.new(
|
2324
2431
|
start_line: keyword.location.start_line,
|
2325
2432
|
start_char: keyword.location.start_char,
|
2433
|
+
start_column: keyword.location.start_column,
|
2326
2434
|
end_line: lineno,
|
2327
|
-
end_char: char_pos
|
2435
|
+
end_char: char_pos,
|
2436
|
+
end_column: current_column
|
2328
2437
|
)
|
2329
2438
|
)
|
2330
2439
|
end
|
@@ -2383,7 +2492,7 @@ module SyntaxTree
|
|
2383
2492
|
node =
|
2384
2493
|
RParen.new(
|
2385
2494
|
value: value,
|
2386
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2495
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2387
2496
|
)
|
2388
2497
|
|
2389
2498
|
tokens << node
|
@@ -2395,10 +2504,13 @@ module SyntaxTree
|
|
2395
2504
|
def on_sclass(target, bodystmt)
|
2396
2505
|
beginning = find_token(Kw, "class")
|
2397
2506
|
ending = find_token(Kw, "end")
|
2507
|
+
start_char = find_next_statement_start(target.location.end_char)
|
2398
2508
|
|
2399
2509
|
bodystmt.bind(
|
2400
|
-
|
2401
|
-
|
2510
|
+
start_char,
|
2511
|
+
start_char - line_counts[target.location.start_line - 1].start,
|
2512
|
+
ending.location.start_char,
|
2513
|
+
ending.location.start_column
|
2402
2514
|
)
|
2403
2515
|
|
2404
2516
|
SClass.new(
|
@@ -2437,7 +2549,7 @@ module SyntaxTree
|
|
2437
2549
|
Statements.new(
|
2438
2550
|
self,
|
2439
2551
|
body: [],
|
2440
|
-
location: Location.fixed(line: lineno, char: char_pos)
|
2552
|
+
location: Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2441
2553
|
)
|
2442
2554
|
end
|
2443
2555
|
|
@@ -2471,7 +2583,7 @@ module SyntaxTree
|
|
2471
2583
|
def on_string_content
|
2472
2584
|
StringContent.new(
|
2473
2585
|
parts: [],
|
2474
|
-
location: Location.fixed(line: lineno, char: char_pos)
|
2586
|
+
location: Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2475
2587
|
)
|
2476
2588
|
end
|
2477
2589
|
|
@@ -2494,18 +2606,22 @@ module SyntaxTree
|
|
2494
2606
|
|
2495
2607
|
statements.bind(
|
2496
2608
|
embexpr_beg.location.end_char,
|
2497
|
-
|
2609
|
+
embexpr_beg.location.end_column,
|
2610
|
+
embexpr_end.location.start_char,
|
2611
|
+
embexpr_end.location.start_column
|
2498
2612
|
)
|
2499
2613
|
|
2500
2614
|
location =
|
2501
2615
|
Location.new(
|
2502
2616
|
start_line: embexpr_beg.location.start_line,
|
2503
2617
|
start_char: embexpr_beg.location.start_char,
|
2618
|
+
start_column: embexpr_beg.location.start_column,
|
2504
2619
|
end_line: [
|
2505
2620
|
embexpr_end.location.end_line,
|
2506
2621
|
statements.location.end_line
|
2507
2622
|
].max,
|
2508
|
-
end_char: embexpr_end.location.end_char
|
2623
|
+
end_char: embexpr_end.location.end_char,
|
2624
|
+
end_column: embexpr_end.location.end_column
|
2509
2625
|
)
|
2510
2626
|
|
2511
2627
|
StringEmbExpr.new(statements: statements, location: location)
|
@@ -2533,11 +2649,13 @@ module SyntaxTree
|
|
2533
2649
|
Location.new(
|
2534
2650
|
start_line: tstring_beg.location.start_line,
|
2535
2651
|
start_char: tstring_beg.location.start_char,
|
2652
|
+
start_column: tstring_beg.location.start_column,
|
2536
2653
|
end_line: [
|
2537
2654
|
tstring_end.location.end_line,
|
2538
2655
|
string.location.end_line
|
2539
2656
|
].max,
|
2540
|
-
end_char: tstring_end.location.end_char
|
2657
|
+
end_char: tstring_end.location.end_char,
|
2658
|
+
end_column: tstring_end.location.end_column
|
2541
2659
|
)
|
2542
2660
|
|
2543
2661
|
StringLiteral.new(
|
@@ -2566,7 +2684,7 @@ module SyntaxTree
|
|
2566
2684
|
node =
|
2567
2685
|
SymBeg.new(
|
2568
2686
|
value: value,
|
2569
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2687
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2570
2688
|
)
|
2571
2689
|
|
2572
2690
|
tokens << node
|
@@ -2620,7 +2738,7 @@ module SyntaxTree
|
|
2620
2738
|
node =
|
2621
2739
|
SymbolsBeg.new(
|
2622
2740
|
value: value,
|
2623
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2741
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2624
2742
|
)
|
2625
2743
|
|
2626
2744
|
tokens << node
|
@@ -2645,7 +2763,7 @@ module SyntaxTree
|
|
2645
2763
|
node =
|
2646
2764
|
TLambda.new(
|
2647
2765
|
value: value,
|
2648
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2766
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2649
2767
|
)
|
2650
2768
|
|
2651
2769
|
tokens << node
|
@@ -2658,7 +2776,7 @@ module SyntaxTree
|
|
2658
2776
|
node =
|
2659
2777
|
TLamBeg.new(
|
2660
2778
|
value: value,
|
2661
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2779
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2662
2780
|
)
|
2663
2781
|
|
2664
2782
|
tokens << node
|
@@ -2693,7 +2811,7 @@ module SyntaxTree
|
|
2693
2811
|
node =
|
2694
2812
|
TStringBeg.new(
|
2695
2813
|
value: value,
|
2696
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2814
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2697
2815
|
)
|
2698
2816
|
|
2699
2817
|
tokens << node
|
@@ -2705,7 +2823,7 @@ module SyntaxTree
|
|
2705
2823
|
def on_tstring_content(value)
|
2706
2824
|
TStringContent.new(
|
2707
2825
|
value: value,
|
2708
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2826
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2709
2827
|
)
|
2710
2828
|
end
|
2711
2829
|
|
@@ -2715,7 +2833,7 @@ module SyntaxTree
|
|
2715
2833
|
node =
|
2716
2834
|
TStringEnd.new(
|
2717
2835
|
value: value,
|
2718
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
2836
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
2719
2837
|
)
|
2720
2838
|
|
2721
2839
|
tokens << node
|
@@ -2731,19 +2849,17 @@ module SyntaxTree
|
|
2731
2849
|
# parentheses they don't get reported as a paren node for some reason.
|
2732
2850
|
|
2733
2851
|
beginning = find_token(Kw, "not")
|
2734
|
-
ending = statement
|
2735
|
-
|
2736
|
-
range = beginning.location.end_char...statement.location.start_char
|
2737
|
-
paren = source[range].include?("(")
|
2852
|
+
ending = statement || beginning
|
2853
|
+
parentheses = source[beginning.location.end_char] == "("
|
2738
2854
|
|
2739
|
-
if
|
2855
|
+
if parentheses
|
2740
2856
|
find_token(LParen)
|
2741
2857
|
ending = find_token(RParen)
|
2742
2858
|
end
|
2743
2859
|
|
2744
2860
|
Not.new(
|
2745
2861
|
statement: statement,
|
2746
|
-
parentheses:
|
2862
|
+
parentheses: parentheses,
|
2747
2863
|
location: beginning.location.to(ending.location)
|
2748
2864
|
)
|
2749
2865
|
else
|
@@ -2789,7 +2905,12 @@ module SyntaxTree
|
|
2789
2905
|
beginning = find_token(Kw, "unless")
|
2790
2906
|
ending = consequent || find_token(Kw, "end")
|
2791
2907
|
|
2792
|
-
statements.bind(
|
2908
|
+
statements.bind(
|
2909
|
+
predicate.location.end_char,
|
2910
|
+
predicate.location.end_column,
|
2911
|
+
ending.location.start_char,
|
2912
|
+
ending.location.start_column
|
2913
|
+
)
|
2793
2914
|
|
2794
2915
|
Unless.new(
|
2795
2916
|
predicate: predicate,
|
@@ -2826,7 +2947,12 @@ module SyntaxTree
|
|
2826
2947
|
end
|
2827
2948
|
|
2828
2949
|
# Update the Statements location information
|
2829
|
-
statements.bind(
|
2950
|
+
statements.bind(
|
2951
|
+
predicate.location.end_char,
|
2952
|
+
predicate.location.end_column,
|
2953
|
+
ending.location.start_char,
|
2954
|
+
ending.location.start_column
|
2955
|
+
)
|
2830
2956
|
|
2831
2957
|
Until.new(
|
2832
2958
|
predicate: predicate,
|
@@ -2865,12 +2991,12 @@ module SyntaxTree
|
|
2865
2991
|
# ) -> VarField
|
2866
2992
|
def on_var_field(value)
|
2867
2993
|
location =
|
2868
|
-
if value
|
2994
|
+
if value && value != :nil
|
2869
2995
|
value.location
|
2870
2996
|
else
|
2871
2997
|
# You can hit this pattern if you're assigning to a splat using
|
2872
2998
|
# pattern matching syntax in Ruby 2.7+
|
2873
|
-
Location.fixed(line: lineno, char: char_pos)
|
2999
|
+
Location.fixed(line: lineno, char: char_pos, column: current_column)
|
2874
3000
|
end
|
2875
3001
|
|
2876
3002
|
VarField.new(value: value, location: location)
|
@@ -2898,7 +3024,7 @@ module SyntaxTree
|
|
2898
3024
|
# :call-seq:
|
2899
3025
|
# on_void_stmt: () -> VoidStmt
|
2900
3026
|
def on_void_stmt
|
2901
|
-
VoidStmt.new(location: Location.fixed(line: lineno, char: char_pos))
|
3027
|
+
VoidStmt.new(location: Location.fixed(line: lineno, char: char_pos, column: current_column))
|
2902
3028
|
end
|
2903
3029
|
|
2904
3030
|
# :call-seq:
|
@@ -2917,9 +3043,13 @@ module SyntaxTree
|
|
2917
3043
|
statements_start = token
|
2918
3044
|
end
|
2919
3045
|
|
3046
|
+
start_char = find_next_statement_start(statements_start.location.end_char)
|
3047
|
+
|
2920
3048
|
statements.bind(
|
2921
|
-
|
2922
|
-
|
3049
|
+
start_char,
|
3050
|
+
start_char - line_counts[statements_start.location.start_line - 1].start,
|
3051
|
+
ending.location.start_char,
|
3052
|
+
ending.location.start_column
|
2923
3053
|
)
|
2924
3054
|
|
2925
3055
|
When.new(
|
@@ -2945,7 +3075,12 @@ module SyntaxTree
|
|
2945
3075
|
end
|
2946
3076
|
|
2947
3077
|
# Update the Statements location information
|
2948
|
-
statements.bind(
|
3078
|
+
statements.bind(
|
3079
|
+
predicate.location.end_char,
|
3080
|
+
predicate.location.end_column,
|
3081
|
+
ending.location.start_char,
|
3082
|
+
ending.location.start_column
|
3083
|
+
)
|
2949
3084
|
|
2950
3085
|
While.new(
|
2951
3086
|
predicate: predicate,
|
@@ -2981,7 +3116,7 @@ module SyntaxTree
|
|
2981
3116
|
# :call-seq:
|
2982
3117
|
# on_word_new: () -> Word
|
2983
3118
|
def on_word_new
|
2984
|
-
Word.new(parts: [], location: Location.fixed(line: lineno, char: char_pos))
|
3119
|
+
Word.new(parts: [], location: Location.fixed(line: lineno, char: char_pos, column: current_column))
|
2985
3120
|
end
|
2986
3121
|
|
2987
3122
|
# :call-seq:
|
@@ -3000,7 +3135,7 @@ module SyntaxTree
|
|
3000
3135
|
node =
|
3001
3136
|
WordsBeg.new(
|
3002
3137
|
value: value,
|
3003
|
-
location: Location.token(line: lineno, char: char_pos, size: value.size)
|
3138
|
+
location: Location.token(line: lineno, char: char_pos, column: current_column, size: value.size)
|
3004
3139
|
)
|
3005
3140
|
|
3006
3141
|
tokens << node
|