Skip to content

Commit c67f65d

Browse files
committed
Switch diagnostics over to using slices
1 parent f79be8e commit c67f65d

6 files changed

Lines changed: 56 additions & 50 deletions

File tree

ext/prism/extension.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -455,16 +455,22 @@ rb_class_new_instance_freeze(int argc, const VALUE *argv, VALUE klass, bool free
455455
* Create a new Location instance from the given parser and bounds.
456456
*/
457457
static inline VALUE
458-
parser_location(const pm_parser_t *parser, VALUE source, bool freeze, uint32_t start, uint32_t length) {
458+
parser_location(VALUE source, bool freeze, uint32_t start, uint32_t length) {
459459
VALUE argv[] = { source, LONG2FIX(start), LONG2FIX(length) };
460460
return rb_class_new_instance_freeze(3, argv, rb_cPrismLocation, freeze);
461461
}
462462

463+
/**
464+
* Create a new Location instance from the given parser and slice.
465+
*/
466+
#define PARSER_LOCATION_SLICE(parser, source, freeze, slice) \
467+
parser_location(source, freeze, slice.start, slice.length)
468+
463469
/**
464470
* Create a new Location instance from the given parser and location.
465471
*/
466472
#define PARSER_LOCATION_LOC(parser, source, freeze, loc) \
467-
parser_location(parser, source, freeze, (uint32_t) (loc.start - parser->start), (uint32_t) (loc.end - loc.start))
473+
parser_location(source, freeze, (uint32_t) (loc.start - parser->start), (uint32_t) (loc.end - loc.start))
468474

469475
/**
470476
* Build a new Comment instance from the given parser and comment.
@@ -500,9 +506,9 @@ parser_comments(const pm_parser_t *parser, VALUE source, bool freeze) {
500506
* Build a new MagicComment instance from the given parser and magic comment.
501507
*/
502508
static inline VALUE
503-
parser_magic_comment(const pm_parser_t *parser, VALUE source, bool freeze, const pm_magic_comment_t *magic_comment) {
504-
VALUE key_loc = parser_location(parser, source, freeze, magic_comment->key.start, magic_comment->key.length);
505-
VALUE value_loc = parser_location(parser, source, freeze, magic_comment->value.start, magic_comment->value.length);
509+
parser_magic_comment(VALUE source, bool freeze, const pm_magic_comment_t *magic_comment) {
510+
VALUE key_loc = parser_location(source, freeze, magic_comment->key.start, magic_comment->key.length);
511+
VALUE value_loc = parser_location(source, freeze, magic_comment->value.start, magic_comment->value.length);
506512
VALUE argv[] = { key_loc, value_loc };
507513
return rb_class_new_instance_freeze(2, argv, rb_cPrismMagicComment, freeze);
508514
}
@@ -519,7 +525,7 @@ parser_magic_comments(const pm_parser_t *parser, VALUE source, bool freeze) {
519525
magic_comment != NULL;
520526
magic_comment = (const pm_magic_comment_t *) magic_comment->node.next
521527
) {
522-
VALUE value = parser_magic_comment(parser, source, freeze, magic_comment);
528+
VALUE value = parser_magic_comment(source, freeze, magic_comment);
523529
rb_ary_push(magic_comments, value);
524530
}
525531

@@ -536,7 +542,7 @@ parser_data_loc(const pm_parser_t *parser, VALUE source, bool freeze) {
536542
if (parser->data_loc.length == 0) {
537543
return Qnil;
538544
} else {
539-
return parser_location(parser, source, freeze, parser->data_loc.start, parser->data_loc.length);
545+
return parser_location(source, freeze, parser->data_loc.start, parser->data_loc.length);
540546
}
541547
}
542548

@@ -554,7 +560,7 @@ parser_errors(const pm_parser_t *parser, rb_encoding *encoding, VALUE source, bo
554560
) {
555561
VALUE type = ID2SYM(rb_intern(pm_diagnostic_id_human(error->diag_id)));
556562
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(error->message, encoding));
557-
VALUE location = PARSER_LOCATION_LOC(parser, source, freeze, error->location);
563+
VALUE location = PARSER_LOCATION_SLICE(parser, source, freeze, error->location);
558564

559565
VALUE level = Qnil;
560566
switch (error->level) {
@@ -594,7 +600,7 @@ parser_warnings(const pm_parser_t *parser, rb_encoding *encoding, VALUE source,
594600
) {
595601
VALUE type = ID2SYM(rb_intern(pm_diagnostic_id_human(warning->diag_id)));
596602
VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(warning->message, encoding));
597-
VALUE location = PARSER_LOCATION_LOC(parser, source, freeze, warning->location);
603+
VALUE location = PARSER_LOCATION_SLICE(parser, source, freeze, warning->location);
598604

599605
VALUE level = Qnil;
600606
switch (warning->level) {

src/prism.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -405,14 +405,14 @@ debug_lex_state_set(pm_parser_t *parser, pm_lex_state_t state, char const * call
405405
*/
406406
static inline void
407407
pm_parser_err(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
408-
pm_diagnostic_list_append(&parser->error_list, start, end, diag_id);
408+
pm_diagnostic_list_append(&parser->error_list, (uint32_t) (start - parser->start), (uint32_t) (end - start), diag_id);
409409
}
410410

411411
/**
412412
* Append an error to the list of errors on the parser using a format string.
413413
*/
414-
#define PM_PARSER_ERR_FORMAT(parser, start, end, diag_id, ...) \
415-
pm_diagnostic_list_append_format(&parser->error_list, start, end, diag_id, __VA_ARGS__)
414+
#define PM_PARSER_ERR_FORMAT(parser_, start_, end_, diag_id_, ...) \
415+
pm_diagnostic_list_append_format(&(parser_)->error_list, (uint32_t) ((start_) - (parser_)->start), (uint32_t) ((end_) - (start_)), diag_id_, __VA_ARGS__)
416416

417417
/**
418418
* Append an error to the list of errors on the parser using the location of the
@@ -490,7 +490,7 @@ pm_parser_err_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_
490490
*/
491491
static inline void
492492
pm_parser_warn(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
493-
pm_diagnostic_list_append(&parser->warning_list, start, end, diag_id);
493+
pm_diagnostic_list_append(&parser->warning_list, (uint32_t) (start - parser->start), (uint32_t) (end - start), diag_id);
494494
}
495495

496496
/**
@@ -514,8 +514,8 @@ pm_parser_warn_node(pm_parser_t *parser, const pm_node_t *node, pm_diagnostic_id
514514
/**
515515
* Append a warning to the list of warnings on the parser using a format string.
516516
*/
517-
#define PM_PARSER_WARN_FORMAT(parser, start, end, diag_id, ...) \
518-
pm_diagnostic_list_append_format(&parser->warning_list, start, end, diag_id, __VA_ARGS__)
517+
#define PM_PARSER_WARN_FORMAT(parser_, start_, end_, diag_id_, ...) \
518+
pm_diagnostic_list_append_format(&(parser_)->warning_list, (uint32_t) ((start_) - (parser_)->start), (uint32_t) ((end_) - (start_)), diag_id_, __VA_ARGS__)
519519

520520
/**
521521
* Append a warning to the list of warnings on the parser using the location of
@@ -3807,7 +3807,7 @@ pm_double_parse(pm_parser_t *parser, const pm_token_t *token) {
38073807
ellipsis = "";
38083808
}
38093809

3810-
pm_diagnostic_list_append_format(&parser->warning_list, token->start, token->end, PM_WARN_FLOAT_OUT_OF_RANGE, warn_width, (const char *) token->start, ellipsis);
3810+
pm_diagnostic_list_append_format(&parser->warning_list, (uint32_t) (token->start - parser->start), (uint32_t) (token->end - token->start), PM_WARN_FLOAT_OUT_OF_RANGE, warn_width, (const char *) token->start, ellipsis);
38113811
value = (value < 0.0) ? -HUGE_VAL : HUGE_VAL;
38123812
}
38133813

@@ -13155,8 +13155,8 @@ pm_hash_key_static_literals_add(pm_parser_t *parser, pm_static_literals_t *liter
1315513155

1315613156
pm_diagnostic_list_append_format(
1315713157
&parser->warning_list,
13158-
duplicated->location.start,
13159-
duplicated->location.end,
13158+
(uint32_t) (duplicated->location.start - parser->start),
13159+
(uint32_t) (duplicated->location.end - duplicated->location.start),
1316013160
PM_WARN_DUPLICATED_HASH_KEY,
1316113161
(int) pm_buffer_length(&buffer),
1316213162
pm_buffer_value(&buffer),
@@ -13178,8 +13178,8 @@ pm_when_clause_static_literals_add(pm_parser_t *parser, pm_static_literals_t *li
1317813178
if ((previous = pm_static_literals_add(&parser->newline_list, parser->start_line, literals, node, false)) != NULL) {
1317913179
pm_diagnostic_list_append_format(
1318013180
&parser->warning_list,
13181-
node->location.start,
13182-
node->location.end,
13181+
(uint32_t) (node->location.start - parser->start),
13182+
(uint32_t) (node->location.end - node->location.start),
1318313183
PM_WARN_DUPLICATED_WHEN_CLAUSE,
1318413184
pm_newline_list_line_column(&parser->newline_list, node->location.start, parser->start_line).line,
1318513185
pm_newline_list_line_column(&parser->newline_list, previous->location.start, parser->start_line).line

src/util/pm_strpbrk.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
* Add an invalid multibyte character error to the parser.
55
*/
66
static inline void
7-
pm_strpbrk_invalid_multibyte_character(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) {
8-
pm_diagnostic_list_append_format(&parser->error_list, start, end, PM_ERR_INVALID_MULTIBYTE_CHARACTER, *start);
7+
pm_strpbrk_invalid_multibyte_character(pm_parser_t *parser, uint32_t start, uint32_t length) {
8+
pm_diagnostic_list_append_format(&parser->error_list, start, length, PM_ERR_INVALID_MULTIBYTE_CHARACTER, parser->start[start]);
99
}
1010

1111
/**
1212
* Set the explicit encoding for the parser to the current encoding.
1313
*/
1414
static inline void
15-
pm_strpbrk_explicit_encoding_set(pm_parser_t *parser, const uint8_t *source, size_t width) {
15+
pm_strpbrk_explicit_encoding_set(pm_parser_t *parser, uint32_t start, uint32_t length) {
1616
if (parser->explicit_encoding != NULL) {
1717
if (parser->explicit_encoding == parser->encoding) {
1818
// Okay, we already locked to this encoding.
1919
} else if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) {
2020
// Not okay, we already found a Unicode escape sequence and this
2121
// conflicts.
22-
pm_diagnostic_list_append_format(&parser->error_list, source, source + width, PM_ERR_MIXED_ENCODING, parser->encoding->name);
22+
pm_diagnostic_list_append_format(&parser->error_list, start, length, PM_ERR_MIXED_ENCODING, parser->encoding->name);
2323
} else {
2424
// Should not be anything else.
2525
assert(false && "unreachable");
@@ -61,7 +61,7 @@ pm_strpbrk_utf8(pm_parser_t *parser, const uint8_t *source, const uint8_t *chars
6161
index++;
6262
} while (index < maximum && pm_encoding_utf_8_char_width(source + index, (ptrdiff_t) (maximum - index)) == 0);
6363

64-
pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index);
64+
pm_strpbrk_invalid_multibyte_character(parser, (uint32_t) ((source + start) - parser->start), (uint32_t) (index - start));
6565
}
6666
}
6767
}
@@ -81,7 +81,7 @@ pm_strpbrk_ascii_8bit(pm_parser_t *parser, const uint8_t *source, const uint8_t
8181
return source + index;
8282
}
8383

84-
if (validate && source[index] >= 0x80) pm_strpbrk_explicit_encoding_set(parser, source, 1);
84+
if (validate && source[index] >= 0x80) pm_strpbrk_explicit_encoding_set(parser, (uint32_t) (source - parser->start), 1);
8585
index++;
8686
}
8787

@@ -105,7 +105,7 @@ pm_strpbrk_multi_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t
105105
index++;
106106
} else {
107107
size_t width = encoding->char_width(source + index, (ptrdiff_t) (maximum - index));
108-
if (validate) pm_strpbrk_explicit_encoding_set(parser, source, width);
108+
if (validate) pm_strpbrk_explicit_encoding_set(parser, (uint32_t) (source - parser->start), (uint32_t) width);
109109

110110
if (width > 0) {
111111
index += width;
@@ -122,7 +122,7 @@ pm_strpbrk_multi_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t
122122
index++;
123123
} while (index < maximum && encoding->char_width(source + index, (ptrdiff_t) (maximum - index)) == 0);
124124

125-
pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index);
125+
pm_strpbrk_invalid_multibyte_character(parser, (uint32_t) ((source + start) - parser->start), (uint32_t) (index - start));
126126
}
127127
}
128128
}
@@ -148,7 +148,7 @@ pm_strpbrk_single_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t
148148
index++;
149149
} else {
150150
size_t width = encoding->char_width(source + index, (ptrdiff_t) (maximum - index));
151-
pm_strpbrk_explicit_encoding_set(parser, source, width);
151+
pm_strpbrk_explicit_encoding_set(parser, (uint32_t) (source - parser->start), (uint32_t) width);
152152

153153
if (width > 0) {
154154
index += width;
@@ -163,7 +163,7 @@ pm_strpbrk_single_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t
163163
index++;
164164
} while (index < maximum && encoding->char_width(source + index, (ptrdiff_t) (maximum - index)) == 0);
165165

166-
pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index);
166+
pm_strpbrk_invalid_multibyte_character(parser, (uint32_t) ((source + start) - parser->start), (uint32_t) (index - start));
167167
}
168168
}
169169
}

