diff options
-rw-r--r-- | lib/prism/parse_result.rb | 57 | ||||
-rw-r--r-- | prism/extension.c | 19 | ||||
-rw-r--r-- | prism/templates/lib/prism/serialize.rb.erb | 8 | ||||
-rw-r--r-- | test/prism/comments_test.rb | 14 |
4 files changed, 60 insertions, 38 deletions
diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index c7f6cdcd16..170a529bea 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -189,45 +189,58 @@ module Prism end end - # This represents a comment that was encountered during parsing. + # This represents a comment that was encountered during parsing. It is the + # base class for all comment types. class Comment - # These are the three types that comments can be from a source file. - # - # :inline comments are the most common. They correspond to comments in the - # source file like this one that start with #. - # - # :embdoc comments are comments that are surrounded by =begin and =end. - # - # :__END__ comments are comments that are after the __END__ keyword in a - # source file. - TYPES = [:inline, :embdoc, :__END__] - - # The type of comment that this comment is. - attr_reader :type - # The location of this comment in the source. attr_reader :location - # Create a new comment object with the given type and location. - def initialize(type, location) - @type = type + # Create a new comment object with the given location. + def initialize(location) @location = location end # Implement the hash pattern matching interface for Comment. def deconstruct_keys(keys) - { type: type, location: location } + { location: location } end - # Returns true if the comment happens on the same line as other code and + # This can only be true for inline comments. + def trailing? + false + end + end + + # InlineComment objects are the most common. They correspond to comments in + # the source file like this one that start with #. + class InlineComment < Comment + # Returns true if this comment happens on the same line as other code and # false if the comment is by itself. def trailing? - type == :inline && !location.start_line_slice.strip.empty? + !location.start_line_slice.strip.empty? end # Returns a string representation of this comment. def inspect - "#<Prism::Comment @type=#{@type.inspect} @location=#{@location.inspect}>" + "#<Prism::InlineComment @location=#{location.inspect}>" + end + end + + # EmbDocComment objects correspond to comments that are surrounded by =begin + # and =end. + class EmbDocComment < Comment + # Returns a string representation of this comment. + def inspect + "#<Prism::EmbDocComment @location=#{location.inspect}>" + end + end + + # DATAComment objects correspond to comments that are after the __END__ + # keyword in a source file. + class DATAComment < Comment + # Returns a string representation of this comment. + def inspect + "#<Prism::DATAComment @location=#{location.inspect}>" end end diff --git a/prism/extension.c b/prism/extension.c index 839a5cda38..1f6e199d2f 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -10,6 +10,9 @@ VALUE rb_cPrismToken; VALUE rb_cPrismLocation; VALUE rb_cPrismComment; +VALUE rb_cPrismInlineComment; +VALUE rb_cPrismEmbDocComment; +VALUE rb_cPrismDATAComment; VALUE rb_cPrismMagicComment; VALUE rb_cPrismParseError; VALUE rb_cPrismParseWarning; @@ -320,21 +323,18 @@ parser_comments(pm_parser_t *parser, VALUE source) { VALUE type; switch (comment->type) { case PM_COMMENT_INLINE: - type = ID2SYM(rb_intern("inline")); + type = rb_cPrismInlineComment; break; case PM_COMMENT_EMBDOC: - type = ID2SYM(rb_intern("embdoc")); + type = rb_cPrismEmbDocComment; break; case PM_COMMENT___END__: - type = ID2SYM(rb_intern("__END__")); - break; - default: - type = ID2SYM(rb_intern("inline")); + type = rb_cPrismDATAComment; break; } - VALUE comment_argv[] = { type, rb_class_new_instance(3, location_argv, rb_cPrismLocation) }; - rb_ary_push(comments, rb_class_new_instance(2, comment_argv, rb_cPrismComment)); + VALUE comment_argv[] = { rb_class_new_instance(3, location_argv, rb_cPrismLocation) }; + rb_ary_push(comments, rb_class_new_instance(1, comment_argv, type)); } return comments; @@ -933,6 +933,9 @@ Init_prism(void) { rb_cPrismToken = rb_define_class_under(rb_cPrism, "Token", rb_cObject); rb_cPrismLocation = rb_define_class_under(rb_cPrism, "Location", rb_cObject); rb_cPrismComment = rb_define_class_under(rb_cPrism, "Comment", rb_cObject); + rb_cPrismInlineComment = rb_define_class_under(rb_cPrism, "InlineComment", rb_cPrismComment); + rb_cPrismEmbDocComment = rb_define_class_under(rb_cPrism, "EmbDocComment", rb_cPrismComment); + rb_cPrismDATAComment = rb_define_class_under(rb_cPrism, "DATAComment", rb_cPrismComment); rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject); rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject); rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject); diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb index ef8ebbbae8..32bc741178 100644 --- a/prism/templates/lib/prism/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -86,7 +86,13 @@ module Prism end def load_comments - load_varint.times.map { Comment.new(Comment::TYPES.fetch(load_varint), load_location) } + load_varint.times.map do + case load_varint + when 0 then InlineComment.new(load_location) + when 1 then EmbDocComment.new(load_location) + when 2 then DATAComment.new(load_location) + end + end end def load_metadata diff --git a/test/prism/comments_test.rb b/test/prism/comments_test.rb index dc43fb6a36..d14409458c 100644 --- a/test/prism/comments_test.rb +++ b/test/prism/comments_test.rb @@ -10,7 +10,7 @@ module Prism assert_comment( source, - :inline, + InlineComment, start_offset: 0, end_offset: 9, start_line: 1, @@ -29,7 +29,7 @@ module Prism assert_comment( source, - :inline, + InlineComment, start_offset: 10, end_offset: 21, start_line: 2, @@ -47,7 +47,7 @@ module Prism assert_comment( source, - :__END__, + DATAComment, start_offset: 0, end_offset: 16, start_line: 1, @@ -62,7 +62,7 @@ module Prism assert_comment( source, - :__END__, + DATAComment, start_offset: 0, end_offset: 18, start_line: 1, @@ -81,7 +81,7 @@ module Prism assert_comment( source, - :embdoc, + EmbDocComment, start_offset: 0, end_offset: 20, start_line: 1, @@ -99,7 +99,7 @@ module Prism assert_comment( source, - :embdoc, + EmbDocComment, start_offset: 0, end_offset: 24, start_line: 1, @@ -138,7 +138,7 @@ module Prism def assert_comment(source, type, start_offset:, end_offset:, start_line:, end_line:, start_column:, end_column:) result = Prism.parse(source) assert result.errors.empty?, result.errors.map(&:message).join("\n") - assert_equal type, result.comments.first.type + assert_kind_of type, result.comments.first location = result.comments.first.location assert_equal start_offset, location.start_offset, -> { "Expected start_offset to be #{start_offset}" } |