@rsconcept/domain 2.0.2 → 2.1.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.
Files changed (59) hide show
  1. package/README.md +1 -1
  2. package/dist/{analyzer-iqAXyROE.d.ts → analyzer-fNhkwO-6.d.ts} +2 -2
  3. package/dist/{ast-annotations-D6KZDu12.d.ts → ast-annotations-CiIx8qBM.d.ts} +2 -2
  4. package/dist/{calculator-k8BGIKmj.d.ts → calculator-DE89LtIM.d.ts} +2 -2
  5. package/dist/cctext/language-api.js.map +1 -1
  6. package/dist/cctext/language.d.ts +7 -4
  7. package/dist/cctext/language.js.map +1 -1
  8. package/dist/{diagnostics-D7SiHAwW.js → diagnostics-CY9sKggB.js} +152 -12
  9. package/dist/diagnostics-CY9sKggB.js.map +1 -0
  10. package/dist/{diagnostics-Clo3mkba.d.ts → diagnostics-EaIt3zIw.d.ts} +28 -6
  11. package/dist/{error-CzIbnP-N.d.ts → error-B0EkIx4K.d.ts} +2 -1
  12. package/dist/graph/graph.d.ts +1 -1
  13. package/dist/graph/graph.js +93 -1
  14. package/dist/graph/graph.js.map +1 -1
  15. package/dist/graph/index.d.ts +1 -1
  16. package/dist/{graph-DR8rL2o3.d.ts → graph-CL73WdW1.d.ts} +15 -2
  17. package/dist/index.d.ts +7 -7
  18. package/dist/index.js +2 -2
  19. package/dist/library/diagnostics.d.ts +2 -2
  20. package/dist/library/diagnostics.js +2 -2
  21. package/dist/library/index.d.ts +2 -2
  22. package/dist/library/index.js +2 -2
  23. package/dist/library/oss-api.d.ts +1 -1
  24. package/dist/library/oss.d.ts +1 -1
  25. package/dist/library/rsengine.d.ts +2 -2
  26. package/dist/library/rsengine.js +1 -1
  27. package/dist/library/rsform-api.d.ts +14 -4
  28. package/dist/library/rsform-api.js +2 -2
  29. package/dist/library/rsform.d.ts +1 -1
  30. package/dist/library/rsmodel-api.d.ts +1 -1
  31. package/dist/library/rsmodel-api.js +1 -1
  32. package/dist/library/rsmodel.d.ts +1 -1
  33. package/dist/library/structure-planner.d.ts +1 -1
  34. package/dist/library/structure-planner.js +1 -1
  35. package/dist/rslang/ast-annotations.d.ts +1 -1
  36. package/dist/rslang/error.d.ts +1 -1
  37. package/dist/rslang/error.js +2 -1
  38. package/dist/rslang/error.js.map +1 -1
  39. package/dist/rslang/eval/calculator.d.ts +1 -1
  40. package/dist/rslang/eval/evaluator.d.ts +1 -1
  41. package/dist/rslang/index.d.ts +4 -4
  42. package/dist/rslang/parser/syntax-errors/index.d.ts +1 -1
  43. package/dist/rslang/semantic/analyzer.d.ts +1 -1
  44. package/dist/rslang/semantic/type-auditor.d.ts +1 -1
  45. package/dist/rslang/semantic/value-auditor.d.ts +1 -1
  46. package/package.json +14 -13
  47. package/src/cctext/language-api.test.ts +5 -0
  48. package/src/cctext/language-api.ts +6 -6
  49. package/src/cctext/language.ts +3 -4
  50. package/src/graph/graph.test.ts +22 -0
  51. package/src/graph/graph.ts +115 -1
  52. package/src/index.ts +2 -0
  53. package/src/library/diagnostics.test.ts +34 -0
  54. package/src/library/diagnostics.ts +81 -2
  55. package/src/library/index.ts +2 -0
  56. package/src/library/rsform-api.test.ts +99 -3
  57. package/src/library/rsform-api.ts +155 -7
  58. package/src/rslang/error.ts +4 -1
  59. package/dist/diagnostics-D7SiHAwW.js.map +0 -1
@@ -287,7 +287,7 @@ var Graph = class Graph {
287
287
  * Finds a cycle in the graph.
288
288
  *
289
289
  * @returns {NodeID[] | null} The cycle if found, otherwise `null`.
290
- * Uses non-recursive DFS.
290
+ * Uses non-recursive DFS. The returned path is closed (first id equals last).
291
291
  */
292
292
  findCycle() {
293
293
  const visited = /* @__PURE__ */ new Set();
@@ -335,6 +335,98 @@ var Graph = class Graph {
335
335
  }
336
336
  return null;
337
337
  }
338
+ /**
339
+ * Finds one closed cycle path per cyclic strongly connected component.
340
+ *
341
+ * @returns Closed paths (first id equals last). Empty when the graph is acyclic.
342
+ */
343
+ findCycles() {
344
+ const components = this.stronglyConnectedComponents();
345
+ const result = [];
346
+ for (const component of components) {
347
+ if (component.length === 1) {
348
+ const id = component[0];
349
+ if (this.hasEdge(id, id)) result.push([id, id]);
350
+ continue;
351
+ }
352
+ const subgraph = new Graph();
353
+ const memberIds = new Set(component);
354
+ for (const id of component) {
355
+ subgraph.addNode(id);
356
+ const node = this.nodes.get(id);
357
+ if (!node) continue;
358
+ for (const child of node.outputs) if (memberIds.has(child)) subgraph.addEdge(id, child);
359
+ }
360
+ const cycle = subgraph.findCycle();
361
+ if (cycle) result.push(cycle);
362
+ }
363
+ return result;
364
+ }
365
+ /**
366
+ * Tarjan strongly connected components (iterative).
367
+ *
368
+ * @returns Node-id arrays; multi-node components are cyclic SCCs, single-node
369
+ * components are acyclic unless the node has a self-loop.
370
+ */
371
+ stronglyConnectedComponents() {
372
+ let index = 0;
373
+ const indices = /* @__PURE__ */ new Map();
374
+ const lowlink = /* @__PURE__ */ new Map();
375
+ const onStack = /* @__PURE__ */ new Set();
376
+ const stack = [];
377
+ const components = [];
378
+ for (const startId of this.nodes.keys()) {
379
+ if (indices.has(startId)) continue;
380
+ const callStack = [{
381
+ nodeId: startId,
382
+ edgeIndex: 0,
383
+ entered: false
384
+ }];
385
+ while (callStack.length > 0) {
386
+ const frame = callStack[callStack.length - 1];
387
+ const node = this.nodes.get(frame.nodeId);
388
+ if (!node) {
389
+ callStack.pop();
390
+ continue;
391
+ }
392
+ if (!frame.entered) {
393
+ frame.entered = true;
394
+ indices.set(frame.nodeId, index);
395
+ lowlink.set(frame.nodeId, index);
396
+ index += 1;
397
+ stack.push(frame.nodeId);
398
+ onStack.add(frame.nodeId);
399
+ }
400
+ if (frame.edgeIndex < node.outputs.length) {
401
+ const child = node.outputs[frame.edgeIndex];
402
+ frame.edgeIndex += 1;
403
+ if (!indices.has(child)) callStack.push({
404
+ nodeId: child,
405
+ edgeIndex: 0,
406
+ entered: false
407
+ });
408
+ else if (onStack.has(child)) lowlink.set(frame.nodeId, Math.min(lowlink.get(frame.nodeId), indices.get(child)));
409
+ continue;
410
+ }
411
+ callStack.pop();
412
+ if (callStack.length > 0) {
413
+ const parentId = callStack[callStack.length - 1].nodeId;
414
+ lowlink.set(parentId, Math.min(lowlink.get(parentId), lowlink.get(frame.nodeId)));
415
+ }
416
+ if (lowlink.get(frame.nodeId) === indices.get(frame.nodeId)) {
417
+ const component = [];
418
+ while (stack.length > 0) {
419
+ const id = stack.pop();
420
+ onStack.delete(id);
421
+ component.push(id);
422
+ if (id === frame.nodeId) break;
423
+ }
424
+ components.push(component);
425
+ }
426
+ }
427
+ }
428
+ return components;
429
+ }
338
430
  };
339
431
  //#endregion
