PtcRunner.Lisp.Analyze.PreludeScope (PtcRunner v0.13.0)

Copy Markdown View Source

Process-local scope for the compiled prelude consulted during a single analysis pass (Capability Prelude V1, plan §4 / §2).

The analyzer's do_analyze/2 is deeply mutually-recursive across ~80 clauses; threading the prelude artifact through every clause would be a cascading refactor for a value only the qualified-ns_symbol clauses and the qualified-definition (protected-write) clauses need. Instead the prelude is stashed in the process dictionary for the duration of one analyze/2 call (set on entry, restored on exit via with_prelude/2). Analysis runs in a fresh bounded sandbox process per PtcRunner.Lisp.run, so this state is naturally request-scoped and never shared across runs.

Two questions this module answers for qualified names like crm/get-user, where ns/symbol arrive STRING-backed (unknown namespaces are not in SourceAtoms so they intern as {:ns_symbol, "crm", "get-user"} — fact #1):

  • fetch_export/2 — is ns/symbol a PUBLIC prelude export, and what is its arity? Private helpers (defn-) have no export record, so they are absent here and stay unreachable by qualified user calls (plan §5 / §8).
  • protected_namespace?/1 — is ns a protected namespace (a reserved host namespace or one declared by the attached prelude)? Used to reject (def ns/x ...) / (defn ns/f ...) writes with a protection fault rather than a generic invalid-qualified-name syntax error (plan §2).

Summary

Functions

The prelude installed for the current analysis pass, or nil.

Looks up ns/symbol (both STRING-backed) in the current prelude's PUBLIC export table. Returns {:ok, %Export{}} or :error.

Whether ns is a namespace DECLARED by the attached prelude (not the reserved host namespaces). Used to turn a qualified call into a known namespace's unknown export into an actionable discovery hint.

Whether ns is a protected namespace for the current analysis pass: a reserved host namespace, or one declared by the attached prelude. Used to reject writes (def/defn) into protected namespaces (plan §2).

Runs fun with prelude installed as the analysis-pass prelude scope, restoring any previously installed scope afterward.

Functions

current()

@spec current() :: PtcRunner.Lisp.Prelude.t() | nil

The prelude installed for the current analysis pass, or nil.

fetch_export(ns, symbol)

@spec fetch_export(term(), term()) ::
  {:ok, PtcRunner.Lisp.Prelude.Export.t()} | :error

Looks up ns/symbol (both STRING-backed) in the current prelude's PUBLIC export table. Returns {:ok, %Export{}} or :error.

prelude_namespace?(ns)

@spec prelude_namespace?(term()) :: boolean()

Whether ns is a namespace DECLARED by the attached prelude (not the reserved host namespaces). Used to turn a qualified call into a known namespace's unknown export into an actionable discovery hint.

protected_namespace?(ns)

@spec protected_namespace?(term()) :: boolean()

Whether ns is a protected namespace for the current analysis pass: a reserved host namespace, or one declared by the attached prelude. Used to reject writes (def/defn) into protected namespaces (plan §2).

with_prelude(prelude, fun)

@spec with_prelude(PtcRunner.Lisp.Prelude.t() | nil, (-> result)) :: result
when result: term()

Runs fun with prelude installed as the analysis-pass prelude scope, restoring any previously installed scope afterward.