aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/prism/parse_result.rb57
-rw-r--r--prism/extension.c19
-rw-r--r--prism/templates/lib/prism/serialize.rb.erb8
-rw-r--r--test/prism/comments_test.rb14
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}" }