circuitscript 0.1.22 → 0.1.24

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 (57) hide show
  1. package/dist/cjs/BaseVisitor.js +35 -23
  2. package/dist/cjs/BomGeneration.js +167 -0
  3. package/dist/cjs/ComponentMatchConditions.js +116 -0
  4. package/dist/cjs/antlr/CircuitScriptLexer.js +247 -244
  5. package/dist/cjs/antlr/CircuitScriptParser.js +1503 -843
  6. package/dist/cjs/builtinMethods.js +6 -1
  7. package/dist/cjs/execute.js +27 -16
  8. package/dist/cjs/graph.js +10 -9
  9. package/dist/cjs/helpers.js +26 -6
  10. package/dist/cjs/layout.js +14 -13
  11. package/dist/cjs/main.js +17 -1
  12. package/dist/cjs/objects/ExecutionScope.js +3 -0
  13. package/dist/cjs/objects/PinDefinition.js +11 -1
  14. package/dist/cjs/objects/types.js +6 -4
  15. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +81 -0
  16. package/dist/cjs/rules-check/rules.js +74 -0
  17. package/dist/cjs/rules-check/unconnected-pins.js +52 -0
  18. package/dist/cjs/visitor.js +124 -5
  19. package/dist/esm/BaseVisitor.js +35 -23
  20. package/dist/esm/BomGeneration.js +137 -0
  21. package/dist/esm/ComponentMatchConditions.js +109 -0
  22. package/dist/esm/antlr/CircuitScriptLexer.js +247 -244
  23. package/dist/esm/antlr/CircuitScriptParser.js +1498 -842
  24. package/dist/esm/antlr/CircuitScriptVisitor.js +7 -0
  25. package/dist/esm/builtinMethods.js +6 -1
  26. package/dist/esm/execute.js +27 -16
  27. package/dist/esm/graph.js +11 -10
  28. package/dist/esm/helpers.js +26 -6
  29. package/dist/esm/layout.js +15 -13
  30. package/dist/esm/main.js +17 -1
  31. package/dist/esm/objects/ExecutionScope.js +3 -0
  32. package/dist/esm/objects/PinDefinition.js +11 -1
  33. package/dist/esm/objects/types.js +7 -5
  34. package/dist/esm/rules-check/no-connect-on-connected-pin.js +77 -0
  35. package/dist/esm/rules-check/rules.js +70 -0
  36. package/dist/esm/rules-check/unconnected-pins.js +48 -0
  37. package/dist/esm/visitor.js +124 -5
  38. package/dist/libs/std.cst +7 -3
  39. package/dist/types/BomGeneration.d.ts +13 -0
  40. package/dist/types/ComponentMatchConditions.d.ts +19 -0
  41. package/dist/types/antlr/CircuitScriptLexer.d.ts +60 -59
  42. package/dist/types/antlr/CircuitScriptParser.d.ts +148 -63
  43. package/dist/types/antlr/CircuitScriptVisitor.d.ts +14 -0
  44. package/dist/types/execute.d.ts +2 -1
  45. package/dist/types/graph.d.ts +6 -1
  46. package/dist/types/helpers.d.ts +5 -2
  47. package/dist/types/layout.d.ts +3 -2
  48. package/dist/types/objects/ExecutionScope.d.ts +8 -2
  49. package/dist/types/objects/ParamDefinition.d.ts +1 -1
  50. package/dist/types/objects/PinDefinition.d.ts +1 -0
  51. package/dist/types/objects/types.d.ts +4 -2
  52. package/dist/types/rules-check/no-connect-on-connected-pin.d.ts +3 -0
  53. package/dist/types/rules-check/rules.d.ts +15 -0
  54. package/dist/types/rules-check/unconnected-pins.d.ts +2 -0
  55. package/dist/types/visitor.d.ts +10 -1
  56. package/libs/std.cst +7 -3
  57. package/package.json +2 -1
@@ -166,7 +166,12 @@ function toString(obj) {
166
166
  return obj.toDisplayString();
167
167
  }
168
168
  else if (obj.toString) {
169
- return obj.toString();
169
+ if (typeof obj === 'object') {
170
+ return JSON.stringify(obj);
171
+ }
172
+ else {
173
+ return obj.toString();
174
+ }
170
175
  }
