class RBS::AST::Ruby::CommentBlock
CommentBlock is a collection of comments
# Comment1 < block1 # Comment2 < # Comment3 < block2
A comment block is a leading block or trailing block.
# This is leading block. # This is the second line of the leading block. foo # This is trailing block. # This is second line of the trailing block.
A leading block is a comment block where all of the comments are at the start of the line content. A trailing block is a comment block where the first comment of the block has something at the line before the comment.
Constants
- AnnotationSyntaxError
Attributes
Buffer
Sub buffer of the contents of the comments
Array[[ Comment, Integer ]]
Public Class Methods
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 60 def self.build(buffer, comments) blocks = [] #: Array[CommentBlock] comments = comments.filter {|comment| comment.is_a?(Prism::InlineComment) } until comments.empty? block_comments = [] #: Array[Prism::Comment] until comments.empty? comment = comments.first or raise last_comment = block_comments.last if last_comment if last_comment.location.end_line + 1 == comment.location.start_line if last_comment.location.start_column == comment.location.start_column unless comment.location.start_line_slice.index(/\S/) block_comments << comments.shift next end end end break else block_comments << comments.shift end end unless block_comments.empty? blocks << CommentBlock.new(buffer, block_comments.dup) end end blocks end
Build comment block instances
(Buffer source_buffer, Array[Comment]) → void
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 9 def initialize(source_buffer, comments) @name = source_buffer.name @offsets = [] # Assume the comment starts with a prefix whitespace prefix_str = "# " ranges = [] #: Array[Range[Integer]] comments.each do |comment| tuple = [comment, 2] #: [Prism::Comment, Integer] unless comment.location.slice.start_with?(prefix_str) tuple[1] = 1 end offsets << tuple start_char = comment.location.start_character_offset + tuple[1] end_char = comment.location.end_character_offset ranges << (start_char ... end_char) end @comment_buffer = source_buffer.sub_buffer(lines: ranges) end
Public Instance Methods
() → AST::Comment?
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 226 def as_comment lines = [] #: Array[String] each_paragraph([]) do |paragraph| case paragraph when Location lines << paragraph.local_source end end string = lines.join("\n") unless string.strip.empty? AST::Comment.new(string: string, location: location) end end
Returns an comment object that contains the docs of from the comment block
It ignores type annotations and syntax errors.
() → Array[Comment]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 211 def comments offsets.map { _1[0]} end
(Array[Symbol] variables) { (Location | AST::Ruby::Annotations::leading_annotation | AnnotationSyntaxError) → void } → void
(Array[Symbol] variables) → Enumerator[Location | AST::Ruby::Annotations::leading_annotation | AnnotationSyntaxError]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 98 def each_paragraph(variables, &block) if block if leading_annotation?(0) yield_annotation(0, 0, 0, variables, &block) else yield_paragraph(0, 0, variables, &block) end else enum_for :each_paragraph, variables end end
Yields paragraph and annotation
A paragraph is a sequence of lines that are separated by annotations. An annotation starts with a line starting with @rbs or :, and may continue with lines that has more leading spaces.
# Line 1 ^ Paragraph 1 # Line 2 | # | # Line 3 v # @rbs ... < Annotation 1 # @rbs ... ^ Annotation 2 # ... | # | # ... v # ^ Paragraph 2 # Line 4 | # Line 5 v
() → Integer
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 50 def end_line comments[-1].location.end_line end
The line number of the last comment in the block
() → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 36 def leading? comment = offsets[0][0] or raise comment.location.start_line_slice.index(/\S/) ? false : true end
Returns true if the comment block is a leading comment, which is attached to the successor node
(Integer index) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 215 def leading_annotation?(index) if index < comment_buffer.line_count text(index).start_with?(/@rbs\b/) and return true comment = offsets[index][0] comment.location.slice.start_with?(/\#:/) and return true end false end
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 174 def line_location(start_line, end_line) start_offset = comment_buffer.ranges[start_line].begin end_offset = comment_buffer.ranges[end_line].end Location.new(comment_buffer, start_offset, end_offset) end
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 54 def line_starts offsets.map do |comment, prefix_size| comment.location.start_character_offset + prefix_size end end
The character index of comment_buffer at the start of the lines
() → Location
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 180 def location() first_comment = comments[0] or raise last_comment = comments[-1] or raise comment_buffer.rbs_location(first_comment.location.join last_comment.location) end
(Integer start_line, Integer end_line, Array[Symbol] variables) → (AST::Ruby::Annotations::leading_annotation | AnnotationSyntaxError)
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 187 def parse_annotation_lines(start_line, end_line, variables) start_pos = comment_buffer.ranges[start_line].begin end_pos = comment_buffer.ranges[end_line].end begin Parser.parse_inline_leading_annotation(comment_buffer, start_pos...end_pos, variables: variables) rescue ParsingError => error AnnotationSyntaxError.new(line_location(start_line, end_line), error) end end
() → Integer
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 46 def start_line comments[0].location.start_line end
The line number of the first comment in the block
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 169 def text(comment_index) range = comment_buffer.ranges[comment_index] comment_buffer.content[range] or raise end
Returns the text content of the comment
() → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 41 def trailing? comment = offsets[0][0] or raise comment.location.start_line_slice.index(/\S/) ? true : false end
Returns true if the comment block is a trailing comment, which is attached to the predecessor node
(Array[Symbol] variables) → (AST::Ruby::Annotations::trailing_annotation | AnnotationSyntaxError | nil)
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 197 def trailing_annotation(variables) if trailing? comment = comments[0] or raise if comment.location.slice.start_with?(/#[:\[]/) begin Parser.parse_inline_trailing_annotation(comment_buffer, 0...comment_buffer.last_position, variables: variables) rescue ParsingError => error location = line_location(0, offsets.size - 1) AnnotationSyntaxError.new(location, error) end end end end
Returns a trailing annotation if it exists
-
Returns
nilif the block is not a type annotation -
Returns an annotation if the block has a type annotation
-
Returns
AnnotationSyntaxErrorif the annotation has a syntax error
(Integer start_line, Integer end_line, Integer current_line, Array[Symbol] variables) { (Location | AST::Ruby::Annotations::leading_annotation | AnnotationSyntaxError) → void } → void
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 130 def yield_annotation(start_line, end_line, current_line, variables, &block) # We already know at start_line..end_line are annotation. while true next_line = current_line + 1 if next_line >= comment_buffer.line_count annotation = parse_annotation_lines(start_line, end_line, variables) yield annotation if end_line > current_line yield_paragraph(end_line + 1, end_line + 1, variables, &block) end return end line_text = text(next_line) if leading_spaces = line_text.index(/\S/) if leading_spaces == 0 # End of annotation yield parse_annotation_lines(start_line, end_line, variables) if leading_annotation?(end_line + 1) yield_annotation(end_line + 1, end_line + 1, end_line + 1, variables, &block) else yield_paragraph(end_line + 1, end_line + 1, variables, &block) end return else current_line = next_line end_line = next_line end else current_line = next_line end end end
(Integer start_line, Integer current_line, Array[Symbol] variables) { (Location | AST::Ruby::Annotations::leading_annotation | AnnotationSyntaxError) → void } → void
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/lib/rbs/ast/ruby/comment_block.rb, line 110 def yield_paragraph(start_line, current_line, variables, &block) # We already know at start_line..current_line are paragraph. while true next_line = current_line + 1 if next_line >= comment_buffer.line_count yield line_location(start_line, current_line) return end if leading_annotation?(next_line) yield line_location(start_line, current_line) return yield_annotation(next_line, next_line, next_line, variables, &block) else current_line = next_line end end end