I am the pure source-text half of Analysis: function/type entry
extraction (strict and lenient), module scoping for multi-module
files, and the canonical source-edit splices (swap/replace/append).
I never touch the code server; beam-side merging stays in
GtBridge.Analysis.
Summary
Functions
I append new_text as a new function just before module's closing end,
located from the parse so a sibling or nested module in the same file doesn't
misdirect it. Returns source unchanged when module has no defmodule to
append to (e.g. a typedstruct-generated module), or the source doesn't parse.
I return the alias/import/require statements ast declares — whole
statements, so formatter-wrapped directives arrive intact. With no
module I sweep the top level and every top-level module (buffer
semantics); given a dotted module name I scope to that module's own
body, so siblings in the same file don't leak theirs in.
I parse source and return the AST function entries (the same shape
all_functions/1 returns minus the runtime-export merging, which
needs the module to be loaded). Works on disk bytes alone, so safe
to call before / after a failed compile.
I extract the top-level defmodule X.Y name from source. Returns
the dotted module string, or nil when the source doesn't define one
or doesn't parse.
I return every module source defines (nested defmodules and
typedstruct module: children included) as dotted-name strings.
Returns [] when the source doesn't parse.
I parse source with the options every source walk uses.
I replace the {name, arity} function within module in source with
new_text (or remove it when new_text is empty), taking the range from
source itself so the splice can't drift. Unknown name/arity returns
source unchanged.
I swap two functions (by {name, arity}) within module in source,
taking ranges from source itself so the splice can't drift. Unknown
name/arity returns source unchanged.
Functions
I append new_text as a new function just before module's closing end,
located from the parse so a sibling or nested module in the same file doesn't
misdirect it. Returns source unchanged when module has no defmodule to
append to (e.g. a typedstruct-generated module), or the source doesn't parse.
I return the alias/import/require statements ast declares — whole
statements, so formatter-wrapped directives arrive intact. With no
module I sweep the top level and every top-level module (buffer
semantics); given a dotted module name I scope to that module's own
body, so siblings in the same file don't leak theirs in.
I parse source and return the AST function entries (the same shape
all_functions/1 returns minus the runtime-export merging, which
needs the module to be loaded). Works on disk bytes alone, so safe
to call before / after a failed compile.
I extract the top-level defmodule X.Y name from source. Returns
the dotted module string, or nil when the source doesn't define one
or doesn't parse.
I return every module source defines (nested defmodules and
typedstruct module: children included) as dotted-name strings.
Returns [] when the source doesn't parse.
I parse source with the options every source walk uses.
I replace the {name, arity} function within module in source with
new_text (or remove it when new_text is empty), taking the range from
source itself so the splice can't drift. Unknown name/arity returns
source unchanged.
@spec swap_functions(String.t(), String.t(), String.t(), arity(), String.t(), arity()) :: String.t()
I swap two functions (by {name, arity}) within module in source,
taking ranges from source itself so the splice can't drift. Unknown
name/arity returns source unchanged.