@shapeshift-labs/frontier-lang-parser 0.3.72 → 0.3.74

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/metadata.js CHANGED
@@ -269,6 +269,9 @@ function mergeResourceGraphBlocks(blocks) {
269
269
  pointerEdgeIds: blocks.flatMap((block) => ids(block.graph?.pointerEdges)),
270
270
  memoryAccessIds: blocks.flatMap((block) => ids(block.graph?.memoryAccesses)),
271
271
  abiBoundaryIds: blocks.flatMap((block) => ids(block.graph?.abiBoundaries)),
272
+ synchronizationEdgeIds: blocks.flatMap((block) => ids(block.graph?.synchronizationEdges)),
273
+ trapIds: blocks.flatMap((block) => ids(block.graph?.traps)),
274
+ undefinedBehaviorIds: blocks.flatMap((block) => ids(block.graph?.undefinedBehaviors)),
272
275
  conflictIds: blocks.flatMap((block) => ids(block.graph?.conflicts)),
273
276
  proofObligationIds: blocks.flatMap((block) => ids(block.graph?.proofObligations)),
274
277
  summary: {
@@ -285,14 +288,19 @@ function mergeResourceGraphBlocks(blocks) {
285
288
  lifetimeRelationCount: sum(blocks, 'lifetimeRelations'),
286
289
  borrowScopeCount: sum(blocks, 'borrowScopes'),
287
290
  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'),
291
+ memoryRegionCount: sum(blocks, 'memoryRegions'), dataLayoutCount: sum(blocks, 'dataLayouts'),
292
+ pointerEdgeCount: sum(blocks, 'pointerEdges'), memoryAccessCount: sum(blocks, 'memoryAccesses'),
293
+ abiBoundaryCount: sum(blocks, 'abiBoundaries'), synchronizationEdgeCount: sum(blocks, 'synchronizationEdges'),
294
+ trapCount: sum(blocks, 'traps'),
295
+ undefinedBehaviorCount: sum(blocks, 'undefinedBehaviors'),
296
+ lowLevelPrimitiveCount: sum(blocks, 'lowLevelPrimitives'),
293
297
  conflictCount: sum(blocks, 'conflicts'),
294
298
  proofObligationCount: sum(blocks, 'proofObligations'),
295
- unsafeBoundariesWithoutProof: sum(blocks, 'unsafeBoundariesWithoutProof')
299
+ unsafeBoundariesWithoutProof: sum(blocks, 'unsafeBoundariesWithoutProof'),
300
+ synchronizationEdgeWithoutProofCount: sum(blocks, 'synchronizationEdgesWithoutProof'),
301
+ failClosedTrapCount: sum(blocks, 'failClosedTraps'),
302
+ trapWithoutProofCount: sum(blocks, 'trapsWithoutProof'),
303
+ undefinedBehaviorWithoutProofCount: sum(blocks, 'undefinedBehaviorsWithoutProof')
296
304
  },
297
305
  metadata: { authoredResourceGraphBlockIds: blocks.map((block) => block.id) }
298
306
  };
@@ -0,0 +1,26 @@
1
+ export function parseLowLevelResourceRecord(kind, common, name, text) {
2
+ if (kind === 'memoryRegion') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), memoryKind: word('memoryKind', text) ?? word('kind', text) ?? name, regionKind: word('regionKind', text), addressSpace: word('addressSpace', text) ?? word('space', text), address: word('address', text) ?? word('baseAddress', text), sizeBytes: number('sizeBytes', text) ?? number('size', text), alignmentBytes: number('alignmentBytes', text) ?? number('alignment', text), pointerWidth: number('pointerWidth', text), endian: word('endian', text) ?? word('endianness', text), volatile: flag('volatile', text), atomic: flag('atomic', text), shared: flag('shared', text) });
3
+ if (kind === 'dataLayout') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), typeId: word('type', text) ?? word('typeId', text), structId: word('struct', text) ?? word('structId', text), fieldId: word('field', text) ?? word('fieldId', text), bitfieldId: word('bitfield', text) ?? word('bitfieldId', text), layoutKind: word('layoutKind', text) ?? word('kind', text), repr: word('repr', text), abi: word('abi', text), endian: word('endian', text) ?? word('endianness', text), sizeBytes: number('sizeBytes', text) ?? number('size', text), alignmentBytes: number('alignmentBytes', text) ?? number('alignment', text), offsetBytes: number('offsetBytes', text) ?? number('offset', text), bitWidth: number('bitWidth', text) ?? number('width', text), fieldOrder: list(text, 'fieldOrder', 'fields'), constraintKinds: list(text, 'constraint', 'constraints', 'constraintKind', 'constraintKinds') });
4
+ if (kind === 'pointerEdge') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), targetResourceId: word('targetResource', text) ?? word('targetResourceId', text) ?? word('target', text), ownerId: word('owner', text) ?? word('ownerId', text), lifetimeRegionId: word('lifetime', text) ?? word('lifetimeRegion', text) ?? word('lifetimeRegionId', text), pointerKind: word('pointerKind', text) ?? word('kind', text) ?? 'pointer', addressSpace: word('addressSpace', text) ?? word('space', text), pointerWidth: number('pointerWidth', text), aliasKind: word('aliasKind', text), mode: word('mode', text), provenance: word('provenance', text), nullable: flag('nullable', text), mutable: flag('mutable', text) });
5
+ if (kind === 'memoryAccess') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), accessKind: word('accessKind', text) ?? word('kind', text) ?? name, operationKind: word('operation', text) ?? word('operationKind', text), memoryOrder: word('memoryOrder', text) ?? word('ordering', text), lockId: word('lock', text) ?? word('lockId', text), synchronizationKey: word('sync', text) ?? word('synchronizationKey', text), reads: list(text, 'read', 'reads'), writes: list(text, 'write', 'writes'), volatile: flag('volatile', text), atomic: flag('atomic', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing' });
6
+ if (kind === 'abiBoundary') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), callableId: word('callable', text) ?? word('callableId', text), functionId: word('function', text) ?? word('functionId', text), boundaryKind: word('boundaryKind', text) ?? word('kind', text) ?? 'abi-boundary', abi: word('abi', text), abiKind: word('abiKind', text), callingConvention: word('callingConvention', text) ?? word('convention', text), pointerWidth: number('pointerWidth', text), endian: word('endian', text) ?? word('endianness', text), ffiBoundary: word('ffiBoundary', text), proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing' });
7
+ if (kind === 'synchronizationEdge') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), fromMemoryAccessId: word('fromAccess', text) ?? word('fromAccessId', text) ?? word('fromMemoryAccess', text) ?? word('fromMemoryAccessId', text) ?? word('from', text), toMemoryAccessId: word('toAccess', text) ?? word('toAccessId', text) ?? word('toMemoryAccess', text) ?? word('toMemoryAccessId', text) ?? word('to', text), edgeKind: word('edgeKind', text) ?? word('synchronizationKind', text) ?? word('syncKind', text) ?? word('kind', text) ?? name, synchronizationKind: word('synchronizationKind', text) ?? word('syncKind', text) ?? word('edgeKind', text) ?? word('kind', text) ?? name, fenceKind: word('fenceKind', text), memoryScope: word('memoryScope', text) ?? word('barrierScope', text) ?? word('scope', text), memoryOrder: word('memoryOrder', text) ?? word('ordering', text), lockId: word('lock', text) ?? word('lockId', text), synchronizationKey: word('sync', text) ?? word('synchronizationKey', text), channelId: word('channel', text) ?? word('channelId', text), actorId: word('actor', text) ?? word('actorId', text), operationKind: word('operation', text) ?? word('operationKind', text), reasonCode: word('reasonCode', text) ?? word('code', text), condition: quoted('condition', text) ?? word('condition', text), status: word('status', text) ?? 'needs-proof', severity: word('severity', text) ?? 'error', proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', message: quoted('message', text), failClosed: common.failClosed ?? true, semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
8
+ if (kind === 'trap') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), ownerId: word('owner', text) ?? word('ownerId', text), loanId: word('loan', text) ?? word('loanId', text), pointerEdgeId: word('pointer', text) ?? word('pointerEdge', text) ?? word('pointerEdgeId', text), memoryAccessId: word('memoryAccess', text) ?? word('memoryAccessId', text), unsafeBoundaryId: word('unsafeBoundary', text) ?? word('unsafeBoundaryId', text), operationKind: word('operation', text) ?? word('operationKind', text), instructionId: word('instruction', text) ?? word('instructionId', text), callableId: word('callable', text) ?? word('callableId', text), trapKind: word('trapKind', text) ?? word('kind', text) ?? name, trapCode: word('trapCode', text) ?? word('code', text), reasonCode: word('reasonCode', text) ?? word('code', text), condition: quoted('condition', text) ?? word('condition', text), status: word('status', text) ?? 'needs-proof', severity: word('severity', text) ?? 'error', proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', message: quoted('message', text), failClosed: common.failClosed ?? true, semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
9
+ if (kind === 'undefinedBehavior') return cleanRecord({ ...common, resourceId: word('resource', text) ?? word('resourceId', text), ownerId: word('owner', text) ?? word('ownerId', text), loanId: word('loan', text) ?? word('loanId', text), pointerEdgeId: word('pointer', text) ?? word('pointerEdge', text) ?? word('pointerEdgeId', text), memoryAccessId: word('memoryAccess', text) ?? word('memoryAccessId', text), unsafeBoundaryId: word('unsafeBoundary', text) ?? word('unsafeBoundaryId', text), operationKind: word('operation', text) ?? word('operationKind', text), undefinedBehaviorKind: word('undefinedBehaviorKind', text) ?? word('behaviorKind', text) ?? word('kind', text) ?? name, language: word('language', text), reasonCode: word('reasonCode', text) ?? word('code', text), condition: quoted('condition', text) ?? word('condition', text), status: word('status', text) ?? 'needs-proof', severity: word('severity', text) ?? 'error', proofStatus: word('proofStatus', text) ?? word('status', text) ?? 'missing', message: quoted('message', text), failClosed: common.failClosed ?? true, semanticEquivalenceClaim: false, runtimeEquivalenceClaim: false });
10
+ return undefined;
11
+ }
12
+
13
+ function word(label, text) { return new RegExp('(?:^|\\s)' + label + '\\s+([^\\s,]+)').exec(text)?.[1]?.trim(); }
14
+ function quoted(label, text) { return new RegExp("(?:^|\\s)" + label + "\\s+[\"']([^\"']+)[\"']").exec(text)?.[1]?.trim(); }
15
+ function flag(label, text) { return new RegExp('(?:^|\\s)' + label + '(?:\\s|$)').test(text) || undefined; }
16
+ function number(label, text) { const value = word(label, text); return value === undefined ? undefined : Number(value); }
17
+ function list(text, ...labels) {
18
+ for (const label of labels) {
19
+ const value = new RegExp('(?:^|\\s)' + label + '\\s+([^\\s]+)').exec(text)?.[1]?.trim();
20
+ if (value) return value.split(/[|,]/).map((item) => item.trim()).filter(Boolean);
21
+ }
22
+ return undefined;
23
+ }
24
+ function cleanRecord(record) {
25
+ return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0)));
26
+ }
@@ -1,4 +1,5 @@
1
1
  import { createRowIdentityTracker } from './row-identity.js';
