@fairfox/polly 0.76.0 → 0.77.1

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.
@@ -811,6 +811,9 @@ var init_tla = __esm(() => {
811
811
  }
812
812
  return /^[a-zA-Z][a-zA-Z0-9_]*$/.test(s);
813
813
  }
814
+ canRepresentAsTLAAction(s) {
815
+ return typeof s === "string" && /[a-zA-Z]/.test(s) && !/[{}();<>=]/.test(s);
816
+ }
814
817
  async generate(config, analysis, moduleName) {
815
818
  if (moduleName) {
816
819
  this.moduleName = moduleName;
@@ -917,8 +920,8 @@ var init_tla = __esm(() => {
917
920
  }
918
921
  validateInputs(_config, analysis) {
919
922
  for (const messageType of analysis.messageTypes) {
920
- if (!this.isValidTLAIdentifier(messageType)) {
921
- throw new Error(`Invalid message type '${messageType}'. TLA+ identifiers must start with a letter and contain only letters, digits, and underscores.`);
923
+ if (!this.canRepresentAsTLAAction(messageType)) {
924
+ throw new Error(`Unrepresentable message type '${messageType}'. A message type must contain at least one letter so it can be sanitized into a TLA+ action name.`);
922
925
  }
923
926
  }
924
927
  }
@@ -1346,16 +1349,16 @@ var init_tla = __esm(() => {
1346
1349
  let validMessageTypes = [];
1347
1350
  const invalidMessageTypes = [];
1348
1351
  for (const msgType of analysis.messageTypes) {
1349
- if (this.isValidTLAIdentifier(msgType)) {
1352
+ if (this.canRepresentAsTLAAction(msgType)) {
1350
1353
  validMessageTypes.push(msgType);
1351
1354
  } else {
1352
1355
  invalidMessageTypes.push(msgType);
1353
1356
  }
1354
1357
  }
1355
1358
  if (invalidMessageTypes.length > 0 && process.env["POLLY_DEBUG"]) {
1356
- console.log(`[WARN] [TLAGenerator] Filtered out ${invalidMessageTypes.length} invalid message type(s):`);
1359
+ console.log(`[WARN] [TLAGenerator] Dropped ${invalidMessageTypes.length} unrepresentable message type(s):`);
1357
1360
  for (const invalid of invalidMessageTypes) {
1358
- console.log(`[WARN] - "${invalid}" (not a valid TLA+ identifier)`);
1361
+ console.log(`[WARN] - "${invalid}" (no letter to form a TLA+ action name)`);
1359
1362
  }
1360
1363
  }
1361
1364
  if (process.env["POLLY_DEBUG"]) {
@@ -1762,7 +1765,7 @@ var init_tla = __esm(() => {
1762
1765
  const validHandlers = [];
1763
1766
  const invalidHandlers = [];
1764
1767
  for (const handler of handlers) {
1765
- if (this.isValidTLAIdentifier(handler.messageType)) {
1768
+ if (this.canRepresentAsTLAAction(handler.messageType)) {
1766
1769
  validHandlers.push(handler);
1767
1770
  } else {
1768
1771
  invalidHandlers.push(handler);
@@ -1773,7 +1776,7 @@ var init_tla = __esm(() => {
1773
1776
  logInvalidHandlers(invalidHandlers) {
1774
1777
  if (invalidHandlers.length === 0 || !process.env["POLLY_DEBUG"])
1775
1778
  return;
1776
- console.log(`[WARN] [TLAGenerator] Filtered out ${invalidHandlers.length} handler(s) with invalid message types:`);
1779
+ console.log(`[WARN] [TLAGenerator] Dropped ${invalidHandlers.length} handler(s) with unrepresentable message types:`);
1777
1780
  for (const handler of invalidHandlers) {
1778
1781
  console.log(`[WARN] - "${handler.messageType}" at ${handler.location.file}:${handler.location.line}`);
1779
1782
  }
@@ -2488,19 +2491,31 @@ var init_tla = __esm(() => {
2488
2491
  }
2489
2492
  resolveCollisions(actionNameToMessageTypes) {
2490
2493
  for (const [baseActionName, messageTypes] of actionNameToMessageTypes.entries()) {
2491
- if (messageTypes.length === 1) {
2492
- const entry = messageTypes[0];
2493
- if (entry) {
2494
- this.resolvedActionNames.set(entry.messageType, baseActionName);
2495
- }
2494
+ const single = messageTypes.length === 1 ? messageTypes[0] : undefined;
2495
+ if (single) {
2496
+ this.resolvedActionNames.set(single.messageType, baseActionName);
2496
2497
  continue;
2497
2498
  }
2498
- for (const entry of messageTypes) {
2499
- const resolvedName = entry.origin === "stateHandler" ? baseActionName.replace(/^Handle/, "HandleFn") : baseActionName;
2500
- this.resolvedActionNames.set(entry.messageType, resolvedName);
2501
- }
2499
+ this.resolveCollidingGroup(baseActionName, messageTypes);
2500
+ }
2501
+ }
2502
+ resolveCollidingGroup(baseActionName, messageTypes) {
2503
+ const usedNames = new Set;
2504
+ for (const entry of messageTypes) {
2505
+ const originName = entry.origin === "stateHandler" ? baseActionName.replace(/^Handle/, "HandleFn") : baseActionName;
2506
+ this.resolvedActionNames.set(entry.messageType, this.uniquify(originName, usedNames));
2502
2507
  }
2503
2508
  }
2509
+ uniquify(name, used) {
2510
+ let candidate = name;
2511
+ let suffix = 2;
2512
+ while (used.has(candidate)) {
2513
+ candidate = `${name}_${suffix}`;
2514
+ suffix++;
2515
+ }
2516
+ used.add(candidate);
2517
+ return candidate;
2518
+ }
2504
2519
  getResolvedActionName(messageType) {
2505
2520
  const resolved = this.resolvedActionNames.get(messageType);
2506
2521
  if (resolved) {
@@ -2526,6 +2541,9 @@ var init_tla = __esm(() => {
2526
2541
  const paramName = value.substring(6);
2527
2542
  return `payload.${this.sanitizeFieldName(paramName)}`;
2528
2543
  }
2544
+ if (value.startsWith("EXPR:")) {
2545
+ return this.tsExpressionToTLA(value.substring(5), false);
2546
+ }
2529
2547
  if (this.isTLAExpression(value)) {
2530
2548
  return this.sanitizeTLAExpression(value);
2531
2549
  }
@@ -2618,7 +2636,7 @@ var init_tla = __esm(() => {
2618
2636
  this.line("\\* Next state relation (extends MessageRouter)");
2619
2637
  this.line("UserNext ==");
2620
2638
  this.indent++;
2621
- const hasValidHandlers = analysis.handlers.some((h) => this.isValidTLAIdentifier(h.messageType));
2639
+ const hasValidHandlers = analysis.handlers.some((h) => this.canRepresentAsTLAAction(h.messageType));
2622
2640
  if (hasValidHandlers) {
2623
2641
  const userPayload = this.unchangedUserStates(undefined, ["payload"]);
2624
2642
  this.line(`\\/ \\E c \\in Contexts : ConnectPort(c) /\\ ${userPayload}`);
@@ -4947,7 +4965,7 @@ class HandlerExtractor {
4947
4965
  const exists = handlers.some((h) => h.messageType === handler.messageType && h.location.file === handler.location.file);
4948
4966
  if (!exists) {
4949
4967
  handlers.push(handler);
4950
- if (this.isValidTLAIdentifier(handler.messageType)) {
4968
+ if (this.canRepresentAsTLAAction(handler.messageType)) {
4951
4969
  messageTypes.add(handler.messageType);
4952
4970
  } else {
4953
4971
  invalidMessageTypes.add(handler.messageType);
@@ -5057,7 +5075,7 @@ class HandlerExtractor {
5057
5075
  const syntheticHandlers = this.createResourceHandlers(resource, context);
5058
5076
  for (const handler of syntheticHandlers) {
5059
5077
  handlers.push(handler);
5060
- if (this.isValidTLAIdentifier(handler.messageType)) {
5078
+ if (this.canRepresentAsTLAAction(handler.messageType)) {
5061
5079
  messageTypes.add(handler.messageType);
5062
5080
  } else {
5063
5081
  invalidMessageTypes.add(handler.messageType);
@@ -5119,7 +5137,7 @@ class HandlerExtractor {
5119
5137
  }
5120
5138
  categorizeHandlerMessageTypes(handlers, messageTypes, invalidMessageTypes) {
5121
5139
  for (const handler of handlers) {
5122
- if (this.isValidTLAIdentifier(handler.messageType)) {
5140
+ if (this.canRepresentAsTLAAction(handler.messageType)) {
5123
5141
  messageTypes.add(handler.messageType);
5124
5142
  } else {
5125
5143
  invalidMessageTypes.add(handler.messageType);
@@ -5134,11 +5152,8 @@ class HandlerExtractor {
5134
5152
  console.log(`[DEBUG] Filtered ${invalidCount} invalid message type(s) from handlers`);
5135
5153
  }
5136
5154
  }
5137
- isValidTLAIdentifier(s) {
5138
- if (!s || s.length === 0) {
5139
- return false;
5140
- }
5141
- return /^[a-zA-Z][a-zA-Z0-9_]*$/.test(s);
5155
+ canRepresentAsTLAAction(s) {
5156
+ return typeof s === "string" && /[a-zA-Z]/.test(s) && !/[{}();<>=]/.test(s);
5142
5157
  }
5143
5158
  extractFromFile(sourceFile) {
5144
5159
  const handlers = [];
@@ -5821,7 +5836,19 @@ class HandlerExtractor {
5821
5836
  const paramName = this.extractPayloadPropertyParam(initializer);
5822
5837
  if (paramName !== null) {
5823
5838
  assignments.push({ field, value: `param:${paramName}` });
5839
+ return;
5824
5840
  }
5841
+ if (this.isTranslatableInitializer(initializer)) {
5842
+ assignments.push({ field, value: `EXPR:${initializer.getText()}` });
5843
+ return;
5844
+ }
5845
+ if (process.env["POLLY_DEBUG"]) {
5846
+ const on = signalName ? ` on ${signalName}.value` : "";
5847
+ console.log(`[WARN] dropped object-literal property '${name}'${on} — initializer kind ${initializer.getKindName()} is not translatable to TLA+`);
5848
+ }
5849
+ }
5850
+ isTranslatableInitializer(node) {
5851
+ return Node2.isBinaryExpression(node) || Node2.isPropertyAccessExpression(node) || Node2.isElementAccessExpression(node) || Node2.isPrefixUnaryExpression(node) || Node2.isPostfixUnaryExpression(node) || Node2.isParenthesizedExpression(node);
5825
5852
  }
5826
5853
  extractPayloadPropertyParam(initializer) {
5827
5854
  if (!Node2.isPropertyAccessExpression(initializer))
@@ -7163,47 +7190,44 @@ class TypeExtractor {
7163
7190
  }
7164
7191
  filterAndLogMessageTypes(messageTypes, handlerMessageTypes) {
7165
7192
  const allMessageTypes = Array.from(new Set([...messageTypes, ...handlerMessageTypes]));
7166
- const validMessageTypes = [];
7167
- const invalidMessageTypes = [];
7193
+ const keptMessageTypes = [];
7194
+ const droppedMessageTypes = [];
7168
7195
  for (const msgType of allMessageTypes) {
7169
- if (this.isValidTLAIdentifier(msgType)) {
7170
- validMessageTypes.push(msgType);
7196
+ if (this.canRepresentAsTLAAction(msgType)) {
7197
+ keptMessageTypes.push(msgType);
7171
7198
  } else {
7172
- invalidMessageTypes.push(msgType);
7199
+ droppedMessageTypes.push(msgType);
7173
7200
  }
7174
7201
  }
7175
- this.logInvalidMessageTypes(invalidMessageTypes);
7176
- return validMessageTypes;
7202
+ this.logDroppedMessageTypes(droppedMessageTypes);
7203
+ return keptMessageTypes;
7177
7204
  }
7178
- logInvalidMessageTypes(invalidMessageTypes) {
7179
- if (invalidMessageTypes.length === 0 || !process.env["POLLY_DEBUG"])
7205
+ logDroppedMessageTypes(droppedMessageTypes) {
7206
+ if (droppedMessageTypes.length === 0)
7180
7207
  return;
7181
- console.log(`[WARN] Filtered out ${invalidMessageTypes.length} invalid message type(s):`);
7182
- for (const invalid of invalidMessageTypes) {
7183
- console.log(`[WARN] - "${invalid}" (not a valid TLA+ identifier)`);
7208
+ console.log(`[WARN] Dropped ${droppedMessageTypes.length} unrepresentable message type(s) (no letter to form a TLA+ action name):`);
7209
+ for (const dropped of droppedMessageTypes) {
7210
+ console.log(`[WARN] - "${dropped}"`);
7184
7211
  }
7185
7212
  }
7186
7213
  filterAndLogHandlers(handlers) {
7187
- const validHandlers = handlers.filter((h) => this.isValidTLAIdentifier(h.messageType));
7188
- this.logInvalidHandlers(handlers, validHandlers);
7189
- return validHandlers;
7214
+ const keptHandlers = handlers.filter((h) => this.canRepresentAsTLAAction(h.messageType));
7215
+ this.logDroppedHandlers(handlers, keptHandlers);
7216
+ return keptHandlers;
7190
7217
  }
7191
- logInvalidHandlers(allHandlers, validHandlers) {
7192
- const filteredHandlerCount = allHandlers.length - validHandlers.length;
7193
- if (filteredHandlerCount === 0 || !process.env["POLLY_DEBUG"])
7218
+ logDroppedHandlers(allHandlers, keptHandlers) {
7219
+ const droppedHandlerCount = allHandlers.length - keptHandlers.length;
7220
+ if (droppedHandlerCount === 0)
7194
7221
  return;
7195
- console.log(`[WARN] Filtered out ${filteredHandlerCount} handler(s) with invalid message types:`);
7222
+ console.log(`[WARN] Dropped ${droppedHandlerCount} handler(s) with unrepresentable message types:`);
7196
7223
  for (const handler of allHandlers) {
7197
- if (!this.isValidTLAIdentifier(handler.messageType)) {
7224
+ if (!this.canRepresentAsTLAAction(handler.messageType)) {
7198
7225
  console.log(`[WARN] - Handler for "${handler.messageType}" at ${handler.location.file}:${handler.location.line}`);
7199
7226
  }
7200
7227
  }
7201
7228
  }
7202
- isValidTLAIdentifier(s) {
7203
- if (!s || s.length === 0) {
7204
- return false;
7205
- }
7206
- return /^[a-zA-Z][a-zA-Z0-9_]*$/.test(s);
7229
+ canRepresentAsTLAAction(s) {
7230
+ return typeof s === "string" && /[a-zA-Z]/.test(s) && !/[{}();<>=]/.test(s);
7207
7231
  }
7208
7232
  extractStateType(filePath) {
7209
7233
  const sourceFile = this.project.getSourceFile(filePath);
@@ -8364,4 +8388,4 @@ main().catch((error) => {
8364
8388
  process.exit(1);
8365
8389
  });
8366
8390
 
8367
- //# debugId=F1AE4F074F9AD2C964756E2164756E21
8391
+ //# debugId=2F2FDDDA92F1E27664756E2164756E21