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:
+52
-22
@@ -14,9 +14,15 @@
|
||||
use crate::dsl::action::ReferentialAction;
|
||||
use crate::dsl::command::{ChangeColumnMode, ColumnSpec, Command, RelationshipSelector};
|
||||
use crate::dsl::grammar::{
|
||||
CommandNode, IdentSource, Node, ValidationError, Word,
|
||||
CommandNode, HintMode, IdentSource, Node, ValidationError, Word,
|
||||
shared::{REFERENTIAL_CLAUSES, TYPE_SLOT, TYPE_VALIDATOR},
|
||||
};
|
||||
|
||||
/// `HintMode` annotation shared by every `NewName` ident slot:
|
||||
/// the user is inventing a name, so the hint panel forces the
|
||||
/// "Type a name [then …]" prose rather than offering schema
|
||||
/// candidates (ADR-0024 §HintMode-per-node).
|
||||
const NEW_NAME_HINT: HintMode = HintMode::ForceProse("hint.ambient_typing_name");
|
||||
use crate::dsl::types::Type;
|
||||
use crate::dsl::walker::outcome::{MatchedKind, MatchedPath};
|
||||
|
||||
@@ -24,7 +30,7 @@ use crate::dsl::walker::outcome::{MatchedKind, MatchedPath};
|
||||
// Building blocks
|
||||
// =================================================================
|
||||
|
||||
const TABLE_NAME_NEW: Node = Node::Ident {
|
||||
const TABLE_NAME_NEW_IDENT: Node = Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "table_name",
|
||||
validator: None,
|
||||
@@ -33,6 +39,10 @@ const TABLE_NAME_NEW: Node = Node::Ident {
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
const TABLE_NAME_NEW: Node = Node::Hinted {
|
||||
mode: NEW_NAME_HINT,
|
||||
inner: &TABLE_NAME_NEW_IDENT,
|
||||
};
|
||||
|
||||
// `writes_table: true` so that the column-name slots that
|
||||
// follow the table name in `drop column` / `rename column` /
|
||||
@@ -61,7 +71,7 @@ const COLUMN_NAME: Node = Node::Ident {
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
|
||||
const COLUMN_NAME_NEW: Node = Node::Ident {
|
||||
const COLUMN_NAME_NEW_IDENT: Node = Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "column_name",
|
||||
validator: None,
|
||||
@@ -70,6 +80,10 @@ const COLUMN_NAME_NEW: Node = Node::Ident {
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
const COLUMN_NAME_NEW: Node = Node::Hinted {
|
||||
mode: NEW_NAME_HINT,
|
||||
inner: &COLUMN_NAME_NEW_IDENT,
|
||||
};
|
||||
|
||||
const RELATIONSHIP_NAME: Node = Node::Ident {
|
||||
source: IdentSource::Relationships,
|
||||
@@ -81,7 +95,7 @@ const RELATIONSHIP_NAME: Node = Node::Ident {
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
|
||||
const RELATIONSHIP_NAME_NEW: Node = Node::Ident {
|
||||
const RELATIONSHIP_NAME_NEW_IDENT: Node = Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "relationship_name",
|
||||
validator: None,
|
||||
@@ -90,6 +104,10 @@ const RELATIONSHIP_NAME_NEW: Node = Node::Ident {
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
const RELATIONSHIP_NAME_NEW: Node = Node::Hinted {
|
||||
mode: NEW_NAME_HINT,
|
||||
inner: &RELATIONSHIP_NAME_NEW_IDENT,
|
||||
};
|
||||
|
||||
// `[to]` and `[table]` connectives.
|
||||
const TO_OPT: Node = Node::Optional(&Node::Word(Word::keyword("to")));
|
||||
@@ -308,6 +326,20 @@ const ADD_SHAPE: Node = Node::Choice(ADD_CHOICES);
|
||||
// rename_column — `rename column [in] [table] <T> : <col> to <new>`
|
||||
// =================================================================
|
||||
|
||||
const NEW_COLUMN_NAME_IDENT: Node = Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "new_column_name",
|
||||
validator: None,
|
||||
highlight_override: None,
|
||||
writes_table: false,
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
const NEW_COLUMN_NAME: Node = Node::Hinted {
|
||||
mode: NEW_NAME_HINT,
|
||||
inner: &NEW_COLUMN_NAME_IDENT,
|
||||
};
|
||||
|
||||
const RENAME_COLUMN_NODES: &[Node] = &[
|
||||
Node::Word(Word::keyword("column")),
|
||||
IN_OPT,
|
||||
@@ -316,15 +348,7 @@ const RENAME_COLUMN_NODES: &[Node] = &[
|
||||
Node::Punct(':'),
|
||||
COLUMN_NAME,
|
||||
Node::Word(Word::keyword("to")),
|
||||
Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "new_column_name",
|
||||
validator: None,
|
||||
highlight_override: None,
|
||||
writes_table: false,
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
},
|
||||
NEW_COLUMN_NAME,
|
||||
];
|
||||
const RENAME_COLUMN: Node = Node::Seq(RENAME_COLUMN_NODES);
|
||||
|
||||
@@ -650,16 +674,22 @@ pub static CHANGE: CommandNode = CommandNode {
|
||||
// (Phase C)
|
||||
// =================================================================
|
||||
|
||||
const COL_NAME_IDENT: Node = Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "col_name",
|
||||
validator: None,
|
||||
highlight_override: None,
|
||||
writes_table: false,
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
};
|
||||
const COL_NAME: Node = Node::Hinted {
|
||||
mode: NEW_NAME_HINT,
|
||||
inner: &COL_NAME_IDENT,
|
||||
};
|
||||
|
||||
const COL_SPEC_NODES: &[Node] = &[
|
||||
Node::Ident {
|
||||
source: IdentSource::NewName,
|
||||
role: "col_name",
|
||||
validator: None,
|
||||
highlight_override: None,
|
||||
writes_table: false,
|
||||
writes_column: false,
|
||||
writes_user_listed_column: false,
|
||||
},
|
||||
COL_NAME,
|
||||
Node::Punct(':'),
|
||||
Node::Ident {
|
||||
source: IdentSource::Types,
|
||||
|
||||
Reference in New Issue
Block a user