2
+ import { parseLowLevelResourceRecord } from './resource-graph-low-level.js';
2
3
 
3
4
  const GROUPS = {
4
5
  resource: 'resources',
@@ -17,6 +18,9 @@ const GROUPS = {
17
18
  pointerEdge: 'pointerEdges',
18
19
  memoryAccess: 'memoryAccesses',
19
20
  abiBoundary: 'abiBoundaries',
21
+ synchronizationEdge: 'synchronizationEdges',
22
+ trap: 'traps',
23
+ undefinedBehavior: 'undefinedBehaviors',
20
24
  conflict: 'conflicts',
21
25
  proofObligation: 'proofObligations'
22
26
  };
@@ -51,6 +55,9 @@ export function parseResourceGraphBlock(block) {
51
55
  pointerEdges: [],
52
56
  memoryAccesses: [],
53
57
  abiBoundaries: [],
58
+ synchronizationEdges: [],
59
+ traps: [],
60
+ undefinedBehaviors: [],
54
61
  conflicts: [],
55
62
  proofObligations: [],
56
63
  parser: { status: 'authored', errors: rowIdentity.errors },
@@ -83,10 +90,14 @@ export function parseResourceGraphBlock(block) {
83
90
  resourceIds: ids(graph.resources),
84
91
  ownerIds: ids(graph.owners),
85
92
  lifetimeRegionIds: ids(graph.lifetimeRegions),
86
- lowLevelPrimitiveIds: ids([...graph.memoryRegions, ...graph.dataLayouts, ...graph.pointerEdges, ...graph.memoryAccesses, ...graph.abiBoundaries]),
93
+ trapIds: ids(graph.traps),
94
+ undefinedBehaviorIds: ids(graph.undefinedBehaviors),
95
+ failClosedTrapIds: ids(graph.traps.filter((record) => record.failClosed)),
96
+ synchronizationEdgeIds: ids(graph.synchronizationEdges),
97
+ lowLevelPrimitiveIds: ids([...graph.memoryRegions, ...graph.dataLayouts, ...graph.pointerEdges, ...graph.memoryAccesses, ...graph.abiBoundaries, ...graph.synchronizationEdges, ...graph.traps, ...graph.undefinedBehaviors]),
87
98
  sourcePaths: unique(allRecords(graph).map((record) => record.sourcePath)),
88
99
  evidenceIds: unique([...graph.evidenceIds, ...allRecords(graph).flatMap((record) => record.evidenceIds ?? [])]),
89
- blockerReasonCodes: unique(graph.conflicts.map((record) => record.reasonCode))
100
+ blockerReasonCodes: unique([...graph.conflicts, ...graph.synchronizationEdges, ...graph.traps, ...graph.undefinedBehaviors].map((record) => record.reasonCode))
90
101
  };
91
102
 
92
103
  return {
@@ -114,11 +125,8 @@ function parseResourceRecord(kind, name, text, graph, authoredLine = {}) {
114
125
  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) });
115
126
  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) });
