@shapeshift-labs/frontier-lang-parser 0.3.70 → 0.3.72
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/dist/gate-admission-evidence-proof-obligations.js +116 -0
- package/dist/gate-admission-evidence.js +45 -14
- package/dist/metadata.js +10 -0
- package/dist/resource-graph.js +66 -6
- package/dist/source-syntax-children.js +13 -4
- package/dist/source-syntax-row-config.js +9 -3
- package/package.json +2 -2
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export function proofObligationRecord(name, text, authoredLine, rowKind) {
|
|
2
|
+
return cleanRecord({
|
|
3
|
+
kind: 'frontier.lang.gateAdmissionEvidence.proofObligation',
|
|
4
|
+
version: 1,
|
|
5
|
+
id: idFrom(text, `gate_admission_obligation_${safeId(name)}`),
|
|
6
|
+
name,
|
|
7
|
+
obligationKind: readInlineWord('kind', text) ?? readInlineWord('obligationKind', text) ?? 'proof',
|
|
8
|
+
status: readInlineWord('status', text) ?? 'missing',
|
|
9
|
+
readiness: readInlineWord('readiness', text),
|
|
10
|
+
capability: readInlineWord('capability', text),
|
|
11
|
+
routeId: readInlineWord('route', text) ?? readInlineWord('routeId', text),
|
|
12
|
+
routeIds: readInlineList(text, 'routeIds'),
|
|
13
|
+
language: readInlineWord('language', text) ?? readInlineWord('sourceLanguage', text),
|
|
14
|
+
sourceLanguage: readInlineWord('sourceLanguage', text) ?? readInlineWord('language', text),
|
|
15
|
+
target: readInlineWord('target', text) ?? readInlineWord('targetLanguage', text),
|
|
16
|
+
sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text),
|
|
17
|
+
sourceHash: readInlineWord('sourceHash', text),
|
|
18
|
+
targetHash: readInlineWord('targetHash', text),
|
|
19
|
+
outputHash: readInlineWord('outputHash', text),
|
|
20
|
+
telemetryHash: readInlineWord('telemetryHash', text),
|
|
21
|
+
gateIds: readInlineList(text, 'gate', 'gateId', 'gateIds'),
|
|
22
|
+
admissionIds: readInlineList(text, 'admission', 'admissionId', 'admissionIds'),
|
|
23
|
+
evidenceIds: readInlineList(text, 'evidence', 'evidenceIds'),
|
|
24
|
+
proofEvidenceIds: readInlineList(text, 'proofEvidence', 'proofEvidenceIds'),
|
|
25
|
+
requiredSignals: readInlineList(text, 'requiredSignal', 'requiredSignals'),
|
|
26
|
+
providedSignals: readInlineList(text, 'providedSignal', 'providedSignals'),
|
|
27
|
+
missingSignals: readInlineList(text, 'missingSignal', 'missingSignals'),
|
|
28
|
+
missingEvidence: readInlineList(text, 'missingEvidence'),
|
|
29
|
+
reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes', 'reason', 'reasons'),
|
|
30
|
+
summary: readInlineQuoted('summary', text) ?? readInlineQuoted('message', text),
|
|
31
|
+
failClosed: true,
|
|
32
|
+
...falseClaims(),
|
|
33
|
+
authoredText: authoredLine.text,
|
|
34
|
+
sourceSpan: authoredLine.sourceSpan,
|
|
35
|
+
authoredSourceSpan: authoredLine.sourceSpan,
|
|
36
|
+
metadata: cleanRecord({ authoredName: name, authoredRowKind: rowKind, ...falseClaims() })
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function unknownRowRecord(line, authoredLine) {
|
|
41
|
+
const rowKind = /^([A-Za-z_$][\w$-]*)\b/.exec(line)?.[1];
|
|
42
|
+
const name = new RegExp('^[A-Za-z_$][\\w$-]*\\s+([A-Za-z_$@/.:*-][\\w$./@:*+-]*)').exec(line)?.[1];
|
|
43
|
+
return cleanRecord({
|
|
44
|
+
kind: 'frontier.lang.gateAdmissionEvidence.unknownRow',
|
|
45
|
+
version: 1,
|
|
46
|
+
id: `gate_admission_unknown_${safeId(rowKind ?? 'row')}_${authoredLine.startOffset}`,
|
|
47
|
+
rowKind,
|
|
48
|
+
normalizedRowKind: 'unknown',
|
|
49
|
+
name: name ?? rowKind ?? 'unknown',
|
|
50
|
+
status: 'unsupported',
|
|
51
|
+
reason: 'unsupported-gate-admission-row',
|
|
52
|
+
code: 'unsupported-gate-admission-row',
|
|
53
|
+
failClosed: true,
|
|
54
|
+
...falseClaims(),
|
|
55
|
+
authoredText: line,
|
|
56
|
+
sourceSpan: authoredLine.sourceSpan,
|
|
57
|
+
authoredSourceSpan: authoredLine.sourceSpan,
|
|
58
|
+
metadata: cleanRecord({ authoredRowKind: rowKind, ...falseClaims() })
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function unsupportedRowProofGapRecord(unknownRow, authoredLine) {
|
|
63
|
+
return cleanRecord({
|
|
64
|
+
kind: 'frontier.lang.gateAdmissionEvidence.proofGap',
|
|
65
|
+
version: 1,
|
|
66
|
+
id: `gate_admission_gap_unsupported_${authoredLine.startOffset}`,
|
|
67
|
+
name: unknownRow.name,
|
|
68
|
+
code: 'unsupported-gate-admission-row',
|
|
69
|
+
status: 'missing',
|
|
70
|
+
evidenceIds: [unknownRow.id],
|
|
71
|
+
summary: `Unsupported gateEvidence row "${unknownRow.rowKind ?? 'unknown'}" requires parser support before admission.`,
|
|
72
|
+
failClosed: true,
|
|
73
|
+
...falseClaims(),
|
|
74
|
+
authoredText: authoredLine.text,
|
|
75
|
+
sourceSpan: authoredLine.sourceSpan,
|
|
76
|
+
authoredSourceSpan: authoredLine.sourceSpan,
|
|
77
|
+
metadata: cleanRecord({ unknownRowId: unknownRow.id, authoredRowKind: unknownRow.rowKind, ...falseClaims() })
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function parserUnsupportedRowError(unknownRow) {
|
|
82
|
+
return cleanRecord({
|
|
83
|
+
code: 'unsupported-gate-admission-row',
|
|
84
|
+
message: `Unsupported gateEvidence row "${unknownRow.rowKind ?? 'unknown'}" must be reviewed before admission.`,
|
|
85
|
+
rowId: unknownRow.id,
|
|
86
|
+
rowKind: unknownRow.rowKind,
|
|
87
|
+
sourceSpan: unknownRow.sourceSpan
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function falseClaims() {
|
|
92
|
+
return {
|
|
93
|
+
autoMergeClaim: false,
|
|
94
|
+
semanticEquivalenceClaim: false,
|
|
95
|
+
runtimeEquivalenceClaim: false,
|
|
96
|
+
gatePassImpliesAdmissionClaim: false,
|
|
97
|
+
targetAdapterReadinessClaim: false
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function idFrom(text, fallback) { return /@id\(\s*["']([^"']+)["']\s*\)/.exec(text)?.[1] ?? fallback; }
|
|
102
|
+
function safeId(value) { return String(value ?? 'record').replace(/[^A-Za-z0-9_$-]+/g, '_'); }
|
|
103
|
+
function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(unquotedText(text))?.[1]?.trim(); }
|
|
104
|
+
function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
|
|
105
|
+
function readInlineList(text, ...labels) {
|
|
106
|
+
const source = unquotedText(text);
|
|
107
|
+
for (const label of labels) {
|
|
108
|
+
const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(source)?.[1]?.trim();
|
|
109
|
+
if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
function unquotedText(text) { return text.replace(/"[^"]*"|'[^']*'/g, (match) => ' '.repeat(match.length)); }
|
|
114
|
+
function cleanRecord(record) {
|
|
115
|
+
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0) && !(value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)));
|
|
116
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { parserUnsupportedRowError, proofObligationRecord, unknownRowRecord, unsupportedRowProofGapRecord } from './gate-admission-evidence-proof-obligations.js';
|
|
2
|
+
|
|
1
3
|
export function parseGateAdmissionEvidenceBlock(block) {
|
|
2
4
|
const name = nameFrom(block.header);
|
|
3
5
|
const surface = {
|
|
@@ -9,7 +11,9 @@ export function parseGateAdmissionEvidenceBlock(block) {
|
|
|
9
11
|
gates: [],
|
|
10
12
|
evidence: [],
|
|
11
13
|
admissions: [],
|
|
14
|
+
proofObligations: [],
|
|
12
15
|
proofGaps: [],
|
|
16
|
+
unknownRows: [],
|
|
13
17
|
parser: { status: 'authored', errors: [] },
|
|
14
18
|
claims: falseClaims(),
|
|
15
19
|
metadata: { authoredName: name, authoredBlockKind: block.kind }
|
|
@@ -17,22 +21,34 @@ export function parseGateAdmissionEvidenceBlock(block) {
|
|
|
17
21
|
for (const authoredLine of readAuthoredLines(block)) {
|
|
18
22
|
const line = authoredLine.text;
|
|
19
23
|
if (!line || line.startsWith('#')) continue;
|
|
20
|
-
const match = /^(gate|evidence|proofEvidence|admission|admissionDecision|gap|proofGap)\s+([A-Za-z_$@/.:*-][\w$./@:*+-]*)(.*)$/.exec(line);
|
|
21
|
-
if (!match)
|
|
24
|
+
const match = /^(gate|evidence|proofEvidence|admission|admissionDecision|proofObligation|obligation|gap|proofGap)\s+([A-Za-z_$@/.:*-][\w$./@:*+-]*)(.*)$/.exec(line);
|
|
25
|
+
if (!match) {
|
|
26
|
+
const unknownRow = unknownRowRecord(line, authoredLine);
|
|
27
|
+
surface.unknownRows.push(unknownRow);
|
|
28
|
+
surface.proofGaps.push(unsupportedRowProofGapRecord(unknownRow, authoredLine));
|
|
29
|
+
surface.parser.status = 'needs-review';
|
|
30
|
+
surface.parser.errors.push(parserUnsupportedRowError(unknownRow));
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
22
33
|
const [, rowKind, rowName, text] = match;
|
|
23
34
|
if (rowKind === 'gate') surface.gates.push(gateRecord(rowName, text, authoredLine));
|
|
24
35
|
else if (rowKind === 'evidence' || rowKind === 'proofEvidence') surface.evidence.push(evidenceRecord(rowName, text, authoredLine, rowKind));
|
|
25
36
|
else if (rowKind === 'admission' || rowKind === 'admissionDecision') surface.admissions.push(admissionRecord(rowName, text, authoredLine));
|
|
37
|
+
else if (rowKind === 'proofObligation' || rowKind === 'obligation') surface.proofObligations.push(proofObligationRecord(rowName, text, authoredLine, rowKind));
|
|
26
38
|
else surface.proofGaps.push(proofGapRecord(rowName, text, authoredLine));
|
|
27
39
|
}
|
|
28
40
|
surface.gateIds = ids(surface.gates);
|
|
29
41
|
surface.evidenceIds = ids(surface.evidence);
|
|
30
42
|
surface.proofEvidenceIds = surface.evidence.filter((record) => record.proof).map((record) => record.id).filter(Boolean);
|
|
31
43
|
surface.admissionIds = ids(surface.admissions);
|
|
44
|
+
surface.proofObligationIds = ids(surface.proofObligations);
|
|
45
|
+
surface.unknownRowIds = ids(surface.unknownRows);
|
|
32
46
|
surface.proofGapCodes = uniqueStrings(surface.proofGaps.map((record) => record.code));
|
|
33
47
|
surface.missingEvidence = uniqueStrings([
|
|
34
48
|
...surface.gates.flatMap((record) => record.missingEvidence ?? []),
|
|
35
49
|
...surface.admissions.flatMap((record) => record.missingEvidence ?? []),
|
|
50
|
+
...surface.proofObligations.flatMap((record) => record.missingEvidence ?? []),
|
|
51
|
+
...surface.proofObligations.flatMap((record) => record.missingSignals ?? []),
|
|
36
52
|
...surface.proofGaps.map((record) => record.code)
|
|
37
53
|
]);
|
|
38
54
|
surface.summary = {
|
|
@@ -40,10 +56,13 @@ export function parseGateAdmissionEvidenceBlock(block) {
|
|
|
40
56
|
evidenceCount: surface.evidence.length,
|
|
41
57
|
proofEvidenceCount: surface.proofEvidenceIds.length,
|
|
42
58
|
admissionCount: surface.admissions.length,
|
|
59
|
+
proofObligationCount: surface.proofObligations.length,
|
|
43
60
|
proofGapCount: surface.proofGaps.length,
|
|
61
|
+
unknownRowCount: surface.unknownRows.length,
|
|
44
62
|
missingEvidenceCount: surface.missingEvidence.length,
|
|
45
63
|
passedGateCount: surface.gates.filter((record) => record.status === 'passed').length,
|
|
46
64
|
failedGateCount: surface.gates.filter((record) => record.status === 'failed').length,
|
|
65
|
+
openProofObligationCount: surface.proofObligations.filter((record) => /missing|blocked|review|open|unknown/.test(record.status ?? '')).length,
|
|
47
66
|
blockedAdmissionCount: surface.admissions.filter((record) => /blocked|missing|failed|review/.test(record.status ?? '')).length
|
|
48
67
|
};
|
|
49
68
|
return surface;
|
|
@@ -53,13 +72,18 @@ export function mergeGateAdmissionEvidenceBlocks(blocks) {
|
|
|
53
72
|
const gates = uniqueRecords(blocks.flatMap((block) => block.gates ?? []));
|
|
54
73
|
const evidence = uniqueRecords(blocks.flatMap((block) => block.evidence ?? []));
|
|
55
74
|
const admissions = uniqueRecords(blocks.flatMap((block) => block.admissions ?? []));
|
|
75
|
+
const proofObligations = uniqueRecords(blocks.flatMap((block) => block.proofObligations ?? []));
|
|
56
76
|
const proofGaps = uniqueRecords(blocks.flatMap((block) => block.proofGaps ?? []));
|
|
77
|
+
const unknownRows = uniqueRecords(blocks.flatMap((block) => block.unknownRows ?? []));
|
|
57
78
|
const proofEvidenceIds = evidence.filter((record) => record.proof).map((record) => record.id).filter(Boolean);
|
|
58
79
|
const missingEvidence = uniqueStrings([
|
|
59
80
|
...gates.flatMap((record) => record.missingEvidence ?? []),
|
|
60
81
|
...admissions.flatMap((record) => record.missingEvidence ?? []),
|
|
82
|
+
...proofObligations.flatMap((record) => record.missingEvidence ?? []),
|
|
83
|
+
...proofObligations.flatMap((record) => record.missingSignals ?? []),
|
|
61
84
|
...proofGaps.map((record) => record.code)
|
|
62
85
|
]);
|
|
86
|
+
const parserErrors = blocks.flatMap((block) => block.parser?.errors ?? []);
|
|
63
87
|
return {
|
|
64
88
|
kind: 'frontier.lang.authoredGateAdmissionEvidenceInput',
|
|
65
89
|
version: 1,
|
|
@@ -70,23 +94,34 @@ export function mergeGateAdmissionEvidenceBlocks(blocks) {
|
|
|
70
94
|
gates,
|
|
71
95
|
evidence,
|
|
72
96
|
admissions,
|
|
97
|
+
proofObligations,
|
|
73
98
|
proofGaps,
|
|
99
|
+
unknownRows,
|
|
74
100
|
gateIds: ids(gates),
|
|
75
101
|
evidenceIds: ids(evidence),
|
|
76
102
|
proofEvidenceIds,
|
|
77
103
|
admissionIds: ids(admissions),
|
|
104
|
+
proofObligationIds: ids(proofObligations),
|
|
105
|
+
unknownRowIds: ids(unknownRows),
|
|
78
106
|
proofGapCodes: uniqueStrings(proofGaps.map((record) => record.code)),
|
|
79
107
|
missingEvidence,
|
|
108
|
+
parser: {
|
|
109
|
+
status: parserErrors.length ? 'needs-review' : 'authored',
|
|
110
|
+
errors: parserErrors
|
|
111
|
+
},
|
|
80
112
|
summary: {
|
|
81
113
|
blockCount: blocks.length,
|
|
82
114
|
gateCount: gates.length,
|
|
83
115
|
evidenceCount: evidence.length,
|
|
84
116
|
proofEvidenceCount: proofEvidenceIds.length,
|
|
85
117
|
admissionCount: admissions.length,
|
|
118
|
+
proofObligationCount: proofObligations.length,
|
|
86
119
|
proofGapCount: proofGaps.length,
|
|
120
|
+
unknownRowCount: unknownRows.length,
|
|
87
121
|
missingEvidenceCount: missingEvidence.length,
|
|
88
122
|
passedGateCount: gates.filter((record) => record.status === 'passed').length,
|
|
89
123
|
failedGateCount: gates.filter((record) => record.status === 'failed').length,
|
|
124
|
+
openProofObligationCount: proofObligations.filter((record) => /missing|blocked|review|open|unknown/.test(record.status ?? '')).length,
|
|
90
125
|
blockedAdmissionCount: admissions.filter((record) => /blocked|missing|failed|review/.test(record.status ?? '')).length
|
|
91
126
|
},
|
|
92
127
|
claims: falseClaims(),
|
|
@@ -124,6 +159,7 @@ function gateRecord(name, text, authoredLine) {
|
|
|
124
159
|
reasonCodes: readInlineList(text, 'reasonCode', 'reasonCodes'),
|
|
125
160
|
failClosed: true,
|
|
126
161
|
claims: falseClaims(),
|
|
162
|
+
authoredText: authoredLine.text,
|
|
127
163
|
sourceSpan: authoredLine.sourceSpan,
|
|
128
164
|
authoredSourceSpan: authoredLine.sourceSpan,
|
|
129
165
|
metadata: cleanRecord({ authoredName: name, summary: readInlineQuoted('summary', text), ...falseClaims() })
|
|
@@ -159,6 +195,8 @@ function evidenceRecord(name, text, authoredLine, rowKind) {
|
|
|
159
195
|
autoMergeClaim: false,
|
|
160
196
|
semanticEquivalenceClaim: false,
|
|
161
197
|
runtimeEquivalenceClaim: false,
|
|
198
|
+
targetAdapterReadinessClaim: false,
|
|
199
|
+
authoredText: authoredLine.text,
|
|
162
200
|
sourceSpan: authoredLine.sourceSpan,
|
|
163
201
|
authoredSourceSpan: authoredLine.sourceSpan,
|
|
164
202
|
metadata: cleanRecord({ authoredName: name, authoredRowKind: rowKind, ...falseClaims() })
|
|
@@ -198,6 +236,8 @@ function admissionRecord(name, text, authoredLine) {
|
|
|
198
236
|
autoMergeClaim: false,
|
|
199
237
|
semanticEquivalenceClaim: false,
|
|
200
238
|
runtimeEquivalenceClaim: false,
|
|
239
|
+
targetAdapterReadinessClaim: false,
|
|
240
|
+
authoredText: authoredLine.text,
|
|
201
241
|
sourceSpan: authoredLine.sourceSpan,
|
|
202
242
|
authoredSourceSpan: authoredLine.sourceSpan,
|
|
203
243
|
metadata: cleanRecord({ authoredName: name, summary: readInlineQuoted('summary', text), ...falseClaims() })
|
|
@@ -221,6 +261,7 @@ function proofGapRecord(name, text, authoredLine) {
|
|
|
221
261
|
summary: readInlineQuoted('summary', text) ?? readInlineQuoted('message', text),
|
|
222
262
|
failClosed: true,
|
|
223
263
|
...falseClaims(),
|
|
264
|
+
authoredText: authoredLine.text,
|
|
224
265
|
sourceSpan: authoredLine.sourceSpan,
|
|
225
266
|
authoredSourceSpan: authoredLine.sourceSpan,
|
|
226
267
|
metadata: cleanRecord({ authoredName: name, ...falseClaims() })
|
|
@@ -237,24 +278,14 @@ function readAuthoredLines(block) {
|
|
|
237
278
|
const trailing = /\s*$/.exec(rawLine)?.[0].length ?? 0;
|
|
238
279
|
const startOffset = lineStart + leading;
|
|
239
280
|
const endOffset = Math.max(startOffset, rawEnd - trailing);
|
|
240
|
-
records.push({
|
|
241
|
-
text: rawLine.trim(),
|
|
242
|
-
startOffset,
|
|
243
|
-
endOffset,
|
|
244
|
-
sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined
|
|
245
|
-
});
|
|
281
|
+
records.push({ text: rawLine.trim(), startOffset, endOffset, sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined });
|
|
246
282
|
lineStart = rawEnd + 1;
|
|
247
283
|
}
|
|
248
284
|
return records;
|
|
249
285
|
}
|
|
250
286
|
|
|
251
287
|
function falseClaims() {
|
|
252
|
-
return {
|
|
253
|
-
autoMergeClaim: false,
|
|
254
|
-
semanticEquivalenceClaim: false,
|
|
255
|
-
runtimeEquivalenceClaim: false,
|
|
256
|
-
gatePassImpliesAdmissionClaim: false
|
|
257
|
-
};
|
|
288
|
+
return { autoMergeClaim: false, semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false, gatePassImpliesAdmissionClaim: false, targetAdapterReadinessClaim: false };
|
|
258
289
|
}
|
|
259
290
|
|
|
260
291
|
function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
|
package/dist/metadata.js
CHANGED
|
@@ -264,6 +264,11 @@ function mergeResourceGraphBlocks(blocks) {
|
|
|
264
264
|
lifetimeRelationIds: blocks.flatMap((block) => ids(block.graph?.lifetimeRelations)),
|
|
265
265
|
borrowScopeIds: blocks.flatMap((block) => ids(block.graph?.borrowScopes)),
|
|
266
266
|
unsafeBoundaryIds: blocks.flatMap((block) => ids(block.graph?.unsafeBoundaries)),
|
|
267
|
+
memoryRegionIds: blocks.flatMap((block) => ids(block.graph?.memoryRegions)),
|
|
268
|
+
dataLayoutIds: blocks.flatMap((block) => ids(block.graph?.dataLayouts)),
|
|
269
|
+
pointerEdgeIds: blocks.flatMap((block) => ids(block.graph?.pointerEdges)),
|
|
270
|
+
memoryAccessIds: blocks.flatMap((block) => ids(block.graph?.memoryAccesses)),
|
|
271
|
+
abiBoundaryIds: blocks.flatMap((block) => ids(block.graph?.abiBoundaries)),
|
|
267
272
|
conflictIds: blocks.flatMap((block) => ids(block.graph?.conflicts)),
|
|
268
273
|
proofObligationIds: blocks.flatMap((block) => ids(block.graph?.proofObligations)),
|
|
269
274
|
summary: {
|
|
@@ -280,6 +285,11 @@ function mergeResourceGraphBlocks(blocks) {
|
|
|
280
285
|
lifetimeRelationCount: sum(blocks, 'lifetimeRelations'),
|
|
281
286
|
borrowScopeCount: sum(blocks, 'borrowScopes'),
|
|
282
287
|
unsafeBoundaryCount: sum(blocks, 'unsafeBoundaries'),
|
|
288
|
+
memoryRegionCount: sum(blocks, 'memoryRegions'),
|
|
289
|
+
dataLayoutCount: sum(blocks, 'dataLayouts'),
|
|
290
|
+
pointerEdgeCount: sum(blocks, 'pointerEdges'),
|
|
291
|
+
memoryAccessCount: sum(blocks, 'memoryAccesses'),
|
|
292
|
+
abiBoundaryCount: sum(blocks, 'abiBoundaries'),
|
|
283
293
|
conflictCount: sum(blocks, 'conflicts'),
|
|
284
294
|
proofObligationCount: sum(blocks, 'proofObligations'),
|
|
285
295
|
unsafeBoundariesWithoutProof: sum(blocks, 'unsafeBoundariesWithoutProof')
|
package/dist/resource-graph.js
CHANGED
|
@@ -12,6 +12,11 @@ const GROUPS = {
|
|
|
12
12
|
lifetimeRelation: 'lifetimeRelations',
|
|
13
13
|
borrowScope: 'borrowScopes',
|
|
14
14
|
unsafeBoundary: 'unsafeBoundaries',
|
|
15
|
+
memoryRegion: 'memoryRegions',
|
|
16
|
+
dataLayout: 'dataLayouts',
|
|
17
|
+
pointerEdge: 'pointerEdges',
|
|
18
|
+
memoryAccess: 'memoryAccesses',
|
|
19
|
+
abiBoundary: 'abiBoundaries',
|
|
15
20
|
conflict: 'conflicts',
|
|
16
21
|
proofObligation: 'proofObligations'
|
|
17
22
|
};
|
|
@@ -41,6 +46,11 @@ export function parseResourceGraphBlock(block) {
|
|
|
41
46
|
borrowScopes: [],
|
|
42
47
|
borrowScopeRegions: [],
|
|
43
48
|
unsafeBoundaries: [],
|
|
49
|
+
memoryRegions: [],
|
|
50
|
+
dataLayouts: [],
|
|
51
|
+
pointerEdges: [],
|
|
52
|
+
memoryAccesses: [],
|
|
53
|
+
abiBoundaries: [],
|
|
44
54
|
conflicts: [],
|
|
45
55
|
proofObligations: [],
|
|
46
56
|
parser: { status: 'authored', errors: rowIdentity.errors },
|
|
@@ -54,14 +64,14 @@ export function parseResourceGraphBlock(block) {
|
|
|
54
64
|
metadata: { name }
|
|
55
65
|
};
|
|
56
66
|
|
|
57
|
-
for (const
|
|
58
|
-
const line =
|
|
67
|
+
for (const authoredLine of readAuthoredLines(block)) {
|
|
68
|
+
const line = authoredLine.text;
|
|
59
69
|
if (!line || line.startsWith('#') || isGraphPropertyLine(line)) continue;
|
|
60
70
|
const match = /^([A-Za-z_$][\w$-]*)\s+([A-Za-z_$][\w$-]*)(.*)$/.exec(line);
|
|
61
71
|
if (!match) continue;
|
|
62
72
|
const [, rowKind, rowName, rest] = match;
|
|
63
73
|
const normalized = normalizeRowKind(rowKind);
|
|
64
|
-
const record = parseResourceRecord(normalized, rowName, rest, graph);
|
|
74
|
+
const record = parseResourceRecord(normalized, rowName, rest, graph, authoredLine);
|
|
65
75
|
const group = GROUPS[normalized];
|
|
66
76
|
if (record && group) rowIdentity.push(graph[group], record, { rowKind, normalizedRowKind: normalized, name: rowName });
|
|
67
77
|
}
|
|
@@ -73,6 +83,7 @@ export function parseResourceGraphBlock(block) {
|
|
|
73
83
|
resourceIds: ids(graph.resources),
|
|
74
84
|
ownerIds: ids(graph.owners),
|
|
75
85
|
lifetimeRegionIds: ids(graph.lifetimeRegions),
|
|
86
|
+
lowLevelPrimitiveIds: ids([...graph.memoryRegions, ...graph.dataLayouts, ...graph.pointerEdges, ...graph.memoryAccesses, ...graph.abiBoundaries]),
|
|
76
87
|
sourcePaths: unique(allRecords(graph).map((record) => record.sourcePath)),
|
|
77
88
|
evidenceIds: unique([...graph.evidenceIds, ...allRecords(graph).flatMap((record) => record.evidenceIds ?? [])]),
|
|
78
89
|
blockerReasonCodes: unique(graph.conflicts.map((record) => record.reasonCode))
|
|
@@ -90,8 +101,8 @@ export function parseResourceGraphBlock(block) {
|
|
|
90
101
|
};
|
|
91
102
|
}
|
|
92
103
|
|
|
93
|
-
function parseResourceRecord(kind, name, text, graph) {
|
|
94
|
-
const common = commonRecord(kind, name, text, graph);
|
|
104
|
+
function parseResourceRecord(kind, name, text, graph, authoredLine = {}) {
|
|
105
|
+
const common = commonRecord(kind, name, text, graph, authoredLine);
|
|
95
106
|
if (kind === 'resource') return cleanRecord({ ...common, resourceKind: readInlineWord('resourceKind', text) ?? readInlineWord('kind', text) ?? name, ownerId: readInlineWord('owner', text) ?? readInlineWord('ownerId', text), ownerName: readInlineWord('ownerName', text) });
|
|
96
107
|
if (kind === 'owner') return cleanRecord({ ...common, ownerKind: readInlineWord('ownerKind', text) ?? readInlineWord('kind', text) ?? 'owner' });
|
|
97
108
|
if (kind === 'loan') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), ownerId: readInlineWord('owner', text) ?? readInlineWord('ownerId', text), lifetimeRegionId: readInlineWord('lifetime', text) ?? readInlineWord('lifetimeRegion', text) ?? readInlineWord('lifetimeRegionId', text), mode: readInlineWord('mode', text) ?? 'unknown', access: readInlineWord('access', text) });
|
|
@@ -103,18 +114,31 @@ function parseResourceRecord(kind, name, text, graph) {
|
|
|
103
114
|
if (kind === 'lifetimeRelation') return cleanRecord({ ...common, relationKind: readInlineWord('relationKind', text) ?? readInlineWord('kind', text) ?? 'outlives', fromLifetimeId: readInlineWord('fromLifetime', text) ?? readInlineWord('fromLifetimeId', text) ?? readInlineWord('from', text), toLifetimeId: readInlineWord('toLifetime', text) ?? readInlineWord('toLifetimeId', text) ?? readInlineWord('to', text), from: readInlineWord('from', text), to: readInlineWord('to', text) });
|
|
104
115
|
if (kind === 'borrowScope') return cleanRecord({ ...common, scopeKind: readInlineWord('scopeKind', text) ?? readInlineWord('kind', text) ?? 'borrow-scope', constraintKind: readInlineWord('constraintKind', text), constraintKinds: readInlineList(text, 'constraint', 'constraints', 'constraintKind', 'constraintKinds') ?? [], ownershipKind: readInlineWord('ownershipKind', text), lifetimeKind: readInlineWord('lifetimeKind', text), controlFlowKind: readInlineWord('controlFlowKind', text), sourceControlFlowId: readInlineWord('sourceControlFlow', text) ?? readInlineWord('sourceControlFlowId', text), lifetimeRegionId: readInlineWord('lifetime', text) ?? readInlineWord('lifetimeRegion', text) ?? readInlineWord('lifetimeRegionId', text), resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text) });
|
|
105
116
|
if (kind === 'unsafeBoundary') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), unsafeBoundary: true, proofStatus: readInlineWord('proofStatus', text) ?? readInlineWord('status', text) ?? 'missing', kind: readInlineWord('kind', text) });
|
|
117
|
+
if (kind === 'memoryRegion') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), memoryKind: readInlineWord('memoryKind', text) ?? readInlineWord('kind', text) ?? name, regionKind: readInlineWord('regionKind', text), addressSpace: readInlineWord('addressSpace', text) ?? readInlineWord('space', text), address: readInlineWord('address', text) ?? readInlineWord('baseAddress', text), sizeBytes: readInlineNumber('sizeBytes', text) ?? readInlineNumber('size', text), alignmentBytes: readInlineNumber('alignmentBytes', text) ?? readInlineNumber('alignment', text), pointerWidth: readInlineNumber('pointerWidth', text), endian: readInlineWord('endian', text) ?? readInlineWord('endianness', text), volatile: readInlineFlag('volatile', text), atomic: readInlineFlag('atomic', text), shared: readInlineFlag('shared', text) });
|
|
118
|
+
if (kind === 'dataLayout') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), typeId: readInlineWord('type', text) ?? readInlineWord('typeId', text), structId: readInlineWord('struct', text) ?? readInlineWord('structId', text), fieldId: readInlineWord('field', text) ?? readInlineWord('fieldId', text), bitfieldId: readInlineWord('bitfield', text) ?? readInlineWord('bitfieldId', text), layoutKind: readInlineWord('layoutKind', text) ?? readInlineWord('kind', text), repr: readInlineWord('repr', text), abi: readInlineWord('abi', text), endian: readInlineWord('endian', text) ?? readInlineWord('endianness', text), sizeBytes: readInlineNumber('sizeBytes', text) ?? readInlineNumber('size', text), alignmentBytes: readInlineNumber('alignmentBytes', text) ?? readInlineNumber('alignment', text), offsetBytes: readInlineNumber('offsetBytes', text) ?? readInlineNumber('offset', text), bitWidth: readInlineNumber('bitWidth', text) ?? readInlineNumber('width', text), fieldOrder: readInlineList(text, 'fieldOrder', 'fields'), constraintKinds: readInlineList(text, 'constraint', 'constraints', 'constraintKind', 'constraintKinds') });
|
|
119
|
+
if (kind === 'pointerEdge') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), targetResourceId: readInlineWord('targetResource', text) ?? readInlineWord('targetResourceId', text) ?? readInlineWord('target', text), ownerId: readInlineWord('owner', text) ?? readInlineWord('ownerId', text), lifetimeRegionId: readInlineWord('lifetime', text) ?? readInlineWord('lifetimeRegion', text) ?? readInlineWord('lifetimeRegionId', text), pointerKind: readInlineWord('pointerKind', text) ?? readInlineWord('kind', text) ?? 'pointer', addressSpace: readInlineWord('addressSpace', text) ?? readInlineWord('space', text), pointerWidth: readInlineNumber('pointerWidth', text), aliasKind: readInlineWord('aliasKind', text), mode: readInlineWord('mode', text), provenance: readInlineWord('provenance', text), nullable: readInlineFlag('nullable', text), mutable: readInlineFlag('mutable', text) });
|
|
120
|
+
if (kind === 'memoryAccess') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), accessKind: readInlineWord('accessKind', text) ?? readInlineWord('kind', text) ?? name, operationKind: readInlineWord('operation', text) ?? readInlineWord('operationKind', text), memoryOrder: readInlineWord('memoryOrder', text) ?? readInlineWord('ordering', text), lockId: readInlineWord('lock', text) ?? readInlineWord('lockId', text), synchronizationKey: readInlineWord('sync', text) ?? readInlineWord('synchronizationKey', text), reads: readInlineList(text, 'read', 'reads'), writes: readInlineList(text, 'write', 'writes'), volatile: readInlineFlag('volatile', text), atomic: readInlineFlag('atomic', text), proofStatus: readInlineWord('proofStatus', text) ?? readInlineWord('status', text) ?? 'missing' });
|
|
121
|
+
if (kind === 'abiBoundary') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), callableId: readInlineWord('callable', text) ?? readInlineWord('callableId', text), functionId: readInlineWord('function', text) ?? readInlineWord('functionId', text), boundaryKind: readInlineWord('boundaryKind', text) ?? readInlineWord('kind', text) ?? 'abi-boundary', abi: readInlineWord('abi', text), abiKind: readInlineWord('abiKind', text), callingConvention: readInlineWord('callingConvention', text) ?? readInlineWord('convention', text), pointerWidth: readInlineNumber('pointerWidth', text), endian: readInlineWord('endian', text) ?? readInlineWord('endianness', text), ffiBoundary: readInlineWord('ffiBoundary', text), proofStatus: readInlineWord('proofStatus', text) ?? readInlineWord('status', text) ?? 'missing' });
|
|
106
122
|
if (kind === 'conflict') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), ownerId: readInlineWord('owner', text) ?? readInlineWord('ownerId', text), loanId: readInlineWord('loan', text) ?? readInlineWord('loanId', text), aliasId: readInlineWord('alias', text) ?? readInlineWord('aliasId', text), unsafeBoundaryId: readInlineWord('unsafeBoundary', text) ?? readInlineWord('unsafeBoundaryId', text), reasonCode: readInlineWord('reasonCode', text), message: readInlineQuoted('message', text), status: readInlineWord('status', text) ?? 'open', severity: readInlineWord('severity', text) ?? 'error' });
|
|
107
123
|
if (kind === 'proofObligation') return cleanRecord({ ...common, resourceId: readInlineWord('resource', text) ?? readInlineWord('resourceId', text), conflictId: readInlineWord('conflict', text) ?? readInlineWord('conflictId', text), kind: readInlineWord('kind', text), status: readInlineWord('status', text) ?? 'open', statement: readInlineQuoted('statement', text) });
|
|
108
124
|
return undefined;
|
|
109
125
|
}
|
|
110
126
|
|
|
111
|
-
function commonRecord(kind, name, text, graph) {
|
|
127
|
+
function commonRecord(kind, name, text, graph, authoredLine = {}) {
|
|
112
128
|
return cleanRecord({
|
|
113
129
|
recordKind: recordKind(kind),
|
|
114
130
|
id: idFrom(text, `${recordPrefix(kind)}_${name}`),
|
|
115
131
|
name,
|
|
116
132
|
sourcePath: readInlineWord('sourcePath', text) ?? readInlineWord('path', text) ?? graph.sourcePath,
|
|
117
133
|
sourceHash: readInlineWord('sourceHash', text) ?? graph.sourceHash,
|
|
134
|
+
sourceSpan: authoredLine.sourceSpan,
|
|
135
|
+
authoredSourceSpan: authoredLine.sourceSpan,
|
|
136
|
+
sourceMapIds: readInlineList(text, 'sourceMap', 'sourceMaps', 'sourceMapId', 'sourceMapIds'),
|
|
137
|
+
sourceMapMappingIds: readInlineList(text, 'sourceMapMapping', 'sourceMapMappings', 'sourceMapMappingId', 'sourceMapMappingIds'),
|
|
138
|
+
proofEvidenceIds: readInlineList(text, 'proofEvidence', 'proofEvidenceId', 'proofEvidenceIds'),
|
|
139
|
+
proofObligationIds: readInlineList(text, 'proofObligation', 'proofObligations', 'proofObligationId', 'proofObligationIds', 'obligation', 'obligations'),
|
|
140
|
+
missingEvidence: readInlineList(text, 'missingEvidence'),
|
|
141
|
+
failClosed: readInlineFlag('failClosed', text),
|
|
118
142
|
evidenceIds: readInlineList(text, 'evidence', 'evidenceIds') ?? graph.evidenceIds,
|
|
119
143
|
metadata: { authoredName: name }
|
|
120
144
|
});
|
|
@@ -134,6 +158,11 @@ function summarize(graph) {
|
|
|
134
158
|
lifetimeRelations: graph.lifetimeRelations.length,
|
|
135
159
|
borrowScopes: graph.borrowScopes.length,
|
|
136
160
|
unsafeBoundaries: graph.unsafeBoundaries.length,
|
|
161
|
+
memoryRegions: graph.memoryRegions.length,
|
|
162
|
+
dataLayouts: graph.dataLayouts.length,
|
|
163
|
+
pointerEdges: graph.pointerEdges.length,
|
|
164
|
+
memoryAccesses: graph.memoryAccesses.length,
|
|
165
|
+
abiBoundaries: graph.abiBoundaries.length,
|
|
137
166
|
conflicts: graph.conflicts.length,
|
|
138
167
|
proofObligations: graph.proofObligations.length,
|
|
139
168
|
unsafeBoundariesWithoutProof: graph.unsafeBoundaries.filter((record) => record.proofStatus !== 'passed').length,
|
|
@@ -155,6 +184,11 @@ function allRecords(graph) {
|
|
|
155
184
|
...graph.lifetimeRelations,
|
|
156
185
|
...graph.borrowScopes,
|
|
157
186
|
...graph.unsafeBoundaries,
|
|
187
|
+
...graph.memoryRegions,
|
|
188
|
+
...graph.dataLayouts,
|
|
189
|
+
...graph.pointerEdges,
|
|
190
|
+
...graph.memoryAccesses,
|
|
191
|
+
...graph.abiBoundaries,
|
|
158
192
|
...graph.conflicts,
|
|
159
193
|
...graph.proofObligations
|
|
160
194
|
];
|
|
@@ -165,6 +199,11 @@ function normalizeRowKind(kind) {
|
|
|
165
199
|
if (kind === 'outlives' || kind === 'lifetimeRelation' || kind === 'lifeRelation') return 'lifetimeRelation';
|
|
166
200
|
if (kind === 'borrow' || kind === 'borrowScope' || kind === 'borrowRegion') return 'borrowScope';
|
|
167
201
|
if (kind === 'unsafe' || kind === 'unsafeBoundary') return 'unsafeBoundary';
|
|
202
|
+
if (kind === 'memory' || kind === 'memoryRegion' || kind === 'region') return 'memoryRegion';
|
|
203
|
+
if (kind === 'layout' || kind === 'dataLayout') return 'dataLayout';
|
|
204
|
+
if (kind === 'pointer' || kind === 'ptr' || kind === 'address') return 'pointerEdge';
|
|
205
|
+
if (kind === 'access' || kind === 'memoryAccess' || kind === 'atomic' || kind === 'volatile') return 'memoryAccess';
|
|
206
|
+
if (kind === 'abi' || kind === 'abiBoundary' || kind === 'callBoundary') return 'abiBoundary';
|
|
168
207
|
if (kind === 'proof' || kind === 'obligation' || kind === 'proofObligation') return 'proofObligation';
|
|
169
208
|
return kind;
|
|
170
209
|
}
|
|
@@ -174,6 +213,11 @@ function recordKind(kind) {
|
|
|
174
213
|
if (kind === 'lifetimeRelation') return 'lifetime-relation';
|
|
175
214
|
if (kind === 'borrowScope') return 'borrow-scope';
|
|
176
215
|
if (kind === 'unsafeBoundary') return 'unsafe-boundary';
|
|
216
|
+
if (kind === 'memoryRegion') return 'memory-region';
|
|
217
|
+
if (kind === 'dataLayout') return 'data-layout';
|
|
218
|
+
if (kind === 'pointerEdge') return 'pointer-edge';
|
|
219
|
+
if (kind === 'memoryAccess') return 'memory-access';
|
|
220
|
+
if (kind === 'abiBoundary') return 'abi-boundary';
|
|
177
221
|
if (kind === 'proofObligation') return 'proof-obligation';
|
|
178
222
|
return kind;
|
|
179
223
|
}
|
|
@@ -195,6 +239,7 @@ function readListLine(label, body) {
|
|
|
195
239
|
}
|
|
196
240
|
function readInlineWord(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
|
|
197
241
|
function readInlineQuoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
|
|
242
|
+
function readInlineFlag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(text) || undefined; }
|
|
198
243
|
function readInlineNumber(label, text) {
|
|
199
244
|
const value = readInlineWord(label, text);
|
|
200
245
|
return value === undefined ? undefined : Number(value);
|
|
@@ -208,6 +253,21 @@ function readInlineList(text, ...labels) {
|
|
|
208
253
|
}
|
|
209
254
|
function ids(records = []) { return records.map((record) => record?.id).filter(Boolean); }
|
|
210
255
|
function unique(values = []) { return [...new Set(values.filter(Boolean))]; }
|
|
256
|
+
function readAuthoredLines(block) {
|
|
257
|
+
const lines = block.body.split('\n');
|
|
258
|
+
const records = [];
|
|
259
|
+
let lineStart = block.syntax?.bodyStartOffset ?? 0;
|
|
260
|
+
for (const rawLine of lines) {
|
|
261
|
+
const rawEnd = lineStart + rawLine.length;
|
|
262
|
+
const leading = /^\s*/.exec(rawLine)?.[0].length ?? 0;
|
|
263
|
+
const trailing = /\s*$/.exec(rawLine)?.[0].length ?? 0;
|
|
264
|
+
const startOffset = lineStart + leading;
|
|
265
|
+
const endOffset = Math.max(startOffset, rawEnd - trailing);
|
|
266
|
+
records.push({ text: rawLine.trim(), sourceSpan: typeof block.sourceSpan === 'function' ? block.sourceSpan(startOffset, endOffset) : undefined });
|
|
267
|
+
lineStart = rawEnd + 1;
|
|
268
|
+
}
|
|
269
|
+
return records;
|
|
270
|
+
}
|
|
211
271
|
function cleanRecord(record) {
|
|
212
272
|
return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
|
|
213
273
|
}
|
|
@@ -227,9 +227,9 @@ function readGenericRowSyntaxChildren(source, block, options, config) {
|
|
|
227
227
|
for (const line of readBodyLines(source, block)) {
|
|
228
228
|
if (!line.text || line.text.startsWith('#')) continue;
|
|
229
229
|
const row = rowPattern.exec(line.text);
|
|
230
|
-
if (!row) continue;
|
|
230
|
+
if (!row) { if (config.childKind === 'gateAdmissionEvidenceRow') children.push(genericUnknownRowChild(source, block, options, line, config, undefined, undefined, 'unsupported-gate-admission-row')); continue; }
|
|
231
231
|
const [, rowKind, name, rest] = row;
|
|
232
|
-
if (!config.rowKinds.has(rowKind)) continue;
|
|
232
|
+
if (!config.rowKinds.has(rowKind)) { if (config.childKind === 'gateAdmissionEvidenceRow') children.push(genericUnknownRowChild(source, block, options, line, config, rowKind, name, 'unsupported-gate-admission-row')); continue; }
|
|
233
233
|
const normalizedRowKind = config.normalize?.(rowKind) ?? rowKind;
|
|
234
234
|
const id = idFrom(rest, `${config.idPrefix}_${safeId(normalizedRowKind)}_${safeId(name)}`);
|
|
235
235
|
let recognized = true;
|
|
@@ -264,10 +264,19 @@ function readGenericRowSyntaxChildren(source, block, options, config) {
|
|
|
264
264
|
return children;
|
|
265
265
|
}
|
|
266
266
|
|
|
267
|
-
function
|
|
268
|
-
|
|
267
|
+
function genericUnknownRowChild(source, block, options, line, config, rowKind, name, reason) {
|
|
268
|
+
const resolvedName = name ?? rowKind ?? 'unknown';
|
|
269
|
+
return cleanRecord({
|
|
270
|
+
kind: config.childKind === 'gateAdmissionEvidenceRow' ? 'gateAdmissionUnknownRow' : 'genericUnknownRow', rowKind,
|
|
271
|
+
normalizedRowKind: 'unknown', name: resolvedName, id: `gate_admission_unknown_${safeId(rowKind ?? 'row')}_${line.startOffset}`,
|
|
272
|
+
header: line.text, startOffset: line.startOffset, endOffset: line.endOffset, location: sourcePosition(source, line.startOffset),
|
|
273
|
+
parentKind: block.kind, parentId: block.id, parentName: block.name, moduleId: block.moduleId, moduleName: block.moduleName,
|
|
274
|
+
sourceSpan: sourceSpan(source, block, line.startOffset, line.endOffset, options), recognized: false, reason
|
|
275
|
+
});
|
|
269
276
|
}
|
|
270
277
|
|
|
278
|
+
function readBodyLines(source, block) { return readTextLines(source, block.bodyStartOffset, block.bodyEndOffset); }
|
|
279
|
+
|
|
271
280
|
function readTextLines(source, startOffset, endOffset) {
|
|
272
281
|
const body = source.slice(startOffset, endOffset);
|
|
273
282
|
const lines = body.split('\n');
|
|
@@ -6,7 +6,7 @@ const interlinguaRows = words('layer constraint edge obligation proofObligation
|
|
|
6
6
|
const packageRows = words('metadata dependency script export gap proofGap evidence proofEvidence');
|
|
7
7
|
const runtimeRows = words('host runtimeHost hostProfile sourceHost targetHost capability hostCapability hostBinding binding requirement runtimeRequirement requiredRuntime evidence proofEvidence gap proofGap');
|
|
8
8
|
const semanticEditRows = words('script semanticEditScript projection semanticEditProjection replay semanticEditReplay');
|
|
9
|
-
const gateAdmissionRows = words('gate evidence proofEvidence admission admissionDecision gap proofGap');
|
|
9
|
+
const gateAdmissionRows = words('gate evidence proofEvidence admission admissionDecision proofObligation obligation gap proofGap');
|
|
10
10
|
|
|
11
11
|
export const ROW_SYNTAX_CONFIG = Object.freeze({
|
|
12
12
|
interlingua: rowConfig('interlinguaRow', 'interlingua_row', interlinguaRows, normalizeInterlinguaRow),
|
|
@@ -16,8 +16,8 @@ export const ROW_SYNTAX_CONFIG = Object.freeze({
|
|
|
16
16
|
runtimeCapabilities: rowConfig('runtimeCapabilityRow', 'runtime_capability_row', runtimeRows, normalizeRuntimeCapabilityRow),
|
|
17
17
|
runtimeCapabilityMatrix: rowConfig('runtimeCapabilityRow', 'runtime_capability_row', runtimeRows, normalizeRuntimeCapabilityRow),
|
|
18
18
|
runtimeHosts: rowConfig('runtimeCapabilityRow', 'runtime_capability_row', runtimeRows, normalizeRuntimeCapabilityRow),
|
|
19
|
-
resourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
20
|
-
semanticResourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
19
|
+
resourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary memory memoryRegion region layout dataLayout pointer ptr address access memoryAccess atomic volatile abi abiBoundary callBoundary conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
20
|
+
semanticResourceGraph: rowConfig('resourceGraphRow', 'resource_graph_row', words('resource owner loan alias move drop escape lifetime lifetimeRegion life outlives lifetimeRelation lifeRelation borrow borrowScope borrowRegion unsafe unsafeBoundary memory memoryRegion region layout dataLayout pointer ptr address access memoryAccess atomic volatile abi abiBoundary callBoundary conflict proof proofObligation obligation'), normalizeResourceGraphRow),
|
|
21
21
|
applicationSurface: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
22
22
|
appHost: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
23
23
|
plugin: rowConfig('applicationSurfaceRow', 'application_surface_row', appRows, normalizeApplicationSurfaceRow),
|
|
@@ -79,6 +79,11 @@ function normalizeResourceGraphRow(rowKind) {
|
|
|
79
79
|
if (rowKind === 'lifeRelation') return 'lifetimeRelation';
|
|
80
80
|
if (rowKind === 'borrowRegion') return 'borrowScope';
|
|
81
81
|
if (rowKind === 'unsafe') return 'unsafeBoundary';
|
|
82
|
+
if (rowKind === 'memory' || rowKind === 'region') return 'memoryRegion';
|
|
83
|
+
if (rowKind === 'layout') return 'dataLayout';
|
|
84
|
+
if (rowKind === 'pointer' || rowKind === 'ptr' || rowKind === 'address') return 'pointerEdge';
|
|
85
|
+
if (rowKind === 'access' || rowKind === 'atomic' || rowKind === 'volatile') return 'memoryAccess';
|
|
86
|
+
if (rowKind === 'abi' || rowKind === 'callBoundary') return 'abiBoundary';
|
|
82
87
|
if (rowKind === 'proof' || rowKind === 'proofObligation') return 'obligation';
|
|
83
88
|
return rowKind;
|
|
84
89
|
}
|
|
@@ -135,6 +140,7 @@ function normalizeSemanticEditRow(rowKind) {
|
|
|
135
140
|
function normalizeGateAdmissionRow(rowKind) {
|
|
136
141
|
if (rowKind === 'proofEvidence') return 'evidence';
|
|
137
142
|
if (rowKind === 'admissionDecision') return 'admission';
|
|
143
|
+
if (rowKind === 'obligation') return 'proofObligation';
|
|
138
144
|
if (rowKind === 'gap') return 'proofGap';
|
|
139
145
|
return rowKind;
|
|
140
146
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-parser",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.72",
|
|
4
4
|
"description": "Parser for the first Frontier Lang .frontier syntax slice.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "node scripts/build.mjs",
|
|
25
|
-
"test": "npm run build && node test/smoke.mjs && node test/member-identity-smoke.mjs && node test/generic-row-parse-identity-smoke.mjs && node test/type-variant-payload-smoke.mjs && node test/type-generic-ref-smoke.mjs && node test/type-parameter-constraints-smoke.mjs && node test/type-structural-expression-smoke.mjs && node test/action-body-smoke.mjs && node test/action-structured-literals-smoke.mjs && node test/action-return-smoke.mjs && node test/action-else-smoke.mjs && node test/action-match-smoke.mjs && node test/action-for-in-smoke.mjs && node test/action-repeat-smoke.mjs && node test/action-call-smoke.mjs && node test/semantic-operation-edit-smoke.mjs && node test/target-projection-aggregate-smoke.mjs && node test/conversion-constraint-fields-smoke.mjs && node test/conversion-evidence-smoke.mjs && node test/package-canvas-surface-smoke.mjs && node test/view-render-graph-smoke.mjs && node test/resource-graph-smoke.mjs && node test/interlingua-smoke.mjs && node test/dialect-registry-smoke.mjs",
|
|
25
|
+
"test": "npm run build && node test/smoke.mjs && node test/member-identity-smoke.mjs && node test/generic-row-parse-identity-smoke.mjs && node test/type-variant-payload-smoke.mjs && node test/type-generic-ref-smoke.mjs && node test/type-parameter-constraints-smoke.mjs && node test/type-structural-expression-smoke.mjs && node test/action-body-smoke.mjs && node test/action-structured-literals-smoke.mjs && node test/action-return-smoke.mjs && node test/action-else-smoke.mjs && node test/action-match-smoke.mjs && node test/action-for-in-smoke.mjs && node test/action-repeat-smoke.mjs && node test/action-call-smoke.mjs && node test/semantic-operation-edit-smoke.mjs && node test/target-projection-aggregate-smoke.mjs && node test/conversion-constraint-fields-smoke.mjs && node test/conversion-evidence-smoke.mjs && node test/gate-admission-evidence-smoke.mjs && node test/package-canvas-surface-smoke.mjs && node test/view-render-graph-smoke.mjs && node test/resource-graph-smoke.mjs && node test/interlingua-smoke.mjs && node test/dialect-registry-smoke.mjs",
|
|
26
26
|
"typecheck": "node ./node_modules/typescript/bin/tsc --noEmit -p test/tsconfig.json",
|
|
27
27
|
"fuzz": "npm run build && node fuzz/smoke.mjs",
|
|
28
28
|
"bench": "npm run build && node bench/smoke.mjs",
|