circuitscript 0.1.29 → 0.1.32

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 (71) hide show
  1. package/dist/cjs/BaseVisitor.js +185 -22
  2. package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
  3. package/dist/cjs/antlr/CircuitScriptLexer.js +241 -236
  4. package/dist/cjs/antlr/CircuitScriptParser.js +1197 -901
  5. package/dist/cjs/builtinMethods.js +6 -2
  6. package/dist/cjs/draw_symbols.js +38 -34
  7. package/dist/cjs/environment.js +28 -4
  8. package/dist/cjs/execute.js +195 -125
  9. package/dist/cjs/globals.js +6 -1
  10. package/dist/cjs/graph.js +14 -12
  11. package/dist/cjs/helpers.js +90 -17
  12. package/dist/cjs/layout.js +50 -25
  13. package/dist/cjs/main.js +16 -14
  14. package/dist/cjs/objects/ClassComponent.js +199 -30
  15. package/dist/cjs/objects/ExecutionScope.js +9 -0
  16. package/dist/cjs/objects/types.js +25 -2
  17. package/dist/cjs/parser.js +6 -2
  18. package/dist/cjs/regenerate-tests.js +3 -3
  19. package/dist/cjs/render.js +5 -3
  20. package/dist/cjs/rules-check/no-connect-on-connected-pin.js +9 -8
  21. package/dist/cjs/rules-check/rules.js +7 -2
  22. package/dist/cjs/rules-check/unconnected-pins.js +10 -8
  23. package/dist/cjs/utils.js +2 -1
  24. package/dist/cjs/validate/SymbolTable.js +7 -1
  25. package/dist/cjs/validate/SymbolValidatorVisitor.js +54 -17
  26. package/dist/cjs/visitor.js +299 -238
  27. package/dist/esm/BaseVisitor.js +187 -24
  28. package/dist/esm/RefdesAnnotationVisitor.js +27 -10
  29. package/dist/esm/antlr/CircuitScriptLexer.js +241 -236
  30. package/dist/esm/antlr/CircuitScriptParser.js +1196 -899
  31. package/dist/esm/antlr/CircuitScriptVisitor.js +4 -1
  32. package/dist/esm/builtinMethods.js +7 -3
  33. package/dist/esm/draw_symbols.js +38 -34
  34. package/dist/esm/environment.js +25 -1
  35. package/dist/esm/execute.js +197 -127
  36. package/dist/esm/globals.js +4 -0
  37. package/dist/esm/graph.js +14 -12
  38. package/dist/esm/helpers.js +91 -18
  39. package/dist/esm/layout.js +51 -26
  40. package/dist/esm/main.js +16 -14
  41. package/dist/esm/objects/ClassComponent.js +201 -30
  42. package/dist/esm/objects/ExecutionScope.js +9 -0
  43. package/dist/esm/objects/types.js +33 -1
  44. package/dist/esm/parser.js +6 -2
  45. package/dist/esm/regenerate-tests.js +3 -3
  46. package/dist/esm/render.js +5 -3
  47. package/dist/esm/rules-check/no-connect-on-connected-pin.js +9 -8
  48. package/dist/esm/rules-check/rules.js +7 -2
  49. package/dist/esm/rules-check/unconnected-pins.js +10 -8
  50. package/dist/esm/utils.js +2 -1
  51. package/dist/esm/validate/SymbolTable.js +5 -0
  52. package/dist/esm/validate/SymbolValidatorVisitor.js +53 -16
  53. package/dist/esm/visitor.js +201 -137
  54. package/dist/types/BaseVisitor.d.ts +27 -10
  55. package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
  56. package/dist/types/antlr/CircuitScriptLexer.d.ts +43 -42
  57. package/dist/types/antlr/CircuitScriptParser.d.ts +102 -58
  58. package/dist/types/antlr/CircuitScriptVisitor.d.ts +8 -2
  59. package/dist/types/environment.d.ts +8 -1
  60. package/dist/types/execute.d.ts +6 -3
  61. package/dist/types/globals.d.ts +4 -0
  62. package/dist/types/graph.d.ts +2 -2
  63. package/dist/types/helpers.d.ts +2 -1
  64. package/dist/types/layout.d.ts +5 -4
  65. package/dist/types/objects/ClassComponent.d.ts +34 -9
  66. package/dist/types/objects/ExecutionScope.d.ts +3 -1
  67. package/dist/types/objects/types.d.ts +40 -3
  68. package/dist/types/validate/SymbolTable.d.ts +1 -0
  69. package/dist/types/validate/SymbolValidatorVisitor.d.ts +6 -6
  70. package/dist/types/visitor.d.ts +10 -2
  71. package/package.json +4 -1
