Walker: node-attached HintMode via Node::Hinted (ADR-0024 §HintMode-per-node)

Replaces the hint resolver's signature-matching (does the expected set
contain all five literal forms? an Ident{NewName}?) with a grammar-
declared annotation. New Node::Hinted { mode, inner } wrapper; the
walker records the mode in WalkContext::pending_hint_mode on entry and
clears it on any successful match (cursor moved past the slot — this
also undoes the leak where a failed Hinted branch of a Choice would
otherwise strand a stale mode). The resolver reads pending_hint_mode
directly.

Value-literal fallback slots carry ProseOnly; NewName ident slots carry
ForceProse. hint_mode_at_input_inner now delegates to
hint_resolution_at_input — one resolution path, no duplicated logic.
No behaviour change; the typing-surface matrix guards it.
This commit is contained in:
claude@clouddev1
2026-05-15 21:58:22 +00:00
parent f1ff5970bf
commit 911a537a83
8 changed files with 193 additions and 165 deletions
+10 -2
View File
@@ -18,7 +18,7 @@
use crate::dsl::command::{Command, RowFilter};
use crate::dsl::grammar::{
CommandNode, IdentSource, Node, ValidationError, Word,
CommandNode, HintMode, IdentSource, Node, ValidationError, Word,
shared::{column_value_list, current_column_value},
};
use crate::dsl::value::Value;
@@ -61,7 +61,15 @@ const VALUE_LITERAL_CHOICES: &[Node] = &[
Node::NumberLit { validator: None },
Node::StringLit,
];
const VALUE_LITERAL: Node = Node::Choice(VALUE_LITERAL_CHOICES);
const VALUE_LITERAL_INNER: Node = Node::Choice(VALUE_LITERAL_CHOICES);
/// Value-literal slot with the `ProseOnly` HintMode
/// (ADR-0024 §HintMode-per-node) — the hint resolver surfaces
/// the generic "Type a value: …" prose rather than the
/// misleading `null`/`true`/`false` candidate trio.
const VALUE_LITERAL: Node = Node::Hinted {
mode: HintMode::ProseOnly("hint.value_literal_slot"),
inner: &VALUE_LITERAL_INNER,
};
// =================================================================
// show — `show (data|table) <T>`