171
176
  else {
172
177
  throw "Could not create string from object: " + obj;
@@ -373,9 +373,9 @@ class ExecutionContext {
373
373
  + pinId + ' in ' + component);
374
374
  }
375
375
  this.scope.setCurrent(component, usePinId);
376
- if (!this.scope.hasNet(component, pinId)) {
376
+ if (!this.scope.hasNet(component, usePinId)) {
377
377
  const tmpNet = new Net_js_1.Net(this.netNamespace, this.getUniqueNetName());
378
- this.scope.setNet(component, pinId, tmpNet);
378
+ this.scope.setNet(component, usePinId, tmpNet);
379
379
  }
380
380
  this.scope.clearActive();
381
381
  if (addSequence) {
@@ -497,7 +497,9 @@ class ExecutionContext {
497
497
  const { start_point: [component, pin, wireId] } = stackRef;
498
498
  this.atComponent(component, pin, { addSequence: true });
499
499
  if (wireId !== -1) {
500
- this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump, wireId, 1]);
500
+ const wireObject = this.scope.wires[wireId];
501
+ this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump,
502
+ wireId, PinDefinition_js_1.PinId.from(1), wireObject]);
501
503
  }
502
504
  }
503
505
  else if (blockType === globals_js_1.BlockTypes.Join || blockType === globals_js_1.BlockTypes.Parallel) {
@@ -623,7 +625,7 @@ class ExecutionContext {
623
625
  type: isVariable ? globals_js_1.ReferenceTypes.variable
624
626
  : globals_js_1.ReferenceTypes.instance,
625
627
  found: (tmpReference.value !== undefined),
626
- parentValue: tmpReference.parentValue,
628
+ rootValue: tmpReference.rootValue,
627
629
  value: tmpReference.value,
628
630
  name: idName,
629
631
  trailers,
@@ -637,16 +639,19 @@ class ExecutionContext {
637
639
  });
638
640
  }
639
641
  resolveTrailers(type, item, trailers = []) {
640
- let parentValue;
642
+ let rootValue;
641
643
  let useValue = item;
642
644
  if (trailers.length > 0) {
643
- parentValue = useValue;
645
+ rootValue = useValue;
644
646
  const trailersPath = trailers.join(".");
645
647
  if (type === globals_js_1.ReferenceTypes.variable) {
646
- useValue = parentValue[trailersPath];
648
+ useValue = rootValue;
649
+ trailers.forEach(trailerPath => {
650
+ useValue = useValue[trailerPath];
651
+ });
647
652
  }
648
653
  else if (type === globals_js_1.ReferenceTypes.instance) {
649
- const tmpComponent = parentValue;
654
+ const tmpComponent = rootValue;
650
655
  if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
651
656
  const usedNet = this.scope.getNet(tmpComponent, new PinDefinition_js_1.PinId(1));
652
657
  if (usedNet) {
@@ -655,20 +660,21 @@ class ExecutionContext {
655
660
  }
656
661
  }
657
662
  else {
658
- useValue = parentValue
663
+ useValue = rootValue
659
664
  .parameters.get(trailersPath);
660
665
  }
661
666
  }
662
667
  }
663
668
  let found = false;
664
- if (parentValue !== undefined && useValue !== undefined) {
669
+ if (rootValue !== undefined && useValue !== undefined) {
665
670
  found = true;
666
671
  }
667
672
  return new types_js_1.AnyReference({
668
673
  found,
669
674
  type: type,
670
- parentValue,
675
+ rootValue,
671
676
  trailers,
677
+ trailerIndex: trailers.length,
672
678
  value: useValue,
673
679
  });
674
680
  }
@@ -769,13 +775,16 @@ class ExecutionContext {
769
775
  childScope.sequence.forEach(sequenceAction => {
770
776
  const [action] = sequenceAction;
771
777
  if (action === ExecutionScope_js_1.SequenceAction.Wire) {
772
- const [, innerWireId, segments] = sequenceAction;
773
- this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireIdOffset + innerWireId, segments]);
778
+ const [, innerWireId, segments, wire] = sequenceAction;
779
+ this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireIdOffset + innerWireId,
780
+ segments, wire]);
774
781
  this.scope.wires.push(new Wire_js_1.Wire(segments));
775
782
  }
