Class: Mutineer::Project::SubjectVisitor
- Inherits:
-
Prism::Visitor
- Object
- Prism::Visitor
- Mutineer::Project::SubjectVisitor
- Defined in:
- lib/mutineer/project.rb
Overview
Walks an AST, maintaining a namespace stack, emitting Subjects. Nested inside Project to signal its private role.
Instance Attribute Summary collapse
-
#subjects ⇒ Object
readonly
Returns the value of attribute subjects.
Instance Method Summary collapse
-
#initialize(file) ⇒ SubjectVisitor
constructor
A new instance of SubjectVisitor.
- #visit_class_node(node) ⇒ Object
- #visit_def_node(node) ⇒ Object
- #visit_module_node(node) ⇒ Object
-
#visit_singleton_class_node(node) ⇒ Object
Methods inside
class << selfare class methods of the enclosing namespace, but their def nodes have no receiver — track the singleton context so they're recorded as singleton (so redefine targets the singleton_class, not instances).
Constructor Details
#initialize(file) ⇒ SubjectVisitor
Returns a new instance of SubjectVisitor.
27 28 29 30 31 32 33 |
# File 'lib/mutineer/project.rb', line 27 def initialize(file) @file = file @namespace_stack = [] @subjects = [] @singleton_depth = 0 super() end |
Instance Attribute Details
#subjects ⇒ Object (readonly)
Returns the value of attribute subjects.
25 26 27 |
# File 'lib/mutineer/project.rb', line 25 def subjects @subjects end |
Instance Method Details
#visit_class_node(node) ⇒ Object
35 36 37 38 39 |
# File 'lib/mutineer/project.rb', line 35 def visit_class_node(node) @namespace_stack.push(extract_constant_name(node.constant_path)) super @namespace_stack.pop end |
#visit_def_node(node) ⇒ Object
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/mutineer/project.rb', line 60 def visit_def_node(node) @subjects << Subject.new( file: @file, namespace: @namespace_stack.dup, name: node.name, singleton: !node.receiver.nil? || @singleton_depth.positive?, def_node: node ) super end |
#visit_module_node(node) ⇒ Object
41 42 43 44 45 |
# File 'lib/mutineer/project.rb', line 41 def visit_module_node(node) @namespace_stack.push(extract_constant_name(node.constant_path)) super @namespace_stack.pop end |
#visit_singleton_class_node(node) ⇒ Object
Methods inside class << self are class methods of the enclosing
namespace, but their def nodes have no receiver — track the singleton
context so they're recorded as singleton (so redefine targets the
singleton_class, not instances). class << some_other_obj can't be
represented against the namespace, so its defs are skipped (not recursed).
52 53 54 55 56 57 58 |
# File 'lib/mutineer/project.rb', line 52 def visit_singleton_class_node(node) return unless node.expression.is_a?(Prism::SelfNode) @singleton_depth += 1 super @singleton_depth -= 1 end |