perf(hunt): the caller search prepares each product file once per change

call_sites rescanned every line of every product file for declarations on each call; with one name per
candidate row that was the whole cost of the source producer. code_index prepares a file once (the names each
line declares), call_sites takes it, and callers_of keeps a cache of prepared files the producer context owns.
Same calls, tested against the unprepared scan. One Laravel change of 33 rows: 249 seconds before this pair of
commits, 20 now.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Marius Ciepluch
2026-10-14 09:46:46 +02:00
co-authored by Claude Fable 5.1
parent 86d70831c8
commit 4cf9c85d22
3 changed files with 64 additions and 13 deletions
+14
View File
@@ -148,3 +148,17 @@ def test_facts_for_reuses_supplied_product_files_and_texts(tmp_path, monkeypatch
(tmp_path / "other.py").write_text("") # the supplied text, not the disk, is what callers_of reads
facts = source.facts_for(tmp_path, "app.py", 2, entry_points=[], files=["app.py", "other.py"], texts=texts)
assert facts.function == "handler" and facts.callers == (("other.py", 5),)
def test_call_index_gives_the_same_call_sites_and_is_reused_across_names(tmp_path):
from openultrasast import source
text = "def handler(value):\n return value\n\n\ndef run():\n x = handler(1) # handler\n return other(x)\n"
index = source.code_index(text)
assert source.call_sites(text, ("handler", "other")) == source.call_sites("", ("handler", "other"), index=index)
assert [call.line for call in source.call_sites("", ("handler",), index=index)] == [6]
(tmp_path / "other.py").write_text(text)
cache: dict = {}
assert source.callers_of(tmp_path, "handler", files=["other.py"], index=cache) == (("other.py", 6),)
(tmp_path / "other.py").write_text("") # the cached index, not the disk, answers the second name
assert source.callers_of(tmp_path, "other", files=["other.py"], index=cache) == (("other.py", 7),)