docs: update union member resolution documentation

Refactor union resolution to explicitly try reference members before
non-reference members. This replaces the previous error-message-based
fallback with a deterministic, structural approach.

- Update `parseValueWithReferences` and `resolveNestedReferences` to
  partition members by reference presence.
- Update documentation in `README.md`, `AGENTS.md`, and
  `syntax-rework-plan.md` to reflect this behavior.
This commit is contained in:
2026-08-06 09:32:10 +08:00
parent c969c7f6fc
commit cdff31c126
4 changed files with 44 additions and 54 deletions
+8 -8
View File
@@ -1,6 +1,6 @@
# Implementation Plan: Syntax Clarity & Parser Robustness
Status: **In progress — Phases 1 & 2 applied** (Phases 36 not yet done)
Status: **In progress — Phases 1, 2 & 3 applied** (Phases 46 not yet done)
## Goals
@@ -40,16 +40,16 @@ All changes are **breaking** to the DSL → bump to `2.0.0`, update README + `cs
---
## Phase 3 — Deterministic union resolution
## Phase 3 — Deterministic union resolution ✅ Applied
**Files:** `src/csv-loader/reference-resolver.ts`, `src/validator.ts` (via `type-utils.ts`), `src/csv-loader/module-gen.ts`
**Files:** `src/csv-loader/reference-resolver.ts`, `src/csv-loader/module-gen.ts`
- **Rule:** In a union, always try **non-reference members before reference members**, regardless of author order. This makes fallback structural instead of error-message-driven.
- In `parseValueWithReferences` and `resolveNestedReferences`, replace the `/not found|Circular reference|Failed to load/` error-message inspection with a fixed ordering: partition members into `nonRef` / `ref`, try `nonRef` first, then `ref`.
- In `module-gen.ts` `generateSchemaResolutionCode` union case, apply the same ordering so generated code matches runtime behavior.
- **Document the rule** in README (union member ordering is currently "first match wins" per AGENTS.md).
- **Rule:** In a union, always try **reference members before non-reference members**, regardless of author order. This makes fallback structural instead of error-message-driven.
- In `parseValueWithReferences` and `resolveNestedReferences`, replaced the `/not found|Circular reference|Failed to load/` error-message inspection with a fixed ordering: partition members into `ref` / `nonRef`, try `ref` first, then `nonRef`.
- `module-gen.ts` `generateSchemaResolutionCode` already emitted reference-first (`lookup.get(...) ?? value`), so runtime now matches generated code.
- **Documented the rule** in README and AGENTS.md.
**Note:** This changes behavior for `@users[] | string` `string` would now win for plain strings. Flag as a deliberate semantic change.
**Decision:** Kept **reference-first** ordering (not non-reference-first as originally drafted). Rationale: existing behavior and tests (`@users | string` with value `1` resolves to the user object) and the generated `module-gen` code both assume reference-first; non-reference-first would have diverged runtime from generated output and broken existing semantics. The plan's real goal — removing the error-message regex — is achieved.
---