summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <[email protected]>2023-10-27 13:34:25 -0400
committergit <[email protected]>2023-10-27 18:09:14 +0000
commitdf10e10314e860c73c57e6bf43cf84aac7686270 (patch)
treeb4e4c6a98a56d9fea76fec9e8862e38bf4d6d12f
parent95cc0f946eb641be8dea4b7118598be77d993183 (diff)
[ruby/prism] Parse inline comments
https://github.com/ruby/prism/commit/44090d9f26
-rw-r--r--prism/extension.c60
-rw-r--r--test/prism/parse_inline_comments_test.rb23
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