Class: SimpleCov::StaticCoverageExtractor::Visitor
- Inherits:
-
Prism::Visitor
- Object
- Prism::Visitor
- SimpleCov::StaticCoverageExtractor::Visitor
- Defined in:
- lib/simplecov/static_coverage_extractor/visitor.rb
Overview
Prism visitor that accumulates branch and method tuples in the shape Ruby’s ‘Coverage` reports. Tuple ids are sequential across the file — `Coverage` uses sequential ids too, so this matches the conventional shape. Only defined when Prism is loadable; `StaticCoverageExtractor.available?` is the runtime gate.
Instance Attribute Summary collapse
-
#branches ⇒ Object
readonly
Returns the value of attribute branches.
-
#methods ⇒ Object
readonly
Returns the value of attribute methods.
Instance Method Summary collapse
-
#initialize ⇒ Visitor
constructor
A new instance of Visitor.
- #visit_case_match_node(node) ⇒ Object
-
#visit_case_node(node) ⇒ Object
‘case`/`when` and `case`/`in` (pattern matching) parse as CaseNode and CaseMatchNode respectively.
-
#visit_class_node(node) ⇒ Object
Track class/module nesting so method tuples carry the lexical class name.
-
#visit_def_node(node) ⇒ Object
‘def name(…)` and `def self.name(…)` both produce DefNode.
-
#visit_if_node(node) ⇒ Object
‘if` / `unless` / postfix-if / postfix-unless / ternary all parse as IfNode (or UnlessNode).
- #visit_module_node(node) ⇒ Object
- #visit_unless_node(node) ⇒ Object
- #visit_until_node(node) ⇒ Object
-
#visit_while_node(node) ⇒ Object
‘while` / `until` loops get a single `:body` arm.
Constructor Details
#initialize ⇒ Visitor
Returns a new instance of Visitor.
29 30 31 32 33 34 35 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 29 def initialize super @branches = {} @methods = {} @next_id = 0 @class_stack = [] end |
Instance Attribute Details
#branches ⇒ Object (readonly)
Returns the value of attribute branches.
27 28 29 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 27 def branches @branches end |
#methods ⇒ Object (readonly)
Returns the value of attribute methods.
27 28 29 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 27 def methods @methods end |
Instance Method Details
#visit_case_match_node(node) ⇒ Object
61 62 63 64 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 61 def visit_case_match_node(node) emit_case_like(node, :in) super end |
#visit_case_node(node) ⇒ Object
‘case`/`when` and `case`/`in` (pattern matching) parse as CaseNode and CaseMatchNode respectively. When there’s no explicit ‘else`, Coverage synthesizes one at the case’s range.
56 57 58 59 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 56 def visit_case_node(node) emit_case_like(node, :when) super end |
#visit_class_node(node) ⇒ Object
Track class/module nesting so method tuples carry the lexical class name. Module + Class are both treated as namespaces here since ‘Coverage` reports both as the constant.
81 82 83 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 81 def visit_class_node(node) with_class(constant_name(node.constant_path)) { super } end |
#visit_def_node(node) ⇒ Object
‘def name(…)` and `def self.name(…)` both produce DefNode. The class context is the surrounding lexical class/module (or `Object` at the top level, matching `Coverage`’s convention).
92 93 94 95 96 97 98 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 92 def visit_def_node(node) loc = node.location class_name = @class_stack.last || "Object" key = [class_name, node.name, loc.start_line, loc.start_column, loc.end_line, loc.end_column] @methods[key] = 0 super end |
#visit_if_node(node) ⇒ Object
‘if` / `unless` / postfix-if / postfix-unless / ternary all parse as IfNode (or UnlessNode). Both carry a `then` arm (the statements body) and an optional `subsequent` (an ElseNode for `else`, another IfNode for `elsif`). When the subsequent is missing, Coverage synthesizes a `:else` arm attributed to the whole condition’s range — we do the same.
43 44 45 46 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 43 def visit_if_node(node) emit_if_like(node) super end |
#visit_module_node(node) ⇒ Object
85 86 87 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 85 def visit_module_node(node) with_class(constant_name(node.constant_path)) { super } end |
#visit_unless_node(node) ⇒ Object
48 49 50 51 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 48 def visit_unless_node(node) emit_if_like(node) super end |
#visit_until_node(node) ⇒ Object
73 74 75 76 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 73 def visit_until_node(node) emit_loop(node, :until) super end |
#visit_while_node(node) ⇒ Object
‘while` / `until` loops get a single `:body` arm. No synthetic else (the loop either runs the body or doesn’t).
68 69 70 71 |
# File 'lib/simplecov/static_coverage_extractor/visitor.rb', line 68 def visit_while_node(node) emit_loop(node, :while) super end |