ETS2Panda Public API Knowledge Base
Version: v1.0 | Last updated: 2026-06-01
This document covers the C API code generation pipeline under ets_frontend/ets2panda/public/. It does NOT cover AST node semantics, checker internals, parser internals, varbinder, or lowering phases (see Static_Frontend_Knowledge_Base.md), nor LSP API behavior (see LSP_Knowledge_Base.md).
Before modifying: read ets2panda/public/AGENTS.md and ets2panda/public/README.md.
Core Model
public/ exposes ets2panda's internal C++ API as a stable, auto-generated C interface (es2panda_lib). This is the single public contract between compiler internals and all external consumers. The C API must never be hand-edited.
| Step | Input | Tool | Output | Failure mode |
|---|---|---|---|---|
| 1. Parse | C++ headers in HEADERS_TO_BE_PARSED |
headers_parser/main.py |
YAML under <build>/gen/headers/ |
Silent empty YAML -- check <build>/gen/logs/ |
| 2. Generate | YAML + cppToCTypes.yaml + ignoredAllowed.yaml |
es2panda_lib.rb |
es2panda_lib.h/.cpp/.inc/.idl |
UNSUPPORTED TYPE error |
| 3. Compile | Generated C code | ninja es2panda-public |
Linked into es2panda binary |
Compilation failure from bad cast expressions |
Responsibility Boundaries
| Responsible for | Not responsible for |
|---|---|
| Generating the stable C API via the automated codegen pipeline | Defining semantics of AST nodes, types, or compiler operations |
Maintaining cppToCTypes.yaml as the single source of truth for C-to-C++ type translation |
Fixing C++ source headers to make them "codegen-friendly" |
Maintaining ignoredAllowed.yaml export filter |
Maintaining backward compatibility without bumping ES2PANDA_LIB_VERSION |
Generating es2panda_lib.idl synchronized with the C API |
Removing C API methods without checking downstream consumers |
| Parsing C++ headers into structured YAML | Hand-editing generated files or bypassing the codegen pipeline |
Providing public_lib::Context bridging C API to internal compiler state |
Adding exported API for types outside the intended public surface |
Constraint Rules
MUST
- MUST run
ninja gen_apiafter any change to headers,cppToCTypes.yaml,ignoredAllowed.yaml, or ERB templates. - MUST add the corresponding
ES2PANDA_API_GENERATEDentry when adding a header toHEADERS_TO_BE_PARSED(one-to-one). - MUST update
es2panda_lib.idl.erbin the same patch as anyes2panda_lib.hchange. - MUST place specific type entries before wildcard entries in
cppToCTypes.yaml(first-match-wins). - MUST set
min_ptr_depthandmax_ptr_depthprecisely on everycppToCTypes.yamlentry. - MUST check
<build>/gen/logs/afterninja gen_yamls-- parser silently produces empty YAML on failure. - MUST increment
ES2PANDA_LIB_VERSIONon A/B-incompatible API changes.
NEVER / DO NOT
- NEVER hand-edit generated files:
es2panda_lib.h,es2panda_lib.cpp, or any.incfile. - NEVER create manual C API function wrappers outside the codegen pipeline.
- NEVER place specific type mappings after wildcard (
\|AstNode\|) rules incppToCTypes.yaml. - NEVER add a class to
ignoredAllowed.yaml'scall_classwithout checking downstream consumers. - DO NOT modify
es2panda_lib.rbwithout a fullninja gen_api+ninja es2panda-plugin-testcycle. - DO NOT hand-edit generated files (
es2panda_lib.h,es2panda_lib.cpp,.incfiles). Whether generated files are tracked in the source tree is a repo-level decision — check the current tree state. If tracked, they MUST be regenerated and committed together with the source-of-truth change, never patched manually.
Key file traps
Source-of-truth priority when debugging a mismatch: 1) C++ header in HEADERS_TO_BE_PARSED (what is exported) → 2) cppToCTypes.yaml (how types translate) → 3) ignoredAllowed.yaml (what is filtered out) → 4) ERB templates (how C code is structured). Always fix the earliest step in this chain.
| File | Trap |
|---|---|
es2panda_lib.h/.cpp |
Auto-generated. Opaque typedefs must not be dereferenced in C code. |
es2panda_lib.rb |
Hand-written. @classes/@ast_nodes are module-global; state accumulates across YAML files. |
cppToCTypes.yaml |
Missing call_cast breaks method calls. Missing constructor_cast breaks constructors. return_args only when return expands to multiple parameters. |
ignoredAllowed.yaml |
Filter order: postfix_contains → args → template_types → return_type → call_class. ignored_list overrides allowed_list. |
CMakeLists.txt |
HEADERS_TO_BE_PARSED is the single source of truth for exported headers. |
headers_parser/ |
Silent failure on parse errors (check ${LIBGEN_DIR}/gen/logs/). |
public.h |
Context::AllocNode<T>() uses ForceSetParent. ClearCheckers()/ClearAnalyzers() do not deallocate -- caller must release. |
Actions Forbidden Without Team Confirmation
| Action | Reason |
|---|---|
Hand-edit es2panda_lib.h non-generated portions |
Will be overwritten; breaks contract |
Change ES2PANDA_LIB_VERSION |
Signals A/B breakage; downstream must be notified |
Remove entries from ignoredAllowed.yaml call_class or allowed_list |
Expands/shinks API surface silently |
Modify Arg/Type/ClassData matching logic in es2panda_lib.rb |
Affects all type codegen |
Rewrite headers_parser/ parsing strategy |
Affects all YAML generation |
Add entire new subsystem to HEADERS_TO_BE_PARSED |
Requires maintenance cost evaluation |
| Delete/rename published C API functions | Use deprecation instead |
Modify Context struct layout in public.h |
Affects all C API implementation functions |
| Add third-party dependencies to codegen pipeline | Requires team review |
| Hand-patch generated files instead of regenerating | Regenerate via ninja gen_api and commit the result; never apply manual fixes to generated output |
Anti-Patterns
| Anti-Pattern | Correct Approach |
|---|---|
| Hand-editing generated files | Modify source of truth and regenerate |
Updating es2panda_lib.h without es2panda_lib.idl.erb |
Same patch, always |
Omitting min_ptr_depth/max_ptr_depth in cppToCTypes.yaml |
Always set precise ranges |
Specific type after wildcard in cppToCTypes.yaml |
Specific before |AstNode| |
HEADERS_TO_BE_PARSED without ES2PANDA_API_GENERATED |
Must be one-to-one |
Skipping header parser log review after ninja gen_yamls |
Always check <build>/gen/logs/ |
| Manual C API wrappers outside codegen pipeline | All C API through codegen |
Modifying es2panda_lib.rb without full rebuild cycle |
ninja gen_api + compile verification |
Pre-Modification Checklist
- Is this a generated file? (If so, hand-editing is forbidden.)
- New class/method: in correct C++ header, header in
HEADERS_TO_BE_PARSED? - New C++ type: correct
cppToCTypes.yamlentry with ptr_depth and cast expressions? - Methods/constructors to hide: correct
ignoredAllowed.yamlfilters? -
es2panda_lib.hchanged:es2panda_lib.idl.erbupdated in same patch? -
ninja gen_apirun and generated code compiles? - New methods have unit tests (
test/unit/public/e2p_test_plugin*)? -
es2panda_lib.rb/enums.rbmodified:ninja es2panda-plugin-testpassed?
Code and Test Anchors
Code entry points
| Component | Path |
|---|---|
| Codegen engine | ets_frontend/ets2panda/public/es2panda_lib.rb |
| Enum extraction | ets_frontend/ets2panda/public/enums.rb |
| Type mappings | ets_frontend/ets2panda/public/cppToCTypes.yaml |
| Export filters | ets_frontend/ets2panda/public/ignoredAllowed.yaml |
| Context bridge | ets_frontend/ets2panda/public/public.h / public.cpp |
| Build pipeline | ets_frontend/ets2panda/public/CMakeLists.txt |
| ERB templates | ets_frontend/ets2panda/public/*.inc.erb, *.idl.erb |
| Header parser entry | ets_frontend/ets2panda/public/headers_parser/main.py |
| Generated output | <build>/tools/es2panda/generated/es2panda_lib/ |
Test commands
# From build directory
ninja es2panda-plugin-test # Unit tests for C API plugin
ninja gen_yamls # Parse headers → YAML
ninja gen_api # YAML → generated C/IDL
ninja es2panda-public # Compile generated C code
Generated output: <build>/tools/es2panda/generated/es2panda_lib/.
Parser logs: <build>/tools/es2panda/generated/es2panda_lib/gen/logs/.
New Public API — Complete Chain Quick-Reference
- Add class/method to correct C++ header under
ets_frontend/ets2panda/. - Add header to
HEADERS_TO_BE_PARSEDinCMakeLists.txt+ correspondingES2PANDA_API_GENERATEDentry. - Add type mapping in
cppToCTypes.yaml(specific before wildcard, precisemin_ptr_depth/max_ptr_depth, required cast expressions). - Hide unwanted methods via
ignoredAllowed.yamlif needed. - Update
es2panda_lib.idl.erbif API surface changes. - Run
ninja gen_apifrom build directory → verify generated output. - Run
ninja es2panda-public→ verify compilation. - Add unit test in
test/unit/public/e2p_test_plugin*. - Run
ninja es2panda-plugin-test→ verify all plugin tests pass.
Verification Commands
Minimal local (from build directory, after each change):
ninja gen_yamls && ninja gen_api && ninja es2panda-public
Release-grade (before submitting):
ninja gen_yamls && ninja gen_api && ninja es2panda-public && ninja es2panda-plugin-test
Done Definition
A public API task is done only when: (1) C++ header correctly expresses intended export; (2) HEADERS_TO_BE_PARSED / cppToCTypes.yaml / ignoredAllowed.yaml correctly updated; (3) es2panda_lib.idl.erb in same patch as es2panda_lib.h change; (4) ninja gen_api produces expected output without errors; (5) generated code compiles; (6) all unit tests pass; (7) no hand-patches remain in generated files.
Related Documents
ets2panda/public/AGENTS.md-- Directory development rulesets2panda/public/README.md-- Detailed codegen docs and type-adding guideets2panda/public/headers_parser/README.md-- Header parser documentationdocs/ets2panda/Static_Frontend_Knowledge_Base.md-- Checker types exposed through C APIAGENTS.md-- Repository-level routing, constraints, and verification expectations