Class: WhyClasses::AST::ClassShape
- Inherits:
-
Object
- Object
- WhyClasses::AST::ClassShape
- 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
-
#node ⇒ Object
readonly
Returns the value of attribute node.
Instance Method Summary collapse
- #attr_fields ⇒ Object
- #attr_macros ⇒ Object
-
#behavior_methods ⇒ Object
Instance methods other than initialize.
-
#initialize(node) ⇒ ClassShape
constructor
A new instance of ClassShape.
- #initialize_method ⇒ Object
- #instance_method_names ⇒ Object
- #instance_methods ⇒ Object
- #instance_variables_read ⇒ Object
- #instance_variables_written ⇒ Object
- #location ⇒ Object
- #module? ⇒ Boolean
- #name ⇒ Object
-
#other_statements ⇒ Object
Body statements that are neither method defs, attr macros, nor bare comments -- e.g.
- #singleton_method_names ⇒ Object
- #singleton_methods ⇒ Object
-
#stateful? ⇒ Boolean
A class "has state" if it stores instance variables that are not merely the constructor writing attr-backed fields.
- #superclass ⇒ Object
- #superclass? ⇒ Boolean
- #uses_metaprogramming? ⇒ Boolean
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
#node ⇒ Object (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_fields ⇒ Object
60 61 62 |
# File 'lib/why_classes/ast/class_shape.rb', line 60 def attr_fields @attr_fields ||= H.attr_fields(node) end |
#attr_macros ⇒ Object
56 57 58 |
# File 'lib/why_classes/ast/class_shape.rb', line 56 def attr_macros @attr_macros ||= H.attr_macros(node) end |
#behavior_methods ⇒ Object
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_method ⇒ Object
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_names ⇒ Object
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_methods ⇒ Object
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_read ⇒ Object
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_written ⇒ Object
82 83 84 |
# File 'lib/why_classes/ast/class_shape.rb', line 82 def instance_variables_written @ivw ||= H.ivars_assigned(node) end |
#location ⇒ Object
101 102 103 |
# File 'lib/why_classes/ast/class_shape.rb', line 101 def location node.location end |
#module? ⇒ Boolean
18 19 20 |
# File 'lib/why_classes/ast/class_shape.rb', line 18 def module? node.type == :module end |
#name ⇒ Object
22 23 24 |
# File 'lib/why_classes/ast/class_shape.rb', line 22 def name @name ||= H.class_name(node) end |
#other_statements ⇒ Object
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_names ⇒ Object
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_methods ⇒ Object
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.
97 98 99 |
# File 'lib/why_classes/ast/class_shape.rb', line 97 def stateful? !instance_variables_written.empty? || !instance_variables_read.empty? end |
#superclass ⇒ Object
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
32 33 34 |
# File 'lib/why_classes/ast/class_shape.rb', line 32 def superclass? !superclass.nil? end |
#uses_metaprogramming? ⇒ Boolean
76 77 78 79 80 |
# File 'lib/why_classes/ast/class_shape.rb', line 76 def return @meta if defined?(@meta) @meta = H.(node) end |