templates/include/prism/diagnostic.h.erb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef struct {
4040
pm_list_node_t node;
4141

4242
/** The location of the diagnostic in the source. */
43-
pm_location_t location;
43+
pm_slice_t location;
4444

4545
/** The ID of the diagnostic. */
4646
pm_diagnostic_id_t diag_id;
@@ -100,25 +100,25 @@ const char * pm_diagnostic_id_human(pm_diagnostic_id_t diag_id);
100100
* memory for its message.
101101
*
102102
* @param list The list to append to.
103-
* @param start The start of the diagnostic.
104-
* @param end The end of the diagnostic.
103+
* @param start The source offset of the start of the diagnostic.
104+
* @param length The length of the diagnostic.
105105
* @param diag_id The diagnostic ID.
106106
* @return Whether the diagnostic was successfully appended.
107107
*/
108-
bool pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id);
108+
bool pm_diagnostic_list_append(pm_list_t *list, uint32_t start, uint32_t length, pm_diagnostic_id_t diag_id);
109109

110110
/**
111111
* Append a diagnostic to the given list of diagnostics that is using a format
112112
* string for its message.
113113
*
114114
* @param list The list to append to.
115-
* @param start The start of the diagnostic.
116-
* @param end The end of the diagnostic.
115+
* @param start The source offset of the start of the diagnostic.
116+
* @param length The length of the diagnostic.
117117
* @param diag_id The diagnostic ID.
118118
* @param ... The arguments to the format string for the message.
119119
* @return Whether the diagnostic was successfully appended.
120120
*/
121-
bool pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...);
121+
bool pm_diagnostic_list_append_format(pm_list_t *list, uint32_t start, uint32_t length, pm_diagnostic_id_t diag_id, ...);
122122