116
127
  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' });
128
+ const lowLevelRecord = parseLowLevelResourceRecord(kind, common, name, text);
129
+ if (lowLevelRecord) return lowLevelRecord;
122
130
  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' });
123
131
  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) });
124
132
  return undefined;
@@ -163,11 +171,19 @@ function summarize(graph) {
163
171
  pointerEdges: graph.pointerEdges.length,
164
172
  memoryAccesses: graph.memoryAccesses.length,
165
173
  abiBoundaries: graph.abiBoundaries.length,
174
+ synchronizationEdges: graph.synchronizationEdges.length,
175
+ traps: graph.traps.length,
176
+ undefinedBehaviors: graph.undefinedBehaviors.length,
177
+ lowLevelPrimitives: graph.memoryRegions.length + graph.dataLayouts.length + graph.pointerEdges.length + graph.memoryAccesses.length + graph.abiBoundaries.length + graph.synchronizationEdges.length + graph.traps.length + graph.undefinedBehaviors.length,
166
178
  conflicts: graph.conflicts.length,
167
179
  proofObligations: graph.proofObligations.length,
168
180
  unsafeBoundariesWithoutProof: graph.unsafeBoundaries.filter((record) => record.proofStatus !== 'passed').length,
181
+ failClosedTraps: graph.traps.filter((record) => record.failClosed).length,
182
+ trapsWithoutProof: graph.traps.filter((record) => record.proofStatus !== 'passed').length,
183
+ undefinedBehaviorsWithoutProof: graph.undefinedBehaviors.filter((record) => record.proofStatus !== 'passed').length,
169
184
  parseErrors: graph.parser?.errors?.length ?? 0,
170
- reasonCodes: unique(graph.conflicts.map((record) => record.reasonCode))
185
+ synchronizationEdgesWithoutProof: graph.synchronizationEdges.filter((record) => record.proofStatus !== 'passed').length,
186
+ reasonCodes: unique([...graph.conflicts, ...graph.synchronizationEdges, ...graph.traps, ...graph.undefinedBehaviors].map((record) => record.reasonCode))
171
187
  };
