From 2c0451f4fd99be287da8cafd3f0951723a0cd8f3 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Thu, 9 Apr 2026 10:26:20 +0900 Subject: [PATCH 1/3] Change rbs_loc_range to byte-based positions Simplify rbs_loc_range struct from 4 fields (start_char, end_char, start_byte, end_byte) back to 2 fields (start, end), now representing byte positions instead of character positions. Update ast_translation template to pass start_byte/end_byte from rbs_location_range, and remove rbs_new_location3 in favor of rbs_new_location2 which now accepts byte positions. Co-Authored-By: Claude Opus 4.6 (1M context) --- ext/rbs_extension/ast_translation.c | 216 +++++++++--------- ext/rbs_extension/legacy_location.c | 6 +- ext/rbs_extension/legacy_location.h | 4 +- .../ext/rbs_extension/ast_translation.c.erb | 6 +- 4 files changed, 116 insertions(+), 116 deletions(-) diff --git a/ext/rbs_extension/ast_translation.c b/ext/rbs_extension/ast_translation.c index c0e0ecb9b..c228e35be 100644 --- a/ext/rbs_extension/ast_translation.c +++ b/ext/rbs_extension/ast_translation.c @@ -57,7 +57,7 @@ VALUE rbs_location_range_to_ruby_location(rbs_translation_context_t ctx, rbs_loc return Qnil; } - return rbs_new_location2(ctx.buffer, range.start_char, range.end_char); + return rbs_new_location2(ctx.buffer, range.start_byte, range.end_byte); } VALUE rbs_location_range_list_to_ruby_array(rbs_translation_context_t ctx, rbs_location_range_list_t *list) { @@ -216,11 +216,11 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 5); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("lt"), (rbs_loc_range) { .start = node->lt_range.start_char, .end = node->lt_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_byte, .end = node->end_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_byte, .end = node->type_params_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("lt"), (rbs_loc_range) { .start = node->lt_range.start_byte, .end = node->lt_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params)); @@ -248,8 +248,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -267,10 +267,10 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 4); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_byte, .end = node->new_name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_byte, .end = node->eq_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_byte, .end = node->old_name_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_type_name @@ -290,8 +290,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -311,8 +311,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -332,10 +332,10 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 4); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_byte, .end = node->end_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_byte, .end = node->type_params_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params)); @@ -362,12 +362,12 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 6); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_char, .end = node->end_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("self_types"), (rbs_loc_range) { .start = node->self_types_range.start_char, .end = node->self_types_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("end"), (rbs_loc_range) { .start = node->end_range.start_byte, .end = node->end_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_byte, .end = node->type_params_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("self_types"), (rbs_loc_range) { .start = node->self_types_range.start_byte, .end = node->self_types_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params)); @@ -395,8 +395,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -414,10 +414,10 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 4); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_byte, .end = node->new_name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_byte, .end = node->eq_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_byte, .end = node->old_name_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_type_name @@ -437,10 +437,10 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 4); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_char, .end = node->eq_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("eq"), (rbs_loc_range) { .start = node->eq_range.start_byte, .end = node->eq_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_byte, .end = node->type_params_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params)); @@ -467,7 +467,7 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 1); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("clauses")), rbs_node_list_to_ruby_array(ctx, node->clauses)); @@ -484,9 +484,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("type_name"), (rbs_loc_range) { .start = node->type_name_range.start_char, .end = node->type_name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("type_name"), (rbs_loc_range) { .start = node->type_name_range.start_byte, .end = node->type_name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_byte, .end = node->new_name_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("type_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type_name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_ast_symbol @@ -504,8 +504,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("namespace"), (rbs_loc_range) { .start = node->namespace_range.start_char, .end = node->namespace_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("star"), (rbs_loc_range) { .start = node->star_range.start_char, .end = node->star_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("namespace"), (rbs_loc_range) { .start = node->namespace_range.start_byte, .end = node->namespace_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("star"), (rbs_loc_range) { .start = node->star_range.start_byte, .end = node->star_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("namespace")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->rbs_namespace)); // rbs_namespace @@ -530,11 +530,11 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 5); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_char, .end = node->new_name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_char, .end = node->old_name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("new_kind"), (rbs_loc_range) { .start = node->new_kind_range.start_char, .end = node->new_kind_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("old_kind"), (rbs_loc_range) { .start = node->old_kind_range.start_char, .end = node->old_kind_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("new_name"), (rbs_loc_range) { .start = node->new_name_range.start_byte, .end = node->new_name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("old_name"), (rbs_loc_range) { .start = node->old_name_range.start_byte, .end = node->old_name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("new_kind"), (rbs_loc_range) { .start = node->new_kind_range.start_byte, .end = node->new_kind_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("old_kind"), (rbs_loc_range) { .start = node->old_kind_range.start_byte, .end = node->old_kind_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("new_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->new_name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("old_name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->old_name)); // rbs_ast_symbol @@ -555,13 +555,13 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 7); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_byte, .end = node->ivar_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_byte, .end = node->ivar_name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_byte, .end = node->visibility_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -584,13 +584,13 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 7); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_byte, .end = node->ivar_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_byte, .end = node->ivar_name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_byte, .end = node->visibility_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -613,13 +613,13 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 7); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_char, .end = node->ivar_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_char, .end = node->ivar_name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar"), (rbs_loc_range) { .start = node->ivar_range.start_byte, .end = node->ivar_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("ivar_name"), (rbs_loc_range) { .start = node->ivar_name_range.start_byte, .end = node->ivar_name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_byte, .end = node->visibility_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -642,9 +642,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -663,9 +663,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -684,9 +684,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -706,9 +706,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -728,9 +728,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_char, .end = node->colon_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("colon"), (rbs_loc_range) { .start = node->colon_range.start_byte, .end = node->colon_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -749,11 +749,11 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 5); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_char, .end = node->kind_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("overloading"), (rbs_loc_range) { .start = node->overloading_range.start_char, .end = node->overloading_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_char, .end = node->visibility_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("kind"), (rbs_loc_range) { .start = node->kind_range.start_byte, .end = node->kind_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("overloading"), (rbs_loc_range) { .start = node->overloading_range.start_byte, .end = node->overloading_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("visibility"), (rbs_loc_range) { .start = node->visibility_range.start_byte, .end = node->visibility_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("kind")), rbs_method_definition_kind_to_ruby(node->kind)); // method_definition_kind @@ -789,9 +789,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 3); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_char, .end = node->keyword_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_required_child(loc, rb_intern("keyword"), (rbs_loc_range) { .start = node->keyword_range.start_byte, .end = node->keyword_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -1078,12 +1078,12 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 6); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("variance"), (rbs_loc_range) { .start = node->variance_range.start_char, .end = node->variance_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("unchecked"), (rbs_loc_range) { .start = node->unchecked_range.start_char, .end = node->unchecked_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("upper_bound"), (rbs_loc_range) { .start = node->upper_bound_range.start_char, .end = node->upper_bound_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("lower_bound"), (rbs_loc_range) { .start = node->lower_bound_range.start_char, .end = node->lower_bound_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("default"), (rbs_loc_range) { .start = node->default_range.start_char, .end = node->default_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("variance"), (rbs_loc_range) { .start = node->variance_range.start_byte, .end = node->variance_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("unchecked"), (rbs_loc_range) { .start = node->unchecked_range.start_byte, .end = node->unchecked_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("upper_bound"), (rbs_loc_range) { .start = node->upper_bound_range.start_byte, .end = node->upper_bound_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("lower_bound"), (rbs_loc_range) { .start = node->lower_bound_range.start_byte, .end = node->lower_bound_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("default"), (rbs_loc_range) { .start = node->default_range.start_byte, .end = node->default_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol rb_hash_aset(h, ID2SYM(rb_intern("variance")), rbs_type_param_variance_to_ruby(node->variance)); // type_param_variance @@ -1105,8 +1105,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("type"), (rbs_loc_range) { .start = node->type_range.start_char, .end = node->type_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_char, .end = node->type_params_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("type"), (rbs_loc_range) { .start = node->type_range.start_byte, .end = node->type_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("type_params"), (rbs_loc_range) { .start = node->type_params_range.start_byte, .end = node->type_params_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("type_params")), rbs_node_list_to_ruby_array(ctx, node->type_params)); rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node @@ -1165,8 +1165,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -1308,8 +1308,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -1327,8 +1327,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); @@ -1365,7 +1365,7 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 1); - rbs_loc_legacy_add_optional_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("type")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->type)); // rbs_node rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_ast_symbol @@ -1383,8 +1383,8 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan VALUE location = rbs_location_range_to_ruby_location(ctx, node->base.location); rbs_loc *loc = rbs_check_location(location); rbs_loc_legacy_alloc_children(loc, 2); - rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_char, .end = node->name_range.end_char }); - rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_char, .end = node->args_range.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("name"), (rbs_loc_range) { .start = node->name_range.start_byte, .end = node->name_range.end_byte }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("args"), (rbs_loc_range) { .start = node->args_range.start_byte, .end = node->args_range.end_byte }); rb_hash_aset(h, ID2SYM(rb_intern("location")), location); rb_hash_aset(h, ID2SYM(rb_intern("name")), rbs_struct_to_ruby_value(ctx, (rbs_node_t *) node->name)); // rbs_type_name rb_hash_aset(h, ID2SYM(rb_intern("args")), rbs_node_list_to_ruby_array(ctx, node->args)); diff --git a/ext/rbs_extension/legacy_location.c b/ext/rbs_extension/legacy_location.c index 36006878e..aec790b9a 100644 --- a/ext/rbs_extension/legacy_location.c +++ b/ext/rbs_extension/legacy_location.c @@ -193,16 +193,16 @@ VALUE rbs_new_location(VALUE buffer, rbs_range_t rg) { rbs_loc *loc; VALUE obj = TypedData_Make_Struct(RBS_Location, rbs_loc, &location_type, loc); - rbs_loc_init(loc, buffer, (rbs_loc_range) { rg.start.char_pos, rg.end.char_pos }); + rbs_loc_init(loc, buffer, (rbs_loc_range) { rg.start.byte_pos, rg.end.byte_pos }); return obj; } -VALUE rbs_new_location2(VALUE buffer, int start_char, int end_char) { +VALUE rbs_new_location2(VALUE buffer, int start_byte, int end_byte) { rbs_loc *loc; VALUE obj = TypedData_Make_Struct(RBS_Location, rbs_loc, &location_type, loc); - rbs_loc_init(loc, buffer, (rbs_loc_range) { .start = start_char, .end = end_char }); + rbs_loc_init(loc, buffer, (rbs_loc_range) { start_byte, end_byte }); return obj; } diff --git a/ext/rbs_extension/legacy_location.h b/ext/rbs_extension/legacy_location.h index 3a00260e9..d665c7c89 100644 --- a/ext/rbs_extension/legacy_location.h +++ b/ext/rbs_extension/legacy_location.h @@ -23,7 +23,7 @@ SUPPRESS_RUBY_HEADER_DIAGNOSTICS_END extern VALUE RBS_Location; /** - * Range of character index for `rbs_loc` locations. + * Range of byte index for `rbs_loc` locations. */ typedef struct { int start; @@ -57,7 +57,7 @@ typedef struct { * */ VALUE rbs_new_location(VALUE buffer, rbs_range_t rg); -VALUE rbs_new_location2(VALUE buffer, int start_char, int end_char); +VALUE rbs_new_location2(VALUE buffer, int start_byte, int end_byte); /** * Return rbs_loc associated with the RBS::Location object. diff --git a/templates/ext/rbs_extension/ast_translation.c.erb b/templates/ext/rbs_extension/ast_translation.c.erb index cf4dba4be..8439a8ddd 100644 --- a/templates/ext/rbs_extension/ast_translation.c.erb +++ b/templates/ext/rbs_extension/ast_translation.c.erb @@ -50,7 +50,7 @@ VALUE rbs_location_range_to_ruby_location(rbs_translation_context_t ctx, rbs_loc return Qnil; } - return rbs_new_location2(ctx.buffer, range.start_char, range.end_char); + return rbs_new_location2(ctx.buffer, range.start_byte, range.end_byte); } VALUE rbs_location_range_list_to_ruby_array(rbs_translation_context_t ctx, rbs_location_range_list_t *list) { @@ -162,9 +162,9 @@ VALUE rbs_struct_to_ruby_value(rbs_translation_context_t ctx, rbs_node_t *instan rbs_loc_legacy_alloc_children(loc, <%= node.locations.size %>); <%- node.locations.each do |location_field| -%> <%- if location_field.required? -%> - rbs_loc_legacy_add_required_child(loc, rb_intern("<%= location_field.name %>"), (rbs_loc_range) { .start = node-><%= location_field.attribute_name %>.start_char, .end = node-><%= location_field.attribute_name %>.end_char }); + rbs_loc_legacy_add_required_child(loc, rb_intern("<%= location_field.name %>"), (rbs_loc_range) { .start = node-><%= location_field.attribute_name %>.start_byte, .end = node-><%= location_field.attribute_name %>.end_byte }); <%- else -%> - rbs_loc_legacy_add_optional_child(loc, rb_intern("<%= location_field.name %>"), (rbs_loc_range) { .start = node-><%= location_field.attribute_name %>.start_char, .end = node-><%= location_field.attribute_name %>.end_char }); + rbs_loc_legacy_add_optional_child(loc, rb_intern("<%= location_field.name %>"), (rbs_loc_range) { .start = node-><%= location_field.attribute_name %>.start_byte, .end = node-><%= location_field.attribute_name %>.end_byte }); <%- end -%> <%- end -%> rb_hash_aset(h, ID2SYM(rb_intern("location")), location); From 4e9d9cb05ffdaa5e0ff198caac5129224b497e8d Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Thu, 9 Apr 2026 10:26:32 +0900 Subject: [PATCH 2/3] Switch Buffer to byte-based and add new Location API Buffer: - Change ranges to use bytesize instead of char size - Use byteslice for lines and sub_buffer - Switch Prism integration from start_character_offset to start_offset Location: - Add start_byte/end_byte as primary byte position methods - Add start_char/end_char for character positions (computed from bytes) - Add start_byte_column/end_byte_column and start_char_column/end_char_column - Deprecate start_pos/end_pos in favor of start_char/start_byte - Deprecate start_column/end_column in favor of start_byte_column/start_char_column - Use byteslice for source extraction Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/rbs/buffer.rb | 13 ++++--- lib/rbs/location_aux.rb | 76 +++++++++++++++++++++++++++++++++-------- sig/location.rbs | 68 +++++++++++++++++++++++++++--------- 3 files changed, 120 insertions(+), 37 deletions(-) diff --git a/lib/rbs/buffer.rb b/lib/rbs/buffer.rb index 313cd428b..088dcf1c8 100644 --- a/lib/rbs/buffer.rb +++ b/lib/rbs/buffer.rb @@ -20,7 +20,7 @@ def initialize(name: nil, content:, parent: nil) end def lines - ranges.map { self.content[_1] || raise } #$ String + ranges.map { content.byteslice(_1) || raise } #$ String end def line_count @@ -31,7 +31,6 @@ def ranges @ranges ||= begin if content.empty? ranges = [0...0] #: Array[Range[Integer]] - lines = [""] else lines = content.lines lines << "" if content.end_with?("\n") @@ -40,9 +39,9 @@ def ranges offset = 0 lines.each do |line| - size0 = line.size + size0 = line.bytesize line = line.chomp - range = offset...(offset+line.size) + range = offset...(offset+line.bytesize) ranges << range offset += size0 @@ -89,9 +88,9 @@ def inspect def rbs_location(location, loc2=nil) if loc2 - Location.new(self.top_buffer, location.start_character_offset, loc2.end_character_offset) + Location.new(self.top_buffer, location.start_offset, loc2.end_offset) else - Location.new(self.top_buffer, location.start_character_offset, location.end_character_offset) + Location.new(self.top_buffer, location.start_offset, location.end_offset) end end @@ -100,7 +99,7 @@ def sub_buffer(lines:) lines.each_with_index do |range, index| start_pos = range.begin end_pos = range.end - slice = content[start_pos...end_pos] or raise + slice = content.byteslice(start_pos, end_pos - start_pos) or raise if slice.include?("\n") raise "Line #{index + 1} cannot contain newline character." end diff --git a/lib/rbs/location_aux.rb b/lib/rbs/location_aux.rb index 9e298805f..5debd9ef8 100644 --- a/lib/rbs/location_aux.rb +++ b/lib/rbs/location_aux.rb @@ -10,7 +10,7 @@ def inspect else source.each_line.first&.chomp&.inspect end - "#<#{self.class}:#{self.__id__} buffer=#{buffer.name}, start=#{start_line}:#{start_column}, pos=#{start_pos}...#{end_pos}, children=#{(rks + ops).join(",")} source=#{src}>" + "#<#{self.class}:#{self.__id__} buffer=#{buffer.name}, start=#{start_line}:#{start_byte_column}, pos=#{start_byte}...#{end_byte}, children=#{(rks + ops).join(",")} source=#{src}>" end def self.new(buffer_ = nil, start_pos_ = nil, end_pos_ = nil, buffer: nil, start_pos: nil, end_pos: nil) @@ -28,14 +28,36 @@ def self.new(buffer_ = nil, start_pos_ = nil, end_pos_ = nil, buffer: nil, start WithChildren = self - def start_pos + def start_byte buffer.absolute_position(_start_pos) || raise end - def end_pos + def end_byte buffer.absolute_position(_end_pos) || raise end + def start_char + top = buffer.top_buffer + top.content.byteslice(0, start_byte)&.length || 0 + end + + def end_char + top = buffer.top_buffer + top.content.byteslice(0, end_byte)&.length || 0 + end + + # @deprecated Use `start_char` or `start_byte` instead. + def start_pos + RBS.print_warning { "`RBS::Location#start_pos` is deprecated. Use `start_char` or `start_byte` instead." } + start_char + end + + # @deprecated Use `end_char` or `end_byte` instead. + def end_pos + RBS.print_warning { "`RBS::Location#end_pos` is deprecated. Use `end_char` or `end_byte` instead." } + end_char + end + def name buffer.name end @@ -44,54 +66,80 @@ def start_line start_loc[0] end - def start_column + def start_byte_column start_loc[1] end + def start_char_column + top = buffer.top_buffer + line, byte_col = top.pos_to_loc(start_byte) + line_range = top.ranges[line - 1] or return 0 + top.content.byteslice(line_range.begin, byte_col)&.length || 0 + end + + def end_byte_column + end_loc[1] + end + + def end_char_column + top = buffer.top_buffer + line, byte_col = top.pos_to_loc(end_byte) + line_range = top.ranges[line - 1] or return 0 + top.content.byteslice(line_range.begin, byte_col)&.length || 0 + end + + # @deprecated Use `start_byte_column` or `start_char_column` instead. + def start_column + RBS.print_warning { "`RBS::Location#start_column` is deprecated. Use `start_byte_column` or `start_char_column` instead." } + start_byte_column + end + def end_line end_loc[0] end + # @deprecated Use `end_byte_column` or `end_char_column` instead. def end_column - end_loc[1] + RBS.print_warning { "`RBS::Location#end_column` is deprecated. Use `end_byte_column` or `end_char_column` instead." } + end_byte_column end def start_loc - @start_loc ||= buffer.top_buffer.pos_to_loc(start_pos) + @start_loc ||= buffer.top_buffer.pos_to_loc(start_byte) end def end_loc - @end_loc ||= buffer.top_buffer.pos_to_loc(end_pos) + @end_loc ||= buffer.top_buffer.pos_to_loc(end_byte) end def range - @range ||= start_pos...end_pos + @range ||= start_byte...end_byte end def source - @source ||= (buffer.top_buffer.content[range] || raise) + @source ||= (buffer.top_buffer.content.byteslice(start_byte, end_byte - start_byte) || raise) end def to_s - "#{name || "-"}:#{start_line}:#{start_column}...#{end_line}:#{end_column}" + "#{name || "-"}:#{start_line}:#{start_byte_column}...#{end_line}:#{end_byte_column}" end def ==(other) other.is_a?(Location) && other.buffer == buffer && - other.start_pos == start_pos && - other.end_pos == end_pos + other.start_byte == start_byte && + other.end_byte == end_byte end def to_json(state = nil) { start: { line: start_line, - column: start_column + column: start_byte_column }, end: { line: end_line, - column: end_column + column: end_byte_column }, buffer: { name: name&.to_s diff --git a/sig/location.rbs b/sig/location.rbs index d27bb616b..976d3fc65 100644 --- a/sig/location.rbs +++ b/sig/location.rbs @@ -1,6 +1,6 @@ module RBS - # Location is the range on buffer, `start_pos..end_pos`. - # The index is based on characters. + # Location is the range on buffer, `start_char..end_char`. + # The index is based on bytes. # # A location can have _child_ locations. # @@ -8,17 +8,37 @@ module RBS # The buffer this location points on. attr_reader buffer (): Buffer - # The absolute start index of character the range starts from + # The absolute start byte position # - # It returns the index in the `buffer.top_buffer`. + # It returns the byte index in the `buffer.top_buffer`. # - attr_reader start_pos (): Integer + def start_byte: () -> Integer - # The absolute end index of character the range ends at + # The absolute end byte position # - # It returns the index in the `buffer.top_buffer`. + # It returns the byte index in the `buffer.top_buffer`. # - attr_reader end_pos (): Integer + def end_byte: () -> Integer + + # The absolute start character position + # + # It returns the character index in the `buffer.top_buffer`. + # Computed from byte position. + # + def start_char: () -> Integer + + # The absolute end character position + # + # It returns the character index in the `buffer.top_buffer`. + # Computed from byte position. + # + def end_char: () -> Integer + + %a{deprecated: use start_char or start_byte instead} + def start_pos: () -> Integer + + %a{deprecated: use end_char or end_byte instead} + def end_pos: () -> Integer def initialize: (Buffer, Integer start_pos, Integer end_pos) -> void @@ -30,37 +50,53 @@ module RBS # Returns the name of the buffer. def name: () -> untyped - # The *raw* index of character the range starts from. + # The *raw* byte index the range starts from. attr_reader _start_pos (): Integer - # The *raw* index of character the range ends at. + # The *raw* byte index the range ends at. attr_reader _end_pos (): Integer # Line of the `start_pos` (1 origin, absolute) attr_reader start_line (): Integer - # Column of the `start_pos` (0 origin, absolute) - attr_reader start_column (): Integer + # Byte column of the `start_pos` (0 origin, absolute) + def start_byte_column: () -> Integer + + # Character column of the `start_pos` (0 origin, absolute) + # Computed from byte position; slower than `start_byte_column`. + def start_char_column: () -> Integer + + %a{deprecated: use start_byte_column or start_char_column instead} + def start_column: () -> Integer # Line of the `end_pos` (1 origin, absolute) attr_reader end_line (): Integer - # Column of the `end_pos` (0 origin, absolute) - attr_reader end_column (): Integer + # Byte column of the `end_pos` (0 origin, absolute) + def end_byte_column: () -> Integer + + # Character column of the `end_pos` (0 origin, absolute) + # Computed from byte position; slower than `end_byte_column`. + def end_char_column: () -> Integer + + %a{deprecated: use end_byte_column or end_char_column instead} + def end_column: () -> Integer # The absolute line-column pair of the start position + # Column is byte-based. # attr_reader start_loc (): Buffer::loc @start_loc: Buffer::loc? # The absolute line-column pair of the end position + # Column is byte-based. # attr_reader end_loc (): Buffer::loc @end_loc: Buffer::loc? - # The absolute range of the start and end position + # The absolute range of the start and end byte position attr_reader range (): Range[Integer] @range: Range[Integer]? @@ -119,7 +155,7 @@ module RBS def local_location: () -> self # Returns the source of `#local_location` - # + # def local_source: () -> String private From a0946f9da25e1db3a48fec6945cd5e9a83cb31fb Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Thu, 9 Apr 2026 10:26:44 +0900 Subject: [PATCH 3/3] Migrate consumers to new byte-based Location API - Rewriter: use start_byte/end_byte, start_byte_column, bytesplice - Errors: use start_byte_column/end_byte_column for marker alignment - Writer: use start_byte_column for indentation - Locator: add byte_column/char_column keyword arguments to find/find2, deprecate column keyword, add char_column_to_byte_column helper - CommentBlock, LocationHelper: use Prism start_offset (byte) instead of start_character_offset (char) - ParserAux, Declarations: use start_byte/end_byte - Update test expectation for byte-based column values Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/rbs/ast/ruby/comment_block.rb | 10 ++--- lib/rbs/ast/ruby/declarations.rb | 4 +- lib/rbs/ast/ruby/helpers/location_helper.rb | 2 +- lib/rbs/errors.rb | 4 +- lib/rbs/locator.rb | 47 ++++++++++++++++++--- lib/rbs/parser_aux.rb | 2 +- lib/rbs/rewriter.rb | 18 ++++---- lib/rbs/writer.rb | 2 +- sig/locator.rbs | 33 ++++++++++++--- test/rbs/type_parsing_test.rb | 2 +- 10 files changed, 92 insertions(+), 32 deletions(-) diff --git a/lib/rbs/ast/ruby/comment_block.rb b/lib/rbs/ast/ruby/comment_block.rb index 34f009cad..995655123 100644 --- a/lib/rbs/ast/ruby/comment_block.rb +++ b/lib/rbs/ast/ruby/comment_block.rb @@ -25,9 +25,9 @@ def initialize(source_buffer, comments) offsets << tuple - start_char = comment.location.start_character_offset + tuple[1] - end_char = comment.location.end_character_offset - ranges << (start_char ... end_char) + start_byte = comment.location.start_offset + tuple[1] + end_byte = comment.location.end_offset + ranges << (start_byte ... end_byte) end @comment_buffer = source_buffer.sub_buffer(lines: ranges) @@ -53,7 +53,7 @@ def end_line def line_starts offsets.map do |comment, prefix_size| - comment.location.start_character_offset + prefix_size + comment.location.start_offset + prefix_size end end @@ -168,7 +168,7 @@ def yield_annotation(start_line, end_line, current_line, variables, &block) def text(comment_index) range = comment_buffer.ranges[comment_index] - comment_buffer.content[range] or raise + comment_buffer.content.byteslice(range) or raise end def line_location(start_line, end_line) diff --git a/lib/rbs/ast/ruby/declarations.rb b/lib/rbs/ast/ruby/declarations.rb index 4651db0c5..6994c22b4 100644 --- a/lib/rbs/ast/ruby/declarations.rb +++ b/lib/rbs/ast/ruby/declarations.rb @@ -44,8 +44,8 @@ def location if type_annotation Location.new( type_name_location.buffer, - type_name_location.start_pos, - type_annotation.location.end_pos + type_name_location.start_byte, + type_annotation.location.end_byte ) else type_name_location diff --git a/lib/rbs/ast/ruby/helpers/location_helper.rb b/lib/rbs/ast/ruby/helpers/location_helper.rb index 677919cc6..9620ffe2c 100644 --- a/lib/rbs/ast/ruby/helpers/location_helper.rb +++ b/lib/rbs/ast/ruby/helpers/location_helper.rb @@ -6,7 +6,7 @@ module Ruby module Helpers module LocationHelper def rbs_location(location) - Location.new(buffer, location.start_character_offset, location.end_character_offset) + Location.new(buffer, location.start_offset, location.end_offset) end end end diff --git a/lib/rbs/errors.rb b/lib/rbs/errors.rb index 9f4e51e77..4fd6c82aa 100644 --- a/lib/rbs/errors.rb +++ b/lib/rbs/errors.rb @@ -34,8 +34,8 @@ def detailed_message(highlight: false, **) # Support only one line return msg unless location.start_line == location.end_line - indent = " " * location.start_column - marker = "^" * ([location.end_column - location.start_column, 1].max or raise) + indent = " " * location.start_byte_column + marker = "^" * ([location.end_byte_column - location.start_byte_column, 1].max or raise) io = StringIO.new io.puts msg diff --git a/lib/rbs/locator.rb b/lib/rbs/locator.rb index 88363e470..eea199517 100644 --- a/lib/rbs/locator.rb +++ b/lib/rbs/locator.rb @@ -10,8 +10,16 @@ def initialize(buffer:, dirs:, decls:) @decls = decls end - def find(line:, column:) - pos = buffer.loc_to_pos([line, column]) + # Find RBS elements at the given position. + # + # Returns a list of components, inner component comes first. + # + # @param line [Integer] Line number (1-origin) + # @param byte_column [Integer] Byte offset within the line (0-origin) + # @param char_column [Integer] Character offset within the line (0-origin). Converted to byte offset internally. + # @param column [Integer] Deprecated. Treated as char column for backwards compatibility. + def find(line:, column: nil, byte_column: nil, char_column: nil) + pos = resolve_position(line: line, column: column, byte_column: byte_column, char_column: char_column) dirs.each do |dir| array = [] #: Array[component] @@ -26,8 +34,14 @@ def find(line:, column:) [] end - def find2(line:, column:) - path = find(line: line, column: column) + # Find RBS elements at the given position, returning the inner most symbol and outer components. + # + # @param line [Integer] Line number (1-origin) + # @param byte_column [Integer] Byte offset within the line (0-origin) + # @param char_column [Integer] Character offset within the line (0-origin). Converted to byte offset internally. + # @param column [Integer] Deprecated. Treated as char column for backwards compatibility. + def find2(line:, column: nil, byte_column: nil, char_column: nil) + path = find(line: line, column: column, byte_column: byte_column, char_column: char_column) return if path.empty? @@ -238,10 +252,33 @@ def find_in_loc(pos, location:, array:) def test_loc(pos, location:) if location - location.start_pos <= pos && pos <= location.end_pos + location.start_byte <= pos && pos <= location.end_byte else false end end + + private + + # Converts char column to byte column within a line. + def char_column_to_byte_column(line, char_column) #: Integer + line_range = buffer.ranges[line - 1] or return 0 + line_content = buffer.content.byteslice(line_range) or return 0 + prefix = line_content.encode(Encoding::UTF_8).chars.first(char_column).join + prefix.bytesize + end + + def resolve_position(line:, column:, byte_column:, char_column:) #: Integer + if byte_column + buffer.loc_to_pos([line, byte_column]) + elsif char_column + buffer.loc_to_pos([line, char_column_to_byte_column(line, char_column)]) + elsif column + RBS.print_warning { "`column` keyword argument of RBS::Locator#find is deprecated. Use `char_column` or `byte_column` instead." } + buffer.loc_to_pos([line, char_column_to_byte_column(line, column)]) + else + raise ArgumentError, "One of `byte_column`, `char_column`, or `column` must be specified" + end + end end end diff --git a/lib/rbs/parser_aux.rb b/lib/rbs/parser_aux.rb index 974c54e20..bae7e707a 100644 --- a/lib/rbs/parser_aux.rb +++ b/lib/rbs/parser_aux.rb @@ -23,7 +23,7 @@ def self.parse_signature(source) resolved = magic_comment(buf) start_pos = if resolved - (resolved.location || raise).end_pos + (resolved.location || raise).end_byte else 0 end diff --git a/lib/rbs/rewriter.rb b/lib/rbs/rewriter.rb index ec1b1d94d..5ad7ba93b 100644 --- a/lib/rbs/rewriter.rb +++ b/lib/rbs/rewriter.rb @@ -13,7 +13,7 @@ def initialize(buffer) def rewrite(location, string) @rewrites.each do |existing_location, _| - if location.start_pos < existing_location.end_pos && existing_location.start_pos < location.end_pos + if location.start_byte < existing_location.end_byte && existing_location.start_byte < location.end_byte raise "Overlapping rewrites: #{existing_location} and #{location}" end end @@ -23,9 +23,9 @@ def rewrite(location, string) end def add_comment(*locations, content:) - earliest = locations.min_by(&:start_pos) or raise "At least one location is required" - insert_pos = earliest.start_pos - indent = " " * earliest.start_column + earliest = locations.min_by(&:start_char) or raise "At least one location is required" + insert_pos = earliest.start_byte + indent = " " * earliest.start_byte_column formatted = format_comment(content, indent) @@ -35,15 +35,15 @@ def add_comment(*locations, content:) def replace_comment(comment, content:) location = comment.location or raise "Comment must have a location" - indent = " " * location.start_column + indent = " " * location.start_byte_column rewrite(location, format_comment(content, indent)) end def delete_comment(comment) location = comment.location or raise "Comment must have a location" - line_start = location.start_pos - location.start_column - line_end = location.end_pos + 1 + line_start = location.start_byte - location.start_byte_column + line_end = location.end_byte + 1 loc = Location.new(buffer, line_start, line_end) rewrite(loc, "") end @@ -51,8 +51,8 @@ def delete_comment(comment) def string result = buffer.content.dup - @rewrites.sort_by { |location, _| location.start_pos }.reverse_each do |location, replacement| - result[location.start_pos...location.end_pos] = replacement + @rewrites.sort_by { |location, _| location.start_byte }.reverse_each do |location, replacement| + result.bytesplice(location.start_byte...location.end_byte, replacement) end result diff --git a/lib/rbs/writer.rb b/lib/rbs/writer.rb index 4d2a1d0d2..b11c91542 100644 --- a/lib/rbs/writer.rb +++ b/lib/rbs/writer.rb @@ -305,7 +305,7 @@ def method_name(name) def write_loc_source(located) if preserve? && loc = located.location - put_lines(loc.source, leading_spaces: loc.start_column) + put_lines(loc.source, leading_spaces: loc.start_byte_column) else yield end diff --git a/sig/locator.rbs b/sig/locator.rbs index a16543bc0..f933f2a78 100644 --- a/sig/locator.rbs +++ b/sig/locator.rbs @@ -27,15 +27,27 @@ module RBS def initialize: (buffer: Buffer, decls: Array[AST::Declarations::t], dirs: Array[AST::Directives::t]) -> void - # Returns list of components. - # Inner component comes first. + # Find RBS elements at the given position. + # Returns a list of components, inner component comes first. # - def find: (line: Integer, column: Integer) -> Array[component] + # `line` is the line number (1-origin). + # `byte_column` is the byte offset within the line (0-origin). + # `char_column` is the character offset within the line (0-origin), converted to byte offset internally. + # + def find: (line: Integer, byte_column: Integer) -> Array[component] + | (line: Integer, char_column: Integer) -> Array[component] + | %a{deprecated: use char_column or byte_column instead} (line: Integer, column: Integer) -> Array[component] - # Returns pair of the inner most symbol and outer components. + # Find RBS elements at the given position, returning the inner most symbol and outer components. # It ensures the array starts with a AST/type component. # - def find2: (line: Integer, column: Integer) -> [Symbol?, Array[component]]? + # `line` is the line number (1-origin). + # `byte_column` is the byte offset within the line (0-origin). + # `char_column` is the character offset within the line (0-origin), converted to byte offset internally. + # + def find2: (line: Integer, byte_column: Integer) -> [Symbol?, Array[component]]? + | (line: Integer, char_column: Integer) -> [Symbol?, Array[component]]? + | %a{deprecated: use char_column or byte_column instead} (line: Integer, column: Integer) -> [Symbol?, Array[component]]? def find_in_directive: (Integer pos, AST::Directives::t, Array[component]) -> bool @@ -52,5 +64,16 @@ module RBS def find_in_loc: (Integer pos, location: Location[untyped, untyped]?, array: Array[component]) -> bool def test_loc: (Integer pos, location: Location[untyped, untyped]?) -> bool + + private + + # Converts a character column offset to a byte column offset within the given line. + # + def char_column_to_byte_column: (Integer line, Integer char_column) -> Integer + + # Resolves line and column arguments to a byte position in the buffer. + # Exactly one of `byte_column`, `char_column`, or `column` must be given. + # + def resolve_position: (line: Integer, column: Integer?, byte_column: Integer?, char_column: Integer?) -> Integer end end diff --git a/test/rbs/type_parsing_test.rb b/test/rbs/type_parsing_test.rb index 97c5754b9..93e5ec181 100644 --- a/test/rbs/type_parsing_test.rb +++ b/test/rbs/type_parsing_test.rb @@ -1027,6 +1027,6 @@ def test_parse__byte_range_incorrect Parser.parse_type(input, byte_range: 2...) end - assert_equal "a.rbs:1:2...1:3: Syntax error: unexpected token for simple type, token=`🐈` (ErrorToken)", exn.message + assert_equal "a.rbs:1:5...1:9: Syntax error: unexpected token for simple type, token=`🐈` (ErrorToken)", exn.message end end