Class: RuboCop::Cop::Style::RbsInline::UnmatchedAnnotations

Inherits:
Base
  • Object
show all
Includes:
RangeHelp, CommentParser, SourceCodeHelper
Defined in:
lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb,
sig/rubocop/cop/style/rbs_inline/unmatched_annotations.rbs

Overview

IRB::Inline annotations comments for parameters should be matched to the parameters.

Examples:

# bad
# @rbs unknown: String
def method(arg); end

# good
# @rbs arg: String
def method(arg); end

Constant Summary collapse

MSG =

Returns:

  • (::String)
'target parameter not found.'

Instance Attribute Summary

Attributes included from CommentParser

#parsed_comments

Instance Method Summary collapse

Methods included from SourceCodeHelper

#annotation_range, #blank_line?, #char_at, #character_offset, #comment_at, #comment_range, #line_range, #location_to_range, #source_code_at

Methods included from CommentParser

#find_doc_style_param_annotations, #find_doc_style_return_annotation, #find_last_consecutive_comment, #find_leading_annotation, #find_method_type_signature_comments, #find_trailing_comment, #overload_type_signatures?, #parse_comments

Instance Method Details

#add_offense_for(annotation) ⇒ void

This method returns an undefined value.

Parameters:

  • annotation (RBS::Inline::AST::Annotations::BlockType, RBS::Inline::AST::Annotations::IvarType, RBS::Inline::AST::Annotations::ReturnType, RBS::Inline::AST::Annotations::VarType)


141
142
143
144
145
146
147
148
149
150
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 141

def add_offense_for(annotation) #: void # rubocop:disable Metrics/AbcSize
  name = annotation_name(annotation)
  loc = annotation.source.comments.first&.location or raise
  source = processed_source.buffer.source.dup.force_encoding('ASCII')
  text = source[loc.start_offset...loc.end_offset] or raise
  comment = text.force_encoding(processed_source.buffer.source.encoding)
  start_offset = loc.start_offset + (comment.index(name) || 0)
  range = range_between(character_offset(start_offset), character_offset(start_offset + name.size))
  add_offense(range)
end

#annotation_name(annotation) ⇒ String

Parameters:

  • annotation (RBS::Inline::AST::Annotations::BlockType, RBS::Inline::AST::Annotations::IvarType, RBS::Inline::AST::Annotations::ReturnType, RBS::Inline::AST::Annotations::VarType)

Returns:

  • (String)


126
127
128
129
130
131
132
133
134
135
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 126

def annotation_name(annotation) #: String
  case annotation
  when RBS::Inline::AST::Annotations::BlockType
    "&#{annotation.name}"
  when RBS::Inline::AST::Annotations::ReturnType
    'return'
  else
    annotation.name.to_s
  end
end

#args_for(node) ⇒ RuboCop::AST::Node

Parameters:

  • node (RuboCop::AST::DefNode)

Returns:

  • (RuboCop::AST::Node)


113
114
115
116
117
118
119
120
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 113

def args_for(node) #: RuboCop::AST::Node
  case node.type
  when :defs
    node.children[2]
  else
    node.children[1]
  end
end

#arguments_for(node) ⇒ Array[String]

Parameters:

  • node (RuboCop::AST::DefNode)

Returns:

  • (Array[String])


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 80

def arguments_for(node) #: Array[String] # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
  args_for(node).children.flat_map do |argument| # rubocop:disable Metrics/BlockLength
    name = argument.children[0]&.to_s
    case argument.type
    when :arg, :optarg, :kwarg, :kwoptarg
      [name]
    when :restarg
      if name
        ["*#{name}", '*']
      else
        ['*']
      end
    when :kwrestarg
      if name
        ["**#{name}", '**']
      else
        ['**']
      end
    when :blockarg
      if name
        ['&', "&#{name}"]
      else
        ['&', '&block']
      end
    when :forward_arg
      ['...']
    else
      raise
    end
  end
end

#on_def(node) ⇒ void

This method returns an undefined value.

Parameters:

  • node (RuboCop::AST::DefNode)


33
34
35
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 33

def on_def(node) #: void
  process(node)
end

#on_defs(node) ⇒ void

This method returns an undefined value.

Parameters:

  • node (RuboCop::AST::DefNode)


38
39
40
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 38

def on_defs(node) #: void
  process(node)
end

#on_investigation_endvoid

This method returns an undefined value.

: void



42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 42

def on_investigation_end #: void
  parsed_comments.each do |comment|
    comment.each_annotation do |annotation|
      case annotation
      when RBS::Inline::AST::Annotations::BlockType,
           RBS::Inline::AST::Annotations::ReturnType,
           RBS::Inline::AST::Annotations::VarType
        add_offense_for(annotation)
      end
    end
  end

  super
end

#on_new_investigationvoid

This method returns an undefined value.

: void



27
28
29
30
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 27

def on_new_investigation #: void
  super
  parse_comments
end

#process(node) ⇒ void

This method returns an undefined value.

Parameters:

  • node (RuboCop::AST::DefNode)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rubocop/cop/style/rbs_inline/unmatched_annotations.rb', line 60

def process(node) #: void # rubocop:disable Metrics/CyclomaticComplexity
  arguments = arguments_for(node)

  comment = parsed_comments.find do |r|
    r.comments.map(&:location).map(&:start_line).include?(node.location.line - 1)
  end
  return unless comment

  parsed_comments.delete(comment)
  comment.each_annotation do |annotation|
    case annotation
    when RBS::Inline::AST::Annotations::IvarType
      add_offense_for(annotation)
    when RBS::Inline::AST::Annotations::VarType, RBS::Inline::AST::Annotations::BlockType
      add_offense_for(annotation) unless arguments.include?(annotation_name(annotation))
    end
  end
end