Files
whetstone_DSL/sprint162_plan.md

184 lines
8.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Sprint 162 Plan: Fix Class Emission in All Language Generators
## Context
A/B test run on 2026-02-25 (see `docs/ab_test_ast_vs_language_first_2026-02-25.md`)
exposed that `whetstone_run_pipeline` Python→C++ emitted an empty namespace when
given a Python class as input. A full audit of all 8 language generators revealed
the root cause is systemic and identical across every language:
**`visitModule` never calls `getChildren("classes")`.**
Every generator's `visitModule` iterates variables and functions only. Parsers
correctly populate the "classes" role during parsing — `ClassDeclaration` nodes
are in the AST — but the module walk skips them entirely. Classes are silently
dropped from all generated output across all 8 languages.
The `visitClassDeclaration` implementations are mostly already written and correct:
| Language | `visitClassDeclaration` | Line range | Status |
|----------|------------------------|------------|--------|
| Python | Yes | PythonGenerator.h:535562 | Good |
| Rust | Yes | RustGenerator.h:427444 | Good — struct + impl |
| Go | Yes | GoGenerator.h:412425 | Good — struct + receivers |
| Java | Yes | JavaGenerator.h:447483 | Good — handles abstract/extends |
| JavaScript | Yes | JavaScriptGenerator.h:454469 | Good — ES6 class syntax |
| TypeScript | Yes (inherited from JS) | — | Good |
| Elisp | Yes | ElispGenerator.h:497513 | Good — cl-defstruct |
| **C++** | **No** | CppGenerator.h | **Missing entirely** |
The fix for 7 languages is adding `getChildren("classes")` iteration to
`visitModule` — approximately 3 lines each. C++ additionally needs
`visitClassDeclaration` written from scratch.
Java and JavaScript have a secondary issue: their `visitModule` reconstructs
classes from function-name heuristics instead of the AST. That heuristic path
must be replaced with the real `getChildren("classes")` iteration.
This sprint fixes all 8 generators in one pass. After this sprint, any language
can emit a class from a parsed AST, and cross-language class transpilation
(e.g. Python → C++, Python → Rust) works end-to-end.
---
## Goals
1. Add `getChildren("classes")` iteration to `visitModule` in all 8 generators
2. Write `visitClassDeclaration` for C++ (the only language missing it entirely)
3. Replace the function-name heuristic in Java and JavaScript `visitModule` with
real AST class iteration
4. End-to-end: the exact Python PriorityQueue from the A/B test must produce
compilable output in C++, Rust, and Go via `run_pipeline`
---
## Steps
### Step 1854: Fix `visitModule` in Python, Rust, Go, Elisp generators (12 tests)
For each of these four generators, add a loop after the existing functions
iteration in `visitModule`:
```cpp
for (auto& cls : node->getChildren("classes")) {
result += dispatchGenerate(cls);
}
```
No other changes — `visitClassDeclaration` already works correctly in all four.
Tests (12, 3 per language): Python class round-trips through parse→generate,
Rust class produces `struct` + `impl` block, Go class produces `type X struct`
with method receivers, Elisp class produces `cl-defstruct` — and for each,
a module containing both a function and a class emits both (function not lost,
class not lost).
### Step 1855: Fix `visitModule` in Java and JavaScript generators (10 tests)
Java and JavaScript use a function-name heuristic to reconstruct classes
(partitioning function names to guess class membership) instead of reading
`getChildren("classes")`. Replace the heuristic path with the real AST iteration.
For both generators, `visitModule` should iterate `getChildren("classes")`
using `dispatchGenerate(cls)` — same pattern as Step 1854.
The existing `visitClassDeclaration` implementations (Java:447483,
JavaScript:454469) remain unchanged.
TypeScript inherits from JavaScript and requires no separate change.
Tests (10): Java class produces correct `public class X { }` syntax, Java class
with extends emits `extends`, Java abstract class emits `abstract`, JavaScript
class produces ES6 `class X { }` syntax, JavaScript class with superclass emits
`extends`, TypeScript class works via inheritance, Java module with function +
class emits both, JavaScript module with function + class emits both, no heuristic
path remains (grep for the old partition logic returns nothing),
regression: existing function-only modules still work correctly.
### Step 1856: Write `visitClassDeclaration` for C++ generator (12 tests)
C++ is the only language missing `visitClassDeclaration` entirely. Add it to
`CppGenerator.h`.
The implementation must emit a complete header-only C++ class:
- `struct` for pure data classes (no methods other than comparators)
- `class` with `public:` section for classes with methods
- Fields with inferred types: Python `str``std::string`, `int``int`,
`bool``bool`, `float``double`, unknown → `auto /* TODO: specify type */`
- Method declarations with `auto` parameter/return types when not inferrable
- Required `#include` directives (`<string>` when string fields present, etc.)
Also add `getChildren("classes")` to C++ `visitModule` (same 3-line pattern
as Step 1854).
Tests (12): empty class emits valid C++ `class X { };`, class with string field
emits `std::string`, class with int field emits `int`, class with unknown field
emits `auto` with TODO comment, class with methods emits method declarations,
visitModule emits both functions and classes, `#include <string>` present when
string field exists, pragma once present at module level, C++ class output
parseable by Whetstone's own CppParser, class with `__init__`-style constructor
emits C++ constructor, class with only fields uses `struct`, class with methods
uses `class` with `public:`.
### Step 1857: End-to-end — Python PriorityQueue → C++, Rust, Go (10 tests)
Create `editor/src/Sprint162EndToEnd.h`.
Uses the exact Python source from the failing 2026-02-25 A/B run. Runs it
through `run_pipeline` targeting C++, Rust, and Go. All three must produce
non-empty, parseable output containing the class definitions.
Expected C++ output: contains `class WorkItem`, `class PriorityQueue`,
`enqueue`, `dequeue`, `std::string`, `int`.
Expected Rust output: contains `struct WorkItem`, `impl PriorityQueue`,
`fn enqueue`, `fn dequeue`.
Expected Go output: contains `type WorkItem struct`, `type PriorityQueue struct`,
method receivers for `enqueue` and `dequeue`.
Tests (10): C++ output non-empty, C++ contains "class WorkItem", C++ contains
"class PriorityQueue", C++ contains "std::string", Rust output non-empty,
Rust contains "struct WorkItem", Rust contains "impl PriorityQueue", Go output
non-empty, Go contains "type WorkItem struct", Go contains "type PriorityQueue struct".
### Step 1858: Sprint 162 Integration Summary (8 tests)
Create `editor/src/Sprint162IntegrationSummary.h`.
Record: steps_completed=5 (18541858), root_cause="visitModule skips
getChildren(classes) in all 8 generators", languages_fixed=8,
new_code_written="CppGenerator::visitClassDeclaration only — all other
visitClassDeclaration implementations pre-existing", ab_test_reference=
"docs/ab_test_ast_vs_language_first_2026-02-25.md", success=true.
Full sprint regression: steps 18541858 pass. All existing function-level
pipeline tests pass (no regression).
Tests (8): struct constructable, steps_completed==5, languages_fixed==8,
root_cause non-empty, all 8 generators emit classes, Python round-trip works,
C++ round-trip works, success==true.
---
## Architecture Gate
- No new files required except Sprint162IntegrationSummary.h and the C++
visitClassDeclaration (added inline to CppGenerator.h, ≤ 600 line limit)
- No new vcpkg dependencies
- The 3-line `getChildren("classes")` fix must be applied consistently across
all generators — no one-off solutions
- Existing function-level output must be unchanged in all generators (regression
tests in Step 1858 enforce this)
- Type inference for C++ must be conservative: unknown → `auto` + comment, never
silently wrong
- Java/JavaScript heuristic class reconstruction must be fully removed, not
left alongside the new path
---
## Note on Scope
This sprint does NOT require writing new `visitClassDeclaration` implementations
for Python, Rust, Go, Java, JavaScript, TypeScript, or Elisp. Those already exist
and are correct. The entire fix for those 7 languages is the `getChildren("classes")`
loop in `visitModule`. Only C++ requires new implementation work.