@@ -160,25 +160,85 @@ async function validateScript(filePath, scriptData, options) {
160
160
  return visitorResolver;
161
161
  }
162
162
  exports.validateScript = validateScript;
163
- async function DefaultPostAnnotationCallback(options, scriptData, tree, tokens, componentLinks) {
163
+ async function DefaultPostAnnotationCallback(options, scriptData, tree, tokens, componentLinks, importedModules, environment) {
164
164
  const { inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
165
165
  if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
166
- const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
167
- await refdesVisitor.visitAsync(tree);
168
- let usePath = inputPath;
169
- if (saveAnnotatedCopy === true) {
170
- const dir = path_1.default.dirname(inputPath);
171
- const ext = path_1.default.extname(inputPath);
172
- const basename = path_1.default.basename(inputPath, ext);
173
- usePath = path_1.default.join(dir, `${basename}.annotated${ext}`);
166
+ const annotatedFiles = [{
167
+ isMainFile: true,
168
+ scriptData,
169
+ tokens,
170
+ tree,
171
+ filePath: inputPath,
172
+ outputType: RefdesOutputType.WithSource
173
+ }];
174
+ for (const module of importedModules) {
175
+ let outputType = RefdesOutputType.None;
176
+ if (module.enableRefdesAnnotation) {
177
+ outputType = RefdesOutputType.WithSource;
178
+ }
179
+ else if (module.enableRefdesAnnotationFile) {
180
+ outputType = RefdesOutputType.CreateExternalFile;
181
+ }
182
+ if (outputType !== RefdesOutputType.None) {
183
+ const { moduleFilePath, moduleName, tokens: moduleTokens, tree: moduleTree } = module;
184
+ const moduleScriptData = await environment.readFile(moduleFilePath, { encoding: 'utf8' });
185
+ annotatedFiles.push({
186
+ tokens: moduleTokens,
187
+ tree: moduleTree,
188
+ filePath: moduleFilePath,
189
+ scriptData: moduleScriptData,
190
+ moduleName,
191
+ outputType
192
+ });
193
+ }
174
194
  }
175
- else if (typeof saveAnnotatedCopy === 'string') {
176
- usePath = saveAnnotatedCopy;
195
+ for (const item of annotatedFiles) {
196
+ const { scriptData, tokens, tree, filePath, moduleName, isMainFile = false } = item;
197
+ const tmpVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
198
+ await tmpVisitor.visit(tree);
199
+ let usePath = filePath;
200
+ if (isMainFile && saveAnnotatedCopy === true) {
201
+ const dir = environment.dirname(filePath);
202
+ const ext = environment.extname(filePath);
203
+ const basename = environment.basename(filePath, ext);
204
+ usePath = environment.join(dir, `${basename}.annotated${ext}`);
205
+ }
206
+ else if (isMainFile && typeof saveAnnotatedCopy === 'string') {
207
+ usePath = saveAnnotatedCopy;
208
+ }
209
+ if (item.outputType === RefdesOutputType.WithSource) {
210
+ environment.writeFileSync(usePath, tmpVisitor.getOutput());
211
+ }
212
+ else if (item.outputType === RefdesOutputType.CreateExternalFile) {
213
+ const dir = environment.dirname(usePath);
214
+ const ext = environment.extname(usePath);
215
+ const basename = environment.basename(filePath, ext);
216
+ usePath = environment.join(dir, `${basename}${globals_js_1.RefdesFileSuffix}`);
217
+ const output = tmpVisitor.getOutputForExternalRefdesFile();
218
+ const inputDir = environment.dirname(inputPath);
219
+ const relativeFilePath = environment.relative(inputDir, filePath);
220
+ const jsonFile = {
221
+ format: 'v1',
222
+ module: moduleName,
223
+ file: relativeFilePath,
224
+ items: output,
225
+ };
226
+ environment.writeFileSync(usePath, JSON.stringify(jsonFile, null, 4));
227
+ }
228
+ let display = 'Refdes annotations';
229
+ if (moduleName) {
230
+ display += ` for module ${moduleName}`;
231
+ }
232
+ console.log(`${display} saved to ${usePath}`);
177
233
  }
178
- console.log('Annotations saved to ' + usePath);
179
- (0, fs_1.writeFileSync)(usePath, refdesVisitor.getOutput());
180
234
  }
181
235
  }
236
+ var RefdesOutputType;
237
+ (function (RefdesOutputType) {
238
+ RefdesOutputType["None"] = "none";
239
+ RefdesOutputType["WithSource"] = "with-source";
240
+ RefdesOutputType["CreateExternalFile"] = "create-external-file";
241
+ })(RefdesOutputType || (RefdesOutputType = {}));
182
242
  async function renderScript(scriptData, outputPath, options) {
183
243
  const parseHandlers = [
184
244
  new KiCadNetListOutputHandler(),
@@ -217,11 +277,17 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
217
277
  environment.setCurrentFile(inputPath);
218
278
  const visitor = new visitor_js_1.ParserVisitor(true, onErrorHandler, environment);
219
279
  visitor.onImportFile = async (visitor, filePath, fileData) => {
220
- const { hasError, hasParseError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, fileData);
280
+ visitor.enterFile(filePath);
281
+ const { hasError, hasParseError, throwError, tree, tokens } = await (0, parser_js_1.parseFileWithVisitor)(visitor, fileData);
282
+ visitor.exitFile();
221
283
  if (hasError || hasParseError) {
222
- throw new utils_js_1.ParseError(`Error parsing imported file: ${filePath}`, undefined, undefined, filePath);
284
+ let importErrorMsg = "";
285
+ if (throwError) {
286
+ importErrorMsg = ": " + throwError.message;
287
+ }
288
+ throw new utils_js_1.ParseError(`Error parsing imported file: ${filePath}${importErrorMsg}`, undefined, undefined, filePath);
223
289
  }
224
- return { hasError, hasParseError };
290
+ return { hasError, hasParseError, tree, tokens };
225
291
  };
226
292
  visitor.log('reading file');
227
293
  visitor.log('done reading file');
@@ -232,6 +298,9 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
232
298
  (0, fs_1.mkdirSync)(dumpDirectory);
233
299
  }
234
300
  }
301
+ if (inputPath !== '') {
302
+ visitor.enterFile(inputPath);
303
+ }
235
304
  const { tree, parser, tokens, parserTimeTaken, lexerTimeTaken, throwError } = await (0, parser_js_1.parseFileWithVisitor)(visitor, scriptData);
236
305
  (0, utils_js_1.printWarnings)(visitor.getWarnings());
237
306
  showStats && console.log('Lexing took:', lexerTimeTaken);
@@ -243,8 +312,9 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
243
312
  throw new utils_js_1.RenderError(`Error during component annotation: ${err}`, 'annotation');
244
313
  }
245
314
  const componentLinks = visitor.getComponentCtxLinks();
315
+ const importedModules = Array.from(visitor.getScope().modules.values());
246
316
  for (let i = 0; i < postAnnotationCallbacks.length; i++) {
247
- await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks);
317
+ await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks, importedModules, environment);
248
318
  }
