diff options
author | Kevin Newton <[email protected]> | 2023-10-27 13:34:25 -0400 |
---|---|---|
committer | git <[email protected]> | 2023-10-27 18:09:14 +0000 |
commit | df10e10314e860c73c57e6bf43cf84aac7686270 (patch) | |
tree | b4e4c6a98a56d9fea76fec9e8862e38bf4d6d12f | |
parent | 95cc0f946eb641be8dea4b7118598be77d993183 (diff) |
[ruby/prism] Parse inline comments
https://github.com/ruby/prism/commit/44090d9f26
-rw-r--r-- | prism/extension.c | 60 | ||||
-rw-r--r-- | test/prism/parse_inline_comments_test.rb | 23 |
2 files changed, 83 insertions, 0 deletions
diff --git a/prism/extension.c b/prism/extension.c index 786adb2c0f..27dbc5c8f7 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -396,6 +396,37 @@ parse_input(pm_string_t *input, const char *filepath) { return result; } +// Parse the given input and return an array of Comment objects. +static VALUE +parse_input_inline_comments(pm_string_t *input, const char *filepath) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), filepath); + + pm_node_t *node = pm_parse(&parser); + rb_encoding *encoding = rb_enc_find(parser.encoding.name); + + VALUE source = pm_source_new(&parser, encoding); + VALUE comments = rb_ary_new(); + + for (pm_comment_t *comment = (pm_comment_t *) parser.comment_list.head; comment != NULL; comment = (pm_comment_t *) comment->node.next) { + if (comment->type != PM_COMMENT_INLINE) continue; + + VALUE location_argv[] = { + source, + LONG2FIX(comment->start - parser.start), + LONG2FIX(comment->end - comment->start) + }; + + VALUE comment_argv[] = { ID2SYM(rb_intern("inline")), rb_class_new_instance(3, location_argv, rb_cPrismLocation) }; + rb_ary_push(comments, rb_class_new_instance(2, comment_argv, rb_cPrismComment)); + } + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + return comments; +} + // Parse the given string and return a ParseResult instance. static VALUE parse(int argc, VALUE *argv, VALUE self) { @@ -436,6 +467,33 @@ parse_file(VALUE self, VALUE filepath) { return value; } +// Parse the given string and return an array of Comment objects. +static VALUE +parse_inline_comments(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + pm_string_t input; + input_load_string(&input, string); + + return parse_input_inline_comments(&input, check_string(filepath)); +} + +// Parse the given file and return an array of Comment objects. +static VALUE +parse_file_inline_comments(VALUE self, VALUE filepath) { + pm_string_t input; + + const char *checked = check_string(filepath); + if (!pm_string_mapped_init(&input, checked)) return Qnil; + + VALUE value = parse_input_inline_comments(&input, checked); + pm_string_free(&input); + + return value; +} + // Parse the given string and return a ParseResult instance. static VALUE parse_lex(int argc, VALUE *argv, VALUE self) { @@ -621,6 +679,8 @@ Init_prism(void) { rb_define_singleton_method(rb_cPrism, "lex_file", lex_file, 1); rb_define_singleton_method(rb_cPrism, "parse", parse, -1); rb_define_singleton_method(rb_cPrism, "parse_file", parse_file, 1); + rb_define_singleton_method(rb_cPrism, "parse_inline_comments", parse_inline_comments, -1); + rb_define_singleton_method(rb_cPrism, "parse_file_inline_comments", parse_file_inline_comments, 1); rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1); rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, 1); diff --git a/test/prism/parse_inline_comments_test.rb b/test/prism/parse_inline_comments_test.rb new file mode 100644 index 0000000000..0087e1e9af --- /dev/null +++ b/test/prism/parse_inline_comments_test.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative "test_helper" + +return if Prism::BACKEND == :FFI + +module Prism + class ParseInlineCommentsTest < TestCase + def test_parse_inline_comments + comments = Prism.parse_inline_comments("# foo") + + assert_kind_of Array, comments + assert_equal 1, comments.length + end + + def test_parse_file_inline_comments + comments = Prism.parse_file_inline_comments(__FILE__) + + assert_kind_of Array, comments + assert_equal 1, comments.length + end + end +end |