Module: RuboCop::Cop::Style::RbsInline::CommentParser

Overview

Utility module for parsing RBS inline comments

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#parsed_commentsObject (readonly)

: Array



14
15
16
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 14

def parsed_comments
  @parsed_comments
end

Instance Method Details

#find_doc_style_param_annotations(def_line) ⇒ Object

Find @rbs parameter annotations before a method definition rubocop:disable Layout/LineLength



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 84

def find_doc_style_param_annotations(def_line) #: Array[RBS::Inline::AST::Annotations::VarType | RBS::Inline::AST::Annotations::BlockType | RBS::Inline::AST::Annotations::SplatParamType | RBS::Inline::AST::Annotations::DoubleSplatParamType]?
  # rubocop:enable Layout/LineLength
  leading_annotation = find_leading_annotation(def_line)
  return unless leading_annotation

  annotations = [] #: Array[RBS::Inline::AST::Annotations::VarType | RBS::Inline::AST::Annotations::BlockType | RBS::Inline::AST::Annotations::SplatParamType | RBS::Inline::AST::Annotations::DoubleSplatParamType] # rubocop:disable Layout/LineLength
  leading_annotation.each_annotation do |annotation|
    case annotation
    when RBS::Inline::AST::Annotations::VarType, RBS::Inline::AST::Annotations::BlockType,
         RBS::Inline::AST::Annotations::SplatParamType, RBS::Inline::AST::Annotations::DoubleSplatParamType
      annotations << annotation
    end
  end
  annotations.empty? ? nil : annotations
end

#find_doc_style_return_annotation(def_line) ⇒ Object

Find @rbs return annotation before a method definition



102
103
104
105
106
107
108
109
110
111
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 102

def find_doc_style_return_annotation(def_line) #: RBS::Inline::AST::Annotations::ReturnType?
  leading_annotation = find_leading_annotation(def_line)
  return unless leading_annotation

  ret = nil #: RBS::Inline::AST::Annotations::ReturnType?
  leading_annotation.each_annotation do |annotation|
    ret = annotation if annotation.is_a?(RBS::Inline::AST::Annotations::ReturnType)
  end
  ret
end

#find_last_consecutive_comment(start_comment, &block) ⇒ Object

Find the last comment in a consecutive block starting from start_comment



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 25

def find_last_consecutive_comment(start_comment, &block) #: Parser::Source::Comment
  start_index = processed_source.comments.index(start_comment)
  return start_comment unless start_index

  last_comment = start_comment
  current_line = start_comment.loc.line

  processed_source.comments.drop(start_index + 1).each do |comment|
    break if comment.loc.line != current_line + 1
    break unless block.call(comment)

    last_comment = comment
    current_line = comment.loc.line
  end

  last_comment
end

#find_leading_annotation(def_line) ⇒ Object

Find the leading annotation comment before the given line



45
46
47
48
49
50
51
52
53
54
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 45

def find_leading_annotation(def_line) #: RBS::Inline::AnnotationParser::ParsingResult?
  parsed_comments.find do |r|
    last_comment = r.comments.last or next
    next unless last_comment.location.start_line + 1 == def_line

    # Exclude trailing inline comments (e.g., `def method = value #: Type`)
    # by verifying all comment lines contain only whitespace before '#'
    r.comments.all? { |c| processed_source.buffer.source_line(c.location.start_line).match?(/\A\s*#/) }
  end
end

#find_method_type_signature_comments(def_line) ⇒ Object

Find method type signature comments (#:) before a method definition



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 58

def find_method_type_signature_comments(def_line) #: Array[Parser::Source::Comment]?
  leading_annotation = find_leading_annotation(def_line)
  return unless leading_annotation

  annotation_lines = leading_annotation.comments
                                       .select { |c| c.location.slice.start_with?('#:') }
                                       .map { |c| c.location.start_line }
  return if annotation_lines.empty?

  comments = processed_source.comments.select do |c|
    annotation_lines.include?(c.loc.expression.line)
  end
  comments.empty? ? nil : comments
end

#find_trailing_comment(line) ⇒ Object

Find trailing comment on the same line as the method definition



75
76
77
78
79
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 75

def find_trailing_comment(line) #: Parser::Source::Comment?
  processed_source.comments.find do |c|
    c.loc.expression.line == line && c.text.match?(/\A#:/)
  end
end

#overload_type_signatures?(def_line) ⇒ Boolean

Returns true if there are 2 or more leading #: method type signature lines (overloads). Overloads cannot be expressed in doc_style format, so they take precedence over style config.

Returns:

  • (Boolean)


116
117
118
119
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 116

def overload_type_signatures?(def_line) #: bool
  comments = find_method_type_signature_comments(def_line)
  comments.is_a?(Array) && comments.size >= 2
end

#parse_commentsObject

Parse comments from the source code



17
18
19
20
# File 'lib/rubocop/cop/style/rbs_inline/comment_parser.rb', line 17

def parse_comments #: Array[RBS::Inline::AnnotationParser::ParsingResult]
  parsed_result = Prism.parse(processed_source.buffer.source)
  @parsed_comments = RBS::Inline::AnnotationParser.parse(parsed_result.comments)
end