776
783
  else if (action === ExecutionScope_js_1.SequenceAction.WireJump) {
777
784
  const jumpWireId = wireIdOffset + sequenceAction[1];
778
- this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump, jumpWireId, 1]);
785
+ const wireObject = this.scope.wires[jumpWireId];
786
+ this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump, jumpWireId,
787
+ PinDefinition_js_1.PinId.from(1), wireObject]);
779
788
  }
780
789
  else if (action === ExecutionScope_js_1.SequenceAction.At || action === ExecutionScope_js_1.SequenceAction.To) {
781
790
  this.scope.sequence.push(sequenceAction);
@@ -823,7 +832,8 @@ class ExecutionContext {
823
832
  };
824
833
  });
825
834
  const wireId = this.scope.wires.length;
826
- this.scope.wires.push(new Wire_js_1.Wire(tmp));
835
+ const newWire = new Wire_js_1.Wire(tmp);
836
+ this.scope.wires.push(newWire);
827
837
  const output = [];
828
838
  segments.forEach(item => {
829
839
  const tmpArray = item.map(item2 => {
@@ -838,12 +848,13 @@ class ExecutionContext {
838
848
  });
839
849
  this.log('add wire: ', output.join("|"));
840
850
  this.scope.setActive(ExecutionScope_js_1.ActiveObject.Wire, wireId);
841
- this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireId, tmp]);
851
+ this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireId, tmp, newWire]);
842
852
  this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
843
853
  if (!this.scope.currentComponent.didSetWireOrientationAngle) {
844
854
  this.applyComponentAngleFromWire(this.scope.currentComponent, this.scope.currentPin, true);
845
855
  this.scope.currentComponent.didSetWireOrientationAngle = true;
846
856
  }
857
+ return newWire;
847
858
  }