172
188
  }
173
189
 
@@ -189,6 +205,9 @@ function allRecords(graph) {
189
205
  ...graph.pointerEdges,
190
206
  ...graph.memoryAccesses,
191
207
  ...graph.abiBoundaries,
208
+ ...graph.synchronizationEdges,
209
+ ...graph.traps,
210
+ ...graph.undefinedBehaviors,
192
211
  ...graph.conflicts,
193
212
  ...graph.proofObligations
194
213
  ];
@@ -204,6 +223,9 @@ function normalizeRowKind(kind) {
204
223
  if (kind === 'pointer' || kind === 'ptr' || kind === 'address') return 'pointerEdge';
205
224
  if (kind === 'access' || kind === 'memoryAccess' || kind === 'atomic' || kind === 'volatile') return 'memoryAccess';
206
225
  if (kind === 'abi' || kind === 'abiBoundary' || kind === 'callBoundary') return 'abiBoundary';
226
+ if (kind === 'sync' || kind === 'synchronization' || kind === 'synchronisation' || kind === 'synchronizationEdge' || kind === 'synchronisationEdge' || kind === 'happensBefore' || kind === 'happens-before' || kind === 'hb' || kind === 'fence' || kind === 'fenceEdge' || kind === 'barrier' || kind === 'barrierEdge') return 'synchronizationEdge';
227
+ if (kind === 'traps') return 'trap';
228
+ if (kind === 'undefined' || kind === 'ub' || kind === 'undefinedBehavior' || kind === 'undefinedBehaviour') return 'undefinedBehavior';
207
229
  if (kind === 'proof' || kind === 'obligation' || kind === 'proofObligation') return 'proofObligation';
208
230
  return kind;
209
231
  }
