srdatalog.viz.source

AST-based rule location extraction.

Walks a Python source file looking for the pattern:

(HEAD_ATOM <= BODY).named("RuleName")[.with_plan(kwargs...)]*

and produces a mapping from rule name → source location, plus, for each .with_plan(...) call, the exact byte-offset range of each keyword argument’s value. The extension uses this to:

  1. Jump to a rule from the visualization sidebar

  2. Replace a specific var_order=[...] / clause_order=[...] value without reformatting the rest of the file

We key rules by the string literal passed to .named(...) because that’s the only name the HIR / JIT stages know them by. Anonymous rules (no .named call) are skipped — the extension has no handle for them anyway.

Module Contents

Classes

PlanCallSpan

Byte-offset range of one .with_plan(...) call on a rule.

PlanKwargSpan

Byte-offset range of one with_plan(kwarg=VALUE) — VALUE only.

RuleLocation

Where a named rule lives in the source + what plans it has.

Functions

find_rule_locations

Walk the AST, return one RuleLocation per .named("X")-suffixed rule.

API

class srdatalog.viz.source.PlanCallSpan[source]

Byte-offset range of one .with_plan(...) call on a rule.

end: int

None

kwargs: list[srdatalog.viz.source.PlanKwargSpan]

‘field(…)’

start: int

None

class srdatalog.viz.source.PlanKwargSpan[source]

Byte-offset range of one with_plan(kwarg=VALUE) — VALUE only.

end: int

None

kwarg: str

None

start: int

None

class srdatalog.viz.source.RuleLocation[source]

Where a named rule lives in the source + what plans it has.

end: int

None

end_line: int

None

name: str

None

plan_calls: list[srdatalog.viz.source.PlanCallSpan]

‘field(…)’

start: int

None

start_line: int

None

srdatalog.viz.source.find_rule_locations(source: str) list[srdatalog.viz.source.RuleLocation][source]

Walk the AST, return one RuleLocation per .named("X")-suffixed rule.

The pattern we recognize: ( HEAD <= BODY ).named(“NAME”).with_plan(kw=VAL, …) …

We accept any number (including zero) of trailing .with_plan(...) calls after .named(...). Rules without .named are skipped.