340
432
  export { Graph, GraphNode };
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","names":[],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/**\n * Module: Custom graph data structure.\n */\n\n/** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */\nexport class GraphNode<NodeID> {\n /** Unique identifier of the node. */\n id: NodeID;\n /** List of outgoing nodes. */\n outputs: NodeID[];\n /** List of incoming nodes. */\n inputs: NodeID[];\n\n constructor(id: NodeID) {\n this.id = id;\n this.outputs = [];\n this.inputs = [];\n }\n\n clone(): GraphNode<NodeID> {\n const result = new GraphNode(this.id);\n result.outputs = [...this.outputs];\n result.inputs = [...this.inputs];\n return result;\n }\n\n addOutput(node: NodeID): void {\n this.outputs.push(node);\n }\n\n addInput(node: NodeID): void {\n this.inputs.push(node);\n }\n\n removeInput(target: NodeID): NodeID | null {\n const index = this.inputs.findIndex(node => node === target);\n return index > -1 ? this.inputs.splice(index, 1)[0] : null;\n }\n\n removeOutput(target: NodeID): NodeID | null {\n const index = this.outputs.findIndex(node => node === target);\n return index > -1 ? this.outputs.splice(index, 1)[0] : null;\n }\n}\n\n/**\n * Represents a Graph.\n *\n * This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.\n */\nexport class Graph<NodeID = number> {\n /** Map of nodes. */\n nodes = new Map<NodeID, GraphNode<NodeID>>();\n\n constructor(arr?: NodeID[][]) {\n if (!arr) {\n return;\n }\n arr.forEach(edge => {\n if (edge.length === 1) {\n this.addNode(edge[0]);\n } else {\n this.addEdge(edge[0], edge[1]);\n }\n });\n }\n\n clone(): Graph<NodeID> {\n const result = new Graph<NodeID>();\n this.nodes.forEach(node => result.nodes.set(node.id, node.clone()));\n return result;\n }\n\n at(target: NodeID): GraphNode<NodeID> | undefined {\n return this.nodes.get(target);\n }\n\n addNode(target: NodeID): GraphNode<NodeID> {\n let node = this.nodes.get(target);\n if (!node) {\n node = new GraphNode(target);\n this.nodes.set(target, node);\n }\n return node;\n }\n\n hasNode(target: NodeID): boolean {\n return !!this.nodes.get(target);\n }\n\n removeNode(target: NodeID): void {\n this.nodes.forEach(node => {\n node.removeInput(target);\n node.removeOutput(target);\n });\n this.nodes.delete(target);\n }\n\n foldNode(target: NodeID): void {\n const nodeToRemove = this.nodes.get(target);\n if (!nodeToRemove) {\n return;\n }\n nodeToRemove.inputs.forEach(input => {\n nodeToRemove.outputs.forEach(output => {\n this.addEdge(input, output);\n });\n });\n this.removeNode(target);\n }\n\n removeIsolated(): GraphNode<NodeID>[] {\n const result: GraphNode<NodeID>[] = [];\n this.nodes.forEach(node => {\n if (node.outputs.length === 0 && node.inputs.length === 0) {\n result.push(node);\n this.nodes.delete(node.id);\n }\n });\n return result;\n }\n\n addEdge(source: NodeID, destination: NodeID): void {\n if (this.hasEdge(source, destination)) {\n return;\n }\n const sourceNode = this.addNode(source);\n const destinationNode = this.addNode(destination);\n sourceNode.addOutput(destinationNode.id);\n destinationNode.addInput(sourceNode.id);\n }\n\n removeEdge(source: NodeID, destination: NodeID): void {\n const sourceNode = this.nodes.get(source);\n const destinationNode = this.nodes.get(destination);\n if (sourceNode && destinationNode) {\n sourceNode.removeOutput(destination);\n destinationNode.removeInput(source);\n }\n }\n\n hasEdge(source: NodeID, destination: NodeID): boolean {\n const sourceNode = this.nodes.get(source);\n if (!sourceNode) {\n return false;\n }\n return !!sourceNode.outputs.find(id => id === destination);\n }\n\n isReachable(source: NodeID, destination: NodeID): boolean {\n return this.expandAllOutputs([source]).includes(destination);\n }\n\n rootNodes(): NodeID[] {\n return [...this.nodes.keys()].filter(id => !this.nodes.get(id)?.inputs.length);\n }\n\n expandOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.outputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.inputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandAllOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandOutputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.outputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n expandAllInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandInputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.inputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n maximizePart(origin: NodeID[]): NodeID[] {\n const outputs: NodeID[] = this.expandAllOutputs(origin);\n const result = [...origin];\n this.topologicalOrder()\n .filter(id => outputs.includes(id))\n .forEach(id => {\n const node = this.nodes.get(id);\n if (node?.inputs.every(parent => result.includes(parent))) {\n result.push(id);\n }\n });\n return result;\n }\n\n topologicalOrder(): NodeID[] {\n const result: NodeID[] = [];\n const marked = new Set<NodeID>();\n const nodeStack: NodeID[] = [];\n this.nodes.forEach(node => {\n if (marked.has(node.id)) {\n return;\n }\n nodeStack.push(node.id);\n while (nodeStack.length > 0) {\n const item = nodeStack[nodeStack.length - 1];\n if (marked.has(item)) {\n if (!result.find(id => id === item)) {\n result.push(item);\n }\n nodeStack.pop();\n } else {\n marked.add(item);\n const itemNode = this.nodes.get(item);\n if (itemNode && itemNode.outputs.length > 0) {\n itemNode.outputs.forEach(child => {\n if (!marked.has(child)) {\n nodeStack.push(child);\n }\n });\n }\n }\n }\n });\n return result.reverse();\n }\n\n /**\n * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive\n * successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).\n */\n sortStable(target: NodeID[]): NodeID[] {\n if (target.length <= 1) {\n return [...target];\n }\n\n const reachable = this.buildTransitiveClosureForSort();\n const testSet = new Set<NodeID>();\n const result: NodeID[] = [];\n\n for (const nodeId of [...target].reverse()) {\n const nodeReachable = reachable.get(nodeId) ?? new Set<NodeID>();\n const needMove = testSet.has(nodeId);\n for (const childId of nodeReachable) {\n testSet.add(childId);\n }\n\n if (!needMove) {\n result.push(nodeId);\n continue;\n }\n\n let inserted = false;\n for (let index = 0; index < result.length; index++) {\n const parent = result[index];\n const parentReachable = reachable.get(parent) ?? new Set<NodeID>();\n if (nodeReachable.has(parent)) {\n if (parentReachable.has(nodeId)) {\n result.push(nodeId);\n } else {\n result.splice(index, 0, nodeId);\n }\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n result.push(nodeId);\n }\n }\n\n result.reverse();\n return result;\n }\n\n private buildTransitiveClosureForSort(): Map<NodeID, Set<NodeID>> {\n const closure = new Map<NodeID, Set<NodeID>>();\n for (const node of this.nodes.values()) {\n closure.set(node.id, new Set(node.outputs));\n }\n\n const order = this.topologicalOrder();\n for (const nodeId of [...order].reverse()) {\n const node = this.at(nodeId);\n if (!node) {\n continue;\n }\n const nodeClosure = closure.get(nodeId) ?? new Set<NodeID>();\n for (const parentId of node.inputs) {\n const parentClosure = closure.get(parentId) ?? new Set<NodeID>();\n for (const childId of nodeClosure) {\n parentClosure.add(childId);\n }\n closure.set(parentId, parentClosure);\n }\n }\n\n return closure;\n }\n\n transitiveReduction() {\n const order = this.topologicalOrder();\n const marked = new Map<NodeID, boolean>();\n order.forEach(nodeID => {\n if (marked.get(nodeID)) {\n return;\n }\n const stack: { id: NodeID; parents: NodeID[] }[] = [];\n stack.push({ id: nodeID, parents: [] });\n while (stack.length > 0) {\n const item = stack.splice(0, 1)[0];\n const node = this.nodes.get(item.id);\n if (node) {\n node.outputs.forEach(child => {\n item.parents.forEach(parent => this.removeEdge(parent, child));\n stack.push({ id: child, parents: [item.id, ...item.parents] });\n });\n }\n marked.set(item.id, true);\n }\n });\n }\n\n /**\n * Finds a cycle in the graph.\n *\n * @returns {NodeID[] | null} The cycle if found, otherwise `null`.\n * Uses non-recursive DFS.\n */\n findCycle(): NodeID[] | null {\n const visited = new Set<NodeID>();\n const nodeStack = new Set<NodeID>();\n const parents = new Map<NodeID, NodeID>();\n\n for (const nodeId of this.nodes.keys()) {\n if (visited.has(nodeId)) {\n continue;\n }\n\n const callStack: { nodeId: NodeID; parentId: NodeID | null }[] = [];\n callStack.push({ nodeId: nodeId, parentId: null });\n while (callStack.length > 0) {\n const { nodeId, parentId } = callStack[callStack.length - 1];\n if (visited.has(nodeId)) {\n nodeStack.delete(nodeId);\n callStack.pop();\n continue;\n }\n visited.add(nodeId);\n nodeStack.add(nodeId);\n if (parentId !== null) {\n parents.set(nodeId, parentId);\n }\n\n const currentNode = this.nodes.get(nodeId)!;\n for (const child of currentNode.outputs) {\n if (!visited.has(child)) {\n callStack.push({ nodeId: child, parentId: nodeId });\n continue;\n }\n if (!nodeStack.has(child)) {\n continue;\n }\n const cycle: NodeID[] = [];\n let current = nodeId;\n cycle.push(child);\n while (current !== child) {\n cycle.push(current);\n current = parents.get(current)!;\n }\n cycle.push(child);\n cycle.reverse();\n return cycle;\n }\n }\n }\n return null;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","names":[],"sources":["../../src/graph/graph.ts"],"sourcesContent":["/**\n * Module: Custom graph data structure.\n */\n\n/** Represents single node of a {@link Graph}, as implemented by storing outgoing and incoming connections. */\nexport class GraphNode<NodeID> {\n /** Unique identifier of the node. */\n id: NodeID;\n /** List of outgoing nodes. */\n outputs: NodeID[];\n /** List of incoming nodes. */\n inputs: NodeID[];\n\n constructor(id: NodeID) {\n this.id = id;\n this.outputs = [];\n this.inputs = [];\n }\n\n clone(): GraphNode<NodeID> {\n const result = new GraphNode(this.id);\n result.outputs = [...this.outputs];\n result.inputs = [...this.inputs];\n return result;\n }\n\n addOutput(node: NodeID): void {\n this.outputs.push(node);\n }\n\n addInput(node: NodeID): void {\n this.inputs.push(node);\n }\n\n removeInput(target: NodeID): NodeID | null {\n const index = this.inputs.findIndex(node => node === target);\n return index > -1 ? this.inputs.splice(index, 1)[0] : null;\n }\n\n removeOutput(target: NodeID): NodeID | null {\n const index = this.outputs.findIndex(node => node === target);\n return index > -1 ? this.outputs.splice(index, 1)[0] : null;\n }\n}\n\n/**\n * Represents a Graph.\n *\n * This class is optimized for TermGraph use case and not supposed to be used as generic graph implementation.\n */\nexport class Graph<NodeID = number> {\n /** Map of nodes. */\n nodes = new Map<NodeID, GraphNode<NodeID>>();\n\n constructor(arr?: NodeID[][]) {\n if (!arr) {\n return;\n }\n arr.forEach(edge => {\n if (edge.length === 1) {\n this.addNode(edge[0]);\n } else {\n this.addEdge(edge[0], edge[1]);\n }\n });\n }\n\n clone(): Graph<NodeID> {\n const result = new Graph<NodeID>();\n this.nodes.forEach(node => result.nodes.set(node.id, node.clone()));\n return result;\n }\n\n at(target: NodeID): GraphNode<NodeID> | undefined {\n return this.nodes.get(target);\n }\n\n addNode(target: NodeID): GraphNode<NodeID> {\n let node = this.nodes.get(target);\n if (!node) {\n node = new GraphNode(target);\n this.nodes.set(target, node);\n }\n return node;\n }\n\n hasNode(target: NodeID): boolean {\n return !!this.nodes.get(target);\n }\n\n removeNode(target: NodeID): void {\n this.nodes.forEach(node => {\n node.removeInput(target);\n node.removeOutput(target);\n });\n this.nodes.delete(target);\n }\n\n foldNode(target: NodeID): void {\n const nodeToRemove = this.nodes.get(target);\n if (!nodeToRemove) {\n return;\n }\n nodeToRemove.inputs.forEach(input => {\n nodeToRemove.outputs.forEach(output => {\n this.addEdge(input, output);\n });\n });\n this.removeNode(target);\n }\n\n removeIsolated(): GraphNode<NodeID>[] {\n const result: GraphNode<NodeID>[] = [];\n this.nodes.forEach(node => {\n if (node.outputs.length === 0 && node.inputs.length === 0) {\n result.push(node);\n this.nodes.delete(node.id);\n }\n });\n return result;\n }\n\n addEdge(source: NodeID, destination: NodeID): void {\n if (this.hasEdge(source, destination)) {\n return;\n }\n const sourceNode = this.addNode(source);\n const destinationNode = this.addNode(destination);\n sourceNode.addOutput(destinationNode.id);\n destinationNode.addInput(sourceNode.id);\n }\n\n removeEdge(source: NodeID, destination: NodeID): void {\n const sourceNode = this.nodes.get(source);\n const destinationNode = this.nodes.get(destination);\n if (sourceNode && destinationNode) {\n sourceNode.removeOutput(destination);\n destinationNode.removeInput(source);\n }\n }\n\n hasEdge(source: NodeID, destination: NodeID): boolean {\n const sourceNode = this.nodes.get(source);\n if (!sourceNode) {\n return false;\n }\n return !!sourceNode.outputs.find(id => id === destination);\n }\n\n isReachable(source: NodeID, destination: NodeID): boolean {\n return this.expandAllOutputs([source]).includes(destination);\n }\n\n rootNodes(): NodeID[] {\n return [...this.nodes.keys()].filter(id => !this.nodes.get(id)?.inputs.length);\n }\n\n expandOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.outputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = [];\n origin.forEach(id => {\n const node = this.nodes.get(id);\n if (node) {\n node.inputs.forEach(child => {\n if (!origin.includes(child) && !result.includes(child)) {\n result.push(child);\n }\n });\n }\n });\n return result;\n }\n\n expandAllOutputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandOutputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.outputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n expandAllInputs(origin: NodeID[]): NodeID[] {\n const result: NodeID[] = this.expandInputs(origin);\n if (result.length === 0) {\n return [];\n }\n\n const marked = new Map<NodeID, boolean>();\n origin.forEach(id => marked.set(id, true));\n let position = 0;\n while (position < result.length) {\n const node = this.nodes.get(result[position]);\n if (node && !marked.get(node.id)) {\n marked.set(node.id, true);\n node.inputs.forEach(child => {\n if (!marked.get(child) && !result.find(id => id === child)) {\n result.push(child);\n }\n });\n }\n position += 1;\n }\n return result;\n }\n\n maximizePart(origin: NodeID[]): NodeID[] {\n const outputs: NodeID[] = this.expandAllOutputs(origin);\n const result = [...origin];\n this.topologicalOrder()\n .filter(id => outputs.includes(id))\n .forEach(id => {\n const node = this.nodes.get(id);\n if (node?.inputs.every(parent => result.includes(parent))) {\n result.push(id);\n }\n });\n return result;\n }\n\n topologicalOrder(): NodeID[] {\n const result: NodeID[] = [];\n const marked = new Set<NodeID>();\n const nodeStack: NodeID[] = [];\n this.nodes.forEach(node => {\n if (marked.has(node.id)) {\n return;\n }\n nodeStack.push(node.id);\n while (nodeStack.length > 0) {\n const item = nodeStack[nodeStack.length - 1];\n if (marked.has(item)) {\n if (!result.find(id => id === item)) {\n result.push(item);\n }\n nodeStack.pop();\n } else {\n marked.add(item);\n const itemNode = this.nodes.get(item);\n if (itemNode && itemNode.outputs.length > 0) {\n itemNode.outputs.forEach(child => {\n if (!marked.has(child)) {\n nodeStack.push(child);\n }\n });\n }\n }\n }\n });\n return result.reverse();\n }\n\n /**\n * Stably reorders the given node ids so that, for this DAG, no node appears before a transitive\n * successor (edges: source → dependent; {@link GraphNode.outputs} lists dependents).\n */\n sortStable(target: NodeID[]): NodeID[] {\n if (target.length <= 1) {\n return [...target];\n }\n\n const reachable = this.buildTransitiveClosureForSort();\n const testSet = new Set<NodeID>();\n const result: NodeID[] = [];\n\n for (const nodeId of [...target].reverse()) {\n const nodeReachable = reachable.get(nodeId) ?? new Set<NodeID>();\n const needMove = testSet.has(nodeId);\n for (const childId of nodeReachable) {\n testSet.add(childId);\n }\n\n if (!needMove) {\n result.push(nodeId);\n continue;\n }\n\n let inserted = false;\n for (let index = 0; index < result.length; index++) {\n const parent = result[index];\n const parentReachable = reachable.get(parent) ?? new Set<NodeID>();\n if (nodeReachable.has(parent)) {\n if (parentReachable.has(nodeId)) {\n result.push(nodeId);\n } else {\n result.splice(index, 0, nodeId);\n }\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n result.push(nodeId);\n }\n }\n\n result.reverse();\n return result;\n }\n\n private buildTransitiveClosureForSort(): Map<NodeID, Set<NodeID>> {\n const closure = new Map<NodeID, Set<NodeID>>();\n for (const node of this.nodes.values()) {\n closure.set(node.id, new Set(node.outputs));\n }\n\n const order = this.topologicalOrder();\n for (const nodeId of [...order].reverse()) {\n const node = this.at(nodeId);\n if (!node) {\n continue;\n }\n const nodeClosure = closure.get(nodeId) ?? new Set<NodeID>();\n for (const parentId of node.inputs) {\n const parentClosure = closure.get(parentId) ?? new Set<NodeID>();\n for (const childId of nodeClosure) {\n parentClosure.add(childId);\n }\n closure.set(parentId, parentClosure);\n }\n }\n\n return closure;\n }\n\n transitiveReduction() {\n const order = this.topologicalOrder();\n const marked = new Map<NodeID, boolean>();\n order.forEach(nodeID => {\n if (marked.get(nodeID)) {\n return;\n }\n const stack: { id: NodeID; parents: NodeID[] }[] = [];\n stack.push({ id: nodeID, parents: [] });\n while (stack.length > 0) {\n const item = stack.splice(0, 1)[0];\n const node = this.nodes.get(item.id);\n if (node) {\n node.outputs.forEach(child => {\n item.parents.forEach(parent => this.removeEdge(parent, child));\n stack.push({ id: child, parents: [item.id, ...item.parents] });\n });\n }\n marked.set(item.id, true);\n }\n });\n }\n\n /**\n * Finds a cycle in the graph.\n *\n * @returns {NodeID[] | null} The cycle if found, otherwise `null`.\n * Uses non-recursive DFS. The returned path is closed (first id equals last).\n */\n findCycle(): NodeID[] | null {\n const visited = new Set<NodeID>();\n const nodeStack = new Set<NodeID>();\n const parents = new Map<NodeID, NodeID>();\n\n for (const nodeId of this.nodes.keys()) {\n if (visited.has(nodeId)) {\n continue;\n }\n\n const callStack: { nodeId: NodeID; parentId: NodeID | null }[] = [];\n callStack.push({ nodeId: nodeId, parentId: null });\n while (callStack.length > 0) {\n const { nodeId, parentId } = callStack[callStack.length - 1];\n if (visited.has(nodeId)) {\n nodeStack.delete(nodeId);\n callStack.pop();\n continue;\n }\n visited.add(nodeId);\n nodeStack.add(nodeId);\n if (parentId !== null) {\n parents.set(nodeId, parentId);\n }\n\n const currentNode = this.nodes.get(nodeId)!;\n for (const child of currentNode.outputs) {\n if (!visited.has(child)) {\n callStack.push({ nodeId: child, parentId: nodeId });\n continue;\n }\n if (!nodeStack.has(child)) {\n continue;\n }\n const cycle: NodeID[] = [];\n let current = nodeId;\n cycle.push(child);\n while (current !== child) {\n cycle.push(current);\n current = parents.get(current)!;\n }\n cycle.push(child);\n cycle.reverse();\n return cycle;\n }\n }\n }\n return null;\n }\n\n /**\n * Finds one closed cycle path per cyclic strongly connected component.\n *\n * @returns Closed paths (first id equals last). Empty when the graph is acyclic.\n */\n findCycles(): NodeID[][] {\n const components = this.stronglyConnectedComponents();\n const result: NodeID[][] = [];\n for (const component of components) {\n if (component.length === 1) {\n const id = component[0];\n if (this.hasEdge(id, id)) {\n result.push([id, id]);\n }\n continue;\n }\n const subgraph = new Graph<NodeID>();\n const memberIds = new Set(component);\n for (const id of component) {\n subgraph.addNode(id);\n const node = this.nodes.get(id);\n if (!node) {\n continue;\n }\n for (const child of node.outputs) {\n if (memberIds.has(child)) {\n subgraph.addEdge(id, child);\n }\n }\n }\n const cycle = subgraph.findCycle();\n if (cycle) {\n result.push(cycle);\n }\n }\n return result;\n }\n\n /**\n * Tarjan strongly connected components (iterative).\n *\n * @returns Node-id arrays; multi-node components are cyclic SCCs, single-node\n * components are acyclic unless the node has a self-loop.\n */\n stronglyConnectedComponents(): NodeID[][] {\n let index = 0;\n const indices = new Map<NodeID, number>();\n const lowlink = new Map<NodeID, number>();\n const onStack = new Set<NodeID>();\n const stack: NodeID[] = [];\n const components: NodeID[][] = [];\n\n /** Tarjan stack frame for iterative {@link Graph.stronglyConnectedComponents}. */\n interface Frame {\n nodeId: NodeID;\n edgeIndex: number;\n entered: boolean;\n }\n for (const startId of this.nodes.keys()) {\n if (indices.has(startId)) {\n continue;\n }\n const callStack: Frame[] = [{ nodeId: startId, edgeIndex: 0, entered: false }];\n while (callStack.length > 0) {\n const frame = callStack[callStack.length - 1];\n const node = this.nodes.get(frame.nodeId);\n if (!node) {\n callStack.pop();\n continue;\n }\n\n if (!frame.entered) {\n frame.entered = true;\n indices.set(frame.nodeId, index);\n lowlink.set(frame.nodeId, index);\n index += 1;\n stack.push(frame.nodeId);\n onStack.add(frame.nodeId);\n }\n\n if (frame.edgeIndex < node.outputs.length) {\n const child = node.outputs[frame.edgeIndex];\n frame.edgeIndex += 1;\n if (!indices.has(child)) {\n callStack.push({ nodeId: child, edgeIndex: 0, entered: false });\n } else if (onStack.has(child)) {\n lowlink.set(frame.nodeId, Math.min(lowlink.get(frame.nodeId)!, indices.get(child)!));\n }\n continue;\n }\n\n callStack.pop();\n if (callStack.length > 0) {\n const parentId = callStack[callStack.length - 1].nodeId;\n lowlink.set(parentId, Math.min(lowlink.get(parentId)!, lowlink.get(frame.nodeId)!));\n }\n\n if (lowlink.get(frame.nodeId) === indices.get(frame.nodeId)) {\n const component: NodeID[] = [];\n while (stack.length > 0) {\n const id = stack.pop()!;\n onStack.delete(id);\n component.push(id);\n if (id === frame.nodeId) {\n break;\n }\n }\n components.push(component);\n }\n }\n }\n return components;\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as Graph } from "../graph-DR8rL2o3.js";
1
+ import { t as Graph } from "../graph-CL73WdW1.js";
2
2
  export { Graph };
@@ -55,10 +55,23 @@ declare class Graph<NodeID = number> {
55
55
  * Finds a cycle in the graph.
56
56
  *
57
57
  * @returns {NodeID[] | null} The cycle if found, otherwise `null`.
58
- * Uses non-recursive DFS.
58
+ * Uses non-recursive DFS. The returned path is closed (first id equals last).
59
59
  */
60
60
  findCycle(): NodeID[] | null;
61
+ /**
62
+ * Finds one closed cycle path per cyclic strongly connected component.
63
+ *
64
+ * @returns Closed paths (first id equals last). Empty when the graph is acyclic.
65
+ */
66
+ findCycles(): NodeID[][];
67
+ /**
68
+ * Tarjan strongly connected components (iterative).
69
+ *
70
+ * @returns Node-id arrays; multi-node components are cyclic SCCs, single-node
71
+ * components are acyclic unless the node has a self-loop.
72
+ */
73
+ stronglyConnectedComponents(): NodeID[][];
61
74
  }
62
75
  //#endregion
63
76
  export { GraphNode as n, Graph as t };
64
- //# sourceMappingURL=graph-DR8rL2o3.d.ts.map
77
+ //# sourceMappingURL=graph-CL73WdW1.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,26 +1,26 @@
1
1
  import { EntityReference, Grammeme, ReferenceType, SyntacticReference, TermContext, WordForm, supportedGrammemes } from "./cctext/language.js";
2
- import { t as Graph } from "./graph-DR8rL2o3.js";
2
+ import { t as Graph } from "./graph-CL73WdW1.js";
3
3
  import { r as printTree, t as CMSyntaxNode } from "./lezer-tree-iS7LpLBJ.js";
4
4
  import { a as TOKEN_ERROR, c as flattenAst, d as printAst, f as visitAstDFS, i as FlatAstNode, l as getNodeIndices, n as AstNodeBase, o as buildTree, r as FlatAST, s as findByUid, t as AstNode, u as getNodeText } from "./ast-C8sIpKdL.js";
5
5
  import { t as Branded } from "./branded-ZlzIcxzu.js";
6
6
  import { n as generateStub, t as applyHash_fnv1a } from "./hash-Y8I4c6Al.js";
7
7
  import { A as makeTypePath, b as Typification, d as EmptySetT, f as ExpressionType, g as TypeClass, m as LogicT, t as AnyTypificationT, v as TypeID, y as TypePath } from "./typification-9lNu9R4k.js";
8
- import { i as RSErrorDescription, r as RSErrorCode } from "./error-CzIbnP-N.js";
9
- import { i as readTypeAnnotation, r as readErrorAnnotation } from "./ast-annotations-D6KZDu12.js";
8
+ import { i as RSErrorDescription, r as RSErrorCode } from "./error-B0EkIx4K.js";
9
+ import { i as readTypeAnnotation, r as readErrorAnnotation } from "./ast-annotations-CiIx8qBM.js";
10
10
  import { d as ValuePath, l as Value, o as TUPLE_ID, p as makeValuePath } from "./value-BduA_ZGp.js";
11
- import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "./calculator-k8BGIKmj.js";
11
+ import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "./calculator-DE89LtIM.js";
12
12
  import { d as printValue } from "./value-api-CXLl_zg0.js";
13
13
  import { t as parser } from "./parser-Bwd8LxJ1.js";
14
14
  import { t as TokenID } from "./token-DeXAmzwr.js";
15
15
  import { t as ValueClass } from "./value-class-CNI-lqXJ.js";
16
- import { a as RSLangAnalyzer, n as AnalysisFast, r as AnalysisFull, t as AnalysisBase } from "./analyzer-iqAXyROE.js";
16
+ import { a as RSLangAnalyzer, n as AnalysisFast, r as AnalysisFull, t as AnalysisBase } from "./analyzer-fNhkwO-6.js";
17
17
  import { n as ArgumentsType } from "./arguments-extractor-ngatANBI.js";
18
18
  import { n as applyAsciiTypeSubstitutions, r as parseTypeText } from "./typification-parser-Dytsv9CI.js";
19
19
  import { n as TypificationNodeData, t as TypificationGraph } from "./typification-graph-BY_oGT82.js";
20
20
  import { a as LibraryItemType, i as LibraryItemReference, n as CurrentVersion, o as LocationHead, r as LibraryItem, s as VersionInfo, t as AccessPolicy } from "./library-CYun28Xz.js";
21
- import { C as TypeInfo, S as Substitution, _ as CstClass, a as hasCstDiagnostic, b as RSForm, c as BasicsContext, d as RSModel, f as RSModelStats, g as Constituenta, h as Attribution, i as assignSchemaDiagnostics, l as DEFAULT_VALUE_TEXT, m as ArgumentValue, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, s as BasicBinding, t as CstDiagnostic, u as EvalStatus, v as CstStatus, x as RSFormStats, y as CstType } from "./diagnostics-Clo3mkba.js";
21
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, a as detectDependencyCycleDiagnostics, b as CstStatus, c as modelStatusCstDiagnostic, d as DEFAULT_VALUE_TEXT, f as EvalStatus, g as ArgumentValue, i as assignSchemaDiagnostics, l as BasicBinding, m as RSModelStats, n as DiagnosticKind, o as formatDependencyCycle, p as RSModel, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic, u as BasicsContext, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "./diagnostics-EaIt3zIw.js";
22
22
  import { FolderNode, FolderTree } from "./library/folder-tree.js";
23
23
  import { n as OssLayout, r as Position2D } from "./oss-layout-3glgAqfn.js";
24
24
  import { Block, CstSubstituteInfo, NodeType, Operation, OperationInput, OperationSchema, OperationSchemaStats, OperationSynthesis, OperationType, OssItem, SubstitutionErrorDescription, SubstitutionErrorType } from "./library/oss.js";
25
25
  import { RSEngine } from "./library/rsengine.js";
26
- export { AccessPolicy, type AnalysisBase, type AnalysisFast, type AnalysisFull, AnyTypificationT, type ArgumentValue, type ArgumentsType, type AstNode, type AstNodeBase, type Attribution, type BasicBinding, type BasicsContext, type Block, type Branded, type CMSyntaxNode, type CalculatorEvaluateOptions, type CalculatorResult, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, type EntityReference, EvalStatus, type ExpressionType, type FlatAST, type FlatAstNode, FolderNode, FolderTree, Grammeme, Graph, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, LogicT, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, type RSErrorDescription, type RSForm, type RSFormStats, RSLangAnalyzer, type RSModel, type RSModelStats, ReferenceType, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type SyntacticReference, TOKEN_ERROR, TUPLE_ID, type TermContext, TokenID, TypeClass, TypeID, type TypeInfo, type TypePath, type Typification, TypificationGraph, type TypificationNodeData, type Value, ValueClass, type ValuePath, type VersionInfo, type WordForm, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, findByUid, flattenAst, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
26
+ export { AccessPolicy, type AnalysisBase, type AnalysisFast, type AnalysisFull, AnyTypificationT, type ArgumentValue, type ArgumentsType, type AstNode, type AstNodeBase, type Attribution, type BasicBinding, type BasicsContext, type Block, type Branded, type CMSyntaxNode, type CalculatorEvaluateOptions, type CalculatorResult, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, type EntityReference, EvalStatus, type ExpressionType, type FlatAST, type FlatAstNode, FolderNode, FolderTree, Grammeme, Graph, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, LogicT, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, type RSErrorDescription, type RSForm, type RSFormStats, RSLangAnalyzer, type RSModel, type RSModelStats, ReferenceType, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type SyntacticReference, TOKEN_ERROR, TUPLE_ID, type TermContext, TokenID, TypeClass, TypeID, type TypeInfo, type TypePath, type Typification, TypificationGraph, type TypificationNodeData, type Value, ValueClass, type ValuePath, type VersionInfo, type WordForm, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, detectDependencyCycleDiagnostics, findByUid, flattenAst, formatDependencyCycle, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
package/dist/index.js CHANGED
@@ -15,10 +15,10 @@ import { RSLangAnalyzer } from "./rslang/semantic/analyzer.js";
15
15
  import { applyAsciiTypeSubstitutions, parseTypeText } from "./rslang/semantic/typification-parser.js";
16
16
  import { TypificationGraph } from "./rslang/typification-graph.js";
17
17
  import { CstClass, CstStatus, CstType } from "./library/rsform.js";
18
- import { a as modelStatusCstDiagnostic, i as hasCstDiagnostic, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind } from "./diagnostics-D7SiHAwW.js";
18
+ import { a as formatDependencyCycle, i as detectDependencyCycleDiagnostics, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind } from "./diagnostics-CY9sKggB.js";
19
19
  import { DEFAULT_VALUE_TEXT, EvalStatus } from "./library/rsmodel.js";
20
20
  import { FolderNode, FolderTree } from "./library/folder-tree.js";
21
21
  import { AccessPolicy, LibraryItemType, LocationHead } from "./library/library.js";
22
22
  import { NodeType, OperationType, SubstitutionErrorType } from "./library/oss.js";
23
23
  import { RSEngine } from "./library/rsengine.js";
24
- export { AccessPolicy, AnyTypificationT, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, EvalStatus, FolderNode, FolderTree, Grammeme, Graph, LibraryItemType, LocationHead, LogicT, NodeType, OperationType, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, RSLangAnalyzer, ReferenceType, SubstitutionErrorType, TOKEN_ERROR, TUPLE_ID, TokenID, TypeClass, TypeID, TypificationGraph, ValueClass, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, findByUid, flattenAst, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
24
+ export { AccessPolicy, AnyTypificationT, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EmptySetT, EvalStatus, FolderNode, FolderTree, Grammeme, Graph, LibraryItemType, LocationHead, LogicT, NodeType, OperationType, RSCalculator, RSDiagnosticCode, RSEngine, RSErrorCode, RSLangAnalyzer, ReferenceType, SubstitutionErrorType, TOKEN_ERROR, TUPLE_ID, TokenID, TypeClass, TypeID, TypificationGraph, ValueClass, applyAsciiTypeSubstitutions, applyHash_fnv1a, assignSchemaDiagnostics, buildTree, detectDependencyCycleDiagnostics, findByUid, flattenAst, formatDependencyCycle, generateStub, getNodeIndices, getNodeText, hasCstDiagnostic, makeTypePath, makeValuePath, modelStatusCstDiagnostic, parseTypeText, printAst, printTree, printValue, readErrorAnnotation, readTypeAnnotation, parser as rslangParser, supportedGrammemes, visitAstDFS };
@@ -1,2 +1,2 @@
1
- import { a as hasCstDiagnostic, i as assignSchemaDiagnostics, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, t as CstDiagnostic } from "../diagnostics-Clo3mkba.js";
2
- export { CstDiagnostic, DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic };
1
+ import { a as detectDependencyCycleDiagnostics, c as modelStatusCstDiagnostic, i as assignSchemaDiagnostics, n as DiagnosticKind, o as formatDependencyCycle, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic } from "../diagnostics-EaIt3zIw.js";
2
+ export { CstDiagnostic, DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic };
@@ -1,2 +1,2 @@
1
- import { a as modelStatusCstDiagnostic, i as hasCstDiagnostic, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind } from "../diagnostics-D7SiHAwW.js";
2
- export { DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic };
1
+ import { a as formatDependencyCycle, i as detectDependencyCycleDiagnostics, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind } from "../diagnostics-CY9sKggB.js";
2
+ export { DiagnosticKind, RSDiagnosticCode, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic };
@@ -1,5 +1,5 @@
1
1
  import { a as LibraryItemType, i as LibraryItemReference, n as CurrentVersion, o as LocationHead, r as LibraryItem, s as VersionInfo, t as AccessPolicy } from "../library-CYun28Xz.js";
2
- import { C as TypeInfo, S as Substitution, _ as CstClass, a as hasCstDiagnostic, b as RSForm, c as BasicsContext, d as RSModel, f as RSModelStats, g as Constituenta, h as Attribution, i as assignSchemaDiagnostics, l as DEFAULT_VALUE_TEXT, m as ArgumentValue, n as DiagnosticKind, o as modelStatusCstDiagnostic, r as RSDiagnosticCode, s as BasicBinding, t as CstDiagnostic, u as EvalStatus, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
2
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, a as detectDependencyCycleDiagnostics, b as CstStatus, c as modelStatusCstDiagnostic, d as DEFAULT_VALUE_TEXT, f as EvalStatus, g as ArgumentValue, i as assignSchemaDiagnostics, l as BasicBinding, m as RSModelStats, n as DiagnosticKind, o as formatDependencyCycle, p as RSModel, r as RSDiagnosticCode, s as hasCstDiagnostic, t as CstDiagnostic, u as BasicsContext, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "../diagnostics-EaIt3zIw.js";
3
3
  import { FolderNode, FolderTree } from "./folder-tree.js";
4
4
  import { n as OssLayout, r as Position2D } from "../oss-layout-3glgAqfn.js";
5
5
  import { Block, CstSubstituteInfo, NodeType, Operation, OperationInput, OperationSchema, OperationSchemaStats, OperationSynthesis, OperationType, OssItem, SubstitutionErrorDescription, SubstitutionErrorType } from "./oss.js";
@@ -99,5 +99,5 @@ declare class TemplateInstantiationPlanner {
99
99
  private collectDependencies;
100
100
  }
101
101
  //#endregion
102
- export { AccessPolicy, type ArgumentValue, type Attribution, type BasicBinding, type BasicsContext, type Block, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSDiagnosticCode, RSEngine, type RSForm, type RSFormStats, type RSModel, type RSModelStats, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type TemplateBindingConflict, type TemplateInstantiationInput, type TemplateInstantiationItem, type TemplateInstantiationPlan, TemplateInstantiationPlanner, type TypeInfo, type VersionInfo, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
102
+ export { AccessPolicy, type ArgumentValue, type Attribution, type BasicBinding, type BasicsContext, type Block, type Constituenta, CstClass, type CstDiagnostic, CstStatus, type CstSubstituteInfo, CstType, type CurrentVersion, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, type LibraryItem, type LibraryItemReference, LibraryItemType, LocationHead, NodeType, type Operation, type OperationInput, type OperationSchema, type OperationSchemaStats, type OperationSynthesis, OperationType, type OssItem, type OssLayout, type Position2D, RSDiagnosticCode, RSEngine, type RSForm, type RSFormStats, type RSModel, type RSModelStats, type Substitution, type SubstitutionErrorDescription, SubstitutionErrorType, type TemplateBindingConflict, type TemplateInstantiationInput, type TemplateInstantiationItem, type TemplateInstantiationPlan, TemplateInstantiationPlanner, type TypeInfo, type VersionInfo, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
103
103
  //# sourceMappingURL=index.d.ts.map
@@ -5,7 +5,7 @@ import { TypeID } from "../rslang/semantic/typification.js";
5
5
  import { labelType } from "../rslang/labels.js";
6
6
  import { applyAliasMapping, isGlobalAlias, parseRSLangExpression, splitTemplateDefinition, substituteLocalAliases, substituteTemplateArgs } from "../rslang/api.js";
7
7
  import { CstClass, CstStatus, CstType } from "./rsform.js";
8
- import { D as isFunctional, a as modelStatusCstDiagnostic, c as applyMappingToConstituents, h as generateAlias, i as hasCstDiagnostic, j as normalizeExpression, l as argumentValuesToMapping, n as RSDiagnosticCode, r as assignSchemaDiagnostics, t as DiagnosticKind, w as inferTemplatedType } from "../diagnostics-D7SiHAwW.js";
8
+ import { E as inferTemplatedType, N as normalizeExpression, _ as generateAlias, a as formatDependencyCycle, d as argumentValuesToMapping, i as detectDependencyCycleDiagnostics, k as isFunctional, n as RSDiagnosticCode, o as hasCstDiagnostic, r as assignSchemaDiagnostics, s as modelStatusCstDiagnostic, t as DiagnosticKind, u as applyMappingToConstituents } from "../diagnostics-CY9sKggB.js";
9
9
  import { DEFAULT_VALUE_TEXT, EvalStatus } from "./rsmodel.js";
10
10
  import { FolderNode, FolderTree } from "./folder-tree.js";
11
11
  import { AccessPolicy, LibraryItemType, LocationHead } from "./library.js";
@@ -284,6 +284,6 @@ function topologicalSort(aliases, refs) {
284
284
  return sorted;
285
285
  }
286
286
  //#endregion
287
- export { AccessPolicy, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, LibraryItemType, LocationHead, NodeType, OperationType, RSDiagnosticCode, RSEngine, SubstitutionErrorType, TemplateInstantiationPlanner, assignSchemaDiagnostics, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
287
+ export { AccessPolicy, CstClass, CstStatus, CstType, DEFAULT_VALUE_TEXT, DiagnosticKind, EvalStatus, FolderNode, FolderTree, LibraryItemType, LocationHead, NodeType, OperationType, RSDiagnosticCode, RSEngine, SubstitutionErrorType, TemplateInstantiationPlanner, assignSchemaDiagnostics, detectDependencyCycleDiagnostics, formatDependencyCycle, hasCstDiagnostic, modelStatusCstDiagnostic, planTemplateInstantiation };
288
288
 
289
289
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
1
  import { r as LibraryItem } from "../library-CYun28Xz.js";
2
- import { S as Substitution, b as RSForm, g as Constituenta } from "../diagnostics-Clo3mkba.js";
2
+ import { S as RSForm, v as Constituenta, w as Substitution } from "../diagnostics-EaIt3zIw.js";
3
3
  import { NodeType, OperationSchema, SubstitutionErrorDescription } from "./oss.js";
4
4
 
5
5
  //#region src/library/oss-api.d.ts
@@ -1,4 +1,4 @@
1
- import { t as Graph } from "../graph-DR8rL2o3.js";
1
+ import { t as Graph } from "../graph-CL73WdW1.js";
2
2
  import { r as LibraryItem } from "../library-CYun28Xz.js";
3
3
  import { n as OssLayout, t as NodePosition } from "../oss-layout-3glgAqfn.js";
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { t as AstNode } from "../ast-C8sIpKdL.js";
2
2
  import { l as Value } from "../value-BduA_ZGp.js";
3
- import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../calculator-k8BGIKmj.js";
4
- import { b as RSForm, c as BasicsContext, d as RSModel, s as BasicBinding, u as EvalStatus, y as CstType } from "../diagnostics-Clo3mkba.js";
3
+ import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../calculator-DE89LtIM.js";
4
+ import { S as RSForm, f as EvalStatus, l as BasicBinding, p as RSModel, u as BasicsContext, x as CstType } from "../diagnostics-EaIt3zIw.js";
5
5
 
6
6
  //#region src/library/rsengine.d.ts
7
7
  /** Services for {@link RSEngine}. */
@@ -4,7 +4,7 @@ import { l as compare } from "../value-COprb2Je.js";
4
4
  import { RSCalculator } from "../rslang/eval/calculator.js";
5
5
  import "../rslang/index.js";
6
6
  import { CstType } from "./rsform.js";
7
- import { D as isFunctional, E as isBasicConcept, T as isBaseSet, g as getAnalysisFor } from "../diagnostics-D7SiHAwW.js";
7
+ import { D as isBaseSet, O as isBasicConcept, k as isFunctional, v as getAnalysisFor } from "../diagnostics-CY9sKggB.js";
8
8
  import { TYPE_BASIC } from "./rsmodel.js";
9
9
  import { inferEvalStatus, isInferrable, tryFixValue } from "./rsmodel-api.js";
10
10
  //#region src/library/rsengine.ts
@@ -1,9 +1,9 @@
1
1
  import { t as AstNode } from "../ast-C8sIpKdL.js";
2
2
  import { g as TypeClass, y as TypePath } from "../typification-9lNu9R4k.js";
3
3
  import { t as ValueClass } from "../value-class-CNI-lqXJ.js";
4
- import { r as AnalysisFull } from "../analyzer-iqAXyROE.js";
4
+ import { r as AnalysisFull } from "../analyzer-fNhkwO-6.js";
5
5
  import { r as LibraryItem } from "../library-CYun28Xz.js";
6
- import { _ as CstClass, b as RSForm, g as Constituenta, m as ArgumentValue, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
6
+ import { C as RSFormStats, S as RSForm, b as CstStatus, g as ArgumentValue, v as Constituenta, x as CstType, y as CstClass } from "../diagnostics-EaIt3zIw.js";
7
7
  import { AliasMapping } from "../rslang/api.js";
8
8
 
9
9
  //#region src/library/rsform-api.d.ts
@@ -80,8 +80,18 @@ declare function addAliasReference(expression: string, alias: string): string;
80
80
  declare function typeClassForCstType(cstType: CstType): TypeClass;
81
81
  /** Checks whether a constituenta type supports formal definitions. */
82
82
  declare function canHaveFormalDefinition(cstType: CstType): boolean;
83
- /** Analyze expression for {@link RSForm}. */
84
83
  declare function getAnalysisFor(expression: string, cstType: CstType, schema: RSForm, alias?: string): AnalysisFull;
84
+ /**
85
+ * When an untyped / bare F·P reference names a constituent on a definition cycle with the
86
+ * current expression, replace that error with {@link RSDiagnosticCode.schemaDependencyCycle}.
87
+ *
88
+ * Covers both semantic `globalNotTyped` (e.g. `F3[σ]`) and parser `globalFuncWithoutArgs`
89
+ * (bare `P1` / `F1` treated as a call without arguments).
90
+ *
91
+ * Uses a draft dependency graph: incoming edges of the edited constituent are taken from
92
+ * `expression`, so Check works before Save.
93
+ */
94
+ declare function refineAnalysisForDependencyCycles(analysis: AnalysisFull, expression: string, schema: RSForm, alias?: string): AnalysisFull;
85
95
  /** Calculate statistics for {@link RSForm}. */
86
96
  declare function calculateSchemaStats(target: RSForm): RSFormStats;
87
97
  /** Finds {@link Constituenta} by structure path. */
@@ -89,5 +99,5 @@ declare function findCstByStructure(schema: RSForm, target: Constituenta, path:
89
99
  /** Retrieves name for piece of target {@link Constituenta} structure. */
90
100
  declare function getStructureName(schema: RSForm, target: Constituenta, path: TypePath): string;
91
101
  //#endregion
92
- export { ConstituentaMappableFields, addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
102
+ export { ConstituentaMappableFields, addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, refineAnalysisForDependencyCycles, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
93
103
  //# sourceMappingURL=rsform-api.d.ts.map
@@ -1,2 +1,2 @@
1
- import { A as isTemplateCst, C as inferTemplate, D as isFunctional, E as isBasicConcept, F as validateAliasFormat, I as validateNewAlias, M as removeAliasReference, N as sortItemsForInlineSynthesis, O as isLogical, P as typeClassForCstType, S as inferStatus, T as isBaseSet, _ as getCstTypePrefix, b as inferClass, c as applyMappingToConstituents, d as canHaveFormalDefinition, f as canHaveManualTypification, g as getAnalysisFor, h as generateAlias, j as normalizeExpression, k as isSchemaIssue, l as argumentValuesToMapping, m as findCstByStructure, o as addAliasReference, p as canProduceStructure, s as applyFilterCategory, u as calculateSchemaStats, v as getStructureName, w as inferTemplatedType, x as inferNewSpawnPosition, y as guessCstType } from "../diagnostics-D7SiHAwW.js";
2
- export { addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
1
+ import { A as isLogical, C as inferNewSpawnPosition, D as isBaseSet, E as inferTemplatedType, F as removeAliasReference, I as sortItemsForInlineSynthesis, L as typeClassForCstType, M as isTemplateCst, N as normalizeExpression, O as isBasicConcept, P as refineAnalysisForDependencyCycles, R as validateAliasFormat, S as inferClass, T as inferTemplate, _ as generateAlias, b as getStructureName, c as addAliasReference, d as argumentValuesToMapping, f as calculateSchemaStats, g as findCstByStructure, h as canProduceStructure, j as isSchemaIssue, k as isFunctional, l as applyFilterCategory, m as canHaveManualTypification, p as canHaveFormalDefinition, u as applyMappingToConstituents, v as getAnalysisFor, w as inferStatus, x as guessCstType, y as getCstTypePrefix, z as validateNewAlias } from "../diagnostics-CY9sKggB.js";
2
+ export { addAliasReference, applyFilterCategory, applyMappingToConstituents, argumentValuesToMapping, calculateSchemaStats, canHaveFormalDefinition, canHaveManualTypification, canProduceStructure, findCstByStructure, generateAlias, getAnalysisFor, getCstTypePrefix, getStructureName, guessCstType, inferClass, inferNewSpawnPosition, inferStatus, inferTemplate, inferTemplatedType, isBaseSet, isBasicConcept, isFunctional, isLogical, isSchemaIssue, isTemplateCst, normalizeExpression, refineAnalysisForDependencyCycles, removeAliasReference, sortItemsForInlineSynthesis, typeClassForCstType, validateAliasFormat, validateNewAlias };
@@ -1,2 +1,2 @@
1
- import { C as TypeInfo, S as Substitution, _ as CstClass, b as RSForm, g as Constituenta, h as Attribution, m as ArgumentValue, v as CstStatus, x as RSFormStats, y as CstType } from "../diagnostics-Clo3mkba.js";
1
+ import { C as RSFormStats, S as RSForm, T as TypeInfo, _ as Attribution, b as CstStatus, g as ArgumentValue, v as Constituenta, w as Substitution, x as CstType, y as CstClass } from "../diagnostics-EaIt3zIw.js";
2
2
  export { ArgumentValue, Attribution, Constituenta, CstClass, CstStatus, CstType, RSForm, RSFormStats, Substitution, TypeInfo };
@@ -1,6 +1,6 @@
1
1
  import { b as Typification, f as ExpressionType } from "../typification-9lNu9R4k.js";
2
2
  import { d as ValuePath, l as Value } from "../value-BduA_ZGp.js";
3
- import { b as RSForm, f as RSModelStats, g as Constituenta, s as BasicBinding, u as EvalStatus, y as CstType } from "../diagnostics-Clo3mkba.js";
3
+ import { S as RSForm, f as EvalStatus, l as BasicBinding, m as RSModelStats, v as Constituenta, x as CstType } from "../diagnostics-EaIt3zIw.js";
4
4
  import { RSEngine } from "./rsengine.js";
5
5
 
6
6
  //#region src/library/rsmodel-api.d.ts
@@ -2,7 +2,7 @@ import { TypeID } from "../rslang/semantic/typification.js";
2
2
  import { O as setNestedValue, _ as extractValue, b as isTupleValue, f as tuple, l as compare, x as makeDefaultValue } from "../value-COprb2Je.js";
3
3
  import "../rslang/index.js";
4
4
  import { CstType } from "./rsform.js";
5
- import { E as isBasicConcept, T as isBaseSet, a as modelStatusCstDiagnostic, u as calculateSchemaStats } from "../diagnostics-D7SiHAwW.js";
5
+ import { D as isBaseSet, O as isBasicConcept, f as calculateSchemaStats, s as modelStatusCstDiagnostic } from "../diagnostics-CY9sKggB.js";
6
6
  import { EvalStatus } from "./rsmodel.js";
7
7
  //#region src/library/rsmodel-api.ts
8
8
  const RANDOM_INTEGER_MIN = -100;
@@ -1,2 +1,2 @@
1
- import { c as BasicsContext, d as RSModel, f as RSModelStats, l as DEFAULT_VALUE_TEXT, p as TYPE_BASIC, s as BasicBinding, u as EvalStatus } from "../diagnostics-Clo3mkba.js";
1
+ import { d as DEFAULT_VALUE_TEXT, f as EvalStatus, h as TYPE_BASIC, l as BasicBinding, m as RSModelStats, p as RSModel, u as BasicsContext } from "../diagnostics-EaIt3zIw.js";
2
2
  export { BasicBinding, BasicsContext, DEFAULT_VALUE_TEXT, EvalStatus, RSModel, RSModelStats, TYPE_BASIC };
@@ -1,5 +1,5 @@
1
1
  import { b as Typification, y as TypePath } from "../typification-9lNu9R4k.js";
2
- import { b as RSForm, g as Constituenta } from "../diagnostics-Clo3mkba.js";
2
+ import { S as RSForm, v as Constituenta } from "../diagnostics-EaIt3zIw.js";
3
3
 
4
4
  //#region src/library/structure-planner.d.ts
5
5
  /** Represents a node in the structure planner. */
@@ -3,7 +3,7 @@ import { labelType } from "../rslang/labels.js";
3
3
  import { splitTemplateDefinition } from "../rslang/api.js";
4
4
  import "../rslang/index.js";
5
5
  import { CstType } from "./rsform.js";
6
- import { m as findCstByStructure } from "../diagnostics-D7SiHAwW.js";
6
+ import { g as findCstByStructure } from "../diagnostics-CY9sKggB.js";
7
7
  //#region src/library/structure-planner.ts
8
8
  /** Structure planner for {@link Constituenta}. */
9
9
  var StructurePlanner = class {
@@ -1,2 +1,2 @@
1
- import { i as readTypeAnnotation, n as annotateType, r as readErrorAnnotation, t as annotateError } from "../ast-annotations-D6KZDu12.js";
1
+ import { i as readTypeAnnotation, n as annotateType, r as readErrorAnnotation, t as annotateError } from "../ast-annotations-CiIx8qBM.js";
2
2
  export { annotateError, annotateType, readErrorAnnotation, readTypeAnnotation };
@@ -1,2 +1,2 @@
1
- import { a as RSErrorInfo, i as RSErrorDescription, n as RSErrorClass, o as getRSErrorPrefix, r as RSErrorCode, s as isCritical, t as ErrorReporter } from "../error-CzIbnP-N.js";
1
+ import { a as RSErrorInfo, i as RSErrorDescription, n as RSErrorClass, o as getRSErrorPrefix, r as RSErrorCode, s as isCritical, t as ErrorReporter } from "../error-B0EkIx4K.js";
2
2
  export { ErrorReporter, RSErrorClass, RSErrorCode, RSErrorDescription, RSErrorInfo, getRSErrorPrefix, isCritical };
@@ -84,7 +84,8 @@ const RSErrorCode = {
84
84
  calculationNotSupported: 33031,
85
85
  calcInvalidData: 33032,
86
86
  cstEmptyDerived: 34913,
87
- definitionNotAllowed: 34914
87
+ definitionNotAllowed: 34914,
88
+ schemaDependencyCycle: 35078
88
89
  };
89
90
  const ERROR_EVALUATION_MASK = 256;
90
91
  const ERROR_LEXER_MASK = 512;
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","names":[],"sources":["../../src/rslang/error.ts"],"sourcesContent":["/** Module: Error types and functions. */\n\n/** Represents error class. */\nexport const RSErrorClass = {\n LEXER: 0,\n PARSER: 1,\n SEMANTIC: 2,\n EVALUATION: 3,\n UNKNOWN: 4\n} as const;\nexport type RSErrorClass = (typeof RSErrorClass)[keyof typeof RSErrorClass];\n\n/** Represents RSLang expression error information. */\nexport interface RSErrorInfo {\n code: RSErrorCode;\n params?: readonly string[];\n}\n\n/** Represents RSLang expression error description. */\nexport interface RSErrorDescription extends RSErrorInfo {\n from: number;\n to: number;\n}\n\n/** Error reporter function type. */\nexport type ErrorReporter = (error: RSErrorDescription) => void;\n\n/** Represents RSLang expression error types. */\nexport const RSErrorCode = {\n unknownSyntax: 0x8400, // 33792\n forbiddenCharacter: 0x8401, // 33793\n bracketMismatch: 0x8409, // 33801\n doubleParenthesis: 0x840a, // 33802\n missingOpenBracket: 0x840b, // 33803\n missingCloseBracket: 0x840c, // 33804\n invalidFilterSyntax: 0x8417, // 33815\n expectedFunctionBody: 0x8418, // 33816\n expectedExpressionBody: 0x8419, // 33817\n expectedLogicBody: 0x841a, // 33818\n expectedQuantifierBody: 0x841b, // 33819\n expectedDeclarativeBody: 0x841c, // 33820\n expectedImperativeBody: 0x841d, // 33821\n expectedRecursiveBody: 0x841e, // 33822\n expectedQuantifierDomain: 0x841f, // 33823\n expectedRightOperand: 0x8420, // 33824\n expectedUnaryOperand: 0x8421, // 33825\n globalFuncParenCall: 0x8422, // 33826\n expectedArgument: 0x8423, // 33827\n expectedLocal: 0x8415, // 33813\n expectedType: 0x8416, // 33814\n\n localNotUsed: 0x2802, // 10242\n\n localUndeclared: 0x8801, // 34817\n localShadowing: 0x8802, // 34818\n localDoubleDeclare: 0x8803, // 34819\n\n typesNotEqual: 0x880a, // 34826\n globalNotTyped: 0x8804, // 34820\n invalidDecart: 0x8805, // 34821\n invalidBoolean: 0x8806, // 34822\n invalidTypeOperation: 0x8807, // 34823\n invalidCard: 0x8808, // 34824\n invalidDebool: 0x8809, // 34825\n globalFuncWithoutArgs: 0x880b, // 34827\n invalidReduce: 0x8810, // 34832\n invalidEnumeration: 0x8813, // 34835\n projectionSetArgumentNotSet: 0x8830, // 34864\n projectionSetArgumentNotTupleSet: 0x8831, // 34865\n projectionSetIndexOutOfRange: 0x8832, // 34866\n projectionTupleArgumentNotTuple: 0x8833, // 34867\n projectionTupleIndexOutOfRange: 0x8834, // 34868\n invalidCortegeDeclare: 0x8814, // 34836\n localOutOfScope: 0x8815, // 34837\n invalidElementPredicate: 0x8816, // 34838\n invalidEmptySetUsage: 0x8817, // 34839\n invalidArgsArity: 0x8818, // 34840\n invalidArgumentType: 0x8819, // 34841\n globalStructure: 0x881c, // 34844\n radicalUsage: 0x8821, // 34849\n invalidFilterArgumentType: 0x8822, // 34850\n invalidFilterArity: 0x8823, // 34851\n arithmeticNotSupported: 0x8824, // 34852\n typesNotCompatible: 0x8825, // 34853\n orderingNotSupported: 0x8826, // 34854\n expectedLogic: 0x8827, // 34855\n expectedSetexpr: 0x8828, // 34856\n invalidArgumentCortegeDeclare: 0x8829, // 34857\n invalidQuantifierDomain: 0x882a, // 34858\n invalidFilterParameterType: 0x882b, // 34859\n invalidFilterIndex: 0x882c, // 34860\n invalidFilterBooleanEchelon: 0x882d, // 34861\n localOutOfScopeParentheses: 0x882e, // 34862\n localUndeclaredInSubexpr: 0x882f, // 34863\n\n globalNoValue: 0x8840, // 34880\n invalidPropertyUsage: 0x8841, // 34881\n\n // Value evaluation (runtime)\n calcUnknownError: 0x8100, // 35328\n setOverflow: 0x8101, // 35329\n booleanBaseLimit: 0x8102, // 35330\n calcGlobalMissing: 0x8103, // 35331\n iterationsLimit: 0x8104, // 35332\n calcInvalidDebool: 0x8105, // 35333\n iterateInfinity: 0x8106, // 35334\n calculationNotSupported: 0x8107, // 35335\n calcInvalidData: 0x8108, // 35336\n\n cstEmptyDerived: 0x8861, // 34913\n definitionNotAllowed: 0x8862 // 34914\n} as const;\nexport type RSErrorCode = (typeof RSErrorCode)[keyof typeof RSErrorCode];\n\nconst ERROR_EVALUATION_MASK = 0x0100;\nconst ERROR_LEXER_MASK = 0x0200;\nconst ERROR_PARSER_MASK = 0x0400;\nconst ERROR_SEMANTIC_MASK = 0x0800;\n\n/** Infers error class from error type (code). */\nfunction inferErrorClass(error: RSErrorCode): RSErrorClass {\n if ((error & ERROR_EVALUATION_MASK) !== 0) {\n return RSErrorClass.EVALUATION;\n } else if ((error & ERROR_LEXER_MASK) !== 0) {\n return RSErrorClass.LEXER;\n } else if ((error & ERROR_PARSER_MASK) !== 0) {\n return RSErrorClass.PARSER;\n } else if ((error & ERROR_SEMANTIC_MASK) !== 0) {\n return RSErrorClass.SEMANTIC;\n } else {\n return RSErrorClass.UNKNOWN;\n }\n}\n\n/** Generate ErrorID label. */\nexport function getRSErrorPrefix(code: RSErrorCode): string {\n const id = code.toString(16).toUpperCase();\n // prettier-ignore\n switch (inferErrorClass(code)) {\n case RSErrorClass.LEXER: return 'L' + id;\n case RSErrorClass.PARSER: return 'P' + id;\n case RSErrorClass.SEMANTIC: return 'S' + id;\n case RSErrorClass.EVALUATION: return 'E' + id;\n case RSErrorClass.UNKNOWN: return 'U' + id;\n }\n}\n\n/** Checks if error is critical. */\nexport function isCritical(code: RSErrorCode): boolean {\n if ((code & 0xf000) === 0x2000) {\n return false;\n }\n return true;\n}\n"],"mappings":";;;AAGA,MAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,UAAU;CACV,YAAY;CACZ,SAAS;AACX;;AAmBA,MAAa,cAAc;CACzB,eAAe;CACf,oBAAoB;CACpB,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,sBAAsB;CACtB,wBAAwB;CACxB,mBAAmB;CACnB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,uBAAuB;CACvB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,qBAAqB;CACrB,kBAAkB;CAClB,eAAe;CACf,cAAc;CAEd,cAAc;CAEd,iBAAiB;CACjB,gBAAgB;CAChB,oBAAoB;CAEpB,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,sBAAsB;CACtB,aAAa;CACb,eAAe;CACf,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,6BAA6B;CAC7B,kCAAkC;CAClC,8BAA8B;CAC9B,iCAAiC;CACjC,gCAAgC;CAChC,uBAAuB;CACvB,iBAAiB;CACjB,yBAAyB;CACzB,sBAAsB;CACtB,kBAAkB;CAClB,qBAAqB;CACrB,iBAAiB;CACjB,cAAc;CACd,2BAA2B;CAC3B,oBAAoB;CACpB,wBAAwB;CACxB,oBAAoB;CACpB,sBAAsB;CACtB,eAAe;CACf,iBAAiB;CACjB,+BAA+B;CAC/B,yBAAyB;CACzB,4BAA4B;CAC5B,oBAAoB;CACpB,6BAA6B;CAC7B,4BAA4B;CAC5B,0BAA0B;CAE1B,eAAe;CACf,sBAAsB;CAGtB,kBAAkB;CAClB,aAAa;CACb,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,mBAAmB;CACnB,iBAAiB;CACjB,yBAAyB;CACzB,iBAAiB;CAEjB,iBAAiB;CACjB,sBAAsB;AACxB;AAGA,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;;AAG5B,SAAS,gBAAgB,OAAkC;CACzD,KAAK,QAAQ,2BAA2B,GACtC,OAAO,aAAa;MACf,KAAK,QAAQ,sBAAsB,GACxC,OAAO,aAAa;MACf,KAAK,QAAQ,uBAAuB,GACzC,OAAO,aAAa;MACf,KAAK,QAAQ,yBAAyB,GAC3C,OAAO,aAAa;MAEpB,OAAO,aAAa;AAExB;;AAGA,SAAgB,iBAAiB,MAA2B;CAC1D,MAAM,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY;CAEzC,QAAQ,gBAAgB,IAAI,GAA5B;EACE,KAAK,aAAa,OAAO,OAAO,MAAM;EACtC,KAAK,aAAa,QAAQ,OAAO,MAAM;EACvC,KAAK,aAAa,UAAU,OAAO,MAAM;EACzC,KAAK,aAAa,YAAY,OAAO,MAAM;EAC3C,KAAK,aAAa,SAAS,OAAO,MAAM;CAC1C;AACF;;AAGA,SAAgB,WAAW,MAA4B;CACrD,KAAK,OAAO,WAAY,MACtB,OAAO;CAET,OAAO;AACT"}
1
+ {"version":3,"file":"error.js","names":[],"sources":["../../src/rslang/error.ts"],"sourcesContent":["/** Module: Error types and functions. */\n\n/** Represents error class. */\nexport const RSErrorClass = {\n LEXER: 0,\n PARSER: 1,\n SEMANTIC: 2,\n EVALUATION: 3,\n UNKNOWN: 4\n} as const;\nexport type RSErrorClass = (typeof RSErrorClass)[keyof typeof RSErrorClass];\n\n/** Represents RSLang expression error information. */\nexport interface RSErrorInfo {\n code: RSErrorCode;\n params?: readonly string[];\n}\n\n/** Represents RSLang expression error description. */\nexport interface RSErrorDescription extends RSErrorInfo {\n from: number;\n to: number;\n}\n\n/** Error reporter function type. */\nexport type ErrorReporter = (error: RSErrorDescription) => void;\n\n/** Represents RSLang expression error types. */\nexport const RSErrorCode = {\n unknownSyntax: 0x8400, // 33792\n forbiddenCharacter: 0x8401, // 33793\n bracketMismatch: 0x8409, // 33801\n doubleParenthesis: 0x840a, // 33802\n missingOpenBracket: 0x840b, // 33803\n missingCloseBracket: 0x840c, // 33804\n invalidFilterSyntax: 0x8417, // 33815\n expectedFunctionBody: 0x8418, // 33816\n expectedExpressionBody: 0x8419, // 33817\n expectedLogicBody: 0x841a, // 33818\n expectedQuantifierBody: 0x841b, // 33819\n expectedDeclarativeBody: 0x841c, // 33820\n expectedImperativeBody: 0x841d, // 33821\n expectedRecursiveBody: 0x841e, // 33822\n expectedQuantifierDomain: 0x841f, // 33823\n expectedRightOperand: 0x8420, // 33824\n expectedUnaryOperand: 0x8421, // 33825\n globalFuncParenCall: 0x8422, // 33826\n expectedArgument: 0x8423, // 33827\n expectedLocal: 0x8415, // 33813\n expectedType: 0x8416, // 33814\n\n localNotUsed: 0x2802, // 10242\n\n localUndeclared: 0x8801, // 34817\n localShadowing: 0x8802, // 34818\n localDoubleDeclare: 0x8803, // 34819\n\n typesNotEqual: 0x880a, // 34826\n globalNotTyped: 0x8804, // 34820\n invalidDecart: 0x8805, // 34821\n invalidBoolean: 0x8806, // 34822\n invalidTypeOperation: 0x8807, // 34823\n invalidCard: 0x8808, // 34824\n invalidDebool: 0x8809, // 34825\n globalFuncWithoutArgs: 0x880b, // 34827\n invalidReduce: 0x8810, // 34832\n invalidEnumeration: 0x8813, // 34835\n projectionSetArgumentNotSet: 0x8830, // 34864\n projectionSetArgumentNotTupleSet: 0x8831, // 34865\n projectionSetIndexOutOfRange: 0x8832, // 34866\n projectionTupleArgumentNotTuple: 0x8833, // 34867\n projectionTupleIndexOutOfRange: 0x8834, // 34868\n invalidCortegeDeclare: 0x8814, // 34836\n localOutOfScope: 0x8815, // 34837\n invalidElementPredicate: 0x8816, // 34838\n invalidEmptySetUsage: 0x8817, // 34839\n invalidArgsArity: 0x8818, // 34840\n invalidArgumentType: 0x8819, // 34841\n globalStructure: 0x881c, // 34844\n radicalUsage: 0x8821, // 34849\n invalidFilterArgumentType: 0x8822, // 34850\n invalidFilterArity: 0x8823, // 34851\n arithmeticNotSupported: 0x8824, // 34852\n typesNotCompatible: 0x8825, // 34853\n orderingNotSupported: 0x8826, // 34854\n expectedLogic: 0x8827, // 34855\n expectedSetexpr: 0x8828, // 34856\n invalidArgumentCortegeDeclare: 0x8829, // 34857\n invalidQuantifierDomain: 0x882a, // 34858\n invalidFilterParameterType: 0x882b, // 34859\n invalidFilterIndex: 0x882c, // 34860\n invalidFilterBooleanEchelon: 0x882d, // 34861\n localOutOfScopeParentheses: 0x882e, // 34862\n localUndeclaredInSubexpr: 0x882f, // 34863\n\n globalNoValue: 0x8840, // 34880\n invalidPropertyUsage: 0x8841, // 34881\n\n // Value evaluation (runtime)\n calcUnknownError: 0x8100, // 35328\n setOverflow: 0x8101, // 35329\n booleanBaseLimit: 0x8102, // 35330\n calcGlobalMissing: 0x8103, // 35331\n iterationsLimit: 0x8104, // 35332\n calcInvalidDebool: 0x8105, // 35333\n iterateInfinity: 0x8106, // 35334\n calculationNotSupported: 0x8107, // 35335\n calcInvalidData: 0x8108, // 35336\n\n cstEmptyDerived: 0x8861, // 34913\n definitionNotAllowed: 0x8862, // 34914\n\n // Schema diagnostics surfaced in expression analysis (same value as RSDiagnosticCode.schemaDependencyCycle).\n schemaDependencyCycle: 0x8906 // 35078\n} as const;\nexport type RSErrorCode = (typeof RSErrorCode)[keyof typeof RSErrorCode];\n\nconst ERROR_EVALUATION_MASK = 0x0100;\nconst ERROR_LEXER_MASK = 0x0200;\nconst ERROR_PARSER_MASK = 0x0400;\nconst ERROR_SEMANTIC_MASK = 0x0800;\n\n/** Infers error class from error type (code). */\nfunction inferErrorClass(error: RSErrorCode): RSErrorClass {\n if ((error & ERROR_EVALUATION_MASK) !== 0) {\n return RSErrorClass.EVALUATION;\n } else if ((error & ERROR_LEXER_MASK) !== 0) {\n return RSErrorClass.LEXER;\n } else if ((error & ERROR_PARSER_MASK) !== 0) {\n return RSErrorClass.PARSER;\n } else if ((error & ERROR_SEMANTIC_MASK) !== 0) {\n return RSErrorClass.SEMANTIC;\n } else {\n return RSErrorClass.UNKNOWN;\n }\n}\n\n/** Generate ErrorID label. */\nexport function getRSErrorPrefix(code: RSErrorCode): string {\n const id = code.toString(16).toUpperCase();\n // prettier-ignore\n switch (inferErrorClass(code)) {\n case RSErrorClass.LEXER: return 'L' + id;\n case RSErrorClass.PARSER: return 'P' + id;\n case RSErrorClass.SEMANTIC: return 'S' + id;\n case RSErrorClass.EVALUATION: return 'E' + id;\n case RSErrorClass.UNKNOWN: return 'U' + id;\n }\n}\n\n/** Checks if error is critical. */\nexport function isCritical(code: RSErrorCode): boolean {\n if ((code & 0xf000) === 0x2000) {\n return false;\n }\n return true;\n}\n"],"mappings":";;;AAGA,MAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,UAAU;CACV,YAAY;CACZ,SAAS;AACX;;AAmBA,MAAa,cAAc;CACzB,eAAe;CACf,oBAAoB;CACpB,iBAAiB;CACjB,mBAAmB;CACnB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,sBAAsB;CACtB,wBAAwB;CACxB,mBAAmB;CACnB,wBAAwB;CACxB,yBAAyB;CACzB,wBAAwB;CACxB,uBAAuB;CACvB,0BAA0B;CAC1B,sBAAsB;CACtB,sBAAsB;CACtB,qBAAqB;CACrB,kBAAkB;CAClB,eAAe;CACf,cAAc;CAEd,cAAc;CAEd,iBAAiB;CACjB,gBAAgB;CAChB,oBAAoB;CAEpB,eAAe;CACf,gBAAgB;CAChB,eAAe;CACf,gBAAgB;CAChB,sBAAsB;CACtB,aAAa;CACb,eAAe;CACf,uBAAuB;CACvB,eAAe;CACf,oBAAoB;CACpB,6BAA6B;CAC7B,kCAAkC;CAClC,8BAA8B;CAC9B,iCAAiC;CACjC,gCAAgC;CAChC,uBAAuB;CACvB,iBAAiB;CACjB,yBAAyB;CACzB,sBAAsB;CACtB,kBAAkB;CAClB,qBAAqB;CACrB,iBAAiB;CACjB,cAAc;CACd,2BAA2B;CAC3B,oBAAoB;CACpB,wBAAwB;CACxB,oBAAoB;CACpB,sBAAsB;CACtB,eAAe;CACf,iBAAiB;CACjB,+BAA+B;CAC/B,yBAAyB;CACzB,4BAA4B;CAC5B,oBAAoB;CACpB,6BAA6B;CAC7B,4BAA4B;CAC5B,0BAA0B;CAE1B,eAAe;CACf,sBAAsB;CAGtB,kBAAkB;CAClB,aAAa;CACb,kBAAkB;CAClB,mBAAmB;CACnB,iBAAiB;CACjB,mBAAmB;CACnB,iBAAiB;CACjB,yBAAyB;CACzB,iBAAiB;CAEjB,iBAAiB;CACjB,sBAAsB;CAGtB,uBAAuB;AACzB;AAGA,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,sBAAsB;;AAG5B,SAAS,gBAAgB,OAAkC;CACzD,KAAK,QAAQ,2BAA2B,GACtC,OAAO,aAAa;MACf,KAAK,QAAQ,sBAAsB,GACxC,OAAO,aAAa;MACf,KAAK,QAAQ,uBAAuB,GACzC,OAAO,aAAa;MACf,KAAK,QAAQ,yBAAyB,GAC3C,OAAO,aAAa;MAEpB,OAAO,aAAa;AAExB;;AAGA,SAAgB,iBAAiB,MAA2B;CAC1D,MAAM,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY;CAEzC,QAAQ,gBAAgB,IAAI,GAA5B;EACE,KAAK,aAAa,OAAO,OAAO,MAAM;EACtC,KAAK,aAAa,QAAQ,OAAO,MAAM;EACvC,KAAK,aAAa,UAAU,OAAO,MAAM;EACzC,KAAK,aAAa,YAAY,OAAO,MAAM;EAC3C,KAAK,aAAa,SAAS,OAAO,MAAM;CAC1C;AACF;;AAGA,SAAgB,WAAW,MAA4B;CACrD,KAAK,OAAO,WAAY,MACtB,OAAO;CAET,OAAO;AACT"}
@@ -1,2 +1,2 @@
1
- import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../../calculator-k8BGIKmj.js";
1
+ import { n as CalculatorResult, r as RSCalculator, t as CalculatorEvaluateOptions } from "../../calculator-DE89LtIM.js";
2
2
  export { CalculatorEvaluateOptions, CalculatorResult, RSCalculator };
@@ -1,5 +1,5 @@
1
1
  import { t as AstNode } from "../../ast-C8sIpKdL.js";
2
- import { t as ErrorReporter } from "../../error-CzIbnP-N.js";
2
+ import { t as ErrorReporter } from "../../error-B0EkIx4K.js";
3
3
  import { l as Value, u as ValueContext } from "../../value-BduA_ZGp.js";
4
4
 
5
5
  //#region src/rslang/eval/evaluator.d.ts