@ldclabs/kip-lang 2.0.2 → 2.2.0
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.
- package/CHANGELOG.md +69 -0
- package/README.md +4 -4
- package/dist/ast.d.ts +75 -58
- package/dist/ast.d.ts.map +1 -1
- package/dist/exec-ast.d.ts +51 -50
- package/dist/exec-ast.d.ts.map +1 -1
- package/dist/formatter.d.ts.map +1 -1
- package/dist/formatter.js +62 -121
- package/dist/formatter.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +112 -97
- package/dist/lower.js.map +1 -1
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +146 -224
- package/dist/parser.js.map +1 -1
- package/dist/semantics.js +66 -35
- package/dist/semantics.js.map +1 -1
- package/dist/token.d.ts +4 -11
- package/dist/token.d.ts.map +1 -1
- package/dist/token.js +8 -22
- package/dist/token.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/src/ast.ts +73 -70
- package/src/exec-ast.ts +53 -42
- package/src/formatter.ts +61 -139
- package/src/index.ts +7 -13
- package/src/lower.ts +134 -106
- package/src/parser.ts +161 -250
- package/src/semantics.ts +63 -37
- package/src/token.ts +8 -22
- package/src/version.ts +1 -1
package/src/semantics.ts
CHANGED
|
@@ -48,13 +48,27 @@ const MODES = new Set([
|
|
|
48
48
|
'imported'
|
|
49
49
|
])
|
|
50
50
|
const SEARCH_MODES = new Set(['keyword', 'semantic', 'hybrid'])
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Everything `TRANSITION ... TO` may name (Spec §52.5): Assertion revision,
|
|
53
|
+
* Evidence correction, Activity status, and the storage lifecycle any element
|
|
54
|
+
* has. The engine matches the state to the target's kind; the toolkit can only
|
|
55
|
+
* reject a word that belongs to none of them.
|
|
56
|
+
*/
|
|
57
|
+
const TRANSITION_STATES = new Set([
|
|
53
58
|
'retracted',
|
|
54
59
|
'superseded',
|
|
55
|
-
'
|
|
60
|
+
'corrected',
|
|
61
|
+
'running',
|
|
62
|
+
'completed',
|
|
63
|
+
'failed',
|
|
64
|
+
'cancelled',
|
|
65
|
+
'archived',
|
|
66
|
+
'tombstoned'
|
|
56
67
|
])
|
|
57
|
-
|
|
68
|
+
/** Moves that name the replacing element with `BY`. */
|
|
69
|
+
const TRANSITION_WITH_BY = new Set(['superseded', 'corrected'])
|
|
70
|
+
/** Moves that may finalize an Activity's fields and topology. */
|
|
71
|
+
const ACTIVITY_STATES = new Set(['running', 'completed', 'failed', 'cancelled'])
|
|
58
72
|
const EVIDENCE_ROLES = new Set(['support', 'challenge', 'context'])
|
|
59
73
|
|
|
60
74
|
/** Signals the Profile fixes to `[0,1]`; none of them is truth. */
|
|
@@ -127,42 +141,51 @@ function analyzeMutationClause(stmt: Statement, diags: Diagnostic[]): void {
|
|
|
127
141
|
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
128
142
|
break
|
|
129
143
|
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
// The target's kind is not known statically, so only the vocabulary is
|
|
145
|
+
// checkable: a state no kind has, a `BY` on a move that takes none, a
|
|
146
|
+
// finalize clause on a move that is not an Activity's.
|
|
147
|
+
case 'TransitionStatement': {
|
|
148
|
+
checkEnum(stmt.to, TRANSITION_STATES, 'TRANSITION TO', diags)
|
|
149
|
+
if (stmt.to.kind === 'StringLiteral') {
|
|
150
|
+
const to = stmt.to.parsed
|
|
151
|
+
if (TRANSITION_WITH_BY.has(to) && !stmt.by) {
|
|
152
|
+
diags.push({
|
|
153
|
+
range: stmt.to.range,
|
|
154
|
+
severity: 'error',
|
|
155
|
+
message: `TRANSITION TO "${to}" names the replacing element with BY`,
|
|
156
|
+
code: 'KIP_2001'
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
if (!TRANSITION_WITH_BY.has(to) && stmt.by && TRANSITION_STATES.has(to)) {
|
|
160
|
+
diags.push({
|
|
161
|
+
range: stmt.by.range,
|
|
162
|
+
severity: 'error',
|
|
163
|
+
message: `TRANSITION TO "${to}" takes no BY`,
|
|
164
|
+
code: 'KIP_2001'
|
|
165
|
+
})
|
|
166
|
+
}
|
|
167
|
+
if (stmt.finalize.length > 0 && !ACTIVITY_STATES.has(to) && TRANSITION_STATES.has(to)) {
|
|
168
|
+
diags.push({
|
|
169
|
+
range: stmt.finalize[0].range,
|
|
170
|
+
severity: 'error',
|
|
171
|
+
message: `TRANSITION TO "${to}" cannot finalize fields or topology; only a pending Activity does`,
|
|
172
|
+
code: 'KIP_2001'
|
|
173
|
+
})
|
|
174
|
+
}
|
|
146
175
|
}
|
|
147
|
-
break
|
|
148
|
-
|
|
149
|
-
case 'ArchiveStatement':
|
|
150
|
-
case 'TombstoneStatement':
|
|
151
|
-
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
152
|
-
break
|
|
153
|
-
|
|
154
|
-
case 'TransitionActivityStatement':
|
|
155
|
-
checkEnum(stmt.to, ACTIVITY_TERMINAL, 'TRANSITION ACTIVITY TO', diags)
|
|
156
176
|
checkStructural(stmt.finalize.find(
|
|
157
177
|
(c): c is SetStructuralClause => c.kind === 'SetStructuralClause'
|
|
158
178
|
), diags)
|
|
179
|
+
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
159
180
|
break
|
|
181
|
+
}
|
|
160
182
|
|
|
161
|
-
// Spec §52.7 names
|
|
162
|
-
// and which SHOULD therefore carry a LIMIT. Warning on the read and on
|
|
183
|
+
// Spec §52.7 names seven statements whose WHERE can select an unbounded
|
|
184
|
+
// set and which SHOULD therefore carry a LIMIT. Warning on the read and on
|
|
163
185
|
// UPDATE while staying silent on the removal ladder had it backwards: an
|
|
164
186
|
// over-broad PURGE is the one that cannot be undone.
|
|
165
187
|
case 'PurgeStatement':
|
|
188
|
+
case 'PurgePayloadStatement':
|
|
166
189
|
case 'SetRetentionStatement':
|
|
167
190
|
if (stmt.where) checkWhere(stmt.where, !!stmt.limit, diags)
|
|
168
191
|
break
|
|
@@ -376,12 +399,15 @@ function collectHandleRefs(
|
|
|
376
399
|
}
|
|
377
400
|
break
|
|
378
401
|
|
|
379
|
-
case '
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
402
|
+
case 'TransitionStatement':
|
|
403
|
+
// `BY ?new` resolves inside the plan; a `?target` is bound by WHERE or
|
|
404
|
+
// by a handle, so only the replacing element is a plan reference.
|
|
405
|
+
if (clause.by && clause.by.kind === 'VariableRef') {
|
|
406
|
+
out.push({ name: clause.by.name.slice(1), range: clause.by.range })
|
|
407
|
+
}
|
|
408
|
+
for (const fin of clause.finalize) {
|
|
409
|
+
if (fin.kind === 'SetFieldsClause') fromObject(fin.assignments)
|
|
410
|
+
else for (const edge of fin.assignments) fromExpression(edge.value)
|
|
385
411
|
}
|
|
386
412
|
break
|
|
387
413
|
}
|
package/src/token.ts
CHANGED
|
@@ -33,8 +33,8 @@ export enum TokenType {
|
|
|
33
33
|
Distinct = 'DISTINCT',
|
|
34
34
|
As = 'AS',
|
|
35
35
|
Of = 'OF',
|
|
36
|
+
At = 'AT',
|
|
36
37
|
Seq = 'SEQ',
|
|
37
|
-
Tx = 'TX',
|
|
38
38
|
Time = 'TIME',
|
|
39
39
|
For = 'FOR',
|
|
40
40
|
Epistemic = 'EPISTEMIC',
|
|
@@ -55,16 +55,12 @@ export enum TokenType {
|
|
|
55
55
|
Assert = 'ASSERT',
|
|
56
56
|
Superseding = 'SUPERSEDING',
|
|
57
57
|
Update = 'UPDATE',
|
|
58
|
-
Retract = 'RETRACT',
|
|
59
|
-
Supersede = 'SUPERSEDE',
|
|
60
|
-
Correct = 'CORRECT',
|
|
61
58
|
Transition = 'TRANSITION',
|
|
62
59
|
Set = 'SET',
|
|
63
60
|
Unset = 'UNSET',
|
|
64
61
|
Retention = 'RETENTION',
|
|
65
|
-
Archive = 'ARCHIVE',
|
|
66
|
-
Tombstone = 'TOMBSTONE',
|
|
67
62
|
Purge = 'PURGE',
|
|
63
|
+
Payload = 'PAYLOAD',
|
|
68
64
|
Confirm = 'CONFIRM',
|
|
69
65
|
Reference = 'REFERENCE',
|
|
70
66
|
Policy = 'POLICY',
|
|
@@ -81,7 +77,6 @@ export enum TokenType {
|
|
|
81
77
|
Facet = 'FACET',
|
|
82
78
|
Expect = 'EXPECT',
|
|
83
79
|
Version = 'VERSION',
|
|
84
|
-
State = 'STATE',
|
|
85
80
|
|
|
86
81
|
// ── Keywords — META ───────────────────────────────────────────────
|
|
87
82
|
Describe = 'DESCRIBE',
|
|
@@ -97,10 +92,7 @@ export enum TokenType {
|
|
|
97
92
|
Primer = 'PRIMER',
|
|
98
93
|
Mode = 'MODE',
|
|
99
94
|
Protocol = 'PROTOCOL',
|
|
100
|
-
Execution = 'EXECUTION',
|
|
101
|
-
Context = 'CONTEXT',
|
|
102
95
|
Capabilities = 'CAPABILITIES',
|
|
103
|
-
Capability = 'CAPABILITY',
|
|
104
96
|
Space = 'SPACE',
|
|
105
97
|
Spaces = 'SPACES',
|
|
106
98
|
Schema = 'SCHEMA',
|
|
@@ -113,13 +105,14 @@ export enum TokenType {
|
|
|
113
105
|
Facets = 'FACETS',
|
|
114
106
|
Types = 'TYPES',
|
|
115
107
|
Policies = 'POLICIES',
|
|
108
|
+
Dependents = 'DEPENDENTS',
|
|
109
|
+
Depth = 'DEPTH',
|
|
116
110
|
Compatibility = 'COMPATIBILITY',
|
|
117
111
|
From = 'FROM',
|
|
118
112
|
Error = 'ERROR',
|
|
119
113
|
Transaction = 'TRANSACTION',
|
|
120
114
|
Idempotency = 'IDEMPOTENCY',
|
|
121
115
|
Capsule = 'CAPSULE',
|
|
122
|
-
Projection = 'PROJECTION',
|
|
123
116
|
Trust = 'TRUST',
|
|
124
117
|
Access = 'ACCESS',
|
|
125
118
|
With = 'WITH',
|
|
@@ -213,8 +206,8 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
213
206
|
['DISTINCT', TokenType.Distinct],
|
|
214
207
|
['AS', TokenType.As],
|
|
215
208
|
['OF', TokenType.Of],
|
|
209
|
+
['AT', TokenType.At],
|
|
216
210
|
['SEQ', TokenType.Seq],
|
|
217
|
-
['TX', TokenType.Tx],
|
|
218
211
|
['TIME', TokenType.Time],
|
|
219
212
|
['FOR', TokenType.For],
|
|
220
213
|
['EPISTEMIC', TokenType.Epistemic],
|
|
@@ -235,16 +228,12 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
235
228
|
['ASSERT', TokenType.Assert],
|
|
236
229
|
['SUPERSEDING', TokenType.Superseding],
|
|
237
230
|
['UPDATE', TokenType.Update],
|
|
238
|
-
['RETRACT', TokenType.Retract],
|
|
239
|
-
['SUPERSEDE', TokenType.Supersede],
|
|
240
|
-
['CORRECT', TokenType.Correct],
|
|
241
231
|
['TRANSITION', TokenType.Transition],
|
|
242
232
|
['SET', TokenType.Set],
|
|
243
233
|
['UNSET', TokenType.Unset],
|
|
244
234
|
['RETENTION', TokenType.Retention],
|
|
245
|
-
['ARCHIVE', TokenType.Archive],
|
|
246
|
-
['TOMBSTONE', TokenType.Tombstone],
|
|
247
235
|
['PURGE', TokenType.Purge],
|
|
236
|
+
['PAYLOAD', TokenType.Payload],
|
|
248
237
|
['CONFIRM', TokenType.Confirm],
|
|
249
238
|
['REFERENCE', TokenType.Reference],
|
|
250
239
|
['POLICY', TokenType.Policy],
|
|
@@ -261,7 +250,6 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
261
250
|
['FACET', TokenType.Facet],
|
|
262
251
|
['EXPECT', TokenType.Expect],
|
|
263
252
|
['VERSION', TokenType.Version],
|
|
264
|
-
['STATE', TokenType.State],
|
|
265
253
|
|
|
266
254
|
// META
|
|
267
255
|
['DESCRIBE', TokenType.Describe],
|
|
@@ -277,10 +265,7 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
277
265
|
['PRIMER', TokenType.Primer],
|
|
278
266
|
['MODE', TokenType.Mode],
|
|
279
267
|
['PROTOCOL', TokenType.Protocol],
|
|
280
|
-
['EXECUTION', TokenType.Execution],
|
|
281
|
-
['CONTEXT', TokenType.Context],
|
|
282
268
|
['CAPABILITIES', TokenType.Capabilities],
|
|
283
|
-
['CAPABILITY', TokenType.Capability],
|
|
284
269
|
['SPACE', TokenType.Space],
|
|
285
270
|
['SPACES', TokenType.Spaces],
|
|
286
271
|
['SCHEMA', TokenType.Schema],
|
|
@@ -293,13 +278,14 @@ export const KEYWORDS: ReadonlyMap<string, TokenType> = new Map([
|
|
|
293
278
|
['FACETS', TokenType.Facets],
|
|
294
279
|
['TYPES', TokenType.Types],
|
|
295
280
|
['POLICIES', TokenType.Policies],
|
|
281
|
+
['DEPENDENTS', TokenType.Dependents],
|
|
282
|
+
['DEPTH', TokenType.Depth],
|
|
296
283
|
['COMPATIBILITY', TokenType.Compatibility],
|
|
297
284
|
['FROM', TokenType.From],
|
|
298
285
|
['ERROR', TokenType.Error],
|
|
299
286
|
['TRANSACTION', TokenType.Transaction],
|
|
300
287
|
['IDEMPOTENCY', TokenType.Idempotency],
|
|
301
288
|
['CAPSULE', TokenType.Capsule],
|
|
302
|
-
['PROJECTION', TokenType.Projection],
|
|
303
289
|
['TRUST', TokenType.Trust],
|
|
304
290
|
['ACCESS', TokenType.Access],
|
|
305
291
|
['WITH', TokenType.With],
|
package/src/version.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* has to load in runtimes with no filesystem; `test/lower.test.mjs` asserts the
|
|
8
8
|
* two stay in step.
|
|
9
9
|
*/
|
|
10
|
-
export const PARSER_VERSION = '2.0
|
|
10
|
+
export const PARSER_VERSION = '2.2.0'
|
|
11
11
|
|
|
12
12
|
/** The KIP specification revision this grammar targets. */
|
|
13
13
|
export const KIP_SPEC_REVISION = '2.0-draft'
|