circuitscript 0.3.2 → 0.4.0
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 +394 -262
- package/dist/cjs/LexerDiagnosticListener.js +375 -0
- package/dist/cjs/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
- package/dist/cjs/annotate/DefaultPostAnnotationCallback.js +126 -0
- package/dist/cjs/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
- package/dist/cjs/annotate/utils.js +70 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +279 -286
- package/dist/cjs/antlr/CircuitScriptParser.js +1954 -3535
- package/dist/cjs/antlr/CircuitScriptParserVisitor.js +7 -0
- package/dist/cjs/cache/deserializer.js +34 -0
- package/dist/cjs/cache/hash.js +8 -0
- package/dist/cjs/cache/serializer.js +122 -0
- package/dist/cjs/cache/storage.js +45 -0
- package/dist/cjs/cache/types.js +4 -0
- package/dist/cjs/{environment.js → environment/environment.js} +18 -6
- package/dist/cjs/environment/esm-environment.js +21 -0
- package/dist/cjs/environment/helpers.js +8 -0
- package/dist/cjs/execute.js +49 -15
- package/dist/cjs/globals.js +9 -1
- package/dist/cjs/helpers.js +3 -485
- package/dist/cjs/importResolver.js +102 -0
- package/dist/cjs/index.js +7 -6
- package/dist/cjs/lexer.js +48 -12
- package/dist/cjs/main.js +14 -4
- package/dist/cjs/objects/ClassComponent.js +1 -1
- package/dist/cjs/objects/ExecutionScope.js +0 -1
- package/dist/cjs/objects/types.js +17 -1
- package/dist/cjs/parser.js +18 -4
- package/dist/cjs/pipeline.js +284 -0
- package/dist/cjs/regenerate-tests.js +4 -3
- package/dist/cjs/render/KiCadNetListOutputHandler.js +30 -0
- package/dist/cjs/render/PaperSizes.js +46 -0
- package/dist/cjs/{draw_symbols.js → render/draw_symbols.js} +58 -36
- package/dist/cjs/{export.js → render/export.js} +2 -2
- package/dist/cjs/{geometry.js → render/geometry.js} +5 -5
- package/dist/cjs/{graph.js → render/graph.js} +7 -7
- package/dist/cjs/{layout.js → render/layout.js} +8 -8
- package/dist/cjs/{render.js → render/render.js} +9 -8
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +1 -1
- package/dist/cjs/rules-check/unconnected-pins.js +1 -1
- package/dist/cjs/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
- package/dist/cjs/semantic-tokens/getSemanticTokens.js +55 -0
- package/dist/cjs/sizing.js +2 -2
- package/dist/cjs/utils.js +2 -2
- package/dist/cjs/validate/SymbolValidatorResolveVisitor.js +6 -0
- package/dist/cjs/validate/SymbolValidatorVisitor.js +34 -39
- package/dist/cjs/validate/validateScript.js +54 -0
- package/dist/cjs/validate.js +5 -4
- package/dist/cjs/visitor.js +140 -204
- package/dist/esm/BaseVisitor.js +396 -264
- package/dist/esm/LexerDiagnosticListener.js +371 -0
- package/dist/esm/{ComponentAnnotater.js → annotate/ComponentAnnotater.js} +29 -15
- package/dist/esm/annotate/DefaultPostAnnotationCallback.js +122 -0
- package/dist/esm/{RefdesAnnotationVisitor.js → annotate/RefdesAnnotationVisitor.js} +8 -82
- package/dist/esm/annotate/utils.js +66 -0
- package/dist/esm/antlr/CircuitScriptLexer.js +279 -286
- package/dist/esm/antlr/CircuitScriptParser.js +1962 -3522
- package/dist/esm/antlr/{CircuitScriptVisitor.js → CircuitScriptParserVisitor.js} +14 -35
- package/dist/esm/cache/deserializer.js +30 -0
- package/dist/esm/cache/hash.js +4 -0
- package/dist/esm/cache/serializer.js +118 -0
- package/dist/esm/cache/storage.js +39 -0
- package/dist/esm/cache/types.js +1 -0
- package/dist/esm/{environment.js → environment/environment.js} +18 -6
- package/dist/esm/environment/esm-environment.js +17 -0
- package/dist/esm/environment/helpers.js +4 -0
- package/dist/esm/execute.js +49 -15
- package/dist/esm/globals.js +8 -0
- package/dist/esm/helpers.js +5 -474
- package/dist/esm/importResolver.js +96 -0
- package/dist/esm/index.js +7 -6
- package/dist/esm/lexer.js +51 -12
- package/dist/esm/main.js +13 -3
- package/dist/esm/objects/ClassComponent.js +1 -1
- package/dist/esm/objects/ExecutionScope.js +0 -1
- package/dist/esm/objects/types.js +21 -1
- package/dist/esm/parser.js +19 -5
- package/dist/esm/pipeline.js +276 -0
- package/dist/esm/regenerate-tests.js +3 -2
- package/dist/esm/render/KiCadNetListOutputHandler.js +20 -0
- package/dist/esm/render/PaperSizes.js +41 -0
- package/dist/esm/{draw_symbols.js → render/draw_symbols.js} +58 -36
- package/dist/esm/{export.js → render/export.js} +2 -2
- package/dist/esm/{geometry.js → render/geometry.js} +5 -5
- package/dist/esm/{graph.js → render/graph.js} +7 -7
- package/dist/esm/{layout.js → render/layout.js} +8 -8
- package/dist/esm/{render.js → render/render.js} +8 -7
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +1 -1
- package/dist/esm/rules-check/unconnected-pins.js +1 -1
- package/dist/esm/{SemanticTokenVisitor.js → semantic-tokens/SemanticTokenVisitor.js} +12 -14
- package/dist/esm/semantic-tokens/getSemanticTokens.js +51 -0
- package/dist/esm/sizing.js +2 -2
- package/dist/esm/utils.js +2 -2
- package/dist/esm/validate/SymbolValidatorResolveVisitor.js +3 -0
- package/dist/esm/validate/SymbolValidatorVisitor.js +36 -41
- package/dist/esm/validate/validateScript.js +50 -0
- package/dist/esm/validate.js +4 -3
- package/dist/esm/visitor.js +142 -206
- package/dist/libs/std.cst +15 -19
- package/dist/types/BaseVisitor.d.ts +25 -18
- package/dist/types/BomGeneration.d.ts +1 -1
- package/dist/types/LexerDiagnosticListener.d.ts +85 -0
- package/dist/types/{ComponentAnnotater.d.ts → annotate/ComponentAnnotater.d.ts} +1 -1
- package/dist/types/annotate/DefaultPostAnnotationCallback.d.ts +7 -0
- package/dist/types/{RefdesAnnotationVisitor.d.ts → annotate/RefdesAnnotationVisitor.d.ts} +6 -8
- package/dist/types/annotate/utils.d.ts +6 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +71 -70
- package/dist/types/antlr/CircuitScriptParser.d.ts +357 -515
- package/dist/types/antlr/{CircuitScriptVisitor.d.ts → CircuitScriptParserVisitor.d.ts} +27 -69
- package/dist/types/cache/deserializer.d.ts +5 -0
- package/dist/types/cache/hash.d.ts +1 -0
- package/dist/types/cache/serializer.d.ts +3 -0
- package/dist/types/cache/storage.d.ts +4 -0
- package/dist/types/cache/types.d.ts +20 -0
- package/dist/types/{environment.d.ts → environment/environment.d.ts} +5 -4
- package/dist/types/environment/esm-environment.d.ts +4 -0
- package/dist/types/environment/helpers.d.ts +2 -0
- package/dist/types/execute.d.ts +3 -2
- package/dist/types/globals.d.ts +1 -0
- package/dist/types/helpers.d.ts +31 -36
- package/dist/types/importResolver.d.ts +4 -0
- package/dist/types/index.d.ts +7 -6
- package/dist/types/lexer.d.ts +9 -5
- package/dist/types/objects/ClassComponent.d.ts +1 -1
- package/dist/types/objects/ExecutionScope.d.ts +1 -4
- package/dist/types/objects/types.d.ts +16 -2
- package/dist/types/parser.d.ts +9 -2
- package/dist/types/pipeline.d.ts +9 -0
- package/dist/types/render/KiCadNetListOutputHandler.d.ts +10 -0
- package/dist/types/render/PaperSizes.d.ts +12 -0
- package/dist/types/{draw_symbols.d.ts → render/draw_symbols.d.ts} +4 -4
- package/dist/types/{export.d.ts → render/export.d.ts} +1 -1
- package/dist/types/{geometry.d.ts → render/geometry.d.ts} +2 -2
- package/dist/types/{graph.d.ts → render/graph.d.ts} +6 -6
- package/dist/types/{layout.d.ts → render/layout.d.ts} +10 -10
- package/dist/types/{render.d.ts → render/render.d.ts} +1 -1
- package/dist/types/{SemanticTokenVisitor.d.ts → semantic-tokens/SemanticTokenVisitor.d.ts} +6 -6
- package/dist/types/semantic-tokens/getSemanticTokens.d.ts +6 -0
- package/dist/types/sizing.d.ts +1 -1
- package/dist/types/utils.d.ts +1 -1
- package/dist/types/validate/SymbolValidatorResolveVisitor.d.ts +3 -0
- package/dist/types/validate/SymbolValidatorVisitor.d.ts +8 -8
- package/dist/types/validate/validateScript.d.ts +3 -0
- package/dist/types/visitor.d.ts +8 -14
- package/libs/std.cst +15 -19
- package/package.json +3 -6
- package/dist/cjs/antlr/CircuitScriptVisitor.js +0 -7
package/dist/esm/helpers.js
CHANGED
|
@@ -1,25 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import { generateKiCadNetList, printTree } from "./export.js";
|
|
4
|
-
import { LayoutEngine } from "./layout.js";
|
|
5
|
-
import { parseFileWithVisitor } from "./parser.js";
|
|
6
|
-
import { generatePdfOutput, generateSvgOutput, renderSheetsToSVG } from "./render.js";
|
|
7
|
-
import { generateDebugSequenceAction, ParseError, ParseSyntaxError, printWarnings, RenderError, resolveToNumericValue, RuntimeExecutionError, sequenceActionString, SimpleStopwatch } from "./utils.js";
|
|
8
|
-
import { ParserVisitor } from "./visitor.js";
|
|
9
|
-
import { SymbolValidatorVisitor } from "./validate/SymbolValidatorVisitor.js";
|
|
10
|
-
import { SymbolValidatorResolveVisitor } from "./validate/SymbolValidatorResolveVisitor.js";
|
|
11
|
-
import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy, RecognitionException } from "antlr4ng";
|
|
1
|
+
import { resolveToNumericValue, SimpleStopwatch } from "./utils.js";
|
|
2
|
+
import { BaseErrorListener, CharStream, CommonTokenStream, DefaultErrorStrategy } from "antlr4ng";
|
|
12
3
|
import { MainLexer } from "./lexer.js";
|
|
13
4
|
import { CircuitScriptParser } from "./antlr/CircuitScriptParser.js";
|
|
14
|
-
import {
|
|
15
|
-
import { defaultPageMarginMM, defaultZoomScale, LengthUnit, MilsToMM, PxToMM, RefdesFileSuffix } from "./globals.js";
|
|
16
|
-
import { FrameParamKeys } from "./objects/Frame.js";
|
|
5
|
+
import { LengthUnit, MilsToMM, PxToMM } from "./globals.js";
|
|
17
6
|
import Big from "big.js";
|
|
18
|
-
import { Logger } from "./logger.js";
|
|
19
|
-
import { NetGraph } from "./graph.js";
|
|
20
|
-
import { RefdesAnnotationVisitor } from "./RefdesAnnotationVisitor.js";
|
|
21
|
-
import { EvaluateERCRules } from "./rules-check/rules.js";
|
|
22
|
-
import { generateBom, generateBomCSV, saveBomOutputCsv } from "./BomGeneration.js";
|
|
23
7
|
export var JSModuleType;
|
|
24
8
|
(function (JSModuleType) {
|
|
25
9
|
JSModuleType["CommonJs"] = "cjs";
|
|
@@ -40,54 +24,7 @@ export function prepareFile(textData) {
|
|
|
40
24
|
tokens
|
|
41
25
|
};
|
|
42
26
|
}
|
|
43
|
-
export
|
|
44
|
-
const { parser, lexer, tokens } = prepareFile(scriptData);
|
|
45
|
-
const tree = parser.script();
|
|
46
|
-
const visitor = new SemanticTokensVisitor(true, null, options.environment, lexer, scriptData);
|
|
47
|
-
parser.removeErrorListeners();
|
|
48
|
-
visitor.onImportFile = async (visitor, filePath, textData) => {
|
|
49
|
-
let hasError = false;
|
|
50
|
-
let hasParseError = false;
|
|
51
|
-
if (textData !== null) {
|
|
52
|
-
const { parser } = prepareFile(textData);
|
|
53
|
-
const tree = parser.script();
|
|
54
|
-
try {
|
|
55
|
-
visitor.visit(tree);
|
|
56
|
-
}
|
|
57
|
-
catch (err) {
|
|
58
|
-
console.log('Error while parsing: ', err);
|
|
59
|
-
hasParseError = true;
|
|
60
|
-
hasError = true;
|
|
61
|
-
throw new ParseError(`Error parsing semantic tokens in imported file: ${err}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
console.log('File does not exist');
|
|
66
|
-
hasError = true;
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
hasError, hasParseError
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
await visitor.visitAsync(tree);
|
|
73
|
-
const semanticTokens = visitor.getTokens();
|
|
74
|
-
const parsedTokens = prepareTokens(tokens.getTokens(), lexer, scriptData);
|
|
75
|
-
const finalParsedTokens = [];
|
|
76
|
-
parsedTokens.forEach(token => {
|
|
77
|
-
const location = `${token.line}_${token.column}_${token.length}`;
|
|
78
|
-
if (semanticTokens.has(location)) {
|
|
79
|
-
finalParsedTokens.push(semanticTokens.get(location));
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
finalParsedTokens.push(token);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
return {
|
|
86
|
-
visitor,
|
|
87
|
-
parsedTokens: finalParsedTokens
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
class TokenErrorListener extends BaseErrorListener {
|
|
27
|
+
export class TokenErrorListener extends BaseErrorListener {
|
|
91
28
|
syntaxError(recognizer, offendingSymbol, line, column, msg, e) {
|
|
92
29
|
console.log(msg);
|
|
93
30
|
}
|
|
@@ -105,375 +42,12 @@ export class ParseErrorStrategy extends DefaultErrorStrategy {
|
|
|
105
42
|
this.endErrorCondition(recognizer);
|
|
106
43
|
}
|
|
107
44
|
}
|
|
108
|
-
export
|
|
109
|
-
const { parser } = prepareFile(scriptData);
|
|
110
|
-
parser.removeErrorListeners();
|
|
111
|
-
parser.errorHandler = new ParseErrorStrategy();
|
|
112
|
-
parser.addErrorListener(new TokenErrorListener());
|
|
113
|
-
const tree = parser.script();
|
|
114
|
-
const visitor = new SymbolValidatorVisitor(true, null, options.environment);
|
|
115
|
-
visitor.enterFile(filePath);
|
|
116
|
-
visitor.onImportFile = async (visitor, filePath, textData) => {
|
|
117
|
-
visitor.enterFile(filePath);
|
|
118
|
-
let hasError = false;
|
|
119
|
-
let hasParseError = false;
|
|
120
|
-
if (textData !== null) {
|
|
121
|
-
const { parser } = prepareFile(textData);
|
|
122
|
-
const tree = parser.script();
|
|
123
|
-
try {
|
|
124
|
-
await visitor.visitAsync(tree);
|
|
125
|
-
visitor.exitFile();
|
|
126
|
-
}
|
|
127
|
-
catch (err) {
|
|
128
|
-
console.log('got an error while parsing tree: ', err);
|
|
129
|
-
hasParseError = true;
|
|
130
|
-
hasError = true;
|
|
131
|
-
throw new ParseError(`Error parsing validation in imported file: ${err}`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
console.log('file does not exist!');
|
|
136
|
-
hasError = true;
|
|
137
|
-
}
|
|
138
|
-
return {
|
|
139
|
-
hasError, hasParseError
|
|
140
|
-
};
|
|
141
|
-
};
|
|
142
|
-
await visitor.visitAsync(tree);
|
|
143
|
-
const symbolTable = visitor.getSymbols();
|
|
144
|
-
symbolTable.clearUndefined();
|
|
145
|
-
const visitorResolver = new SymbolValidatorResolveVisitor(true, null, options.environment);
|
|
146
|
-
visitorResolver.enterFile(filePath);
|
|
147
|
-
visitorResolver.setSymbols(visitor.getSymbols());
|
|
148
|
-
visitorResolver.onImportFile = visitor.onImportFile;
|
|
149
|
-
await visitorResolver.visitAsync(tree);
|
|
150
|
-
return visitorResolver;
|
|
151
|
-
}
|
|
152
|
-
async function DefaultPostAnnotationCallback(options, scriptData, tree, tokens, componentLinks, importedLibraries, environment) {
|
|
153
|
-
const { inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
|
|
154
|
-
if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
|
|
155
|
-
const sourceAnnotatedFiles = [{
|
|
156
|
-
isMainFile: true,
|
|
157
|
-
scriptData,
|
|
158
|
-
tokens,
|
|
159
|
-
tree,
|
|
160
|
-
filePath: inputPath,
|
|
161
|
-
outputType: RefdesOutputType.WithSource
|
|
162
|
-
}];
|
|
163
|
-
const externalRefdesLibraries = [];
|
|
164
|
-
for (const library of importedLibraries) {
|
|
165
|
-
let outputType = RefdesOutputType.None;
|
|
166
|
-
if (library.enableRefdesAnnotation) {
|
|
167
|
-
outputType = RefdesOutputType.WithSource;
|
|
168
|
-
}
|
|
169
|
-
else if (library.enableRefdesAnnotationFile) {
|
|
170
|
-
outputType = RefdesOutputType.CreateExternalFile;
|
|
171
|
-
}
|
|
172
|
-
if (outputType !== RefdesOutputType.None) {
|
|
173
|
-
const { libraryFilePath, libraryName, tokens: libTokens, tree: libTree } = library;
|
|
174
|
-
const libraryScriptData = await environment.readFile(libraryFilePath, { encoding: 'utf8' });
|
|
175
|
-
const annotatedFile = {
|
|
176
|
-
tokens: libTokens,
|
|
177
|
-
tree: libTree,
|
|
178
|
-
filePath: libraryFilePath,
|
|
179
|
-
scriptData: libraryScriptData,
|
|
180
|
-
libraryName,
|
|
181
|
-
outputType
|
|
182
|
-
};
|
|
183
|
-
if (outputType === RefdesOutputType.CreateExternalFile) {
|
|
184
|
-
externalRefdesLibraries.push(annotatedFile);
|
|
185
|
-
}
|
|
186
|
-
else {
|
|
187
|
-
sourceAnnotatedFiles.push(annotatedFile);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
for (const item of sourceAnnotatedFiles) {
|
|
192
|
-
const { scriptData, tokens, tree, filePath, libraryName, isMainFile = false } = item;
|
|
193
|
-
const tmpVisitor = new RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
194
|
-
await tmpVisitor.visit(tree);
|
|
195
|
-
let usePath = filePath;
|
|
196
|
-
if (isMainFile && saveAnnotatedCopy === true) {
|
|
197
|
-
const dir = environment.dirname(filePath);
|
|
198
|
-
const ext = environment.extname(filePath);
|
|
199
|
-
const basename = environment.basename(filePath, ext);
|
|
200
|
-
usePath = environment.join(dir, `${basename}.annotated${ext}`);
|
|
201
|
-
}
|
|
202
|
-
else if (isMainFile && typeof saveAnnotatedCopy === 'string') {
|
|
203
|
-
usePath = saveAnnotatedCopy;
|
|
204
|
-
}
|
|
205
|
-
environment.writeFileSync(usePath, tmpVisitor.getOutput());
|
|
206
|
-
let display = 'Refdes annotations';
|
|
207
|
-
if (libraryName) {
|
|
208
|
-
display += ` for library ${libraryName}`;
|
|
209
|
-
}
|
|
210
|
-
console.log(`${display} saved to ${usePath}`);
|
|
211
|
-
}
|
|
212
|
-
if (externalRefdesLibraries.length > 0) {
|
|
213
|
-
const inputDir = environment.dirname(inputPath);
|
|
214
|
-
const inputExt = environment.extname(inputPath);
|
|
215
|
-
const inputBasename = environment.basename(inputPath, inputExt);
|
|
216
|
-
const refdesFilePath = environment.join(inputDir, `${inputBasename}${RefdesFileSuffix}`);
|
|
217
|
-
const libraries = [];
|
|
218
|
-
for (const item of externalRefdesLibraries) {
|
|
219
|
-
const { scriptData, tokens, tree, filePath, libraryName } = item;
|
|
220
|
-
const tmpVisitor = new RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
221
|
-
await tmpVisitor.visit(tree);
|
|
222
|
-
const output = tmpVisitor.getOutputForExternalRefdesFile();
|
|
223
|
-
const relativeFilePath = environment.relative(inputDir, filePath);
|
|
224
|
-
libraries.push({
|
|
225
|
-
name: libraryName,
|
|
226
|
-
path: relativeFilePath,
|
|
227
|
-
items: output,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
const sortedLibs = libraries.sort((a, b) => {
|
|
231
|
-
return a.name.localeCompare(b.name);
|
|
232
|
-
});
|
|
233
|
-
const jsonFile = {
|
|
234
|
-
format: 'v1',
|
|
235
|
-
description: 'Stores external refdes for libraries',
|
|
236
|
-
libraries: sortedLibs,
|
|
237
|
-
};
|
|
238
|
-
environment.writeFileSync(refdesFilePath, JSON.stringify(jsonFile, null, 4));
|
|
239
|
-
console.log(`External refdes annotations saved to ${refdesFilePath}`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
var RefdesOutputType;
|
|
45
|
+
export var RefdesOutputType;
|
|
244
46
|
(function (RefdesOutputType) {
|
|
245
47
|
RefdesOutputType["None"] = "none";
|
|
246
48
|
RefdesOutputType["WithSource"] = "with-source";
|
|
247
49
|
RefdesOutputType["CreateExternalFile"] = "create-external-file";
|
|
248
50
|
})(RefdesOutputType || (RefdesOutputType = {}));
|
|
249
|
-
export async function renderScript(scriptData, outputPath, options) {
|
|
250
|
-
const parseHandlers = [
|
|
251
|
-
new KiCadNetListOutputHandler(),
|
|
252
|
-
];
|
|
253
|
-
return renderScriptCustom(scriptData, outputPath, options, parseHandlers, [DefaultPostAnnotationCallback]);
|
|
254
|
-
}
|
|
255
|
-
export async function renderScriptCustom(scriptData, outputPath, options, parseHandlers, postAnnotationCallbacks) {
|
|
256
|
-
const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, inputPath = '', bomOutputPath = undefined, environment } = options;
|
|
257
|
-
const errors = [];
|
|
258
|
-
const onErrorHandler = (message, context, error) => {
|
|
259
|
-
if (error && error instanceof RuntimeExecutionError) {
|
|
260
|
-
errors.push(error);
|
|
261
|
-
}
|
|
262
|
-
else if (error && error instanceof RecognitionException) {
|
|
263
|
-
if (context !== null) {
|
|
264
|
-
errors.push(new ParseSyntaxError(message, context.start, context.stop));
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
if (error.recognizer) {
|
|
268
|
-
const recognizer = error.recognizer;
|
|
269
|
-
errors.push(new ParseSyntaxError(message, {
|
|
270
|
-
line: recognizer.currentTokenStartLine,
|
|
271
|
-
column: recognizer.currentTokenColumn
|
|
272
|
-
}));
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
errors.push(new ParseSyntaxError(message));
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
errors.push(new ParseError(message, context.start, context.stop));
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
environment.setCurrentFile(inputPath);
|
|
284
|
-
const visitor = new ParserVisitor(true, onErrorHandler, environment);
|
|
285
|
-
visitor.onImportFile = async (visitor, filePath, fileData) => {
|
|
286
|
-
visitor.enterFile(filePath);
|
|
287
|
-
const { hasError, hasParseError, throwError, tree, tokens } = await parseFileWithVisitor(visitor, fileData);
|
|
288
|
-
visitor.exitFile();
|
|
289
|
-
if (hasError || hasParseError) {
|
|
290
|
-
let importErrorMsg = "";
|
|
291
|
-
if (throwError) {
|
|
292
|
-
importErrorMsg = ": " + throwError.message;
|
|
293
|
-
}
|
|
294
|
-
throw new ParseError(`Error parsing imported file: ${filePath}${importErrorMsg}`, undefined, undefined, filePath);
|
|
295
|
-
}
|
|
296
|
-
return { hasError, hasParseError, tree, tokens };
|
|
297
|
-
};
|
|
298
|
-
visitor.log('reading file');
|
|
299
|
-
visitor.log('done reading file');
|
|
300
|
-
const dumpDirectory = environment.getRelativeToModule('/dump/');
|
|
301
|
-
if (dumpData) {
|
|
302
|
-
console.log('Dump data to:', dumpDirectory);
|
|
303
|
-
if (!environment.existsSync(dumpDirectory)) {
|
|
304
|
-
environment.mkdirSync(dumpDirectory);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
if (inputPath !== '') {
|
|
308
|
-
visitor.enterFile(inputPath);
|
|
309
|
-
}
|
|
310
|
-
const { tree, parser, tokens, parserTimeTaken, lexerTimeTaken, throwError } = await parseFileWithVisitor(visitor, scriptData);
|
|
311
|
-
printWarnings(visitor.getWarnings());
|
|
312
|
-
showStats && console.log('Lexing took:', lexerTimeTaken);
|
|
313
|
-
showStats && console.log('Parsing took:', parserTimeTaken);
|
|
314
|
-
try {
|
|
315
|
-
visitor.annotateComponents();
|
|
316
|
-
}
|
|
317
|
-
catch (err) {
|
|
318
|
-
throw new RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
319
|
-
}
|
|
320
|
-
const componentLinks = visitor.getComponentCtxLinks();
|
|
321
|
-
const importedLibraries = Array.from(visitor.getScope().libraries.values());
|
|
322
|
-
for (let i = 0; i < postAnnotationCallbacks.length; i++) {
|
|
323
|
-
await postAnnotationCallbacks[i](options, scriptData, tree, tokens, componentLinks, importedLibraries, environment);
|
|
324
|
-
}
|
|
325
|
-
if (dumpNets) {
|
|
326
|
-
const nets = visitor.dumpNets();
|
|
327
|
-
nets.forEach(item => console.log(item.join(" | ")));
|
|
328
|
-
}
|
|
329
|
-
dumpData && environment.writeFileSync(dumpDirectory + 'tree.lisp', tree.toStringTree(null, parser));
|
|
330
|
-
dumpData && environment.writeFileSync(dumpDirectory + 'raw-parser.txt', visitor.logger.dump());
|
|
331
|
-
if (throwError) {
|
|
332
|
-
throw throwError;
|
|
333
|
-
}
|
|
334
|
-
let svgOutput = "";
|
|
335
|
-
if (errors.length === 0) {
|
|
336
|
-
const { frameComponent } = visitor.applySheetFrameComponent();
|
|
337
|
-
const { sequence, nets } = visitor.getGraph();
|
|
338
|
-
if (enableBom && bomOutputPath) {
|
|
339
|
-
const documentVariable = visitor.getScope().variables.get('document');
|
|
340
|
-
const bomConfig = documentVariable.bom;
|
|
341
|
-
const bomData = generateBom(bomConfig, visitor.getScope().getInstances());
|
|
342
|
-
const bomCsvOutput = generateBomCSV(bomData);
|
|
343
|
-
await saveBomOutputCsv(environment, bomCsvOutput, bomOutputPath);
|
|
344
|
-
console.log('Generated BOM file', bomOutputPath);
|
|
345
|
-
}
|
|
346
|
-
const tmpSequence = generateDebugSequenceAction(sequence).map(item => sequenceActionString(item));
|
|
347
|
-
dumpData && environment.writeFileSync(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
|
|
348
|
-
try {
|
|
349
|
-
let fileExtension = null;
|
|
350
|
-
let outputDefaultZoom = defaultZoomScale;
|
|
351
|
-
if (outputPath) {
|
|
352
|
-
fileExtension = path.extname(outputPath).substring(1);
|
|
353
|
-
}
|
|
354
|
-
for (let i = 0; i < parseHandlers.length; i++) {
|
|
355
|
-
const handler = parseHandlers[i];
|
|
356
|
-
if (handler.beforeRender) {
|
|
357
|
-
const keepParsing = handler.parse(visitor, outputPath, fileExtension);
|
|
358
|
-
if (!keepParsing) {
|
|
359
|
-
return {
|
|
360
|
-
svgOutput: null,
|
|
361
|
-
errors
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
const logger = new Logger();
|
|
367
|
-
const graphEngine = new NetGraph(logger);
|
|
368
|
-
const layoutEngine = new LayoutEngine(logger);
|
|
369
|
-
const layoutTimer = new SimpleStopwatch();
|
|
370
|
-
let sheetFrames;
|
|
371
|
-
try {
|
|
372
|
-
const { graph, containerFrames } = graphEngine.generateLayoutGraph(sequence, nets);
|
|
373
|
-
sheetFrames = layoutEngine.runLayout(graph, containerFrames, nets);
|
|
374
|
-
if (enableErc) {
|
|
375
|
-
const ercResults = EvaluateERCRules(visitor, graph, nets);
|
|
376
|
-
if (ercResults.length > 0) {
|
|
377
|
-
console.log(`ERC found ${ercResults.length} items:`);
|
|
378
|
-
ercResults.forEach((item, index) => {
|
|
379
|
-
console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
|
|
380
|
-
});
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
console.log('No ERC issues found');
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
catch (err) {
|
|
388
|
-
throw new RenderError(`Error during layout generation: ${err}`, 'layout');
|
|
389
|
-
}
|
|
390
|
-
layoutEngine.printWarnings();
|
|
391
|
-
showStats && console.log('Layout took:', layoutTimer.lap());
|
|
392
|
-
dumpData && environment.writeFileSync(dumpDirectory + 'raw-layout.txt', layoutEngine.logger.dump());
|
|
393
|
-
const generateSvgTimer = new SimpleStopwatch();
|
|
394
|
-
const renderLogger = new Logger();
|
|
395
|
-
let svgCanvas;
|
|
396
|
-
try {
|
|
397
|
-
svgCanvas = renderSheetsToSVG(sheetFrames, renderLogger);
|
|
398
|
-
}
|
|
399
|
-
catch (err) {
|
|
400
|
-
throw new RenderError(`Error during SVG generation: ${err}`, 'svg_generation');
|
|
401
|
-
}
|
|
402
|
-
showStats && console.log('Render took:', generateSvgTimer.lap());
|
|
403
|
-
dumpData && environment.writeFileSync(dumpDirectory + 'raw-render.txt', renderLogger.dump());
|
|
404
|
-
try {
|
|
405
|
-
if (fileExtension === "pdf") {
|
|
406
|
-
outputDefaultZoom = 1;
|
|
407
|
-
}
|
|
408
|
-
svgOutput = generateSvgOutput(svgCanvas, outputDefaultZoom);
|
|
409
|
-
}
|
|
410
|
-
catch (err) {
|
|
411
|
-
throw new RenderError(`Error generating SVG output: ${err}`, 'svg_output');
|
|
412
|
-
}
|
|
413
|
-
if (outputPath) {
|
|
414
|
-
if (fileExtension === 'svg') {
|
|
415
|
-
try {
|
|
416
|
-
environment.writeFileSync(outputPath, svgOutput);
|
|
417
|
-
}
|
|
418
|
-
catch (err) {
|
|
419
|
-
throw new RenderError(`Error writing SVG file: ${err}`, 'file_output');
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
else if (fileExtension === 'pdf') {
|
|
423
|
-
let sheetSize = "A4";
|
|
424
|
-
let sheetSizeDefined = false;
|
|
425
|
-
if (frameComponent) {
|
|
426
|
-
sheetSize = frameComponent.getParam(FrameParamKeys.PaperSize);
|
|
427
|
-
sheetSizeDefined = true;
|
|
428
|
-
}
|
|
429
|
-
try {
|
|
430
|
-
const doc = new PDFDocument({
|
|
431
|
-
layout: 'landscape',
|
|
432
|
-
size: sheetSize
|
|
433
|
-
});
|
|
434
|
-
const outputStream = environment.createWriteStream(outputPath);
|
|
435
|
-
generatePdfOutput(doc, svgCanvas, sheetSize, sheetSizeDefined, outputDefaultZoom);
|
|
436
|
-
doc.pipe(outputStream);
|
|
437
|
-
doc.end();
|
|
438
|
-
}
|
|
439
|
-
catch (err) {
|
|
440
|
-
throw new RenderError(`Error generating PDF file: ${err}`, 'pdf_output');
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
else {
|
|
444
|
-
throw new RenderError(`Invalid output format: ${fileExtension}`, 'file_output');
|
|
445
|
-
}
|
|
446
|
-
console.log('Generated file', outputPath);
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
catch (err) {
|
|
450
|
-
throw new RenderError(`Error during rendering: ${err}`, 'output_generation');
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
return {
|
|
454
|
-
svgOutput,
|
|
455
|
-
errors
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
export class ParseOutputHandler {
|
|
459
|
-
beforeRender = false;
|
|
460
|
-
afterRender = false;
|
|
461
|
-
}
|
|
462
|
-
export class KiCadNetListOutputHandler extends ParseOutputHandler {
|
|
463
|
-
beforeRender = true;
|
|
464
|
-
parse(visitor, outputPath, fileExtension) {
|
|
465
|
-
if (outputPath !== null && fileExtension === "net") {
|
|
466
|
-
const { tree: kiCadNetList, missingFootprints } = generateKiCadNetList(visitor.getNetList());
|
|
467
|
-
missingFootprints.forEach(entry => {
|
|
468
|
-
console.log(`${entry.refdes} (${entry.instanceName}) does not have footprint`);
|
|
469
|
-
});
|
|
470
|
-
visitor.environment.writeFileSync(outputPath, printTree(kiCadNetList));
|
|
471
|
-
console.log('Generated file', outputPath);
|
|
472
|
-
return false;
|
|
473
|
-
}
|
|
474
|
-
return true;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
51
|
export function detectJSModuleType() {
|
|
478
52
|
if (typeof __filename === 'undefined' &&
|
|
479
53
|
typeof __dirname === 'undefined') {
|
|
@@ -516,46 +90,3 @@ export function milsToMM(value) {
|
|
|
516
90
|
}
|
|
517
91
|
return resolveToNumericValue(value.toBigNumber().mul(new Big(MilsToMM)).round(6));
|
|
518
92
|
}
|
|
519
|
-
export function pxToMM(value) {
|
|
520
|
-
return value * PxToMM;
|
|
521
|
-
}
|
|
522
|
-
const PaperSizes = {
|
|
523
|
-
'A0': [1189, 841],
|
|
524
|
-
'A1': [841, 594],
|
|
525
|
-
'A2': [594, 420],
|
|
526
|
-
'A3': [420, 297],
|
|
527
|
-
'A4': [297, 210],
|
|
528
|
-
'A5': [210, 148],
|
|
529
|
-
'A6': [148, 105],
|
|
530
|
-
};
|
|
531
|
-
export const PaperGridReferences = {
|
|
532
|
-
'A0': [16, 24],
|
|
533
|
-
'A1': [12, 16],
|
|
534
|
-
'A2': [8, 12],
|
|
535
|
-
'A3': [6, 8],
|
|
536
|
-
'A4': [4, 6],
|
|
537
|
-
};
|
|
538
|
-
export function isSupportedPaperSize(type) {
|
|
539
|
-
if (PaperSizes[type]) {
|
|
540
|
-
return true;
|
|
541
|
-
}
|
|
542
|
-
return false;
|
|
543
|
-
}
|
|
544
|
-
export function getPaperSize(type, margin = defaultPageMarginMM) {
|
|
545
|
-
if (PaperSizes[type]) {
|
|
546
|
-
const [width, height] = PaperSizes[type];
|
|
547
|
-
const useWidth = width - margin * 2;
|
|
548
|
-
const useHeight = height - margin * 2;
|
|
549
|
-
return {
|
|
550
|
-
width: Math.floor(useWidth * (1 / MilsToMM)),
|
|
551
|
-
height: Math.floor(useHeight * (1 / MilsToMM)),
|
|
552
|
-
widthMM: useWidth,
|
|
553
|
-
heightMM: useHeight,
|
|
554
|
-
originalWidthMM: width,
|
|
555
|
-
originalHeightMM: height,
|
|
556
|
-
};
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
return getPaperSize('A4');
|
|
560
|
-
}
|
|
561
|
-
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const IMPORT_SIMPLE_RE = /^import\s+"([^"]+)"/;
|
|
2
|
+
const IMPORT_FROM_RE = /^from\s+"([^"]*)"\s+import\b/;
|
|
3
|
+
export function extractImportNames(fileData) {
|
|
4
|
+
const names = [];
|
|
5
|
+
for (const rawLine of fileData.split('\n')) {
|
|
6
|
+
const line = rawLine.trim();
|
|
7
|
+
if (line === '' || line.startsWith('//') || line.startsWith('#'))
|
|
8
|
+
continue;
|
|
9
|
+
const simple = IMPORT_SIMPLE_RE.exec(line);
|
|
10
|
+
if (simple) {
|
|
11
|
+
names.push(simple[1]);
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const from = IMPORT_FROM_RE.exec(line);
|
|
15
|
+
if (from) {
|
|
16
|
+
names.push(from[1]);
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
return names;
|
|
22
|
+
}
|
|
23
|
+
async function resolveImportPath(name, environment) {
|
|
24
|
+
let useName = name;
|
|
25
|
+
if (!name.endsWith('.cst')) {
|
|
26
|
+
useName = name + '.cst';
|
|
27
|
+
}
|
|
28
|
+
const absPath = environment.getAbsPathRelativeToCurrentFolder(useName);
|
|
29
|
+
const executionDirectory = environment.getCurrentDirectory();
|
|
30
|
+
const relPath = environment.relative(executionDirectory, absPath);
|
|
31
|
+
if (await environment.exists(relPath)) {
|
|
32
|
+
return relPath;
|
|
33
|
+
}
|
|
34
|
+
const libPath = environment.getRelativeToDefaultLibs(useName);
|
|
35
|
+
if (await environment.exists(libPath)) {
|
|
36
|
+
return libPath;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
export async function resolveAllImportFilepaths(rootFilePath, scriptData, environment) {
|
|
41
|
+
const visited = new Set();
|
|
42
|
+
const result = [];
|
|
43
|
+
async function walk(filePath, passedInScriptData) {
|
|
44
|
+
if (filePath !== undefined && filePath !== null && filePath !== '') {
|
|
45
|
+
if (visited.has(filePath))
|
|
46
|
+
return;
|
|
47
|
+
visited.add(filePath);
|
|
48
|
+
}
|
|
49
|
+
let fileData;
|
|
50
|
+
if (passedInScriptData === undefined || passedInScriptData === null) {
|
|
51
|
+
try {
|
|
52
|
+
fileData = await environment.readFile(filePath, { encoding: 'utf8' });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
fileData = passedInScriptData;
|
|
60
|
+
}
|
|
61
|
+
if (fileData) {
|
|
62
|
+
const importNames = extractImportNames(fileData);
|
|
63
|
+
const savedFile = environment.getCurrentFile();
|
|
64
|
+
if (filePath) {
|
|
65
|
+
environment.setCurrentFile(filePath);
|
|
66
|
+
}
|
|
67
|
+
for (const name of importNames) {
|
|
68
|
+
const resolvedPath = await resolveImportPath(name, environment);
|
|
69
|
+
if (resolvedPath) {
|
|
70
|
+
result.push(resolvedPath);
|
|
71
|
+
await walk(resolvedPath);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (filePath) {
|
|
75
|
+
environment.setCurrentFile(savedFile);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
await walk(rootFilePath, scriptData);
|
|
80
|
+
const uniqueResults = new Set(result);
|
|
81
|
+
return Array.from(uniqueResults);
|
|
82
|
+
}
|
|
83
|
+
export async function loadImportsIntoMemoryStore(filepaths, environment) {
|
|
84
|
+
const store = new Map();
|
|
85
|
+
for (const filePath of filepaths) {
|
|
86
|
+
if (store.has(filePath))
|
|
87
|
+
continue;
|
|
88
|
+
try {
|
|
89
|
+
const content = await environment.readFile(filePath, { encoding: 'utf8' });
|
|
90
|
+
store.set(filePath, content);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return store;
|
|
96
|
+
}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
export * from './draw_symbols.js';
|
|
1
|
+
export * from './render/draw_symbols.js';
|
|
2
2
|
export * from './execute.js';
|
|
3
3
|
export * from './export.js';
|
|
4
|
-
export * from './geometry.js';
|
|
4
|
+
export * from './render/geometry.js';
|
|
5
5
|
export * from './globals.js';
|
|
6
6
|
export * from './helpers.js';
|
|
7
|
-
export * from './layout.js';
|
|
7
|
+
export * from './render/layout.js';
|
|
8
8
|
export * from './lexer.js';
|
|
9
|
+
export * from './LexerDiagnosticListener.js';
|
|
9
10
|
export * from './logger.js';
|
|
10
11
|
export * from './parser.js';
|
|
11
|
-
export * from './render.js';
|
|
12
|
+
export * from './render/render.js';
|
|
12
13
|
export * from './utils.js';
|
|
13
14
|
export * from './visitor.js';
|
|
14
15
|
export * from './sizing.js';
|
|
@@ -17,5 +18,5 @@ export * from './builtinMethods.js';
|
|
|
17
18
|
export * from './validate/SymbolTable.js';
|
|
18
19
|
export * from './validate/SymbolValidatorResolveVisitor.js';
|
|
19
20
|
export * from './validate/SymbolValidatorVisitor.js';
|
|
20
|
-
export * from './environment.js';
|
|
21
|
-
export * from './RefdesAnnotationVisitor.js';
|
|
21
|
+
export * from './environment/environment.js';
|
|
22
|
+
export * from './annotate/RefdesAnnotationVisitor.js';
|