123123
/**
124124
* Deallocate the internal state of the given diagnostic list.

templates/src/diagnostic.c.erb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -447,12 +447,12 @@ pm_diagnostic_level(pm_diagnostic_id_t diag_id) {
447447
* Append an error to the given list of diagnostic.
448448
*/
449449
bool
450-
pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) {
450+
pm_diagnostic_list_append(pm_list_t *list, uint32_t start, uint32_t length, pm_diagnostic_id_t diag_id) {
451451
pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) xcalloc(1, sizeof(pm_diagnostic_t));
452452
if (diagnostic == NULL) return false;
453453

454454
*diagnostic = (pm_diagnostic_t) {
455-
.location = { start, end },
455+
.location = { .start = start, .length = length },
456456
.diag_id = diag_id,
457457
.message = pm_diagnostic_message(diag_id),
458458
.owned = false,
@@ -468,7 +468,7 @@ pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *
468468
* string for its message.
469469
*/
470470
bool
471-
pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...) {
471+
pm_diagnostic_list_append_format(pm_list_t *list, uint32_t start, uint32_t length, pm_diagnostic_id_t diag_id, ...) {
472472
va_list arguments;
473473
va_start(arguments, diag_id);
474474

@@ -485,19 +485,19 @@ pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const ui
485485
return false;
486486
}
487487

488-
size_t length = (size_t) (result + 1);
489-
char *message = (char *) xmalloc(length);
488+
size_t message_length = (size_t) (result + 1);
489+
char *message = (char *) xmalloc(message_length);
490490
if (message == NULL) {
491491
xfree(diagnostic);
492492
return false;
493493
}
494494

495495
va_start(arguments, diag_id);
496-
vsnprintf(message, length, format, arguments);
496+
vsnprintf(message, message_length, format, arguments);
497497
va_end(arguments);
498498

499499
*diagnostic = (pm_diagnostic_t) {
500-
.location = { start, end },
500+
.location = { .start = start, .length = length },
501501
.diag_id = diag_id,
502502
.message = message,
503503
.owned = true,

templates/src/serialize.c.erb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) {
241241
}
242242

243243
static void
244-
pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
244+
pm_serialize_diagnostic(pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
245245
// serialize the type
246246
pm_buffer_append_varuint(buffer, (uint32_t) diagnostic->diag_id);
247247

@@ -251,18 +251,18 @@ pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buf
251251
pm_buffer_append_string(buffer, diagnostic->message, message_length);
252252

253253
// serialize location
254-
pm_serialize_location(parser, &diagnostic->location, buffer);
254+
pm_serialize_slice(&diagnostic->location, buffer);
255255

256256
pm_buffer_append_byte(buffer, diagnostic->level);
257257
}
258258

259259
static void
260-
pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
260+
pm_serialize_diagnostic_list(pm_list_t *list, pm_buffer_t *buffer) {
261261
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list)));
262262

263263
pm_diagnostic_t *diagnostic;
264264
for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) {
265-
pm_serialize_diagnostic(parser, diagnostic, buffer);
265+
pm_serialize_diagnostic(diagnostic, buffer);
266266
}
267267
}
268268

@@ -286,8 +286,8 @@ pm_serialize_metadata(pm_parser_t *parser, pm_buffer_t *buffer) {
286286
<%- end -%>
287287
pm_serialize_magic_comment_list(&parser->magic_comment_list, buffer);
288288
pm_serialize_data_loc(parser, buffer);
289-
pm_serialize_diagnostic_list(parser, &parser->error_list, buffer);
290-
pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer);
289+
pm_serialize_diagnostic_list(&parser->error_list, buffer);
290+
pm_serialize_diagnostic_list(&parser->warning_list, buffer);
291291
}
292292

293293
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"

0 commit comments

Comments
 (0)