Class: WhyClasses::AST::ClassShape

Inherits:
Object
  • Object
show all
Defined in:
lib/why_classes/ast/class_shape.rb

Overview

A computed-once summary of a single class (or module) node. Rules read a ClassShape instead of re-walking the AST.

Constant Summary collapse

H =
NodeHelpers

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node) ⇒ ClassShape

Returns a new instance of ClassShape.



14
15
16
# File 'lib/why_classes/ast/class_shape.rb', line 14

def initialize(node)
  @node = node
end

Instance Attribute Details

#nodeObject (readonly)

Returns the value of attribute node.



12
13
14
# File 'lib/why_classes/ast/class_shape.rb', line 12

def node
  @node
end

Instance Method Details

#attr_fieldsObject



60
61
62
# File 'lib/why_classes/ast/class_shape.rb', line 60

def attr_fields
  @attr_fields ||= H.attr_fields(node)
end

#attr_macrosObject



56
57
58
# File 'lib/why_classes/ast/class_shape.rb', line 56

def attr_macros
  @attr_macros ||= H.attr_macros(node)
end

#behavior_methodsObject

Instance methods other than initialize.



91
92
93
# File 'lib/why_classes/ast/class_shape.rb', line 91

def behavior_methods
  instance_methods.reject { |m| m.children[0] == :initialize }
end

#initialize_methodObject



52
53
54
# File 'lib/why_classes/ast/class_shape.rb', line 52

def initialize_method
  @initialize_method ||= H.initialize_method(node)
end

#instance_method_namesObject



40
41
42
# File 'lib/why_classes/ast/class_shape.rb', line 40

def instance_method_names
  instance_methods.map { |m| m.children[0] }
end

#instance_methodsObject



36
37
38
# File 'lib/why_classes/ast/class_shape.rb', line 36

def instance_methods
  @instance_methods ||= H.instance_methods(node)
end

#instance_variables_readObject



86
87
88
# File 'lib/why_classes/ast/class_shape.rb', line 86

def instance_variables_read
  @ivr ||= H.ivars_read(node)
end

#instance_variables_writtenObject



82
83
84
# File 'lib/why_classes/ast/class_shape.rb', line 82

def instance_variables_written
  @ivw ||= H.ivars_assigned(node)
end

#locationObject



101
102
103
# File 'lib/why_classes/ast/class_shape.rb', line 101

def location
  node.location
end

#module?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/why_classes/ast/class_shape.rb', line 18

def module?
  node.type == :module
end

#nameObject



22
23
24
# File 'lib/why_classes/ast/class_shape.rb', line 22

def name
  @name ||= H.class_name(node)
end

#other_statementsObject

Body statements that are neither method defs, attr macros, nor bare comments -- e.g. constants, includes, other macro calls.



66
67
68
69
70
71
72
73
74
# File 'lib/why_classes/ast/class_shape.rb', line 66

def other_statements
  @other_statements ||= begin
    skip = instance_methods + singleton_methods
    H.body_statements(H.class_body(node)).reject do |s|
      skip.include?(s) ||
        (H.node?(s) && s.type == :send && %i[attr_reader attr_writer attr_accessor].include?(s.children[1]))
    end.select { |s| H.node?(s) }
  end
end

#singleton_method_namesObject



48
49
50
# File 'lib/why_classes/ast/class_shape.rb', line 48

def singleton_method_names
  singleton_methods.map { |m| m.children[1] || m.children[0] }
end

#singleton_methodsObject



44
45
46
# File 'lib/why_classes/ast/class_shape.rb', line 44

def singleton_methods
  @singleton_methods ||= H.singleton_methods(node)
end

#stateful?Boolean

A class "has state" if it stores instance variables that are not merely the constructor writing attr-backed fields.

Returns:

  • (Boolean)


97
98
99
# File 'lib/why_classes/ast/class_shape.rb', line 97

def stateful?
  !instance_variables_written.empty? || !instance_variables_read.empty?
end

#superclassObject



26
27
28
29
30
# File 'lib/why_classes/ast/class_shape.rb', line 26

def superclass
  return nil if module?

  @superclass ||= H.superclass_path(node)
end

#superclass?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/why_classes/ast/class_shape.rb', line 32

def superclass?
  !superclass.nil?
end

#uses_metaprogramming?Boolean

Returns:

  • (Boolean)


76
77
78
79
80
# File 'lib/why_classes/ast/class_shape.rb', line 76

def uses_metaprogramming?
  return @meta if defined?(@meta)

  @meta = H.uses_metaprogramming?(node)
end