848
859
  addPoint(pointId, userDefined = true) {
849
860
  if (this.scope.instances.has(pointId)) {
package/dist/cjs/graph.js CHANGED
@@ -106,8 +106,9 @@ class NetGraph {
106
106
  break;
107
107
  }
108
108
  case ExecutionScope_js_1.SequenceAction.Wire: {
109
- const [, wireId, wireSegments] = sequenceStep;
109
+ const [, wireId, , wire] = sequenceStep;
110
110
  let useNet;
111
+ const wireSegments = wire.path;
111
112
  if (previousNode !== null) {
112
113
  const [prevNodeType, prevNodeItem] = graph.node(previousNode);
113
114
  if (prevNodeType === RenderItemType.Component) {
@@ -123,15 +124,15 @@ class NetGraph {
123
124
  useNet = prevNodeItem.net;
124
125
  }
125
126
  }
126
- const wire = new layout_js_1.RenderWire(useNet, (0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), wireSegments);
127
- wire.id = wireId;
128
- wire.netName = useNet.toString();
129
- const wireName = getWireName(wire.id);
130
- graph.setNode(wireName, [RenderItemType.Wire, wire, index]);
127
+ const renderWire = new layout_js_1.RenderWire(useNet, (0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), wireSegments, wire);
128
+ renderWire.id = wireId;
129
+ renderWire.netName = useNet.toString();
130
+ const wireName = getWireName(renderWire.id);
131
+ graph.setNode(wireName, [RenderItemType.Wire, renderWire, index]);
131
132
  let tmpPreviousNode = previousNode;
132
- this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
133
+ this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, PinDefinition_js_1.PinId.from(0), index));
133
134
  previousNode = wireName;
134
- previousPin = 1;
135
+ previousPin = PinDefinition_js_1.PinId.from(1);
135
136
  const wireSegmentsInfo = wireSegments.map(item => {
136
137
  const tmp = {
137
138
  direction: item.direction,
@@ -165,7 +166,7 @@ class NetGraph {
165
166
  wirePin = sequenceStep[2];
166
167
  }
167
168
  previousNode = wireName;
168
- previousPin = wirePin;
169
+ previousPin = PinDefinition_js_1.PinId.from(wirePin);
169
170
  break;
170
171
  }
171
172
  case ExecutionScope_js_1.SequenceAction.Frame: {
@@ -25,6 +25,8 @@ const big_js_1 = __importDefault(require("big.js"));
25
25
  const logger_js_1 = require("./logger.js");
26
26
  const graph_js_1 = require("./graph.js");
27
27
  const RefdesAnnotationVisitor_js_1 = require("./RefdesAnnotationVisitor.js");
28
+ const rules_js_1 = require("./rules-check/rules.js");
29
+ const BomGeneration_js_1 = require("./BomGeneration.js");
28
30
  var JSModuleType;
29
31
  (function (JSModuleType) {
30
32
  JSModuleType["CommonJs"] = "cjs";
@@ -166,7 +168,7 @@ async function renderScript(scriptData, outputPath, options) {
166
168
  }
167
169
  exports.renderScript = renderScript;
168
170
  async function renderScriptCustom(scriptData, outputPath, options, parseHandlers) {
169
- const { dumpNets = false, dumpData = false, showStats = false, environment, inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
171
+ const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, bomOutputPath = undefined, environment, inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
170
172
  const errors = [];
171
173
  const onErrorHandler = (message, context, error) => {
172
174
  if (error && error instanceof utils_js_1.RuntimeExecutionError) {
@@ -220,10 +222,10 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
220
222
  catch (err) {
221
223
  throw new utils_js_1.RenderError(`Error during component annotation: ${err}`, 'annotation');
222
224
  }
223
- const componentLinks = visitor.getComponentCtxLinks();
224
- const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
225
- await refdesVisitor.visitAsync(tree);
226
225
  if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
226
+ const componentLinks = visitor.getComponentCtxLinks();
227
+ const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
228
+ await refdesVisitor.visitAsync(tree);
227
229
  let usePath = inputPath;
228
230
  if (saveAnnotatedCopy === true) {
229
231
  const dir = path_1.default.dirname(inputPath);
@@ -234,6 +236,7 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
234
236
  else if (typeof saveAnnotatedCopy === 'string') {
235
237
  usePath = saveAnnotatedCopy;
236
238
  }
239
+ console.log('Annotations saved to ' + usePath);
237
240
  (0, fs_1.writeFileSync)(usePath, refdesVisitor.getOutput());
238
241
  }
239
242
  if (dumpNets) {
@@ -249,6 +252,14 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
249
252
  if (errors.length === 0) {
250
253
  const { frameComponent } = visitor.applySheetFrameComponent();
251
254
  const { sequence, nets } = visitor.getGraph();
255
+ if (enableBom && bomOutputPath) {
256
+ const documentVariable = visitor.getScope().variables.get('document');
257
+ const bomConfig = documentVariable.bom;
258
+ const bomData = (0, BomGeneration_js_1.generateBom)(bomConfig, visitor.getScope().getInstances());
259
+ const bomCsvOutput = (0, BomGeneration_js_1.generateBomCSV)(bomData);
260
+ await (0, BomGeneration_js_1.saveBomOutputCsv)(bomCsvOutput, bomOutputPath);
261
+ console.log('Generated BOM file', bomOutputPath);
262
+ }
252
263
  const tmpSequence = (0, utils_js_1.generateDebugSequenceAction)(sequence).map(item => (0, utils_js_1.sequenceActionString)(item));
253
264
  dumpData && (0, fs_1.writeFileSync)(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
254
265
  try {
@@ -277,6 +288,15 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
277
288
  try {
278
289
  const { graph, containerFrames } = graphEngine.generateLayoutGraph(sequence, nets);
279
290
  sheetFrames = layoutEngine.runLayout(graph, containerFrames, nets);
291
+ if (enableErc) {
292
+ const ercResults = (0, rules_js_1.EvaluateERCRules)(visitor, graph, nets);
293
+ if (ercResults.length > 0) {
294
+ console.log(`ERC found ${ercResults.length} items:`);
295
+ ercResults.forEach((item, index) => {
296
+ console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
297
+ });
298
+ }
299
+ }
280
300
  }
281
301
  catch (err) {
282
302
  throw new utils_js_1.RenderError(`Error during layout generation: ${err}`, 'layout');
@@ -360,9 +380,9 @@ exports.ParseOutputHandler = ParseOutputHandler;
360
380
  class KiCadNetListOutputHandler extends ParseOutputHandler {
361
381
  constructor() {
362
382
  super(...arguments);
363
- this.afterRender = true;
383
+ this.beforeRender = true;
364
384
  }
365
- parse(visitor, outputPath, fileExtension, extra = null) {
385
+ parse(visitor, outputPath, fileExtension) {
366
386
  if (outputPath !== null && fileExtension === "net") {
367
387
  const { tree: kiCadNetList, missingFootprints } = (0, export_js_1.generateKiCadNetList)(visitor.getNetList());
368
388
  missingFootprints.forEach(entry => {
@@ -56,23 +56,23 @@ class LayoutEngine {
56
56
  const sheetFrameObjects = sheetFrames.map(sheet => {
57
57
  const items = this.flattenFrameItems(sheet);
58
58
  const components = items.filter(item => item instanceof RenderComponent);
59
- const wires = items.filter(item => item instanceof RenderWire);
59
+ const renderWires = items.filter(item => item instanceof RenderWire);
60
60
  const textObjects = items.filter(item => item instanceof RenderText);
61
61
  const frames = items.filter(item => item instanceof RenderFrame);
62
- const wireGroups = new Map();
63
- wires.forEach(wire => {
62
+ const renderWireGroups = new Map();
63
+ renderWires.forEach(wire => {
64
64
  const { netName } = wire;
65
- if (!wireGroups.has(netName)) {
66
- wireGroups.set(netName, []);
65
+ if (!renderWireGroups.has(netName)) {
66
+ renderWireGroups.set(netName, []);
67
67
  }
68
- wireGroups.get(netName).push(wire);
68
+ renderWireGroups.get(netName).push(wire);
69
69
  });
70
- const { junctions, mergedWires } = this.findJunctions(wireGroups, renderNets);
70
+ const { junctions, mergedWires } = this.findJunctions(renderWireGroups, renderNets);
71
71
  return {
72
72
  frame: sheet,
73
73
  frames,
74
74
  components,
75
- wires,
75
+ wires: renderWires,
76
76
  textObjects,
77
77
  junctions,
78
78
  mergedWires
@@ -124,12 +124,12 @@ class LayoutEngine {
124
124
  });
125
125
  return items;
126
126
  }
127
- findJunctions(wireGroups, nets) {
127
+ findJunctions(renderWireGroups, nets) {
128
128
  const junctions = [];
129
129
  const mergedWires = [];
130
130
  const debugSegments = false;
131
- for (const [netName, wires] of wireGroups) {
132
- const allLines = wires.map(wire => {
131
+ for (const [netName, renderWires] of renderWireGroups) {
132
+ const allLines = renderWires.map(wire => {
133
133
  return wire.points.map(pt => {
134
134
  return {
135
135
  x: wire.x.add(pt.x),
@@ -848,7 +848,7 @@ class LayoutEngine {
848
848
  item.y = fromY.sub(pinPosition.y);
849
849
  }
850
850
  else if (item instanceof RenderWire) {
851
- if (pin === 0) {
851
+ if (pin.getValue() === 0) {
852
852
  item.x = fromX;
853
853
  item.y = fromY;
854
854
  }
@@ -1023,7 +1023,7 @@ class RenderObject {
1023
1023
  }
1024
1024
  exports.RenderObject = RenderObject;
1025
1025
  class RenderWire extends RenderObject {
1026
- constructor(net, x, y, segments) {
1026
+ constructor(net, x, y, segments, wire) {
1027
1027
  super();
1028
1028
  this.segments = [];
1029
1029
  this.points = [];
@@ -1031,6 +1031,7 @@ class RenderWire extends RenderObject {
1031
1031
  this.x = x;
1032
1032
  this.y = y;
1033
1033
  this.segments = segments;
1034
+ this.wire = wire;
1034
1035
  this.refreshPoints();
1035
1036
  }
1036
1037
  refreshPoints() {
package/dist/cjs/main.js CHANGED
@@ -26,7 +26,9 @@ async function main() {
26
26
  .option('-n, --dump-nets', 'Dump out net information')
27
27
  .option('-d, --dump-data', 'Dump data during parsing')
28
28
  .option('-s, --stats', 'Show stats during generation')
29
- .option('-x, --skip-output', 'Skip output generation');
29
+ .option('-x, --skip-output', 'Skip output generation')
30
+ .option('-e, --erc', 'Enable ERC output')
31
+ .option('-b, --bom [output-path]', 'Generate Bill of Materials in csv format');
30
32
  commander_1.program.addHelpText('before', figlet_1.default.textSync('circuitscript', {
31
33
  font: 'Small Slant'
32
34
  }));
@@ -39,6 +41,9 @@ async function main() {
39
41
  const watchFileChanges = options.watch;
40
42
  const dumpNets = options.dumpNets;
41
43
  const dumpData = options.dumpData;
44
+ const enableErc = options.erc;
45
+ const enableBom = options.bom !== undefined;
46
+ let bomOutputPath = options.bom;
42
47
  if (options.currentDirectory) {
43
48
  throw "Parameter not supported yet";
44
49
  }
@@ -77,10 +82,21 @@ async function main() {
77
82
  if (options.annotatedPath !== undefined) {
78
83
  saveAnnotatedCopyPath = options.annotatedPath;
79
84
  }
85
+ if (enableBom && (bomOutputPath === true || bomOutputPath === undefined)) {
86
+ if (inputFilePath) {
87
+ bomOutputPath = inputFilePath + '.bom.csv';
88
+ }
89
+ else {
90
+ bomOutputPath = 'output.bom.csv';
91
+ }
92
+ }
80
93
  const scriptOptions = {
81
94
  dumpNets,
82
95
  dumpData,
83
96
  showStats: options.stats,
97
+ enableErc,
98
+ enableBom,
99
+ bomOutputPath,
84
100
  environment: env,
85
101
  inputPath: inputFilePath,
86
102
  updateSource,
@@ -166,6 +166,9 @@ class ExecutionScope {
166
166
  const propertyTree = this.findPropertyKeyTree(visitor);
167
167
  lastHandler && lastHandler(propertyTree, value, valueCtx);
168
168
  }
169
+ getInstances() {
170
+ return Array.from(this.instances.values());
171
+ }
169
172
  }
170
173
  exports.ExecutionScope = ExecutionScope;
171
174
  ExecutionScope.scopeId = 0;
@@ -29,10 +29,20 @@ class PinId {
29
29
  }
30
30
  equals(other) {
31
31
  if (other instanceof PinId) {
32
- return this.value === other.value;
32
+ return this.value === other.value
33
+ && this.getType() === other.getType();
33
34
  }
34
35
  return this.value === other;
35
36
  }
37
+ getHashValue() {
38
+ if (this.type === PinIdType.Int) {
39
+ return 'int-' + this.value;
40
+ }
41
+ else if (this.type === PinIdType.Str) {
42
+ return 'str-' + this.value;
43
+ }
44
+ return '';
45
+ }
36
46
  static from(value) {
37
47
  if (value instanceof ParamDefinition_js_1.NumericValue) {
38
48
  return new PinId(value.toNumber());
@@ -20,6 +20,7 @@ class AnyReference {
20
20
  constructor(refType) {
21
21
  this.found = false;
22
22
  this.trailers = [];
23
+ this.trailerIndex = -1;
23
24
  this.referenceName = 'AnyReference';
24
25
  if (refType.value instanceof AnyReference
25
26
  && refType.value.type !== globals_js_1.ReferenceTypes.function) {
@@ -28,9 +29,10 @@ class AnyReference {
28
29
  this.found = refType.found;
29
30
  this.name = refType.name;
30
31
  this.trailers = refType.trailers;
32
+ this.trailerIndex = refType.trailerIndex;
31
33
  this.type = refType.type ?? globals_js_1.ReferenceTypes.unknown;
32
34
  this.value = refType.value;
33
- this.parentValue = refType.parentValue;
35
+ this.rootValue = refType.rootValue;
34
36
  }
35
37
  toString() {
36
38
  return `[${this.referenceName} name: ${this.name} trailers:${this.trailers} found: ${this.found}]`;
@@ -65,13 +67,13 @@ class DeclaredReference extends AnyReference {
65
67
  }
66
68
  toDisplayString() {
67
69
  let returnValue = undefined;
68
- if (this.parentValue) {
70
+ if (this.rootValue) {
69
71
  const trailersString = this.trailers.join(".");
70
72
  if (this.type === 'instance') {
71
- returnValue = this.parentValue.parameters.get(trailersString);
73
+ returnValue = this.rootValue.parameters.get(trailersString);
72
74
  }
73
75
  else if (this.type === 'variable') {
74
- returnValue = this.parentValue[trailersString];
76
+ returnValue = this.rootValue[trailersString];
75
77
  }
76
78
  }
77
79
  else {
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuleCheck_NoConnectOnConnectedPin = void 0;
4
+ const graph_js_1 = require("../graph.js");
5
+ const rules_js_1 = require("./rules.js");
6
+ function RuleCheck_NoConnectOnConnectedPin(graph, nets) {
7
+ const allNodes = graph.nodes();
8
+ const items = [];
9
+ const netComponentPins = new Map();
10
+ const pinMapping = new Map();
11
+ const makeComponentPinHash = (instanceName, pin) => {
12
+ return instanceName + '-' + pin.getHashValue();
13
+ };
14
+ nets.forEach(item => {
15
+ const [component, pin, net] = item;
16
+ if (!netComponentPins.has(net)) {
17
+ netComponentPins.set(net, []);
18
+ }
19
+ const items = netComponentPins.get(net);
20
+ items.push([
21
+ component.instanceName,
22
+ pin
23
+ ]);
24
+ netComponentPins.set(net, items);
25
+ pinMapping.set(makeComponentPinHash(component.instanceName, pin), net);
26
+ });
27
+ allNodes.forEach(node => {
28
+ const nodeInfo = graph.node(node);
29
+ if (nodeInfo[0] === graph_js_1.RenderItemType.Component) {
30
+ const { component } = nodeInfo[1];
31
+ if (component.hasParam('no_connect')) {
32
+ const instanceName = component.instanceName;
33
+ const edges = graph.nodeEdges(node);
34
+ const otherNodes = [];
35
+ edges.forEach(edge => {
36
+ const edgeInfo = graph.edge(edge.v, edge.w);
37
+ let targetComponentName;
38
+ let targetPin;
39
+ if (edge.v === instanceName) {
40
+ otherNodes.push(edge.w);
41
+ targetComponentName = edge.w;
42
+ targetPin = edgeInfo[3];
43
+ }
44
+ else {
45
+ targetComponentName = edge.v;
46
+ targetPin = edgeInfo[1];
47
+ }
48
+ const componentPinHash = makeComponentPinHash(targetComponentName, targetPin);
49
+ if (pinMapping.has(componentPinHash)) {
50
+ const net = pinMapping.get(componentPinHash);
51
+ const tmpNetComponentPins = netComponentPins.get(net);
52
+ const remainingItems = tmpNetComponentPins.filter(item => {
53
+ if (item[0] === instanceName) {
54
+ return false;
55
+ }
56
+ else if (item[0] === targetComponentName
57
+ && item[1].getHashValue() === targetPin.getHashValue()) {
58
+ return false;
59
+ }
60
+ return true;
61
+ });
62
+ if (remainingItems.length > 0) {
63
+ const targetInfo = graph.node(targetComponentName);
64
+ const tmpComponent = targetInfo[1];
65
+ items.push({
66
+ type: rules_js_1.ERC_Rules.NoConnectOnConnectedPin,
67
+ instance: component,
68
+ target: {
69
+ instance: tmpComponent.component,
70
+ pin: targetPin
71
+ }
72
+ });
73
+ }
74
+ }
75
+ });
76
+ }
77
+ }
78
+ });
79
+ return items;
80
+ }
81
+ exports.RuleCheck_NoConnectOnConnectedPin = RuleCheck_NoConnectOnConnectedPin;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EvaluateERCRules = exports.ERC_Rules = void 0;
4
+ const unconnected_pins_js_1 = require("./unconnected-pins.js");
5
+ const no_connect_on_connected_pin_js_1 = require("./no-connect-on-connected-pin.js");
6
+ var ERC_Rules;
7
+ (function (ERC_Rules) {
8
+ ERC_Rules["UnconnectedPin"] = "UNCONNECTED-PIN";
9
+ ERC_Rules["UnconnectedWire"] = "UNCONNECTED-WIRE";
10
+ ERC_Rules["NoConnectOnConnectedPin"] = "NO-CONNECT-ON-CONNECTED-PIN";
11
+ })(ERC_Rules || (exports.ERC_Rules = ERC_Rules = {}));
12
+ function EvaluateERCRules(visitor, graph, nets) {
13
+ const ruleCheckItems = [];
14
+ const creationCtx = visitor.creationCtx;
15
+ ruleCheckItems.push(...(0, unconnected_pins_js_1.RuleCheck_UnconnectedPinsWires)(graph), ...(0, no_connect_on_connected_pin_js_1.RuleCheck_NoConnectOnConnectedPin)(graph, nets));
16
+ const reportItems = [];
17
+ ruleCheckItems.forEach(item => {
18
+ const { type } = item;
19
+ switch (type) {
20
+ case ERC_Rules.UnconnectedPin:
21
+ {
22
+ const instance = item.instance;
23
+ const token = getComponentFirstCtxToken(instance);
24
+ if (token) {
25
+ reportItems.push({
26
+ type,
27
+ start: token,
28
+ message: `Unconnected pin ${item.pin} for component`
29
+ });
30
+ }
31
+ }
32
+ break;
33
+ case ERC_Rules.UnconnectedWire:
34
+ {
35
+ const wire = item.wire;
36
+ if (creationCtx.has(wire)) {
37
+ const tmpCtx = creationCtx.get(wire);
38
+ const startToken = tmpCtx.start;
39
+ reportItems.push({
40
+ type,
41
+ start: startToken,
42
+ message: `Unconnected wire end`
43
+ });
44
+ }
45
+ }
46
+ break;
47
+ case ERC_Rules.NoConnectOnConnectedPin:
48
+ {
49
+ const instance = item.instance;
50
+ const token = getComponentFirstCtxToken(instance);
51
+ if (token) {
52
+ reportItems.push({
53
+ type,
54
+ start: token,
55
+ message: `No connect on connected pin`
56
+ });
57
+ }
58
+ }
59
+ break;
60
+ }
61
+ });
62
+ const sortedReport = reportItems.toSorted((a, b) => {
63
+ return a.start.start - b.start.start;
64
+ });
65
+ return sortedReport;
66
+ }
67
+ exports.EvaluateERCRules = EvaluateERCRules;
68
+ function getComponentFirstCtxToken(instance) {
69
+ if (instance.ctxReferences.length > 0) {
70
+ const { ctx } = instance.ctxReferences[0];
71
+ return ctx.start;
72
+ }
73
+ return null;
74
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuleCheck_UnconnectedPinsWires = void 0;
4
+ const graph_js_1 = require("../graph.js");
5
+ const rules_js_1 = require("./rules.js");
6
+ function RuleCheck_UnconnectedPinsWires(graph) {
7
+ const items = [];
8
+ const allNodes = graph.nodes();
9
+ allNodes.forEach(node => {
10
+ const nodeInfo = graph.node(node);
11
+ if (nodeInfo[0] === graph_js_1.RenderItemType.Component) {
12
+ const { component } = nodeInfo[1];
13
+ const edges = graph.nodeEdges(node);
14
+ const instanceName = component.instanceName;
15
+ const connectedPins = [];
16
+ edges.forEach(edge => {
17
+ const edgeInfo = graph.edge(edge.v, edge.w);
18
+ let pin;
19
+ if (edge.v === instanceName) {
20
+ pin = edgeInfo[1];
21
+ }
22
+ else if (edge.w === instanceName) {
23
+ pin = edgeInfo[3];
24
+ }
25
+ connectedPins.push(pin.getHashValue());
26
+ });
27
+ const pinIds = Array.from(component.pins.keys());
28
+ pinIds.forEach(pinId => {
29
+ const hashValue = pinId.getHashValue();
30
+ if (connectedPins.indexOf(hashValue) === -1) {
31
+ items.push({
32
+ type: rules_js_1.ERC_Rules.UnconnectedPin,
33
+ instance: component,
34
+ pin: pinId,
35
+ });
36
+ }
37
+ });
38
+ }
39
+ else if (nodeInfo[0] === graph_js_1.RenderItemType.Wire) {
40
+ const renderWire = nodeInfo[1];
41
+ const edges = graph.nodeEdges(node);
42
+ if (edges.length < 2) {
43
+ items.push({
44
+ type: rules_js_1.ERC_Rules.UnconnectedWire,
45
+ wire: renderWire.wire,
46
+ });
47
+ }
48
+ }
49
+ });
50
+ return items;
51
+ }
52
+ exports.RuleCheck_UnconnectedPinsWires = RuleCheck_UnconnectedPinsWires;