module SimpleCov::StaticCoverageExtractor

def available?

`available?`-returns-false fallback path in SimulateCoverage's spec.
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)

extract — fall back to empty hashes."
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)

callers to keep every Coverage entry (no false drops).
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