249
319
  if (dumpNets) {
250
320
  const nets = visitor.dumpNets();
@@ -303,6 +373,9 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
303
373
  console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
304
374
  });
305
375
  }
376
+ else {
377
+ console.log('No ERC issues found');
378
+ }
306
379
  }
307
380
  }
308
381
  catch (err) {
@@ -306,7 +306,8 @@ class LayoutEngine {
306
306
  const avoidAreas = [];
307
307
  if (frameParams.has(Frame_js_1.FrameParamKeys.SheetType)) {
308
308
  const frameComponent = frameParams.get(Frame_js_1.FrameParamKeys.SheetType);
309
- const frameDrawing = frameComponent.displayProp;
309
+ const frameComponentUnit = frameComponent.getUnit();
310
+ const frameDrawing = frameComponentUnit.displayProp;
310
311
  frameDrawing.variables = (0, utils_js_1.combineMaps)(frameComponent.parameters, frameParams);
311
312
  const rects = ExtractDrawingRects(frameDrawing);
312
313
  const drawableRect = rects.find(rect => rect.className === 'plot-area');
@@ -565,7 +566,7 @@ class LayoutEngine {
565
566
  accum.push(item);
566
567
  }
567
568
  else if (item instanceof RenderComponent) {
568
- const { instanceName } = item.component;
569
+ const { instanceName } = item.component.getUnit(item.unitId);
569
570
  if (ignoreItems.indexOf(instanceName) === -1) {
570
571
  const withinSubgraph = subgraphInfo.find(subgraphInfo => {
571
572
  return subgraphInfo.components.indexOf(instanceName) !== -1;
@@ -697,7 +698,9 @@ class LayoutEngine {
697
698
  const [, node1] = graph.node(firstNodeId);
698
699
  let defaultPin = new PinDefinition_js_1.PinId(1);
699
700
  if (node1 instanceof RenderComponent) {
700
- defaultPin = node1.component.getDefaultPin();
701
+ const unitId = node1.unitId;
702
+ const componentUnit = node1.component.getUnit(unitId);
703
+ defaultPin = componentUnit.pinsFlat[0].id;
701
704
  }
702
705
  this.placeNodeAtPosition((0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), node1, defaultPin);
703
706
  return;
@@ -771,7 +774,8 @@ class LayoutEngine {
771
774
  }
772
775
  [node1, node2].forEach(item => {
773
776
  if (item instanceof RenderWire && item.isEndAutoLength()) {
774
- const [instance, pin] = item.getEndAuto();
777
+ const [component, pin] = item.getEndAuto();
778
+ const instance = component.getUnitForPin(pin);
775
779
  const [, targetNode] = graph.node(instance.instanceName);
776
780
  this.print('wire', item, 'auto length to target:', instance, pin);
777
781
  if (targetNode.isFloating) {
@@ -928,24 +932,43 @@ function getNeighbours(graph, nodeIds) {
928
932
  return accum;
929
933
  }, []);
930
934
  }
931
- function applyComponentParamsToSymbol(component, symbol) {
932
- const { widthProp = null, heightProp = null } = component;
933
- const newMap = new Map(component.parameters);
934
- if (!newMap.has('refdes')) {
935
- newMap.set('refdes', component.assignedRefDes ?? "?");
935
+ function applyComponentParamsToSymbol(componentUnit, symbol) {
936
+ const { widthProp = null, heightProp = null } = componentUnit;
937
+ const newMap = new Map(componentUnit.parameters);
938
+ const ignoreParams = [
939
+ globals_js_1.ParamKeys.angle,
940
+ globals_js_1.ParamKeys.flip,
941
+ globals_js_1.ParamKeys.flipX,
942
+ globals_js_1.ParamKeys.flipY,
943
+ ];
944
+ const parentParams = componentUnit.parent.parameters;
945
+ parentParams.forEach((value, key) => {
946
+ if (ignoreParams.indexOf(key) === -1) {
947
+ newMap.set(key, value);
948
+ }
949
+ });
950
+ const refdesKey = 'refdes';
951
+ if (!newMap.has(refdesKey)) {
952
+ newMap.set(refdesKey, componentUnit.parent.assignedRefDes ?? "?");
953
+ }
954
+ if (componentUnit.refdesSuffix !== "") {
955
+ const tmpRefdes = newMap.get(refdesKey);
956
+ newMap.set(refdesKey, `${tmpRefdes}${componentUnit.refdesSuffix}`);
936
957
  }
937
958
  symbol.drawing.variables = newMap;
938
- if (component.parameters.has(globals_js_1.ParamKeys.angle)) {
939
- const value = component.parameters.get(globals_js_1.ParamKeys.angle).toNumber();
959
+ if (componentUnit.parameters.has(globals_js_1.ParamKeys.angle)) {
960
+ const value = componentUnit.parameters.get(globals_js_1.ParamKeys.angle).toNumber();
940
961
  symbol.angle = value;
941
962
  }
942
- if (component.parameters.has(globals_js_1.ParamKeys.flipX)) {
963
+ if (componentUnit.parameters.has(globals_js_1.ParamKeys.flipX)) {
943
964
  symbol.flipX =
944
- component.parameters.get(globals_js_1.ParamKeys.flipX);
965
+ componentUnit.parameters.get(globals_js_1.ParamKeys.flipX)
966
+ .toNumber();
945
967
  }
946
- if (component.parameters.has(globals_js_1.ParamKeys.flipY)) {
968
+ if (componentUnit.parameters.has(globals_js_1.ParamKeys.flipY)) {
947
969
  symbol.flipY =
948
- component.parameters.get(globals_js_1.ParamKeys.flipY);
970
+ componentUnit.parameters.get(globals_js_1.ParamKeys.flipY)
971
+ .toNumber();
949
972
  }
950
973
  if (symbol instanceof draw_symbols_js_1.SymbolCustom) {
951
974
  if (widthProp) {
@@ -1183,10 +1206,12 @@ class RenderWire extends RenderObject {
1183
1206
  }
1184
1207
  exports.RenderWire = RenderWire;
1185
1208
  class RenderComponent extends RenderObject {
1186
- constructor(component, width, height) {
1209
+ constructor(component, unitId, width, height) {
1187
1210
  super();
1211
+ this.unitId = globals_js_1.DefaultComponentUnit;
1188
1212
  this.displaySymbol = null;
1189
1213
  this.component = component;
1214
+ this.unitId = unitId;
1190
1215
  this.width = width;
1191
1216
  this.height = height;
1192
1217
  }
@@ -1272,22 +1297,22 @@ class RenderJunction {
1272
1297
  }
1273
1298
  }
1274
1299
  exports.RenderJunction = RenderJunction;
1275
- function CalculatePinPositions(component) {
1300
+ function CalculatePinPositions(unit) {
1276
1301
  const pinPositionMapping = new Map();
1277
1302
  let tmpSymbol;
1278
- if (component.displayProp !== null
1279
- && component.displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
1280
- tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(component.displayProp);
1303
+ if (unit.displayProp !== null
1304
+ && unit.displayProp instanceof draw_symbols_js_1.SymbolDrawing) {
1305
+ tmpSymbol = new draw_symbols_js_1.SymbolPlaceholder(unit.displayProp);
1281
1306
  }
1282
1307
  else {
1283
- const symbolPinDefinitions = (0, graph_js_1.generateLayoutPinDefinition)(component);
1284
- tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions, component.pinsMaxPositions);
1308
+ const symbolPinDefinitions = (0, graph_js_1.generateLayoutPinDefinition)(unit);
1309
+ tmpSymbol = new draw_symbols_js_1.SymbolCustom(symbolPinDefinitions, unit.pinsMaxPositions);
1285
1310
  }
1286
- applyComponentParamsToSymbol(component, tmpSymbol);
1311
+ applyComponentParamsToSymbol(unit, tmpSymbol);
1287
1312
  tmpSymbol.refreshDrawing();
1288
- const pins = component.pins;
1313
+ const pins = unit.pins;
1289
1314
  pins.forEach((value, key) => {
1290
- if (component._unplacedPins.indexOf(key) === -1) {
1315
+ if (unit._unplacedPins.indexOf(key) === -1) {
1291
1316
  pinPositionMapping.set(key, tmpSymbol.pinPosition(key));
1292
1317
  }
1293
1318
  });
package/dist/cjs/main.js CHANGED
@@ -57,22 +57,20 @@ async function main() {
57
57
  return;
58
58
  }
59
59
  let scriptData;
60
- if (args.length > 0 && args[0]) {
61
- inputFilePath = args[0];
62
- if ((await env.exists(inputFilePath))) {
63
- scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
64
- }
65
- else {
66
- console.error("Error: File could not be found");
67
- return;
68
- }
69
- }
70
- else if (options.input) {
60
+ if (options.input) {
71
61
  scriptData = options.input;
72
62
  }
73
63
  else {
74
- console.error("Error: No input provided");
75
- return;
64
+ if (args.length > 0 && args[0]) {
65
+ inputFilePath = args[0];
66
+ if ((await env.exists(inputFilePath))) {
67
+ scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
68
+ }
69
+ else {
70
+ console.error("Error: File could not be found");
71
+ return;
72
+ }
73
+ }
76
74
  }
77
75
  let updateSource = false;
78
76
  if (options.updateSource !== undefined) {
@@ -103,7 +101,10 @@ async function main() {
103
101
  saveAnnotatedCopy: saveAnnotatedCopyPath,
104
102
  };
105
103
  let outputPath = null;
106
- if (args.length > 0 && args[1]) {
104
+ if (options.input && args.length > 0 && args[0]) {
105
+ outputPath = args[0];
106
+ }
107
+ else if (args.length > 0 && args[1]) {
107
108
  outputPath = args[1];
108
109
  }
109
110
  const output = await parseFile(scriptData, outputPath, scriptOptions);
@@ -133,6 +134,7 @@ async function parseFile(scriptData, outputPath, scriptOptions) {
133
134
  }
134
135
  catch (error) {
135
136
  console.error(`Unexpected Error: ${error}`);
137
+ console.log(error.stack);
136
138
  }
137
139
  return null;
138
140
  }
@@ -1,36 +1,153 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ModuleComponent = exports.ClassComponent = void 0;
3
+ exports.ModuleComponent = exports.ClassComponent = exports.ComponentUnit = void 0;
4
4
  const draw_symbols_js_1 = require("../draw_symbols.js");
5
5
  const PinDefinition_js_1 = require("./PinDefinition.js");
6
6
  const PinTypes_js_1 = require("./PinTypes.js");
7
7
  const globals_js_1 = require("../globals.js");
8
8
  const utils_js_1 = require("../utils.js");
9
- class ClassComponent {
10
- constructor(instanceName, numPins) {
9
+ class ComponentUnit {
10
+ get instanceName() {
11
+ return `${this.parent.instanceName},${this.unitId}`;
12
+ }
13
+ constructor(unitId, parent) {
14
+ this.refdesSuffix = "A";
15
+ this.suffix = null;
11
16
  this.parameters = new Map();
12
17
  this.pins = new Map();
13
- this.pinNets = new Map();
14
- this.pinWires = new Map();
18
+ this.pinsFlat = [];
15
19
  this.pinsMaxPositions = new Map();
16
- this._copyID = null;
17
- this._copyFrom = null;
18
- this._unplacedPins = [];
19
20
  this.arrangeProps = null;
20
21
  this.displayProp = null;
21
22
  this.widthProp = null;
22
23
  this.heightProp = null;
23
- this.typeProp = null;
24
- this.copyProp = false;
25
24
  this.angleProp = 0;
26
25
  this.followWireOrientationProp = true;
27
26
  this.wireOrientationAngle = 0;
28
27
  this.useWireOrientationAngle = true;
29
28
  this.didSetWireOrientationAngle = false;
29
+ this._unplacedPins = [];
30
+ this.unitId = unitId;
31
+ this.parent = parent;
32
+ }
33
+ clone() {
34
+ const unit = new ComponentUnit(this.unitId, this.parent);
35
+ unit.numPins = this.numPins;
36
+ unit.angleProp = this.angleProp;
37
+ unit.widthProp = this.widthProp;
38
+ unit.heightProp = this.heightProp;
39
+ if (this.displayProp instanceof draw_symbols_js_1.SymbolDrawingCommands) {
40
+ unit.displayProp = this.displayProp.clone();
41
+ }
42
+ if (this.arrangeProps !== null) {
43
+ unit.arrangeProps = new Map(this.arrangeProps);
44
+ }
45
+ for (const [key, value] of this.pins) {
46
+ unit.pins.set(key, value);
47
+ }
48
+ unit.pinsFlat = [...this.pinsFlat];
49
+ for (const [key, value] of this.pinsMaxPositions) {
50
+ unit.pinsMaxPositions.set(key, value);
51
+ }
52
+ unit._unplacedPins = [...this._unplacedPins];
53
+ unit.followWireOrientationProp = this.followWireOrientationProp;
54
+ unit.wireOrientationAngle = this.wireOrientationAngle;
55
+ unit.useWireOrientationAngle = this.useWireOrientationAngle;
56
+ unit.didSetWireOrientationAngle = this.didSetWireOrientationAngle;
57
+ return unit;
58
+ }
59
+ setParam(key, value) {
60
+ this.parameters.set(key, value);
61
+ }
62
+ isEqual(other) {
63
+ if (this === other)
64
+ return true;
65
+ if (this.unitId !== other.unitId)
66
+ return false;
67
+ if (this.numPins !== other.numPins)
68
+ return false;
69
+ if (this.angleProp !== other.angleProp)
70
+ return false;
71
+ if (this.widthProp !== other.widthProp)
72
+ return false;
73
+ if (this.heightProp !== other.heightProp)
74
+ return false;
75
+ if (this.followWireOrientationProp !== other.followWireOrientationProp)
76
+ return false;
77
+ if (this.wireOrientationAngle !== other.wireOrientationAngle)
78
+ return false;
79
+ if (this.useWireOrientationAngle !== other.useWireOrientationAngle)
80
+ return false;
81
+ if (this.didSetWireOrientationAngle !== other.didSetWireOrientationAngle)
82
+ return false;
83
+ if (this.displayProp === null && other.displayProp !== null)
84
+ return false;
85
+ if (this.displayProp !== null && other.displayProp === null)
86
+ return false;
87
+ if (this.displayProp !== null && other.displayProp !== null && !this.displayProp.eq(other.displayProp))
88
+ return false;
89
+ if (this.arrangeProps === null && other.arrangeProps !== null)
90
+ return false;
91
+ if (this.arrangeProps !== null && other.arrangeProps === null)
92
+ return false;
93
+ if (this.arrangeProps !== null && other.arrangeProps !== null) {
94
+ if (this.arrangeProps.size !== other.arrangeProps.size)
95
+ return false;
96
+ for (const [key, value] of this.arrangeProps) {
97
+ const otherValue = other.arrangeProps.get(key);
98
+ if (!otherValue || value.length !== otherValue.length)
99
+ return false;
100
+ for (let i = 0; i < value.length; i++) {
101
+ if (!value[i].equals(otherValue[i]))
102
+ return false;
103
+ }
104
+ }
105
+ }
106
+ if (this.parameters.size !== other.parameters.size)
107
+ return false;
108
+ for (const [key, value] of this.parameters) {
109
+ if (!other.parameters.has(key) || other.parameters.get(key) !== value)
110
+ return false;
111
+ }
112
+ if (this.pins.size !== other.pins.size)
113
+ return false;
114
+ for (const [key, value] of this.pins) {
115
+ let found = false;
116
+ for (const [otherKey, otherValue] of other.pins) {
117
+ if (key.equals(otherKey) && value === otherValue) {
118
+ found = true;
119
+ break;
120
+ }
121
+ }
122
+ if (!found)
123
+ return false;
124
+ }
125
+ if (this.parent !== other.parent) {
126
+ return false;
127
+ }
128
+ return true;
129
+ }
130
+ }
131
+ exports.ComponentUnit = ComponentUnit;
132
+ class ClassComponent {
133
+ constructor(instanceName, numPins) {
134
+ this.parameters = new Map();
135
+ this.pins = new Map();
136
+ this.pinNets = new Map();
137
+ this.pinWires = new Map();
138
+ this.pinsMaxPositions = new Map();
139
+ this.units = [];
140
+ this._copyID = null;
141
+ this._copyFrom = null;
142
+ this._unplacedPins = [];
143
+ this.typeProp = null;
144
+ this.copyProp = false;
30
145
  this.assignedRefDes = null;
31
146
  this.placeHolderRefDes = null;
147
+ this.forceSaveRefdesAnnotation = false;
32
148
  this.ctxReferences = [];
33
149
  this._creationIndex = -1;
150
+ this.pinUnitMap = new Map();
34
151
  this.instanceName = instanceName;
35
152
  this.numPins = numPins;
36
153
  }
@@ -121,31 +238,32 @@ class ClassComponent {
121
238
  return component;
122
239
  }
123
240
  isEqual(other) {
124
- return this.instanceName === other.instanceName
125
- && this.numPins === other.numPins
126
- && this._copyID === other._copyID
127
- && this.arrangeProps === other.arrangeProps
128
- && ((this.displayProp === null && other.displayProp === null)
129
- ||
130
- (this.displayProp !== null && other.displayProp !== null && this.displayProp.eq(other.displayProp)))
131
- && this.widthProp === other.widthProp
132
- && this.typeProp === other.typeProp
133
- && this._cachedPins === other._cachedPins
134
- && this._cachedParams === other._cachedParams;
241
+ if (this === other)
242
+ return true;
243
+ if (this.instanceName !== other.instanceName)
244
+ return false;
245
+ if (this._copyID !== other._copyID)
246
+ return false;
247
+ if (this.typeProp !== other.typeProp)
248
+ return false;
249
+ if (this._cachedPins !== other._cachedPins)
250
+ return false;
251
+ if (this._cachedParams !== other._cachedParams)
252
+ return false;
253
+ for (let i = 0; i < this.units.length; i++) {
254
+ if (other.units[i] === undefined) {
255
+ return false;
256
+ }
257
+ if (!other.units[i].isEqual(this.units[i])) {
258
+ return false;
259
+ }
260
+ }
261
+ return true;
135
262
  }
136
263
  clone() {
137
264
  const component = new ClassComponent(this.instanceName, this.numPins);
138
265
  component._copyID = this._copyID;
139
- component.arrangeProps = this.arrangeProps;
140
- component.widthProp = this.widthProp;
141
266
  component.typeProp = this.typeProp;
142
- component.angleProp = this.angleProp;
143
- component.followWireOrientationProp = this.followWireOrientationProp;
144
- component.useWireOrientationAngle = this.useWireOrientationAngle;
145
- if (this.displayProp instanceof draw_symbols_js_1.SymbolDrawingCommands) {
146
- component.displayProp =
147
- this.displayProp.clone();
148
- }
149
267
  for (const [key, value] of this.parameters) {
150
268
  if (key === globals_js_1.ParamKeys.flipX || key === globals_js_1.ParamKeys.flipY || key === globals_js_1.ParamKeys.angle) {
151
269
  continue;
@@ -158,9 +276,60 @@ class ClassComponent {
158
276
  for (const [key, value] of this.pinsMaxPositions) {
159
277
  component.pinsMaxPositions.set(key, value);
160
278
  }
279
+ component.units = this.units.map(unit => {
280
+ const tmpUnit = unit.clone();
281
+ tmpUnit.parent = component;
282
+ return tmpUnit;
283
+ });
161
284
  component.refreshCache();
285
+ component.refreshPinUnitMap();
162
286
  return component;
163
287
  }
288
+ getUnit(unitId = null) {
289
+ if (unitId === null) {
290
+ return this.units[0];
291
+ }
292
+ else {
293
+ return this.units.find(item => {
294
+ return item.unitId === unitId;
295
+ });
296
+ }
297
+ }
298
+ addDefaultUnit(displayProp) {
299
+ const tmpUnit = new ComponentUnit(globals_js_1.DefaultComponentUnit, this);
300
+ tmpUnit.pins = this.pins;
301
+ const pinsFlat = [];
302
+ this.pins.forEach(pin => {
303
+ pinsFlat.push(pin);
304
+ });
305
+ tmpUnit.pinsFlat = pinsFlat;
306
+ tmpUnit.numPins = this.numPins;
307
+ tmpUnit.pinsMaxPositions = new Map();
308
+ tmpUnit.displayProp = displayProp;
309
+ tmpUnit.angleProp = 0;
310
+ tmpUnit.followWireOrientationProp = true;
311
+ this.units.push(tmpUnit);
312
+ this.refreshPinUnitMap();
313
+ }
314
+ refreshPinUnitMap() {
315
+ for (const unit of this.units) {
316
+ const { pinsFlat } = unit;
317
+ for (const pin of pinsFlat) {
318
+ this.pinUnitMap.set(pin.id, unit);
319
+ }
320
+ }
321
+ }
322
+ getUnitForPin(pinId) {
323
+ if (typeof pinId === "number") {
324
+ throw new utils_js_1.RuntimeExecutionError("Invalid pin id");
325
+ }
326
+ for (const [tmpPin, componentUnit] of this.pinUnitMap) {
327
+ if (tmpPin.equals(pinId)) {
328
+ return componentUnit;
329
+ }
330
+ }
331
+ throw new utils_js_1.RuntimeExecutionError("Could not find unit for pin: " + pinId);
332
+ }
164
333
  }
165
334
  exports.ClassComponent = ClassComponent;
166
335
  class ModuleComponent extends ClassComponent {
@@ -12,6 +12,7 @@ class ExecutionScope {
12
12
  this.functionCounter = new Map();
13
13
  this.variables = new Map();
14
14
  this.symbols = new Map();
15
+ this.modules = new Map();
15
16
  this.blockStack = new Map();
16
17
  this.contextStack = [];
17
18
  this.onPropertyHandler = [];
@@ -169,6 +170,14 @@ class ExecutionScope {
169
170
  getInstances() {
170
171
  return Array.from(this.instances.values());
171
172
  }
173
+ copyTo(scope) {
174
+ this.functions.forEach((value, key) => {
175
+ scope.functions.set(key, value);
176
+ });
177
+ this.variables.forEach((value, key) => {
178
+ scope.variables.set(key, value);
179
+ });
180
+ }
172
181
  }
173
182
  exports.ExecutionScope = ExecutionScope;
174
183
  ExecutionScope.scopeId = 0;