Class: RuboCop::Cop::Sorbet::ForbidTStruct::TStructWalker

Inherits:
Object
  • Object
show all
Extended by:
AST::NodePattern::Macros
Includes:
AST::Traversal
Defined in:
lib/rubocop/cop/sorbet/forbid_t_struct.rb

Overview

This class walks down the class body of a T::Struct and collects all the properties that will need to be translated into attr_reader and attr_accessor methods.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(style = "sig") ⇒ TStructWalker

Returns a new instance of TStructWalker.



81
82
83
84
85
86
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 81

def initialize(style = "sig")
  @props = []
  @has_extend_t_sig = false
  @extend_t_sig_node = nil
  @style = style
end

Instance Attribute Details

#extend_t_sig_nodeObject (readonly)

Returns the value of attribute extend_t_sig_node.



79
80
81
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 79

def extend_t_sig_node
  @extend_t_sig_node
end

#has_extend_t_sigObject (readonly)

Returns the value of attribute has_extend_t_sig.



79
80
81
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 79

def has_extend_t_sig
  @has_extend_t_sig
end

#propsObject (readonly)

Returns the value of attribute props.



79
80
81
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 79

def props
  @props
end

Instance Method Details

#extend_t_sig?(node) ⇒ Object



89
90
91
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 89

def_node_matcher :extend_t_sig?, <<~PATTERN
  (send _ :extend (const (const {nil? | cbase} :T) :Sig))
PATTERN

#on_send(node) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 98

def on_send(node)
  if extend_t_sig?(node)
    # So we know we won't need to generate again a `extend T::Sig` line in the new class body
    @has_extend_t_sig = true
    @extend_t_sig_node = node
    return
  end

  return unless t_struct_prop?(node)

  kind = node.method?(:const) ? :attr_reader : :attr_accessor
  name = node.first_argument.source.delete_prefix(":")
  type = node.arguments[1].source
  default = nil
  factory = nil

  node.arguments[2..-1].each do |arg|
    next unless arg.hash_type?

    arg.each_pair do |key, value|
      case key.source
      when "default"
        default = value.source
      when "factory"
        factory = value.source
      end
    end
  end

  @props << Property.new(node, kind, name, type, default: default, factory: factory, style: @style)
end

#t_struct_prop?(node) ⇒ Object



94
95
96
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 94

def_node_matcher(:t_struct_prop?, <<~PATTERN)
  (send nil? {:const :prop} ...)
PATTERN