jruby-prism-parser 0.23.0.pre.SNAPSHOT-java → 0.24.0-java
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/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
|