Chunks .erl/.hrl files by calling :epp in-process (no subprocess),
so macros and includes are resolved exactly as the compiler would resolve
them.
Ported from extract_chunks.erl plus the chunk-assembly logic in
chunker.py (spec merging, oversized-chunk splitting) in the original
Python-orchestrated pipeline. Parsing and the file-ownership fix (forms
belonging to an -include'd header are dropped rather than chunked
under the including file — see Beamscope.ErlangForms for why)
are shared with the call-graph extractor.
Falls back to TextChunker's line-window only when parsing succeeds but
yields zero chunks (e.g. a header with no forms) — a genuinely fatal
parse failure (the file can't even be opened) yields no chunks at all,
matching chunker.py exactly: its line-window fallback is gated on the
extractor's exit code being 0, which a fatal failure never is.