@hydranium/core 1.0.0-next.357 → 1.0.0-next.358

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,8 +12,9 @@
12
12
  *
13
13
  * **These live beside the key provider because the constraint is the key
14
14
  * provider's.** `NameBasedKeyProvider` keys a node the `NameProvider` gives no
15
- * name from its position, as `` `${$containerProperty}@${$containerIndex}` ``,
16
- * so a node appended with a bare `array.push` carries neither and
15
+ * name from its position, as `` `${$containerProperty}@${$containerIndex}` ``
16
+ * (`` `${$containerProperty}@` `` in a single-valued property), so a node
17
+ * appended with a bare `array.push` carries neither and
17
18
  * `getElementKey` answers `undefined` — the element has no key at all, and the
18
19
  * GLSP index cannot address it. Deleting from the middle of such a list must
19
20
  * renumber the survivors, or an id derived later in the same command names the
@@ -1 +1 @@
1
- {"version":3,"file":"containment.d.ts","sourceRoot":"","sources":["../../../src/langium/keys/containment.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnI;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,SAAS,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAYhH"}
1
+ {"version":3,"file":"containment.d.ts","sourceRoot":"","sources":["../../../src/langium/keys/containment.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnI;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,SAAS,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAYhH"}
@@ -1 +1 @@
1
- {"version":3,"file":"containment.js","sourceRoot":"","sources":["../../../src/langium/keys/containment.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAmClF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAyB,SAAkB,EAAE,QAAgB,EAAE,QAAkB,EAAE,KAAa;IACxH,MAAM,OAAO,GAAG,KAAwB,CAAC;IACzC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACtC,OAAO,CAAC,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAyB,QAAkB,EAAE,QAA6B;IACrG,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC;IACZ,CAAC;IACD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IACnD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,KAAyB,CAAC,eAAe,GAAG,KAAK,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"containment.js","sourceRoot":"","sources":["../../../src/langium/keys/containment.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAoClF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAyB,SAAkB,EAAE,QAAgB,EAAE,QAAkB,EAAE,KAAa;IACxH,MAAM,OAAO,GAAG,KAAwB,CAAC;IACzC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,kBAAkB,GAAG,QAAQ,CAAC;IACtC,OAAO,CAAC,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AAChB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAyB,QAAkB,EAAE,QAA6B;IACrG,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,CAAC;IACZ,CAAC;IACD,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;IACnD,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,KAAyB,CAAC,eAAe,GAAG,KAAK,CAAC;QACnD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,OAAO,CAAC;AAClB,CAAC"}
@@ -42,20 +42,25 @@ import { type NameProvider } from '../naming/name-provider.js';
42
42
  * `NameProvider` gives no name. For grammars with unnamed element types the
43
43
  * reorder / insert / delete stability above does NOT apply to those nodes:
44
44
  * their keys move when their index moves, so a mid-array insert or delete
45
- * renumbers every later sibling.
45
+ * renumbers every later sibling. A node held in a single-valued property has
46
+ * no `$containerIndex` and falls back to `` `${$containerProperty}@` ``; the
47
+ * trailing `@` keeps its key apart from a sibling named after the property.
46
48
  *
47
49
  * Two consequences for a caller creating such nodes programmatically
48
50
  * (a GLSP operation handler is the usual case):
49
51
  *
50
- * - A node appended with a bare `array.push` has no `$containerProperty` /
51
- * `$containerIndex`, so `getElementKey` returns `undefined` and the node
52
- * has no key at all. The containment plumbing has to be stamped.
52
+ * - A node appended with a bare `array.push`, or assigned to a single-valued
53
+ * property without its `$containerProperty`, has no container position, so
54
+ * `getElementKey` returns `undefined` and the node has no key at all. The
55
+ * containment plumbing has to be stamped.
53
56
  * - After a removal, surviving siblings need their `$containerIndex`
54
57
  * renumbered, or a key derived afterwards addresses the wrong node.
55
58
  *
56
- * {@link appendChild} and {@link removeChildren} discharge both, and ship
57
- * beside this provider because the constraint is this provider's rather than
58
- * any caller's.
59
+ * {@link appendChild} and {@link removeChildren} discharge both for arrays,
60
+ * and ship beside this provider because the constraint is this provider's
61
+ * rather than any caller's. A single-valued property needs no helper: build
62
+ * the node with its `$container` and `$containerProperty`, which
63
+ * `buildAstNode` accepts.
59
64
  *
60
65
  * Adopters that need insert / delete stability for unnamed types should
61
66
  * give those types a name in the grammar, or bind a key provider whose
@@ -94,9 +99,11 @@ export declare class NameBasedKeyProvider implements ElementKeyProvider {
94
99
  */
95
100
  protected isSemanticRoot(node: AstNode): boolean;
96
101
  /**
97
- * Fallback segment for unnamed intermediate ancestors —
98
- * `containerProperty@containerIndex`. Returns `undefined` when the
99
- * node has no container position, which short-circuits the walk.
102
+ * Segment for a node the `NameProvider` gives no name —
103
+ * `containerProperty@containerIndex`, or `containerProperty@` when the
104
+ * container holds no array in that property, attached or not. Returns
105
+ * `undefined` when the node has no container position: the node itself
106
+ * then has no key, and an ancestor's level is left out of the key.
100
107
  */
101
108
  protected unidentifiedSegment(node: AstNode): string | undefined;
102
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"name-based-key-provider.d.ts","sourceRoot":"","sources":["../../../src/langium/keys/name-based-key-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,KAAK,kBAAkB,EAAwB,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAKzD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB;IAJtD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,YACsB,QAAQ,EAAE,sBAAsB,EACnD,OAAO,GAAE,cAAmB,EAI9B;IAED,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqBhD;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAEjE;IAED;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAQ/C;IAED;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK/D;CACH"}
1
+ {"version":3,"file":"name-based-key-provider.d.ts","sourceRoot":"","sources":["../../../src/langium/keys/name-based-key-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAElF,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,KAAK,kBAAkB,EAAwB,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AACH,qBAAa,oBAAqB,YAAW,kBAAkB;IAKzD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB;IAJtD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAElC,YACsB,QAAQ,EAAE,sBAAsB,EACnD,OAAO,GAAE,cAAmB,EAI9B;IAED,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqBhD;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAEjE;IAED;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAQ/C;IAED;;;;;;OAMG;IACH,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU/D;CACH"}
@@ -37,20 +37,25 @@ import { resolveElementByScan } from './element-key-provider.js';
37
37
  * `NameProvider` gives no name. For grammars with unnamed element types the
38
38
  * reorder / insert / delete stability above does NOT apply to those nodes:
39
39
  * their keys move when their index moves, so a mid-array insert or delete
40
- * renumbers every later sibling.
40
+ * renumbers every later sibling. A node held in a single-valued property has
41
+ * no `$containerIndex` and falls back to `` `${$containerProperty}@` ``; the
42
+ * trailing `@` keeps its key apart from a sibling named after the property.
41
43
  *
42
44
  * Two consequences for a caller creating such nodes programmatically
43
45
  * (a GLSP operation handler is the usual case):
44
46
  *
45
- * - A node appended with a bare `array.push` has no `$containerProperty` /
46
- * `$containerIndex`, so `getElementKey` returns `undefined` and the node
47
- * has no key at all. The containment plumbing has to be stamped.
47
+ * - A node appended with a bare `array.push`, or assigned to a single-valued
48
+ * property without its `$containerProperty`, has no container position, so
49
+ * `getElementKey` returns `undefined` and the node has no key at all. The
50
+ * containment plumbing has to be stamped.
48
51
  * - After a removal, surviving siblings need their `$containerIndex`
49
52
  * renumbered, or a key derived afterwards addresses the wrong node.
50
53
  *
51
- * {@link appendChild} and {@link removeChildren} discharge both, and ship
52
- * beside this provider because the constraint is this provider's rather than
53
- * any caller's.
54
+ * {@link appendChild} and {@link removeChildren} discharge both for arrays,
55
+ * and ship beside this provider because the constraint is this provider's
56
+ * rather than any caller's. A single-valued property needs no helper: build
57
+ * the node with its `$container` and `$containerProperty`, which
58
+ * `buildAstNode` accepts.
54
59
  *
55
60
  * Adopters that need insert / delete stability for unnamed types should
56
61
  * give those types a name in the grammar, or bind a key provider whose
@@ -124,15 +129,22 @@ export class NameBasedKeyProvider {
124
129
  return false;
125
130
  }
126
131
  /**
127
- * Fallback segment for unnamed intermediate ancestors —
128
- * `containerProperty@containerIndex`. Returns `undefined` when the
129
- * node has no container position, which short-circuits the walk.
132
+ * Segment for a node the `NameProvider` gives no name —
133
+ * `containerProperty@containerIndex`, or `containerProperty@` when the
134
+ * container holds no array in that property, attached or not. Returns
135
+ * `undefined` when the node has no container position: the node itself
136
+ * then has no key, and an ancestor's level is left out of the key.
130
137
  */
131
138
  unidentifiedSegment(node) {
132
- if (node.$containerProperty === undefined || node.$containerIndex === undefined) {
139
+ const property = node.$containerProperty;
140
+ if (property === undefined) {
133
141
  return undefined;
134
142
  }
135
- return `${node.$containerProperty}@${node.$containerIndex}`;
143
+ if (node.$containerIndex !== undefined) {
144
+ return `${property}@${node.$containerIndex}`;
145
+ }
146
+ // An array member without its index stays keyless rather than share `property@` with its siblings.
147
+ return Array.isArray(node.$container?.[property]) ? undefined : `${property}@`;
136
148
  }
137
149
  }
138
150
  //# sourceMappingURL=name-based-key-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"name-based-key-provider.js","sourceRoot":"","sources":["../../../src/langium/keys/name-based-key-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;kFAOkF;AAMlF,OAAO,EAA2B,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAG1F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,MAAM,OAAO,oBAAoB;IAKR,QAAQ;IAJX,YAAY,CAAe;IAC3B,MAAM,CAAS;IAElC,YACsB,QAAgC,EACnD,OAAO,GAAmB,EAAE;wBADT,QAAQ;QAG3B,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5G,CAAC;IAED,aAAa,CAAC,IAAc;QACzB,IAAI,CAAC,IAAI,EAAE,CAAC;YACT,OAAO,SAAS,CAAC;QACpB,CAAC;QACD,IAAI,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC9E,IAAI,CAAC,EAAE,EAAE,CAAC;YACP,OAAO,SAAS,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACb,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC;QAClD,IAAI,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YACzF,IAAI,OAAO,EAAE,CAAC;gBACX,EAAE,GAAG,OAAO,GAAG,SAAS,GAAG,EAAE,CAAC;YACjC,CAAC;YACD,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC;QAC9B,CAAC;QACD,OAAO,EAAE,CAAC;IACb,CAAC;IAED;;;;;;;OAOG;IACH,cAAc,CAAC,GAAW,EAAE,OAAgB;QACzC,OAAO,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;;;;;;OAYG;IACO,cAAc,CAAC,IAAa;QACnC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,KAAK,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACO,mBAAmB,CAAC,IAAa;QACxC,IAAI,IAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YAC/E,OAAO,SAAS,CAAC;QACpB,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;IAC/D,CAAC;CACH"}
1
+ {"version":3,"file":"name-based-key-provider.js","sourceRoot":"","sources":["../../../src/langium/keys/name-based-key-provider.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hydranium/core",
3
- "version": "1.0.0-next.357",
3
+ "version": "1.0.0-next.358",
4
4
  "description": "Foundational runtime of the hydranium framework: AST coordination layer (services, integrity, AST extension, serialization, multi-client documents) plus the LSP textual head at the /lsp subpath. Consumed by protocol-head packages (@hydranium/data-server, @hydranium/glsp-server).",
5
5
  "keywords": [
6
6
  "ast",
@@ -87,8 +87,8 @@
87
87
  "diff": "^5.2.0"
88
88
  },
89
89
  "devDependencies": {
90
- "@hydranium/langium": "1.0.0-next.357",
91
- "@hydranium/protocol": "1.0.0-next.357",
90
+ "@hydranium/langium": "1.0.0-next.358",
91
+ "@hydranium/protocol": "1.0.0-next.358",
92
92
  "@playwright/test": "^1.55.0",
93
93
  "@types/diff": "^5.2.0",
94
94
  "fake-indexeddb": "^6.2.5",
@@ -101,8 +101,8 @@
101
101
  "vscode-languageserver-types": "3.18.0"
102
102
  },
103
103
  "peerDependencies": {
104
- "@hydranium/langium": "1.0.0-next.357",
105
- "@hydranium/protocol": "1.0.0-next.357",
104
+ "@hydranium/langium": "1.0.0-next.358",
105
+ "@hydranium/protocol": "1.0.0-next.358",
106
106
  "@playwright/test": "^1.40.0",
107
107
  "vscode-jsonrpc": "^9.0.0",
108
108
  "vscode-languageserver": "~10.0.1",
@@ -13,8 +13,9 @@
13
13
  *
14
14
  * **These live beside the key provider because the constraint is the key
15
15
  * provider's.** `NameBasedKeyProvider` keys a node the `NameProvider` gives no
16
- * name from its position, as `` `${$containerProperty}@${$containerIndex}` ``,
17
- * so a node appended with a bare `array.push` carries neither and
16
+ * name from its position, as `` `${$containerProperty}@${$containerIndex}` ``
17
+ * (`` `${$containerProperty}@` `` in a single-valued property), so a node
18
+ * appended with a bare `array.push` carries neither and
18
19
  * `getElementKey` answers `undefined` — the element has no key at all, and the
19
20
  * GLSP index cannot address it. Deleting from the middle of such a list must
20
21
  * renumber the survivors, or an id derived later in the same command names the
@@ -44,20 +44,25 @@ import { type NameProvider } from '../naming/name-provider.js';
44
44
  * `NameProvider` gives no name. For grammars with unnamed element types the
45
45
  * reorder / insert / delete stability above does NOT apply to those nodes:
46
46
  * their keys move when their index moves, so a mid-array insert or delete
47
- * renumbers every later sibling.
47
+ * renumbers every later sibling. A node held in a single-valued property has
48
+ * no `$containerIndex` and falls back to `` `${$containerProperty}@` ``; the
49
+ * trailing `@` keeps its key apart from a sibling named after the property.
48
50
  *
49
51
  * Two consequences for a caller creating such nodes programmatically
50
52
  * (a GLSP operation handler is the usual case):
51
53
  *
52
- * - A node appended with a bare `array.push` has no `$containerProperty` /
53
- * `$containerIndex`, so `getElementKey` returns `undefined` and the node
54
- * has no key at all. The containment plumbing has to be stamped.
54
+ * - A node appended with a bare `array.push`, or assigned to a single-valued
55
+ * property without its `$containerProperty`, has no container position, so
56
+ * `getElementKey` returns `undefined` and the node has no key at all. The
57
+ * containment plumbing has to be stamped.
55
58
  * - After a removal, surviving siblings need their `$containerIndex`
56
59
  * renumbered, or a key derived afterwards addresses the wrong node.
57
60
  *
58
- * {@link appendChild} and {@link removeChildren} discharge both, and ship
59
- * beside this provider because the constraint is this provider's rather than
60
- * any caller's.
61
+ * {@link appendChild} and {@link removeChildren} discharge both for arrays,
62
+ * and ship beside this provider because the constraint is this provider's
63
+ * rather than any caller's. A single-valued property needs no helper: build
64
+ * the node with its `$container` and `$containerProperty`, which
65
+ * `buildAstNode` accepts.
61
66
  *
62
67
  * Adopters that need insert / delete stability for unnamed types should
63
68
  * give those types a name in the grammar, or bind a key provider whose
@@ -137,14 +142,21 @@ export class NameBasedKeyProvider implements ElementKeyProvider {
137
142
  }
138
143
 
139
144
  /**
140
- * Fallback segment for unnamed intermediate ancestors —
141
- * `containerProperty@containerIndex`. Returns `undefined` when the
142
- * node has no container position, which short-circuits the walk.
145
+ * Segment for a node the `NameProvider` gives no name —
146
+ * `containerProperty@containerIndex`, or `containerProperty@` when the
147
+ * container holds no array in that property, attached or not. Returns
148
+ * `undefined` when the node has no container position: the node itself
149
+ * then has no key, and an ancestor's level is left out of the key.
143
150
  */
144
151
  protected unidentifiedSegment(node: AstNode): string | undefined {
145
- if (node.$containerProperty === undefined || node.$containerIndex === undefined) {
152
+ const property = node.$containerProperty;
153
+ if (property === undefined) {
146
154
  return undefined;
147
155
  }
148
- return `${node.$containerProperty}@${node.$containerIndex}`;
156
+ if (node.$containerIndex !== undefined) {
157
+ return `${property}@${node.$containerIndex}`;
158
+ }
159
+ // An array member without its index stays keyless rather than share `property@` with its siblings.
160
+ return Array.isArray((node.$container as Record<string, unknown> | undefined)?.[property]) ? undefined : `${property}@`;
149
161
  }
150
162
  }