module SimpleCov::StaticCoverageExtractor
def available?
report. Asserted-on by callers; tested indirectly via the
itself IS loadable — i.e., on every engine that exercises the dogfood
The Prism-unavailable arm of this ternary is unreachable when Prism
simplecov:disable branch
def available? defined?(::Prism) ? true : false end
def call(source)
when Prism isn't available; callers should treat that as "couldn't
`Coverage.result[path]` produces. Returns nil on parse failure or
`{"branches" => {...}, "methods" => {...}}` matching the shape that
Parse `source` (a string of Ruby) and return a hash of the form
def call(source) # simplecov:disable branch — `then` arm unreachable when Prism IS loadable return nil unless available? # simplecov:enable branch result = ::Prism.parse(source) return nil if result.failure? visitor = Visitor.new visitor.visit(result.value) {"branches" => visitor.branches, "methods" => visitor.methods} rescue StandardError # simplecov:disable line # Parser errors beyond the .failure? check, unsupported AST shapes, # or anything else: fall back to empty hashes rather than crashing # the whole report. Defensive; hard to trigger from a real source # input that Prism accepts at parse time. nil # simplecov:enable line end
def real_source_positions(source)
Returns nil when Prism is unavailable or parsing fails, signaling
(name, start_line) since a method name is unique at any line.
false-negative for an opt-in filter. Method matching uses
eval-generated one will keep both, which is an acceptable
differences. Coincidental line-sharing between a real branch and an
start_line alone is the conservative choice that tolerates those
column positions (and, for some constructs, its type), so matching on
Static extraction and Coverage can still disagree on a branch's exact
Branch matching is start_line-only rather than by the full tuple.
}
methods: Set[[name, start_line], ...] # e.g., [[:foo, 7], [:bar, 13]]
branches: Set[start_line, ...], # e.g., [3, 12, 20]
{
SimpleCov.ignore_methods, #1046). Returns a hash:
`:eval_generated` filter (SimpleCov.ignore_branches /
Summarize a source file's REAL branch and method positions, for the
def real_source_positions(source) extracted = call(source) return nil unless extracted { branches: extracted["branches"].keys.to_set { |tuple| tuple[2] }, methods: extracted["methods"].keys.to_set { |tuple| [tuple[1], tuple[2]] } } end