jruby-prism-parser 0.23.0.pre.SNAPSHOT-java → 0.24.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -1
- data/docs/releasing.md +1 -1
- data/ext/prism/api_node.c +2232 -1787
- data/ext/prism/extension.h +1 -1
- data/include/prism/util/pm_newline_list.h +4 -3
- data/include/prism/version.h +2 -2
- data/jruby-prism.jar +0 -0
- data/lib/prism/desugar_compiler.rb +225 -80
- data/lib/prism/dsl.rb +302 -299
- data/lib/prism/ffi.rb +102 -76
- data/lib/prism/node.rb +3624 -2114
- data/lib/prism/parse_result.rb +12 -4
- data/lib/prism/serialize.rb +594 -298
- data/lib/prism/translation/parser/compiler.rb +1 -1
- data/lib/prism/translation/parser/rubocop.rb +11 -3
- data/lib/prism/translation/parser.rb +15 -3
- data/lib/prism/translation/parser33.rb +12 -0
- data/lib/prism/translation/parser34.rb +12 -0
- data/lib/prism/translation/ripper.rb +144 -25
- data/lib/prism/version.rb +1 -1
- data/prism.gemspec +2 -0
- data/src/prettyprint.c +3 -3
- data/src/prism.c +48 -33
- data/src/util/pm_newline_list.c +6 -3
- metadata +7 -5
@@ -1477,7 +1477,7 @@ module Prism
|
|
1477
1477
|
# ^^^^^
|
1478
1478
|
def visit_string_node(node)
|
1479
1479
|
if node.opening&.start_with?("<<")
|
1480
|
-
children, closing = visit_heredoc(InterpolatedStringNode.new(node.opening_loc, [node.copy(opening_loc: nil, closing_loc: nil, location: node.content_loc)], node.closing_loc, node.location))
|
1480
|
+
children, closing = visit_heredoc(InterpolatedStringNode.new(node.send(:source), node.opening_loc, [node.copy(opening_loc: nil, closing_loc: nil, location: node.content_loc)], node.closing_loc, node.location))
|
1481
1481
|
builder.string_compose(token(node.opening_loc), children, closing)
|
1482
1482
|
elsif node.opening == "?"
|
1483
1483
|
builder.character([node.unescaped, srange(node.location)])
|
@@ -9,18 +9,26 @@ require "prism/translation/parser"
|
|
9
9
|
module Prism
|
10
10
|
module Translation
|
11
11
|
class Parser
|
12
|
-
# This is the special version
|
12
|
+
# This is the special version numbers that should be used in RuboCop
|
13
13
|
# configuration files to trigger using prism.
|
14
|
+
|
15
|
+
# For Ruby 3.3
|
14
16
|
VERSION_3_3 = 80_82_73_83_77.33
|
15
17
|
|
18
|
+
# For Ruby 3.4
|
19
|
+
VERSION_3_4 = 80_82_73_83_77.34
|
20
|
+
|
16
21
|
# This module gets prepended into RuboCop::AST::ProcessedSource.
|
17
22
|
module ProcessedSource
|
18
23
|
# Redefine parser_class so that we can inject the prism parser into the
|
19
24
|
# list of known parsers.
|
20
25
|
def parser_class(ruby_version)
|
21
26
|
if ruby_version == Prism::Translation::Parser::VERSION_3_3
|
22
|
-
require "prism/translation/
|
23
|
-
Prism::Translation::
|
27
|
+
require "prism/translation/parser33"
|
28
|
+
Prism::Translation::Parser33
|
29
|
+
elsif ruby_version == Prism::Translation::Parser::VERSION_3_4
|
30
|
+
require "prism/translation/parser34"
|
31
|
+
Prism::Translation::Parser34
|
24
32
|
else
|
25
33
|
super
|
26
34
|
end
|
@@ -43,7 +43,7 @@ module Prism
|
|
43
43
|
source = source_buffer.source
|
44
44
|
|
45
45
|
offset_cache = build_offset_cache(source)
|
46
|
-
result = unwrap(Prism.parse(source, filepath: source_buffer.name), offset_cache)
|
46
|
+
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version)), offset_cache)
|
47
47
|
|
48
48
|
build_ast(result.value, offset_cache)
|
49
49
|
ensure
|
@@ -56,7 +56,7 @@ module Prism
|
|
56
56
|
source = source_buffer.source
|
57
57
|
|
58
58
|
offset_cache = build_offset_cache(source)
|
59
|
-
result = unwrap(Prism.parse(source, filepath: source_buffer.name), offset_cache)
|
59
|
+
result = unwrap(Prism.parse(source, filepath: source_buffer.name, version: convert_for_prism(version)), offset_cache)
|
60
60
|
|
61
61
|
[
|
62
62
|
build_ast(result.value, offset_cache),
|
@@ -75,7 +75,7 @@ module Prism
|
|
75
75
|
offset_cache = build_offset_cache(source)
|
76
76
|
result =
|
77
77
|
begin
|
78
|
-
unwrap(Prism.parse_lex(source, filepath: source_buffer.name), offset_cache)
|
78
|
+
unwrap(Prism.parse_lex(source, filepath: source_buffer.name, version: convert_for_prism(version)), offset_cache)
|
79
79
|
rescue ::Parser::SyntaxError
|
80
80
|
raise if !recover
|
81
81
|
end
|
@@ -168,6 +168,18 @@ module Prism
|
|
168
168
|
)
|
169
169
|
end
|
170
170
|
|
171
|
+
# Converts the version format handled by Parser to the format handled by Prism.
|
172
|
+
def convert_for_prism(version)
|
173
|
+
case version
|
174
|
+
when 33
|
175
|
+
"3.3.0"
|
176
|
+
when 34
|
177
|
+
"3.4.0"
|
178
|
+
else
|
179
|
+
"latest"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
171
183
|
require_relative "parser/compiler"
|
172
184
|
require_relative "parser/lexer"
|
173
185
|
|
@@ -222,6 +222,44 @@ module Prism
|
|
222
222
|
on_break(on_args_add_block(args_val, false))
|
223
223
|
end
|
224
224
|
|
225
|
+
# Visit an AliasMethodNode.
|
226
|
+
def visit_alias_method_node(node)
|
227
|
+
# For both the old and new name, if there is a colon in the symbol
|
228
|
+
# name (e.g. 'alias :foo :bar') then we do *not* emit the [:symbol] wrapper around
|
229
|
+
# the lexer token (e.g. :@ident) inside [:symbol_literal]. But if there
|
230
|
+
# is no colon (e.g. 'alias foo bar') then we *do* still emit the [:symbol] wrapper.
|
231
|
+
|
232
|
+
if node.new_name.is_a?(SymbolNode) && !node.new_name.opening
|
233
|
+
new_name_val = visit_symbol_literal_node(node.new_name, no_symbol_wrapper: true)
|
234
|
+
else
|
235
|
+
new_name_val = visit(node.new_name)
|
236
|
+
end
|
237
|
+
if node.old_name.is_a?(SymbolNode) && !node.old_name.opening
|
238
|
+
old_name_val = visit_symbol_literal_node(node.old_name, no_symbol_wrapper: true)
|
239
|
+
else
|
240
|
+
old_name_val = visit(node.old_name)
|
241
|
+
end
|
242
|
+
|
243
|
+
on_alias(new_name_val, old_name_val)
|
244
|
+
end
|
245
|
+
|
246
|
+
# Visit an AliasGlobalVariableNode.
|
247
|
+
def visit_alias_global_variable_node(node)
|
248
|
+
on_var_alias(visit(node.new_name), visit(node.old_name))
|
249
|
+
end
|
250
|
+
|
251
|
+
# Visit a GlobalVariableReadNode.
|
252
|
+
def visit_global_variable_read_node(node)
|
253
|
+
bounds(node.location)
|
254
|
+
on_gvar(node.name.to_s)
|
255
|
+
end
|
256
|
+
|
257
|
+
# Visit a BackReferenceReadNode.
|
258
|
+
def visit_back_reference_read_node(node)
|
259
|
+
bounds(node.location)
|
260
|
+
on_backref(node.name.to_s)
|
261
|
+
end
|
262
|
+
|
225
263
|
# Visit an AndNode.
|
226
264
|
def visit_and_node(node)
|
227
265
|
visit_binary_operator(node)
|
@@ -326,23 +364,7 @@ module Prism
|
|
326
364
|
|
327
365
|
# Visit an InterpolatedStringNode node.
|
328
366
|
def visit_interpolated_string_node(node)
|
329
|
-
|
330
|
-
case part
|
331
|
-
when StringNode
|
332
|
-
bounds(part.content_loc)
|
333
|
-
on_tstring_content(part.content)
|
334
|
-
when EmbeddedStatementsNode
|
335
|
-
on_string_embexpr(visit(part))
|
336
|
-
else
|
337
|
-
raise NotImplementedError, "Unexpected node type in InterpolatedStringNode"
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
string_list = parts.inject(on_string_content) do |items, item|
|
342
|
-
on_string_add(items, item)
|
343
|
-
end
|
344
|
-
|
345
|
-
on_string_literal(string_list)
|
367
|
+
on_string_literal(visit_enumerated_node(node))
|
346
368
|
end
|
347
369
|
|
348
370
|
# Visit an EmbeddedStatementsNode node.
|
@@ -352,15 +374,12 @@ module Prism
|
|
352
374
|
|
353
375
|
# Visit a SymbolNode node.
|
354
376
|
def visit_symbol_node(node)
|
355
|
-
|
356
|
-
|
357
|
-
tstring_val = on_tstring_content(node.value.to_s)
|
358
|
-
return on_dyna_symbol(on_string_add(on_string_content, tstring_val))
|
359
|
-
end
|
377
|
+
visit_symbol_literal_node(node)
|
378
|
+
end
|
360
379
|
|
361
|
-
|
362
|
-
|
363
|
-
|
380
|
+
# Visit an InterpolatedSymbolNode node.
|
381
|
+
def visit_interpolated_symbol_node(node)
|
382
|
+
on_dyna_symbol(visit_enumerated_node(node))
|
364
383
|
end
|
365
384
|
|
366
385
|
# Visit a StatementsNode node.
|
@@ -459,6 +478,25 @@ module Prism
|
|
459
478
|
end
|
460
479
|
end
|
461
480
|
|
481
|
+
# Visit an InterpolatedStringNode or an InterpolatedSymbolNode node.
|
482
|
+
def visit_enumerated_node(node)
|
483
|
+
parts = node.parts.map do |part|
|
484
|
+
case part
|
485
|
+
when StringNode
|
486
|
+
bounds(part.content_loc)
|
487
|
+
on_tstring_content(part.content)
|
488
|
+
when EmbeddedStatementsNode
|
489
|
+
on_string_embexpr(visit(part))
|
490
|
+
else
|
491
|
+
raise NotImplementedError, "Unexpected node type in visit_enumerated_node"
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
parts.inject(on_string_content) do |items, item|
|
496
|
+
on_string_add(items, item)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
462
500
|
# Visit an operation-and-assign node, such as +=.
|
463
501
|
def visit_binary_op_assign(node, operator: node.operator)
|
464
502
|
bounds(node.name_loc)
|
@@ -487,6 +525,87 @@ module Prism
|
|
487
525
|
on_assign(on_aref_field(visit(node.receiver), args_val), assign_val)
|
488
526
|
end
|
489
527
|
|
528
|
+
# In an alias statement Ripper will emit @kw instead of @ident if the object
|
529
|
+
# being aliased is a Ruby keyword. For instance, in the line "alias :foo :if",
|
530
|
+
# the :if is treated as a lexer keyword. So we need to know what symbols are
|
531
|
+
# also keywords.
|
532
|
+
RUBY_KEYWORDS = [
|
533
|
+
"alias",
|
534
|
+
"and",
|
535
|
+
"begin",
|
536
|
+
"BEGIN",
|
537
|
+
"break",
|
538
|
+
"case",
|
539
|
+
"class",
|
540
|
+
"def",
|
541
|
+
"defined?",
|
542
|
+
"do",
|
543
|
+
"else",
|
544
|
+
"elsif",
|
545
|
+
"end",
|
546
|
+
"END",
|
547
|
+
"ensure",
|
548
|
+
"false",
|
549
|
+
"for",
|
550
|
+
"if",
|
551
|
+
"in",
|
552
|
+
"module",
|
553
|
+
"next",
|
554
|
+
"nil",
|
555
|
+
"not",
|
556
|
+
"or",
|
557
|
+
"redo",
|
558
|
+
"rescue",
|
559
|
+
"retry",
|
560
|
+
"return",
|
561
|
+
"self",
|
562
|
+
"super",
|
563
|
+
"then",
|
564
|
+
"true",
|
565
|
+
"undef",
|
566
|
+
"unless",
|
567
|
+
"until",
|
568
|
+
"when",
|
569
|
+
"while",
|
570
|
+
"yield",
|
571
|
+
"__ENCODING__",
|
572
|
+
"__FILE__",
|
573
|
+
"__LINE__",
|
574
|
+
]
|
575
|
+
|
576
|
+
# Ripper has several methods of emitting a symbol literal. Inside an alias
|
577
|
+
# sometimes it suppresses the [:symbol] wrapper around ident. If the symbol
|
578
|
+
# is also the name of a keyword (e.g. :if) it will emit a :@kw wrapper, not
|
579
|
+
# an :@ident wrapper, with similar treatment for constants and operators.
|
580
|
+
def visit_symbol_literal_node(node, no_symbol_wrapper: false)
|
581
|
+
if (opening = node.opening) && (['"', "'"].include?(opening[-1]) || opening.start_with?("%s"))
|
582
|
+
bounds(node.value_loc)
|
583
|
+
str_val = node.value.to_s
|
584
|
+
if str_val == ""
|
585
|
+
return on_dyna_symbol(on_string_content)
|
586
|
+
else
|
587
|
+
tstring_val = on_tstring_content(str_val)
|
588
|
+
return on_dyna_symbol(on_string_add(on_string_content, tstring_val))
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
bounds(node.value_loc)
|
593
|
+
node_name = node.value.to_s
|
594
|
+
if RUBY_KEYWORDS.include?(node_name)
|
595
|
+
token_val = on_kw(node_name)
|
596
|
+
elsif node_name.length == 0
|
597
|
+
raise NotImplementedError
|
598
|
+
elsif /[[:upper:]]/.match(node_name[0])
|
599
|
+
token_val = on_const(node_name)
|
600
|
+
elsif /[[:punct:]]/.match(node_name[0])
|
601
|
+
token_val = on_op(node_name)
|
602
|
+
else
|
603
|
+
token_val = on_ident(node_name)
|
604
|
+
end
|
605
|
+
sym_val = no_symbol_wrapper ? token_val : on_symbol(token_val)
|
606
|
+
on_symbol_literal(sym_val)
|
607
|
+
end
|
608
|
+
|
490
609
|
# Visit a node that represents a number. We need to explicitly handle the
|
491
610
|
# unary - operator.
|
492
611
|
def visit_number(node)
|
data/lib/prism/version.rb
CHANGED
data/prism.gemspec
CHANGED
@@ -92,6 +92,8 @@ Gem::Specification.new do |spec|
|
|
92
92
|
"lib/prism/serialize.rb",
|
93
93
|
"lib/prism/translation.rb",
|
94
94
|
"lib/prism/translation/parser.rb",
|
95
|
+
"lib/prism/translation/parser33.rb",
|
96
|
+
"lib/prism/translation/parser34.rb",
|
95
97
|
"lib/prism/translation/parser/compiler.rb",
|
96
98
|
"lib/prism/translation/parser/lexer.rb",
|
97
99
|
"lib/prism/translation/parser/rubocop.rb",
|
data/src/prettyprint.c
CHANGED
@@ -44,9 +44,9 @@ prettyprint_source(pm_buffer_t *output_buffer, const uint8_t *source, size_t len
|
|
44
44
|
|
45
45
|
static inline void
|
46
46
|
prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) {
|
47
|
-
pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start);
|
48
|
-
pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end);
|
49
|
-
pm_buffer_append_format(output_buffer, "(%
|
47
|
+
pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start, parser->start_line);
|
48
|
+
pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end, parser->start_line);
|
49
|
+
pm_buffer_append_format(output_buffer, "(%" PRIi32 ",%" PRIu32 ")-(%" PRIi32 ",%" PRIu32 ")", start.line, start.column, end.line, end.column);
|
50
50
|
}
|
51
51
|
|
52
52
|
static inline void
|
data/src/prism.c
CHANGED
@@ -51,6 +51,7 @@ debug_context(pm_context_t context) {
|
|
51
51
|
case PM_CONTEXT_IF: return "IF";
|
52
52
|
case PM_CONTEXT_MAIN: return "MAIN";
|
53
53
|
case PM_CONTEXT_MODULE: return "MODULE";
|
54
|
+
case PM_CONTEXT_NONE: return "NONE";
|
54
55
|
case PM_CONTEXT_PARENS: return "PARENS";
|
55
56
|
case PM_CONTEXT_POSTEXE: return "POSTEXE";
|
56
57
|
case PM_CONTEXT_PREDICATE: return "PREDICATE";
|
@@ -14205,7 +14206,6 @@ parse_strings(pm_parser_t *parser, pm_node_t *current) {
|
|
14205
14206
|
// If we get here, then we have an end of a label immediately
|
14206
14207
|
// after a start. In that case we'll create an empty symbol
|
14207
14208
|
// node.
|
14208
|
-
pm_token_t opening = not_provided(parser);
|
14209
14209
|
pm_token_t content = parse_strings_empty_content(parser->previous.start);
|
14210
14210
|
pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &content, &parser->previous);
|
14211
14211
|
|
@@ -16769,7 +16769,18 @@ parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding
|
|
16769
16769
|
if (is_single_value && match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) {
|
16770
16770
|
pm_token_t rescue = parser->current;
|
16771
16771
|
parser_lex(parser);
|
16772
|
-
|
16772
|
+
|
16773
|
+
bool accepts_command_call_inner = false;
|
16774
|
+
|
16775
|
+
// RHS can accept command call iff the value is a call with arguments but without paranthesis.
|
16776
|
+
if (PM_NODE_TYPE_P(value, PM_CALL_NODE)) {
|
16777
|
+
pm_call_node_t *call_node = (pm_call_node_t *)value;
|
16778
|
+
if ((call_node->arguments != NULL) && (call_node->opening_loc.start == NULL)) {
|
16779
|
+
accepts_command_call_inner = true;
|
16780
|
+
}
|
16781
|
+
}
|
16782
|
+
|
16783
|
+
pm_node_t *right = parse_expression(parser, binding_power, accepts_command_call_inner, PM_ERR_RESCUE_MODIFIER_VALUE);
|
16773
16784
|
|
16774
16785
|
return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right);
|
16775
16786
|
}
|
@@ -18115,7 +18126,7 @@ typedef struct {
|
|
18115
18126
|
pm_diagnostic_t *error;
|
18116
18127
|
|
18117
18128
|
/** The start line of the diagnostic message. */
|
18118
|
-
|
18129
|
+
int32_t line;
|
18119
18130
|
|
18120
18131
|
/** The column start of the diagnostic message. */
|
18121
18132
|
uint32_t column_start;
|
@@ -18147,12 +18158,13 @@ typedef struct {
|
|
18147
18158
|
#define PM_COLOR_RESET "\033[0m"
|
18148
18159
|
|
18149
18160
|
static inline pm_error_t *
|
18150
|
-
pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_t *newline_list) {
|
18161
|
+
pm_parser_errors_format_sort(const pm_parser_t *parser, const pm_list_t *error_list, const pm_newline_list_t *newline_list) {
|
18151
18162
|
pm_error_t *errors = calloc(error_list->size, sizeof(pm_error_t));
|
18163
|
+
int32_t start_line = parser->start_line;
|
18152
18164
|
|
18153
18165
|
for (pm_diagnostic_t *error = (pm_diagnostic_t *) error_list->head; error != NULL; error = (pm_diagnostic_t *) error->node.next) {
|
18154
|
-
pm_line_column_t start = pm_newline_list_line_column(newline_list, error->location.start);
|
18155
|
-
pm_line_column_t end = pm_newline_list_line_column(newline_list, error->location.end);
|
18166
|
+
pm_line_column_t start = pm_newline_list_line_column(newline_list, error->location.start, start_line);
|
18167
|
+
pm_line_column_t end = pm_newline_list_line_column(newline_list, error->location.end, start_line);
|
18156
18168
|
|
18157
18169
|
// We're going to insert this error into the array in sorted order. We
|
18158
18170
|
// do this by finding the first error that has a line number greater
|
@@ -18163,8 +18175,8 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
|
|
18163
18175
|
(index < error_list->size) &&
|
18164
18176
|
(errors[index].error != NULL) &&
|
18165
18177
|
(
|
18166
|
-
(errors[index].line <
|
18167
|
-
(errors[index].line ==
|
18178
|
+
(errors[index].line < start.line) ||
|
18179
|
+
((errors[index].line == start.line) && (errors[index].column_start < start.column))
|
18168
18180
|
)
|
18169
18181
|
) index++;
|
18170
18182
|
|
@@ -18177,18 +18189,18 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
|
|
18177
18189
|
// Finally, we'll insert the error into the array.
|
18178
18190
|
uint32_t column_end;
|
18179
18191
|
if (start.line == end.line) {
|
18180
|
-
column_end =
|
18192
|
+
column_end = end.column;
|
18181
18193
|
} else {
|
18182
|
-
column_end = (uint32_t) (newline_list->offsets[start.line] - newline_list->offsets[start.line -
|
18194
|
+
column_end = (uint32_t) (newline_list->offsets[start.line - start_line + 1] - newline_list->offsets[start.line - start_line] - 1);
|
18183
18195
|
}
|
18184
18196
|
|
18185
18197
|
// Ensure we have at least one column of error.
|
18186
|
-
if (
|
18198
|
+
if (start.column == column_end) column_end++;
|
18187
18199
|
|
18188
18200
|
errors[index] = (pm_error_t) {
|
18189
18201
|
.error = error,
|
18190
|
-
.line =
|
18191
|
-
.column_start =
|
18202
|
+
.line = start.line,
|
18203
|
+
.column_start = start.column,
|
18192
18204
|
.column_end = column_end
|
18193
18205
|
};
|
18194
18206
|
}
|
@@ -18197,17 +18209,19 @@ pm_parser_errors_format_sort(const pm_list_t *error_list, const pm_newline_list_
|
|
18197
18209
|
}
|
18198
18210
|
|
18199
18211
|
static inline void
|
18200
|
-
pm_parser_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *newline_list, const char *number_prefix,
|
18201
|
-
|
18212
|
+
pm_parser_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *newline_list, const char *number_prefix, int32_t line, pm_buffer_t *buffer) {
|
18213
|
+
size_t index = (size_t) (line - parser->start_line);
|
18214
|
+
|
18215
|
+
const uint8_t *start = &parser->start[newline_list->offsets[index]];
|
18202
18216
|
const uint8_t *end;
|
18203
18217
|
|
18204
|
-
if (
|
18218
|
+
if (index >= newline_list->size - 1) {
|
18205
18219
|
end = parser->end;
|
18206
18220
|
} else {
|
18207
|
-
end = &parser->start[newline_list->offsets[
|
18221
|
+
end = &parser->start[newline_list->offsets[index + 1]];
|
18208
18222
|
}
|
18209
18223
|
|
18210
|
-
pm_buffer_append_format(buffer, number_prefix,
|
18224
|
+
pm_buffer_append_format(buffer, number_prefix, line);
|
18211
18225
|
pm_buffer_append_string(buffer, (const char *) start, (size_t) (end - start));
|
18212
18226
|
|
18213
18227
|
if (end == parser->end && end[-1] != '\n') {
|
@@ -18225,25 +18239,26 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18225
18239
|
|
18226
18240
|
// First, we're going to sort all of the errors by line number using an
|
18227
18241
|
// insertion sort into a newly allocated array.
|
18242
|
+
const int32_t start_line = parser->start_line;
|
18228
18243
|
const pm_newline_list_t *newline_list = &parser->newline_list;
|
18229
|
-
pm_error_t *errors = pm_parser_errors_format_sort(error_list, newline_list);
|
18244
|
+
pm_error_t *errors = pm_parser_errors_format_sort(parser, error_list, newline_list);
|
18230
18245
|
|
18231
18246
|
// Now we're going to determine how we're going to format line numbers and
|
18232
18247
|
// blank lines based on the maximum number of digits in the line numbers
|
18233
18248
|
// that are going to be displayed.
|
18234
18249
|
pm_error_format_t error_format;
|
18235
|
-
|
18250
|
+
int32_t max_line_number = errors[error_list->size - 1].line - start_line;
|
18236
18251
|
|
18237
18252
|
if (max_line_number < 10) {
|
18238
18253
|
if (colorize) {
|
18239
18254
|
error_format = (pm_error_format_t) {
|
18240
|
-
.number_prefix = PM_COLOR_GRAY "%1"
|
18255
|
+
.number_prefix = PM_COLOR_GRAY "%1" PRIi32 " | " PM_COLOR_RESET,
|
18241
18256
|
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
|
18242
18257
|
.divider = PM_COLOR_GRAY " ~~~~~" PM_COLOR_RESET "\n"
|
18243
18258
|
};
|
18244
18259
|
} else {
|
18245
18260
|
error_format = (pm_error_format_t) {
|
18246
|
-
.number_prefix = "%1"
|
18261
|
+
.number_prefix = "%1" PRIi32 " | ",
|
18247
18262
|
.blank_prefix = " | ",
|
18248
18263
|
.divider = " ~~~~~\n"
|
18249
18264
|
};
|
@@ -18251,13 +18266,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18251
18266
|
} else if (max_line_number < 100) {
|
18252
18267
|
if (colorize) {
|
18253
18268
|
error_format = (pm_error_format_t) {
|
18254
|
-
.number_prefix = PM_COLOR_GRAY "%2"
|
18269
|
+
.number_prefix = PM_COLOR_GRAY "%2" PRIi32 " | " PM_COLOR_RESET,
|
18255
18270
|
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
|
18256
18271
|
.divider = PM_COLOR_GRAY " ~~~~~~" PM_COLOR_RESET "\n"
|
18257
18272
|
};
|
18258
18273
|
} else {
|
18259
18274
|
error_format = (pm_error_format_t) {
|
18260
|
-
.number_prefix = "%2"
|
18275
|
+
.number_prefix = "%2" PRIi32 " | ",
|
18261
18276
|
.blank_prefix = " | ",
|
18262
18277
|
.divider = " ~~~~~~\n"
|
18263
18278
|
};
|
@@ -18265,13 +18280,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18265
18280
|
} else if (max_line_number < 1000) {
|
18266
18281
|
if (colorize) {
|
18267
18282
|
error_format = (pm_error_format_t) {
|
18268
|
-
.number_prefix = PM_COLOR_GRAY "%3"
|
18283
|
+
.number_prefix = PM_COLOR_GRAY "%3" PRIi32 " | " PM_COLOR_RESET,
|
18269
18284
|
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
|
18270
18285
|
.divider = PM_COLOR_GRAY " ~~~~~~~" PM_COLOR_RESET "\n"
|
18271
18286
|
};
|
18272
18287
|
} else {
|
18273
18288
|
error_format = (pm_error_format_t) {
|
18274
|
-
.number_prefix = "%3"
|
18289
|
+
.number_prefix = "%3" PRIi32 " | ",
|
18275
18290
|
.blank_prefix = " | ",
|
18276
18291
|
.divider = " ~~~~~~~\n"
|
18277
18292
|
};
|
@@ -18279,13 +18294,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18279
18294
|
} else if (max_line_number < 10000) {
|
18280
18295
|
if (colorize) {
|
18281
18296
|
error_format = (pm_error_format_t) {
|
18282
|
-
.number_prefix = PM_COLOR_GRAY "%4"
|
18297
|
+
.number_prefix = PM_COLOR_GRAY "%4" PRIi32 " | " PM_COLOR_RESET,
|
18283
18298
|
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
|
18284
18299
|
.divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n"
|
18285
18300
|
};
|
18286
18301
|
} else {
|
18287
18302
|
error_format = (pm_error_format_t) {
|
18288
|
-
.number_prefix = "%4"
|
18303
|
+
.number_prefix = "%4" PRIi32 " | ",
|
18289
18304
|
.blank_prefix = " | ",
|
18290
18305
|
.divider = " ~~~~~~~~\n"
|
18291
18306
|
};
|
@@ -18293,13 +18308,13 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18293
18308
|
} else {
|
18294
18309
|
if (colorize) {
|
18295
18310
|
error_format = (pm_error_format_t) {
|
18296
|
-
.number_prefix = PM_COLOR_GRAY "%5"
|
18311
|
+
.number_prefix = PM_COLOR_GRAY "%5" PRIi32 " | " PM_COLOR_RESET,
|
18297
18312
|
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
|
18298
18313
|
.divider = PM_COLOR_GRAY " ~~~~~~~~" PM_COLOR_RESET "\n"
|
18299
18314
|
};
|
18300
18315
|
} else {
|
18301
18316
|
error_format = (pm_error_format_t) {
|
18302
|
-
.number_prefix = "%5"
|
18317
|
+
.number_prefix = "%5" PRIi32 " | ",
|
18303
18318
|
.blank_prefix = " | ",
|
18304
18319
|
.divider = " ~~~~~~~~\n"
|
18305
18320
|
};
|
@@ -18314,7 +18329,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18314
18329
|
// the source before the error to give some context. We'll be careful not to
|
18315
18330
|
// display the same line twice in case the errors are close enough in the
|
18316
18331
|
// source.
|
18317
|
-
|
18332
|
+
int32_t last_line = 0;
|
18318
18333
|
const pm_encoding_t *encoding = parser->encoding;
|
18319
18334
|
|
18320
18335
|
for (size_t index = 0; index < error_list->size; index++) {
|
@@ -18360,7 +18375,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18360
18375
|
pm_buffer_append_string(buffer, error_format.blank_prefix, error_format.blank_prefix_length);
|
18361
18376
|
|
18362
18377
|
size_t column = 0;
|
18363
|
-
const uint8_t *start = &parser->start[newline_list->offsets[error->line -
|
18378
|
+
const uint8_t *start = &parser->start[newline_list->offsets[error->line - start_line]];
|
18364
18379
|
|
18365
18380
|
while (column < error->column_end) {
|
18366
18381
|
if (column < error->column_start) {
|
@@ -18384,7 +18399,7 @@ pm_parser_errors_format(const pm_parser_t *parser, pm_buffer_t *buffer, bool col
|
|
18384
18399
|
// Here we determine how many lines of padding to display after the
|
18385
18400
|
// error, depending on where the next error is in source.
|
18386
18401
|
last_line = error->line;
|
18387
|
-
|
18402
|
+
int32_t next_line = (index == error_list->size - 1) ? ((int32_t) newline_list->size) : errors[index + 1].line;
|
18388
18403
|
|
18389
18404
|
if (next_line - last_line > 1) {
|
18390
18405
|
pm_buffer_append_string(buffer, " ", 2);
|
data/src/util/pm_newline_list.c
CHANGED
@@ -51,7 +51,7 @@ pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) {
|
|
51
51
|
* are returned.
|
52
52
|
*/
|
53
53
|
pm_line_column_t
|
54
|
-
pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor) {
|
54
|
+
pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line) {
|
55
55
|
assert(cursor >= list->start);
|
56
56
|
size_t offset = (size_t) (cursor - list->start);
|
57
57
|
|
@@ -62,7 +62,7 @@ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor
|
|
62
62
|
size_t mid = left + (right - left) / 2;
|
63
63
|
|
64
64
|
if (list->offsets[mid] == offset) {
|
65
|
-
return ((pm_line_column_t) { mid +
|
65
|
+
return ((pm_line_column_t) { ((int32_t) mid) + start_line, 0 });
|
66
66
|
}
|
67
67
|
|
68
68
|
if (list->offsets[mid] < offset) {
|
@@ -72,7 +72,10 @@ pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor
|
|
72
72
|
}
|
73
73
|
}
|
74
74
|
|
75
|
-
return ((pm_line_column_t) {
|
75
|
+
return ((pm_line_column_t) {
|
76
|
+
.line = ((int32_t) left) + start_line - 1,
|
77
|
+
.column = (uint32_t) (offset - list->offsets[left - 1])
|
78
|
+
});
|
76
79
|
}
|
77
80
|
|
78
81
|
/**
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jruby-prism-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- JRuby Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -96,6 +96,8 @@ files:
|
|
96
96
|
- lib/prism/translation/parser/compiler.rb
|
97
97
|
- lib/prism/translation/parser/lexer.rb
|
98
98
|
- lib/prism/translation/parser/rubocop.rb
|
99
|
+
- lib/prism/translation/parser33.rb
|
100
|
+
- lib/prism/translation/parser34.rb
|
99
101
|
- lib/prism/translation/ripper.rb
|
100
102
|
- lib/prism/translation/ruby_parser.rb
|
101
103
|
- lib/prism/version.rb
|
@@ -144,11 +146,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
144
146
|
version: 2.7.0
|
145
147
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
148
|
requirements:
|
147
|
-
- - "
|
149
|
+
- - ">="
|
148
150
|
- !ruby/object:Gem::Version
|
149
|
-
version:
|
151
|
+
version: '0'
|
150
152
|
requirements:
|
151
|
-
- jar org.jruby, jruby-prism, 0.
|
153
|
+
- jar org.jruby, jruby-prism, 0.24.0, :scope => :runtime
|
152
154
|
rubygems_version: 3.3.26
|
153
155
|
signing_key:
|
154
156
|
specification_version: 4
|