@@ -218,6 +240,8 @@ function recordKind(kind) {
218
240
  if (kind === 'pointerEdge') return 'pointer-edge';
219
241
  if (kind === 'memoryAccess') return 'memory-access';
220
242
  if (kind === 'abiBoundary') return 'abi-boundary';
243
+ if (kind === 'synchronizationEdge') return 'synchronization-edge';
244
+ if (kind === 'undefinedBehavior') return 'undefined-behavior';
221
245
  if (kind === 'proofObligation') return 'proof-obligation';
222
246
  return kind;
223
247
  }
@@ -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 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),
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 sync synchronization synchronisation synchronizationEdge synchronisationEdge happensBefore hb fence fenceEdge barrier barrierEdge trap traps undefined undefinedBehavior undefinedBehaviour ub 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 sync synchronization synchronisation synchronizationEdge synchronisationEdge happensBefore hb fence fenceEdge barrier barrierEdge trap traps undefined undefinedBehavior undefinedBehaviour ub 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),
@@ -84,6 +84,9 @@ function normalizeResourceGraphRow(rowKind) {
84
84
  if (rowKind === 'pointer' || rowKind === 'ptr' || rowKind === 'address') return 'pointerEdge';
85
85
  if (rowKind === 'access' || rowKind === 'atomic' || rowKind === 'volatile') return 'memoryAccess';
86
86
  if (rowKind === 'abi' || rowKind === 'callBoundary') return 'abiBoundary';
87
+ if (rowKind === 'sync' || rowKind === 'synchronization' || rowKind === 'synchronisation' || rowKind === 'synchronisationEdge' || rowKind === 'happensBefore' || rowKind === 'hb' || rowKind === 'fence' || rowKind === 'fenceEdge' || rowKind === 'barrier' || rowKind === 'barrierEdge') return 'synchronizationEdge';
88
+ if (rowKind === 'traps') return 'trap';
89
+ if (rowKind === 'undefined' || rowKind === 'undefinedBehaviour' || rowKind === 'ub') return 'undefinedBehavior';
87
90
  if (rowKind === 'proof' || rowKind === 'proofObligation') return 'obligation';
88
91
  return rowKind;
89
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shapeshift-labs/frontier-lang-parser",
3
- "version": "0.3.72",
3
+ "version": "0.3.74",
4
4
  "description": "Parser for the first Frontier Lang .frontier syntax slice.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",