Class: RuboCop::Cop::RBS::Layout::AnnotationIndentation

Inherits:
RBS::CopBase
  • Object
show all
Extended by:
AutoCorrector
Defined in:
lib/rubocop/cop/rbs/layout/annotation_indentation.rb

Overview

Checks the indentation of annotations in RBS.

Examples:

# bad
# comment
  %a{pure}
def foo: () -> void

# good
# comment
%a{pure}
def foo: () -> void

Constant Summary collapse

MSG =
"Incorrect indentation detected (column %<expect>s instead of %<actual>s)."

Instance Attribute Summary

Attributes inherited from RBS::CopBase

#processed_rbs_source

Instance Method Summary collapse

Methods inherited from RBS::CopBase

documentation_url, #investigation_rbs, #location_to_range, #on_new_investigation, #on_other_file, #on_rbs_attribute, #on_rbs_class, #on_rbs_constant, #on_rbs_def, #on_rbs_global, #on_rbs_interface, #on_rbs_module, #on_rbs_parsing_error, #on_rbs_private, #on_rbs_public, #on_rbs_type_alias, #on_rbs_var, #parse_rbs, #rbs_buffer, #tokenize, #walk

Methods included from RBS::OnTypeHelper

#on_not_type, #on_type

Instance Method Details

#on_rbs_new_investigationObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rubocop/cop/rbs/layout/annotation_indentation.rb', line 25

def on_rbs_new_investigation
  indent_start_lines = Set.new
  indent_end_lines = Set.new
  ignore_poses = Set.new
  processed_rbs_source.decls.each do |decl|
    walk_decl(decl) do |d|
      indent_start_lines << d.location.start_line
      indent_end_lines << d.location.end_line
      d.members.each do |member|
        case member
        when ::RBS::AST::Members::MethodDefinition
          member.overloads.each do |overload|
            overload.annotations.each do |annotation|
              ignore_poses << annotation.location.start_pos
            end
          end
        end
      end
    end
  end

  expected_width = 0
  last_annotation_line = -1
  processed_rbs_source.tokens.each do |token|
    case token.type
    when :kMODULE, :kCLASS, :kINTERFACE
      next unless indent_start_lines.include?(token.location.start_line)

      expected_width += 2
    when :kEND
      next unless indent_end_lines.include?(token.location.start_line)

      expected_width -= 2
    when :tANNOTATION
      next if ignore_poses.include?(token.location.start_pos)

      if token.location.start_column == expected_width
        last_annotation_line = token.location.start_line
        next
      end
      next if last_annotation_line == token.location.start_line

      token_range = location_to_range(token.location)
      message = format(MSG, expect: expected_width, actual: token.location.start_column)
      last_annotation_line = token.location.start_line
      add_offense(token_range, message: message) do |corrector|
        line_start_pos = processed_source.buffer.line_range(token.location.start_line).begin_pos
        indent = range_between(line_start_pos, token.location.start_pos)
        corrector.replace(indent, ' ' * expected_width)
      end
    end
  end
end

#walk_decl(decl, &block) ⇒ Object



79
80
81
82
83
84
# File 'lib/rubocop/cop/rbs/layout/annotation_indentation.rb', line 79

def walk_decl(decl, &block)
  if decl.respond_to?(:members)
    yield decl
    decl.members.each { |member| walk_decl(member, &block) }
  end
end