circuitscript 0.1.31 → 0.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BaseVisitor.js +37 -3
- package/dist/cjs/RefdesAnnotationVisitor.js +27 -10
- package/dist/cjs/antlr/CircuitScriptParser.js +990 -831
- package/dist/cjs/draw_symbols.js +38 -34
- package/dist/cjs/environment.js +24 -4
- package/dist/cjs/execute.js +107 -68
- package/dist/cjs/globals.js +4 -2
- package/dist/cjs/graph.js +14 -12
- package/dist/cjs/helpers.js +85 -16
- package/dist/cjs/layout.js +50 -25
- package/dist/cjs/main.js +16 -18
- package/dist/cjs/objects/ClassComponent.js +199 -30
- package/dist/cjs/objects/types.js +5 -1
- package/dist/cjs/regenerate-tests.js +3 -3
- package/dist/cjs/render.js +5 -3
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +9 -8
- package/dist/cjs/rules-check/rules.js +7 -2
- package/dist/cjs/rules-check/unconnected-pins.js +10 -8
- package/dist/cjs/utils.js +2 -1
- package/dist/cjs/validate/SymbolValidatorVisitor.js +0 -10
- package/dist/cjs/visitor.js +284 -191
- package/dist/esm/BaseVisitor.js +37 -3
- package/dist/esm/RefdesAnnotationVisitor.js +27 -10
- package/dist/esm/antlr/CircuitScriptParser.js +989 -830
- package/dist/esm/antlr/CircuitScriptVisitor.js +1 -0
- package/dist/esm/draw_symbols.js +38 -34
- package/dist/esm/environment.js +21 -1
- package/dist/esm/execute.js +108 -69
- package/dist/esm/globals.js +2 -0
- package/dist/esm/graph.js +14 -12
- package/dist/esm/helpers.js +86 -17
- package/dist/esm/layout.js +51 -26
- package/dist/esm/main.js +16 -18
- package/dist/esm/objects/ClassComponent.js +201 -30
- package/dist/esm/objects/types.js +7 -1
- package/dist/esm/regenerate-tests.js +3 -3
- package/dist/esm/render.js +5 -3
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +9 -8
- package/dist/esm/rules-check/rules.js +7 -2
- package/dist/esm/rules-check/unconnected-pins.js +10 -8
- package/dist/esm/utils.js +2 -1
- package/dist/esm/validate/SymbolValidatorVisitor.js +0 -10
- package/dist/esm/visitor.js +185 -92
- package/dist/types/BaseVisitor.d.ts +15 -5
- package/dist/types/RefdesAnnotationVisitor.d.ts +2 -0
- package/dist/types/antlr/CircuitScriptParser.d.ts +32 -14
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +2 -0
- package/dist/types/environment.d.ts +7 -1
- package/dist/types/execute.d.ts +4 -1
- package/dist/types/globals.d.ts +2 -0
- package/dist/types/graph.d.ts +2 -2
- package/dist/types/helpers.d.ts +2 -1
- package/dist/types/layout.d.ts +5 -4
- package/dist/types/objects/ClassComponent.d.ts +34 -9
- package/dist/types/objects/types.d.ts +19 -3
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +0 -4
- package/dist/types/visitor.d.ts +7 -1
- package/package.json +1 -1
package/dist/esm/helpers.js
CHANGED
|
@@ -13,7 +13,7 @@ import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy,
|
|
|
13
13
|
import { MainLexer } from "./lexer.js";
|
|
14
14
|
import { CircuitScriptParser } from "./antlr/CircuitScriptParser.js";
|
|
15
15
|
import { prepareTokens, SemanticTokensVisitor } from "./SemanticTokenVisitor.js";
|
|
16
|
-
import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM } from "./globals.js";
|
|
16
|
+
import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM, RefdesFileSuffix } from "./globals.js";
|
|
17
17
|
import { FrameParamKeys } from "./objects/Frame.js";
|
|
18
18
|
import Big from "big.js";
|
|
19
19
|
import { Logger } from "./logger.js";
|
|
@@ -150,25 +150,85 @@ export async function validateScript(filePath, scriptData, options) {
|
|
|
150
150
|
await visitorResolver.visitAsync(tree);
|
|
151
151
|
return visitorResolver;
|
|
152
152
|
}
|
|
153
|
-
async function DefaultPostAnnotationCallback(options, scriptData, tree, tokens, componentLinks) {
|
|
153
|
+
async function DefaultPostAnnotationCallback(options, scriptData, tree, tokens, componentLinks, importedModules, environment) {
|
|
154
154
|
const { inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
|
|
155
155
|
if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
156
|
+
const annotatedFiles = [{
|
|
157
|
+
isMainFile: true,
|
|
158
|
+
scriptData,
|
|
159
|
+
tokens,
|
|
160
|
+
tree,
|
|
161
|
+
filePath: inputPath,
|
|
162
|
+
outputType: RefdesOutputType.WithSource
|
|
163
|
+
}];
|
|
164
|
+
for (const module of importedModules) {
|
|
165
|
+
let outputType = RefdesOutputType.None;
|
|
166
|
+
if (module.enableRefdesAnnotation) {
|
|
167
|
+
outputType = RefdesOutputType.WithSource;
|
|
168
|
+
}
|
|
169
|
+
else if (module.enableRefdesAnnotationFile) {
|
|
170
|
+
outputType = RefdesOutputType.CreateExternalFile;
|
|
171
|
+
}
|
|
172
|
+
if (outputType !== RefdesOutputType.None) {
|
|
173
|
+
const { moduleFilePath, moduleName, tokens: moduleTokens, tree: moduleTree } = module;
|
|
174
|
+
const moduleScriptData = await environment.readFile(moduleFilePath, { encoding: 'utf8' });
|
|
175
|
+
annotatedFiles.push({
|
|
176
|
+
tokens: moduleTokens,
|
|
177
|
+
tree: moduleTree,
|
|
178
|
+
filePath: moduleFilePath,
|
|
179
|
+
scriptData: moduleScriptData,
|
|
180
|
+
moduleName,
|
|
181
|
+
outputType
|
|
182
|
+
});
|
|
183
|
+
}
|
|
164
184
|
}
|
|
165
|
-
|
|
166
|
-
|
|
185
|
+
for (const item of annotatedFiles) {
|
|
186
|
+
const { scriptData, tokens, tree, filePath, moduleName, isMainFile = false } = item;
|
|
187
|
+
const tmpVisitor = new RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
188
|
+
await tmpVisitor.visit(tree);
|
|
189
|
+
let usePath = filePath;
|
|
190
|
+
if (isMainFile && saveAnnotatedCopy === true) {
|
|
191
|
+
const dir = environment.dirname(filePath);
|
|
192
|
+
const ext = environment.extname(filePath);
|
|
193
|
+
const basename = environment.basename(filePath, ext);
|
|
194
|
+
usePath = environment.join(dir, `${basename}.annotated${ext}`);
|
|
195
|
+
}
|
|
196
|
+
else if (isMainFile && typeof saveAnnotatedCopy === 'string') {
|
|
197
|
+
usePath = saveAnnotatedCopy;
|
|
198
|
+
}
|
|
199
|
+
if (item.outputType === RefdesOutputType.WithSource) {
|
|
200
|
+
environment.writeFileSync(usePath, tmpVisitor.getOutput());
|
|
201
|
+
}
|
|
202
|
+
else if (item.outputType === RefdesOutputType.CreateExternalFile) {
|
|
203
|
+
const dir = environment.dirname(usePath);
|
|
204
|
+
const ext = environment.extname(usePath);
|
|
205
|
+
const basename = environment.basename(filePath, ext);
|
|
206
|
+
usePath = environment.join(dir, `${basename}${RefdesFileSuffix}`);
|
|
207
|
+
const output = tmpVisitor.getOutputForExternalRefdesFile();
|
|
208
|
+
const inputDir = environment.dirname(inputPath);
|
|
209
|
+
const relativeFilePath = environment.relative(inputDir, filePath);
|
|
210
|
+
const jsonFile = {
|
|
211
|
+
format: 'v1',
|
|
212
|
+
module: moduleName,
|
|
213
|
+
file: relativeFilePath,
|
|
214
|
+
items: output,
|
|
215
|
+
};
|
|
216
|
+
environment.writeFileSync(usePath, JSON.stringify(jsonFile, null, 4));
|
|
217
|
+
}
|
|
218
|
+
let display = 'Refdes annotations';
|
|
219
|
+
if (moduleName) {
|
|
220
|
+
display += ` for module ${moduleName}`;
|
|
221
|
+
}
|
|
222
|
+
console.log(`${display} saved to ${usePath}`);
|
|
167
223
|
}
|
|
168
|
-
console.log('Annotations saved to ' + usePath);
|
|
169
|
-
writeFileSync(usePath, refdesVisitor.getOutput());
|
|
170
224
|
}
|
|
171
225
|
}
|
|
226
|
+
var RefdesOutputType;
|
|
227
|
+
(function (RefdesOutputType) {
|
|
228
|
+
RefdesOutputType["None"] = "none";
|
|
229
|
+
RefdesOutputType["WithSource"] = "with-source";
|
|
230
|
+
RefdesOutputType["CreateExternalFile"] = "create-external-file";
|
|
231
|
+
})(RefdesOutputType || (RefdesOutputType = {}));
|
|
172
232
|
export async function renderScript(scriptData, outputPath, options) {
|
|
173
233
|
const parseHandlers = [
|
|
174
234
|
new KiCadNetListOutputHandler(),
|
|
@@ -206,7 +266,9 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
|
|
|
206
266
|
environment.setCurrentFile(inputPath);
|
|
207
267
|
const visitor = new ParserVisitor(true, onErrorHandler, environment);
|
|
208
268
|
visitor.onImportFile = async (visitor, filePath, fileData) => {
|
|
209
|
-
|
|
269
|
+
visitor.enterFile(filePath);
|
|
270
|
+
const { hasError, hasParseError, throwError, tree, tokens } = await parseFileWithVisitor(visitor, fileData);
|
|
271
|
+
visitor.exitFile();
|
|
210
272
|
if (hasError || hasParseError) {
|
|
211
273
|
let importErrorMsg = "";
|
|
212
274
|
if (throwError) {
|
|
@@ -214,7 +276,7 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
|
|
|
214
276
|
}
|
|
215
277
|
throw new ParseError(`Error parsing imported file: ${filePath}${importErrorMsg}`, undefined, undefined, filePath);
|
|
216
278
|
}
|
|
217
|
-
return { hasError, hasParseError };
|
|
279
|
+
return { hasError, hasParseError, tree, tokens };
|
|
218
280
|
};
|
|
219
281
|
visitor.log('reading file');
|
|
220
282
|
visitor.log('done reading file');
|
|
@@ -225,6 +287,9 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
|
|
|
225
287
|
mkdirSync(dumpDirectory);
|
|
226
288
|
}
|
|
227
289
|
}
|
|
290
|
+
if (inputPath !== '') {
|
|
291
|
+
visitor.enterFile(inputPath);
|
|
292
|
+
}
|
|
228
293
|
const { tree, parser, tokens, parserTimeTaken, lexerTimeTaken, throwError } = await parseFileWithVisitor(visitor, scriptData);
|
|
229
294
|
printWarnings(visitor.getWarnings());
|
|
230
295
|
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
@@ -236,8 +301,9 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
|
|
|
236
301
|
throw new RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
237
302
|
}
|
|
238
303
|
const componentLinks = visitor.getComponentCtxLinks();
|
|
304
|
+
const importedModules = Array.from(visitor.getScope().modules.values());
|
|
239
305
|
for (let i = 0; i < postAnnotationCallbacks.length; i++) {
|
|
240
|
-
await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks);
|
|
306
|
+
await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks, importedModules, environment);
|
|
241
307
|
}
|
|
242
308
|
if (dumpNets) {
|
|
243
309
|
const nets = visitor.dumpNets();
|
|
@@ -296,6 +362,9 @@ export async function renderScriptCustom(scriptData, outputPath, options, parseH
|
|
|
296
362
|
console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
|
|
297
363
|
});
|
|
298
364
|
}
|
|
365
|
+
else {
|
|
366
|
+
console.log('No ERC issues found');
|
|
367
|
+
}
|
|
299
368
|
}
|
|
300
369
|
}
|
|
301
370
|
catch (err) {
|
package/dist/esm/layout.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import graphlib from '@dagrejs/graphlib';
|
|
2
2
|
const { alg } = graphlib;
|
|
3
3
|
import { SymbolCustom, SymbolDrawing, SymbolPlaceholder, SymbolText, PlaceHolderCommands } from "./draw_symbols.js";
|
|
4
|
-
import { defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, NetGraphicsParams, ParamKeys, WireAutoDirection } from './globals.js';
|
|
4
|
+
import { DefaultComponentUnit, defaultFrameTitleTextSize, defaultGridSizeUnits, FrameType, NetGraphicsParams, ParamKeys, WireAutoDirection } from './globals.js';
|
|
5
5
|
import { Geometry, HorizontalAlign, VerticalAlign } from './geometry.js';
|
|
6
6
|
import { FixedFrameIds, Frame, FrameParamKeys, FramePlotDirection } from './objects/Frame.js';
|
|
7
7
|
import { areasOverlap, combineMaps, getBoundsSize, printBounds, resizeBounds, resizeToNearestGrid, roundValue, toNearestGrid } from './utils.js';
|
|
@@ -301,7 +301,8 @@ export class LayoutEngine {
|
|
|
301
301
|
const avoidAreas = [];
|
|
302
302
|
if (frameParams.has(FrameParamKeys.SheetType)) {
|
|
303
303
|
const frameComponent = frameParams.get(FrameParamKeys.SheetType);
|
|
304
|
-
const
|
|
304
|
+
const frameComponentUnit = frameComponent.getUnit();
|
|
305
|
+
const frameDrawing = frameComponentUnit.displayProp;
|
|
305
306
|
frameDrawing.variables = combineMaps(frameComponent.parameters, frameParams);
|
|
306
307
|
const rects = ExtractDrawingRects(frameDrawing);
|
|
307
308
|
const drawableRect = rects.find(rect => rect.className === 'plot-area');
|
|
@@ -560,7 +561,7 @@ export class LayoutEngine {
|
|
|
560
561
|
accum.push(item);
|
|
561
562
|
}
|
|
562
563
|
else if (item instanceof RenderComponent) {
|
|
563
|
-
const { instanceName } = item.component;
|
|
564
|
+
const { instanceName } = item.component.getUnit(item.unitId);
|
|
564
565
|
if (ignoreItems.indexOf(instanceName) === -1) {
|
|
565
566
|
const withinSubgraph = subgraphInfo.find(subgraphInfo => {
|
|
566
567
|
return subgraphInfo.components.indexOf(instanceName) !== -1;
|
|
@@ -692,7 +693,9 @@ export class LayoutEngine {
|
|
|
692
693
|
const [, node1] = graph.node(firstNodeId);
|
|
693
694
|
let defaultPin = new PinId(1);
|
|
694
695
|
if (node1 instanceof RenderComponent) {
|
|
695
|
-
|
|
696
|
+
const unitId = node1.unitId;
|
|
697
|
+
const componentUnit = node1.component.getUnit(unitId);
|
|
698
|
+
defaultPin = componentUnit.pinsFlat[0].id;
|
|
696
699
|
}
|
|
697
700
|
this.placeNodeAtPosition(numeric(0), numeric(0), node1, defaultPin);
|
|
698
701
|
return;
|
|
@@ -766,7 +769,8 @@ export class LayoutEngine {
|
|
|
766
769
|
}
|
|
767
770
|
[node1, node2].forEach(item => {
|
|
768
771
|
if (item instanceof RenderWire && item.isEndAutoLength()) {
|
|
769
|
-
const [
|
|
772
|
+
const [component, pin] = item.getEndAuto();
|
|
773
|
+
const instance = component.getUnitForPin(pin);
|
|
770
774
|
const [, targetNode] = graph.node(instance.instanceName);
|
|
771
775
|
this.print('wire', item, 'auto length to target:', instance, pin);
|
|
772
776
|
if (targetNode.isFloating) {
|
|
@@ -922,24 +926,43 @@ function getNeighbours(graph, nodeIds) {
|
|
|
922
926
|
return accum;
|
|
923
927
|
}, []);
|
|
924
928
|
}
|
|
925
|
-
export function applyComponentParamsToSymbol(
|
|
926
|
-
const { widthProp = null, heightProp = null } =
|
|
927
|
-
const newMap = new Map(
|
|
928
|
-
|
|
929
|
-
|
|
929
|
+
export function applyComponentParamsToSymbol(componentUnit, symbol) {
|
|
930
|
+
const { widthProp = null, heightProp = null } = componentUnit;
|
|
931
|
+
const newMap = new Map(componentUnit.parameters);
|
|
932
|
+
const ignoreParams = [
|
|
933
|
+
ParamKeys.angle,
|
|
934
|
+
ParamKeys.flip,
|
|
935
|
+
ParamKeys.flipX,
|
|
936
|
+
ParamKeys.flipY,
|
|
937
|
+
];
|
|
938
|
+
const parentParams = componentUnit.parent.parameters;
|
|
939
|
+
parentParams.forEach((value, key) => {
|
|
940
|
+
if (ignoreParams.indexOf(key) === -1) {
|
|
941
|
+
newMap.set(key, value);
|
|
942
|
+
}
|
|
943
|
+
});
|
|
944
|
+
const refdesKey = 'refdes';
|
|
945
|
+
if (!newMap.has(refdesKey)) {
|
|
946
|
+
newMap.set(refdesKey, componentUnit.parent.assignedRefDes ?? "?");
|
|
947
|
+
}
|
|
948
|
+
if (componentUnit.refdesSuffix !== "") {
|
|
949
|
+
const tmpRefdes = newMap.get(refdesKey);
|
|
950
|
+
newMap.set(refdesKey, `${tmpRefdes}${componentUnit.refdesSuffix}`);
|
|
930
951
|
}
|
|
931
952
|
symbol.drawing.variables = newMap;
|
|
932
|
-
if (
|
|
933
|
-
const value =
|
|
953
|
+
if (componentUnit.parameters.has(ParamKeys.angle)) {
|
|
954
|
+
const value = componentUnit.parameters.get(ParamKeys.angle).toNumber();
|
|
934
955
|
symbol.angle = value;
|
|
935
956
|
}
|
|
936
|
-
if (
|
|
957
|
+
if (componentUnit.parameters.has(ParamKeys.flipX)) {
|
|
937
958
|
symbol.flipX =
|
|
938
|
-
|
|
959
|
+
componentUnit.parameters.get(ParamKeys.flipX)
|
|
960
|
+
.toNumber();
|
|
939
961
|
}
|
|
940
|
-
if (
|
|
962
|
+
if (componentUnit.parameters.has(ParamKeys.flipY)) {
|
|
941
963
|
symbol.flipY =
|
|
942
|
-
|
|
964
|
+
componentUnit.parameters.get(ParamKeys.flipY)
|
|
965
|
+
.toNumber();
|
|
943
966
|
}
|
|
944
967
|
if (symbol instanceof SymbolCustom) {
|
|
945
968
|
if (widthProp) {
|
|
@@ -1176,13 +1199,15 @@ export class RenderWire extends RenderObject {
|
|
|
1176
1199
|
}
|
|
1177
1200
|
export class RenderComponent extends RenderObject {
|
|
1178
1201
|
component;
|
|
1202
|
+
unitId = DefaultComponentUnit;
|
|
1179
1203
|
symbol;
|
|
1180
1204
|
width;
|
|
1181
1205
|
height;
|
|
1182
1206
|
displaySymbol = null;
|
|
1183
|
-
constructor(component, width, height) {
|
|
1207
|
+
constructor(component, unitId, width, height) {
|
|
1184
1208
|
super();
|
|
1185
1209
|
this.component = component;
|
|
1210
|
+
this.unitId = unitId;
|
|
1186
1211
|
this.width = width;
|
|
1187
1212
|
this.height = height;
|
|
1188
1213
|
}
|
|
@@ -1271,22 +1296,22 @@ export class RenderJunction {
|
|
|
1271
1296
|
this.net = net;
|
|
1272
1297
|
}
|
|
1273
1298
|
}
|
|
1274
|
-
export function CalculatePinPositions(
|
|
1299
|
+
export function CalculatePinPositions(unit) {
|
|
1275
1300
|
const pinPositionMapping = new Map();
|
|
1276
1301
|
let tmpSymbol;
|
|
1277
|
-
if (
|
|
1278
|
-
&&
|
|
1279
|
-
tmpSymbol = new SymbolPlaceholder(
|
|
1302
|
+
if (unit.displayProp !== null
|
|
1303
|
+
&& unit.displayProp instanceof SymbolDrawing) {
|
|
1304
|
+
tmpSymbol = new SymbolPlaceholder(unit.displayProp);
|
|
1280
1305
|
}
|
|
1281
1306
|
else {
|
|
1282
|
-
const symbolPinDefinitions = generateLayoutPinDefinition(
|
|
1283
|
-
tmpSymbol = new SymbolCustom(symbolPinDefinitions,
|
|
1307
|
+
const symbolPinDefinitions = generateLayoutPinDefinition(unit);
|
|
1308
|
+
tmpSymbol = new SymbolCustom(symbolPinDefinitions, unit.pinsMaxPositions);
|
|
1284
1309
|
}
|
|
1285
|
-
applyComponentParamsToSymbol(
|
|
1310
|
+
applyComponentParamsToSymbol(unit, tmpSymbol);
|
|
1286
1311
|
tmpSymbol.refreshDrawing();
|
|
1287
|
-
const pins =
|
|
1312
|
+
const pins = unit.pins;
|
|
1288
1313
|
pins.forEach((value, key) => {
|
|
1289
|
-
if (
|
|
1314
|
+
if (unit._unplacedPins.indexOf(key) === -1) {
|
|
1290
1315
|
pinPositionMapping.set(key, tmpSymbol.pinPosition(key));
|
|
1291
1316
|
}
|
|
1292
1317
|
});
|
package/dist/esm/main.js
CHANGED
|
@@ -14,7 +14,6 @@ export default async function main() {
|
|
|
14
14
|
.argument('[input path]', 'Input path')
|
|
15
15
|
.argument('[output path]', 'Output path')
|
|
16
16
|
.option('-i, --input text <input text>', 'Input text directly')
|
|
17
|
-
.option('-c, --current-directory <path>', 'Set current directory')
|
|
18
17
|
.option('-u, --update-source', 'Update source file with refdes annotation')
|
|
19
18
|
.option('-j, --annotated-path [file-path]', 'Save annotated source file at given path')
|
|
20
19
|
.option('-w, --watch', 'Watch for file changes')
|
|
@@ -39,9 +38,6 @@ export default async function main() {
|
|
|
39
38
|
const enableErc = options.erc;
|
|
40
39
|
const enableBom = options.bom !== undefined;
|
|
41
40
|
let bomOutputPath = options.bom;
|
|
42
|
-
if (options.currentDirectory) {
|
|
43
|
-
throw "Parameter not supported yet";
|
|
44
|
-
}
|
|
45
41
|
if (watchFileChanges) {
|
|
46
42
|
console.log('watching for file changes...');
|
|
47
43
|
}
|
|
@@ -52,22 +48,20 @@ export default async function main() {
|
|
|
52
48
|
return;
|
|
53
49
|
}
|
|
54
50
|
let scriptData;
|
|
55
|
-
if (
|
|
56
|
-
inputFilePath = args[0];
|
|
57
|
-
if ((await env.exists(inputFilePath))) {
|
|
58
|
-
scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
console.error("Error: File could not be found");
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
else if (options.input) {
|
|
51
|
+
if (options.input) {
|
|
66
52
|
scriptData = options.input;
|
|
67
53
|
}
|
|
68
54
|
else {
|
|
69
|
-
|
|
70
|
-
|
|
55
|
+
if (args.length > 0 && args[0]) {
|
|
56
|
+
inputFilePath = args[0];
|
|
57
|
+
if ((await env.exists(inputFilePath))) {
|
|
58
|
+
scriptData = await env.readFile(inputFilePath, { encoding: 'utf-8' });
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
console.error("Error: File could not be found");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
71
65
|
}
|
|
72
66
|
let updateSource = false;
|
|
73
67
|
if (options.updateSource !== undefined) {
|
|
@@ -98,7 +92,10 @@ export default async function main() {
|
|
|
98
92
|
saveAnnotatedCopy: saveAnnotatedCopyPath,
|
|
99
93
|
};
|
|
100
94
|
let outputPath = null;
|
|
101
|
-
if (args.length > 0 && args[
|
|
95
|
+
if (options.input && args.length > 0 && args[0]) {
|
|
96
|
+
outputPath = args[0];
|
|
97
|
+
}
|
|
98
|
+
else if (args.length > 0 && args[1]) {
|
|
102
99
|
outputPath = args[1];
|
|
103
100
|
}
|
|
104
101
|
const output = await parseFile(scriptData, outputPath, scriptOptions);
|
|
@@ -127,6 +124,7 @@ async function parseFile(scriptData, outputPath, scriptOptions) {
|
|
|
127
124
|
}
|
|
128
125
|
catch (error) {
|
|
129
126
|
console.error(`Unexpected Error: ${error}`);
|
|
127
|
+
console.log(error.stack);
|
|
130
128
|
}
|
|
131
129
|
return null;
|
|
132
130
|
}
|
|
@@ -1,8 +1,133 @@
|
|
|
1
1
|
import { SymbolDrawingCommands } from '../draw_symbols.js';
|
|
2
2
|
import { PinDefinition, PinId, PinIdType } from './PinDefinition.js';
|
|
3
3
|
import { PinTypes } from './PinTypes.js';
|
|
4
|
-
import { ParamKeys } from '../globals.js';
|
|
4
|
+
import { DefaultComponentUnit, ParamKeys } from '../globals.js';
|
|
5
5
|
import { RuntimeExecutionError } from '../utils.js';
|
|
6
|
+
export class ComponentUnit {
|
|
7
|
+
parent;
|
|
8
|
+
unitId;
|
|
9
|
+
refdesSuffix = "A";
|
|
10
|
+
suffix = null;
|
|
11
|
+
get instanceName() {
|
|
12
|
+
return `${this.parent.instanceName},${this.unitId}`;
|
|
13
|
+
}
|
|
14
|
+
parameters = new Map();
|
|
15
|
+
numPins;
|
|
16
|
+
pins = new Map();
|
|
17
|
+
pinsFlat = [];
|
|
18
|
+
pinsMaxPositions = new Map();
|
|
19
|
+
arrangeProps = null;
|
|
20
|
+
displayProp = null;
|
|
21
|
+
widthProp = null;
|
|
22
|
+
heightProp = null;
|
|
23
|
+
angleProp = 0;
|
|
24
|
+
followWireOrientationProp = true;
|
|
25
|
+
wireOrientationAngle = 0;
|
|
26
|
+
useWireOrientationAngle = true;
|
|
27
|
+
didSetWireOrientationAngle = false;
|
|
28
|
+
_unplacedPins = [];
|
|
29
|
+
constructor(unitId, parent) {
|
|
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 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
|
+
}
|
|
6
131
|
export class ClassComponent {
|
|
7
132
|
instanceName;
|
|
8
133
|
numPins;
|
|
@@ -11,27 +136,21 @@ export class ClassComponent {
|
|
|
11
136
|
pinNets = new Map();
|
|
12
137
|
pinWires = new Map();
|
|
13
138
|
pinsMaxPositions = new Map();
|
|
139
|
+
units = [];
|
|
14
140
|
_cachedPins;
|
|
15
141
|
_cachedParams;
|
|
16
142
|
_copyID = null;
|
|
17
143
|
_copyFrom = null;
|
|
18
144
|
_pointLinkComponent;
|
|
19
145
|
_unplacedPins = [];
|
|
20
|
-
arrangeProps = null;
|
|
21
|
-
displayProp = null;
|
|
22
|
-
widthProp = null;
|
|
23
|
-
heightProp = null;
|
|
24
146
|
typeProp = null;
|
|
25
147
|
copyProp = false;
|
|
26
|
-
angleProp = 0;
|
|
27
|
-
followWireOrientationProp = true;
|
|
28
|
-
wireOrientationAngle = 0;
|
|
29
|
-
useWireOrientationAngle = true;
|
|
30
|
-
didSetWireOrientationAngle = false;
|
|
31
148
|
assignedRefDes = null;
|
|
32
149
|
placeHolderRefDes = null;
|
|
150
|
+
forceSaveRefdesAnnotation = false;
|
|
33
151
|
ctxReferences = [];
|
|
34
152
|
_creationIndex = -1;
|
|
153
|
+
pinUnitMap = new Map();
|
|
35
154
|
constructor(instanceName, numPins) {
|
|
36
155
|
this.instanceName = instanceName;
|
|
37
156
|
this.numPins = numPins;
|
|
@@ -123,31 +242,32 @@ export class ClassComponent {
|
|
|
123
242
|
return component;
|
|
124
243
|
}
|
|
125
244
|
isEqual(other) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
245
|
+
if (this === other)
|
|
246
|
+
return true;
|
|
247
|
+
if (this.instanceName !== other.instanceName)
|
|
248
|
+
return false;
|
|
249
|
+
if (this._copyID !== other._copyID)
|
|
250
|
+
return false;
|
|
251
|
+
if (this.typeProp !== other.typeProp)
|
|
252
|
+
return false;
|
|
253
|
+
if (this._cachedPins !== other._cachedPins)
|
|
254
|
+
return false;
|
|
255
|
+
if (this._cachedParams !== other._cachedParams)
|
|
256
|
+
return false;
|
|
257
|
+
for (let i = 0; i < this.units.length; i++) {
|
|
258
|
+
if (other.units[i] === undefined) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (!other.units[i].isEqual(this.units[i])) {
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return true;
|
|
137
266
|
}
|
|
138
267
|
clone() {
|
|
139
268
|
const component = new ClassComponent(this.instanceName, this.numPins);
|
|
140
269
|
component._copyID = this._copyID;
|
|
141
|
-
component.arrangeProps = this.arrangeProps;
|
|
142
|
-
component.widthProp = this.widthProp;
|
|
143
270
|
component.typeProp = this.typeProp;
|
|
144
|
-
component.angleProp = this.angleProp;
|
|
145
|
-
component.followWireOrientationProp = this.followWireOrientationProp;
|
|
146
|
-
component.useWireOrientationAngle = this.useWireOrientationAngle;
|
|
147
|
-
if (this.displayProp instanceof SymbolDrawingCommands) {
|
|
148
|
-
component.displayProp =
|
|
149
|
-
this.displayProp.clone();
|
|
150
|
-
}
|
|
151
271
|
for (const [key, value] of this.parameters) {
|
|
152
272
|
if (key === ParamKeys.flipX || key === ParamKeys.flipY || key === ParamKeys.angle) {
|
|
153
273
|
continue;
|
|
@@ -160,9 +280,60 @@ export class ClassComponent {
|
|
|
160
280
|
for (const [key, value] of this.pinsMaxPositions) {
|
|
161
281
|
component.pinsMaxPositions.set(key, value);
|
|
162
282
|
}
|
|
283
|
+
component.units = this.units.map(unit => {
|
|
284
|
+
const tmpUnit = unit.clone();
|
|
285
|
+
tmpUnit.parent = component;
|
|
286
|
+
return tmpUnit;
|
|
287
|
+
});
|
|
163
288
|
component.refreshCache();
|
|
289
|
+
component.refreshPinUnitMap();
|
|
164
290
|
return component;
|
|
165
291
|
}
|
|
292
|
+
getUnit(unitId = null) {
|
|
293
|
+
if (unitId === null) {
|
|
294
|
+
return this.units[0];
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
return this.units.find(item => {
|
|
298
|
+
return item.unitId === unitId;
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
addDefaultUnit(displayProp) {
|
|
303
|
+
const tmpUnit = new ComponentUnit(DefaultComponentUnit, this);
|
|
304
|
+
tmpUnit.pins = this.pins;
|
|
305
|
+
const pinsFlat = [];
|
|
306
|
+
this.pins.forEach(pin => {
|
|
307
|
+
pinsFlat.push(pin);
|
|
308
|
+
});
|
|
309
|
+
tmpUnit.pinsFlat = pinsFlat;
|
|
310
|
+
tmpUnit.numPins = this.numPins;
|
|
311
|
+
tmpUnit.pinsMaxPositions = new Map();
|
|
312
|
+
tmpUnit.displayProp = displayProp;
|
|
313
|
+
tmpUnit.angleProp = 0;
|
|
314
|
+
tmpUnit.followWireOrientationProp = true;
|
|
315
|
+
this.units.push(tmpUnit);
|
|
316
|
+
this.refreshPinUnitMap();
|
|
317
|
+
}
|
|
318
|
+
refreshPinUnitMap() {
|
|
319
|
+
for (const unit of this.units) {
|
|
320
|
+
const { pinsFlat } = unit;
|
|
321
|
+
for (const pin of pinsFlat) {
|
|
322
|
+
this.pinUnitMap.set(pin.id, unit);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
getUnitForPin(pinId) {
|
|
327
|
+
if (typeof pinId === "number") {
|
|
328
|
+
throw new RuntimeExecutionError("Invalid pin id");
|
|
329
|
+
}
|
|
330
|
+
for (const [tmpPin, componentUnit] of this.pinUnitMap) {
|
|
331
|
+
if (tmpPin.equals(pinId)) {
|
|
332
|
+
return componentUnit;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
throw new RuntimeExecutionError("Could not find unit for pin: " + pinId);
|
|
336
|
+
}
|
|
166
337
|
}
|
|
167
338
|
export class ModuleComponent extends ClassComponent {
|
|
168
339
|
moduleContainsExpressions;
|
|
@@ -135,10 +135,16 @@ export class ImportedModule {
|
|
|
135
135
|
specifiedImports;
|
|
136
136
|
moduleNamespace;
|
|
137
137
|
moduleFilePath;
|
|
138
|
-
|
|
138
|
+
enableRefdesAnnotation = false;
|
|
139
|
+
enableRefdesAnnotationFile = false;
|
|
140
|
+
tree;
|
|
141
|
+
tokens;
|
|
142
|
+
constructor(moduleName, moduleNamespace, moduleFilePath, tree, tokens, context, flag, specifiedImports) {
|
|
139
143
|
this.moduleName = moduleName;
|
|
140
144
|
this.moduleNamespace = moduleNamespace;
|
|
141
145
|
this.moduleFilePath = moduleFilePath;
|
|
146
|
+
this.tree = tree;
|
|
147
|
+
this.tokens = tokens;
|
|
142
148
|
this.context = context;
|
|
143
149
|
this.importHandlingFlag = flag;
|
|
144
150
|
this.specifiedImports = specifiedImports;
|