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

#initializeTStructWalker

Returns a new instance of TStructWalker.



57
58
59
60
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 57

def initialize
  @props = []
  @has_extend_t_sig = false
end

Instance Attribute Details

#has_extend_t_sigObject (readonly)

Returns the value of attribute has_extend_t_sig.



55
56
57
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 55

def has_extend_t_sig
  @has_extend_t_sig
end

#propsObject (readonly)

Returns the value of attribute props.



55
56
57
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 55

def props
  @props
end

Instance Method Details

#extend_t_sig?(node) ⇒ Object



63
64
65
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 63

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

#on_send(node) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 72

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
    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)
end

#t_struct_prop?(node) ⇒ Object



68
69
70
# File 'lib/rubocop/cop/sorbet/forbid_t_struct.rb', line 68

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