diff --git a/ext/prism/extension.c b/ext/prism/extension.c index 71c2d91b98..0fde54f4d1 100644 --- a/ext/prism/extension.c +++ b/ext/prism/extension.c @@ -471,9 +471,12 @@ parser_location(const pm_parser_t *parser, VALUE source, bool freeze, const uint */ static inline VALUE parser_comment(const pm_parser_t *parser, VALUE source, bool freeze, const pm_comment_t *comment) { - VALUE argv[] = { PARSER_LOCATION_LOC(parser, source, freeze, comment->location) }; + VALUE argv[] = { + comment->trailing ? Qtrue : Qfalse, + PARSER_LOCATION_LOC(parser, source, freeze, comment->location) + }; VALUE type = (comment->type == PM_COMMENT_EMBDOC) ? rb_cPrismEmbDocComment : rb_cPrismInlineComment; - return rb_class_new_instance_freeze(1, argv, type, freeze); + return rb_class_new_instance_freeze(2, argv, type, freeze); } /** diff --git a/include/prism/parser.h b/include/prism/parser.h index 95d7aac710..70dadadae3 100644 --- a/include/prism/parser.h +++ b/include/prism/parser.h @@ -467,6 +467,8 @@ typedef struct pm_comment { /** The type of comment that we've found. */ pm_comment_type_t type; + + bool trailing; } pm_comment_t; /** diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index 3570af136a..9df46cd8af 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -513,8 +513,15 @@ class Comment # The location of this comment in the source. attr_reader :location + # Returns true if this comment happens on the same line as other code and + # false if the comment is by itself. + def trailing? + @trailing + end + # Create a new comment object with the given location. - def initialize(location) + def initialize(trailing, location) + @trailing = trailing @location = location end @@ -532,12 +539,6 @@ def slice # 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? - !location.start_line_slice.strip.empty? - end - # Returns a string representation of this comment. def inspect "#" @@ -547,11 +548,6 @@ def inspect # EmbDocComment objects correspond to comments that are surrounded by =begin # and =end. class EmbDocComment < Comment - # This can only be true for inline comments. - def trailing? - false - end - # Returns a string representation of this comment. def inspect "#" diff --git a/src/prism.c b/src/prism.c index cd4d166a12..b25e321ab0 100644 --- a/src/prism.c +++ b/src/prism.c @@ -9291,12 +9291,13 @@ parser_lex_callback(pm_parser_t *parser) { * Return a new comment node of the specified type. */ static inline pm_comment_t * -parser_comment(pm_parser_t *parser, pm_comment_type_t type) { +parser_comment(pm_parser_t *parser, pm_comment_type_t type, bool trailing) { pm_comment_t *comment = (pm_comment_t *) xcalloc(1, sizeof(pm_comment_t)); if (comment == NULL) return NULL; *comment = (pm_comment_t) { .type = type, + .trailing = trailing, .location = { parser->current.start, parser->current.end } }; @@ -9324,7 +9325,7 @@ lex_embdoc(pm_parser_t *parser) { parser_lex_callback(parser); // Now, create a comment that is going to be attached to the parser. - pm_comment_t *comment = parser_comment(parser, PM_COMMENT_EMBDOC); + pm_comment_t *comment = parser_comment(parser, PM_COMMENT_EMBDOC, false); if (comment == NULL) return PM_TOKEN_EOF; // Now, loop until we find the end of the embedded documentation or the end @@ -9831,7 +9832,11 @@ parser_lex(pm_parser_t *parser) { // If we found a comment while lexing, then we're going to // add it to the list of comments in the file and keep // lexing. - pm_comment_t *comment = parser_comment(parser, PM_COMMENT_INLINE); + bool trailing = true; + if (parser->previous.type == PM_TOKEN_EOF || parser->previous.type == PM_TOKEN_NEWLINE) { + trailing = false; + } + pm_comment_t *comment = parser_comment(parser, PM_COMMENT_INLINE, trailing); pm_list_append(&parser->comment_list, (pm_list_node_t *) comment); if (ending) parser->current.end++; diff --git a/templates/lib/prism/serialize.rb.erb b/templates/lib/prism/serialize.rb.erb index 526be67431..fb207859e6 100644 --- a/templates/lib/prism/serialize.rb.erb +++ b/templates/lib/prism/serialize.rb.erb @@ -295,8 +295,8 @@ module Prism Array.new(load_varuint) do comment = case load_varuint - when 0 then InlineComment.new(load_location_object(freeze)) - when 1 then EmbDocComment.new(load_location_object(freeze)) + when 0 then InlineComment.new(load_boolean, load_location_object(freeze)) + when 1 then EmbDocComment.new(load_boolean, load_location_object(freeze)) end comment.freeze if freeze @@ -450,6 +450,10 @@ module Prism value end + def load_boolean + io.getbyte != 0 + end + def load_double io.read(8).unpack1("D") end diff --git a/templates/src/serialize.c.erb b/templates/src/serialize.c.erb index 3e15a11039..1cd3c35b1a 100644 --- a/templates/src/serialize.c.erb +++ b/templates/src/serialize.c.erb @@ -173,6 +173,9 @@ pm_serialize_comment(pm_parser_t *parser, pm_comment_t *comment, pm_buffer_t *bu // serialize type pm_buffer_append_byte(buffer, (uint8_t) comment->type); + // serialize trailing + pm_buffer_append_byte(buffer, (uint8_t) comment->trailing); + // serialize location pm_serialize_location(parser, &comment->location, buffer); }