RpcElixir.Types.FromInferred (elixir_ts_rpc v0.0.1)

Copy Markdown View Source

EXPERIMENTAL backend that reads signatures inferred by Elixir's set-theoretic type system from the ExCk BEAM chunk, instead of user-written @spec.

Not the recommended path. Use RpcElixir.Types.FromSpec for any real workload. This module exists so we can track the new type system as it evolves toward a public introspection API.

Hard caveats:

  • Private API. ExCk chunk format and the Module.Types.Descr term shape are both undocumented compiler internals. The chunk version (:elixir_checker_v3 on Elixir 1.19) and Descr shape have changed every minor release. Expect breakage on upgrade.
  • Requires Code.compiler_options(infer_signatures: true) at compile time of the target module. Without it the chunk only carries function names, not signatures.
  • Inference is lossy. Most argument types come back as dynamic unless the function pattern-matches or guards on input. Returns fare better.
  • Anything we can't translate becomes %{kind: "dynamic"} rather than raising, so calling code can decide whether to fall back to FromSpec.

Summary

Functions

Convenience for the RPC convention call(input, context) :: {:ok, output}.

Returns the inferred argument and return type maps for the given MFA, or {:error, :no_signature} if unavailable.

Functions

fetch_rpc(module, function)

@spec fetch_rpc(module(), atom()) ::
  {:ok,
   %{
     input: RpcElixir.Types.internal_spec(),
     output: RpcElixir.Types.internal_spec(),
     error: RpcElixir.Types.internal_spec() | nil
   }}
  | {:error, :no_signature}
  | {:error, {:invalid_return, RpcElixir.Types.internal_spec()}}

Convenience for the RPC convention call(input, context) :: {:ok, output}.

Inference cannot prove an {:error, _} branch unless the body explicitly returns one, so the recovered shape is usually a single {:ok, T} tuple. Returns {:ok, %{input: t, output: t, error: t | nil}} when that pattern is recognized, else {:error, {:invalid_return, t}}.

fetch_signature(module, function, arity)

@spec fetch_signature(module(), atom(), non_neg_integer()) ::
  {:ok,
   %{
     args: [RpcElixir.Types.internal_spec()],
     return: RpcElixir.Types.internal_spec()
   }}
  | {:error, :no_signature}

Returns the inferred argument and return type maps for the given MFA, or {:error, :no_signature} if unavailable.