@opcat-labs/scrypt-ts-transpiler-opcat 1.0.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.
Files changed (53) hide show
  1. package/dist/compile/compilerWrapper.d.ts +203 -0
  2. package/dist/compile/compilerWrapper.d.ts.map +1 -0
  3. package/dist/compile/compilerWrapper.js +1019 -0
  4. package/dist/compile/compilerWrapper.js.map +1 -0
  5. package/dist/compile/findCompiler.d.ts +3 -0
  6. package/dist/compile/findCompiler.d.ts.map +1 -0
  7. package/dist/compile/findCompiler.js +102 -0
  8. package/dist/compile/findCompiler.js.map +1 -0
  9. package/dist/compile/getBinary.d.ts +3 -0
  10. package/dist/compile/getBinary.d.ts.map +1 -0
  11. package/dist/compile/getBinary.js +94 -0
  12. package/dist/compile/getBinary.js.map +1 -0
  13. package/dist/debug.d.ts +25 -0
  14. package/dist/debug.d.ts.map +1 -0
  15. package/dist/debug.js +110 -0
  16. package/dist/debug.js.map +1 -0
  17. package/dist/index.d.ts +12 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +110 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/indexer.d.ts +52 -0
  22. package/dist/indexer.d.ts.map +1 -0
  23. package/dist/indexer.js +189 -0
  24. package/dist/indexer.js.map +1 -0
  25. package/dist/relinker.d.ts +44 -0
  26. package/dist/relinker.d.ts.map +1 -0
  27. package/dist/relinker.js +321 -0
  28. package/dist/relinker.js.map +1 -0
  29. package/dist/resolver.d.ts +3 -0
  30. package/dist/resolver.d.ts.map +1 -0
  31. package/dist/resolver.js +280 -0
  32. package/dist/resolver.js.map +1 -0
  33. package/dist/scryptParser.d.ts +31 -0
  34. package/dist/scryptParser.d.ts.map +1 -0
  35. package/dist/scryptParser.js +372 -0
  36. package/dist/scryptParser.js.map +1 -0
  37. package/dist/snippets.d.ts +39 -0
  38. package/dist/snippets.d.ts.map +1 -0
  39. package/dist/snippets.js +54 -0
  40. package/dist/snippets.js.map +1 -0
  41. package/dist/transpiler.d.ts +314 -0
  42. package/dist/transpiler.d.ts.map +1 -0
  43. package/dist/transpiler.js +4239 -0
  44. package/dist/transpiler.js.map +1 -0
  45. package/dist/types.d.ts +33 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +31 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/utils.d.ts +23 -0
  50. package/dist/utils.d.ts.map +1 -0
  51. package/dist/utils.js +352 -0
  52. package/dist/utils.js.map +1 -0
  53. package/package.json +43 -0
@@ -0,0 +1,1019 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.compileContractAsync = exports.compileContract = exports.getStaticDeclaration = exports.getAliasDeclaration = exports.getContractDeclaration = exports.getLibraryDeclaration = exports.getStructDeclaration = exports.getABIDeclaration = exports.getContractName = exports.getFullFilePath = exports.compilerVersion = exports.handleCompilerOutput = exports.compile = exports.settings2cmd = exports.compileAsync = exports.doCompileAsync = exports.DebugModeTag = exports.CompileResult = exports.BuildType = exports.CompileErrorType = exports.SOURCE_REG = void 0;
30
+ const child_process_1 = require("child_process");
31
+ const fs_1 = require("fs");
32
+ const path_1 = require("path");
33
+ const rimraf_1 = require("rimraf");
34
+ const json_bigint_1 = __importDefault(require("json-bigint"));
35
+ const resolver_1 = require("../resolver");
36
+ const utils_1 = require("../utils");
37
+ const findCompiler_1 = require("./findCompiler");
38
+ const bitcoinjs_lib_1 = require("@scrypt-inc/bitcoinjs-lib");
39
+ const tools = __importStar(require("uint8array-tools"));
40
+ const scrypt_ts_opcat_1 = require("@opcat-labs/scrypt-ts-opcat");
41
+ const indexer_1 = require("../indexer");
42
+ const relinker_1 = require("../relinker");
43
+ const SYNTAX_ERR_REG = /(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):\n([^\n]+\n){3}(unexpected (?<unexpected>[^\n]+)\nexpecting (?<expecting>[^\n]+)|(?<message>[^\n]+))/g;
44
+ const SEMANTIC_ERR_REG = /Error:(\s|\n)*(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+):*\n(?<message>[^\n]+)\n/g;
45
+ const INTERNAL_ERR_REG = /Internal error:(?<message>.+)/;
46
+ const WARNING_REG = /Warning:(\s|\n)*(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+):*\n(?<message>[^\n]+)\n/g;
47
+ const JSONbigAlways = (0, json_bigint_1.default)({ alwaysParseAsBig: true, constructorAction: 'preserve' });
48
+ //SOURCE_REG parser src eg: [0:6:3:8:4#Bar.constructor:0]
49
+ exports.SOURCE_REG = /^(?<fileIndex>-?\d+):(?<line>\d+):(?<col>\d+):(?<endLine>\d+):(?<endCol>\d+)(#(?<tagStr>.+))?/;
50
+ const RELATED_INFORMATION_REG = /(?<filePath>[^\s]+):(?<line>\d+):(?<column>\d+):(?<line1>\d+):(?<column1>\d+)/gi;
51
+ // see VERSIONLOG.md
52
+ var CompileErrorType;
53
+ (function (CompileErrorType) {
54
+ CompileErrorType["SyntaxError"] = "SyntaxError";
55
+ CompileErrorType["SemanticError"] = "SemanticError";
56
+ CompileErrorType["InternalError"] = "InternalError";
57
+ CompileErrorType["Warning"] = "Warning";
58
+ })(CompileErrorType || (exports.CompileErrorType = CompileErrorType = {}));
59
+ var BuildType;
60
+ (function (BuildType) {
61
+ BuildType["Debug"] = "debug";
62
+ BuildType["Release"] = "release";
63
+ })(BuildType || (exports.BuildType = BuildType = {}));
64
+ class CompileResult {
65
+ constructor(errors, warnings) {
66
+ this.errors = errors;
67
+ this.warnings = warnings;
68
+ }
69
+ toArtifact() {
70
+ const errors = this.errors.filter((e) => e.type !== CompileErrorType.Warning);
71
+ if (errors.length > 0) {
72
+ throw new Error(`CompileResult contains errors: ${errors.map((e) => e.message).join('\n')}`);
73
+ }
74
+ const artifact = {
75
+ version: scrypt_ts_opcat_1.CURRENT_CONTRACT_ARTIFACT_VERSION,
76
+ compilerVersion: this.compilerVersion || '0.0.0',
77
+ contract: this.contract || '',
78
+ md5: this.md5 || '',
79
+ structs: this.structs || [],
80
+ library: this.library || [],
81
+ alias: this.alias || [],
82
+ abi: this.abi || [],
83
+ stateProps: this.stateProps || [],
84
+ stateType: this.stateType,
85
+ buildType: this.buildType || BuildType.Release,
86
+ file: this.file || '',
87
+ hex: this.hex || '',
88
+ };
89
+ return artifact;
90
+ }
91
+ }
92
+ exports.CompileResult = CompileResult;
93
+ var DebugModeTag;
94
+ (function (DebugModeTag) {
95
+ DebugModeTag["FuncStart"] = "F0";
96
+ DebugModeTag["FuncEnd"] = "F1";
97
+ DebugModeTag["LoopStart"] = "L0";
98
+ })(DebugModeTag || (exports.DebugModeTag = DebugModeTag = {}));
99
+ function toOutputDir(artifactsDir, sourcePath) {
100
+ return (0, path_1.join)(artifactsDir, (0, path_1.basename)(sourcePath) + '-' + (0, utils_1.sha1)(sourcePath).substring(0, 10));
101
+ }
102
+ function doCompileAsync(source, settings, callback) {
103
+ const sourcePath = source.path;
104
+ const srcDir = (0, path_1.dirname)(sourcePath);
105
+ const curWorkingDir = settings.cwd || srcDir;
106
+ const timeout = settings.timeout || 1200000;
107
+ const sourceContent = source.content !== undefined ? source.content : (0, fs_1.readFileSync)(sourcePath, 'utf8');
108
+ const cmd = settings2cmd(sourcePath, settings);
109
+ const childProcess = (0, child_process_1.exec)(cmd, { cwd: curWorkingDir, timeout, killSignal: 'SIGKILL' }, (error, stdout) => {
110
+ if (error) {
111
+ console.error(`exec error: ${error} stdout: ${stdout}`);
112
+ if (callback) {
113
+ callback(error, null);
114
+ }
115
+ return;
116
+ }
117
+ if (callback) {
118
+ callback(null, {
119
+ path: sourcePath,
120
+ output: stdout,
121
+ });
122
+ }
123
+ });
124
+ const stdin = childProcess.stdin;
125
+ if (stdin) {
126
+ stdin.write(sourceContent, (error) => {
127
+ if (error) {
128
+ if (callback) {
129
+ callback(error, null);
130
+ }
131
+ return;
132
+ }
133
+ stdin.end();
134
+ });
135
+ }
136
+ return childProcess;
137
+ }
138
+ exports.doCompileAsync = doCompileAsync;
139
+ function compileAsync(source, settings) {
140
+ settings = Object.assign({}, defaultCompilingSettings, settings);
141
+ return new Promise((resolve, reject) => {
142
+ doCompileAsync(source, settings, (error, data) => {
143
+ if (error) {
144
+ reject(error);
145
+ return;
146
+ }
147
+ if (data) {
148
+ try {
149
+ const result = handleCompilerOutput(source.path, settings, data.output);
150
+ resolve(result);
151
+ }
152
+ catch (error) {
153
+ reject(error);
154
+ }
155
+ }
156
+ });
157
+ });
158
+ }
159
+ exports.compileAsync = compileAsync;
160
+ const defaultCompilingSettings = {
161
+ ast: true,
162
+ asm: false,
163
+ hex: true,
164
+ debug: false,
165
+ artifact: false,
166
+ outputDir: '',
167
+ outputToFiles: false,
168
+ cwd: '',
169
+ cmdPrefix: '',
170
+ cmdArgs: '',
171
+ buildType: BuildType.Release,
172
+ stdout: false,
173
+ sourceMap: false,
174
+ timeout: 1200000, // in ms
175
+ optimize: false,
176
+ };
177
+ function settings2cmd(sourcePath, settings) {
178
+ const srcDir = (0, path_1.dirname)(sourcePath);
179
+ //dir that store artifact file
180
+ const artifactDir = settings.outputDir || srcDir;
181
+ //dir that store ast,asm file
182
+ const outputDir = toOutputDir(artifactDir, sourcePath);
183
+ const cmdPrefix = settings.cmdPrefix || (0, findCompiler_1.findCompiler)();
184
+ let outOption = `-o "${outputDir}"`;
185
+ if (settings.stdout) {
186
+ outOption = '--stdout';
187
+ return `"${cmdPrefix}" compile ${settings.asm || settings.artifact ? '--asm' : ''} ${settings.hex ? '--hex' : ''} ${settings.optimize ? '-O' : ''} ${settings.ast || settings.artifact ? '--ast' : ''} ${settings.debug == true ? '--debug' : ''} -r ${outOption} ${settings.cmdArgs ? settings.cmdArgs : ''}`;
188
+ }
189
+ else {
190
+ if (!(0, fs_1.existsSync)(outputDir)) {
191
+ (0, fs_1.mkdirSync)(outputDir);
192
+ }
193
+ }
194
+ return `"${cmdPrefix}" compile ${settings.hex ? '--hex' : ''} ${settings.optimize ? '-O' : ''} ${settings.ast || settings.artifact ? '--ast' : ''} ${settings.debug == true ? '--debug' : ''} ${settings.sourceMap == true ? '--source-map' : ''} -r ${outOption} ${settings.cmdArgs ? settings.cmdArgs : ''}`;
195
+ }
196
+ exports.settings2cmd = settings2cmd;
197
+ function compile(source, settings) {
198
+ const sourcePath = source.path;
199
+ const srcDir = (0, path_1.dirname)(sourcePath);
200
+ //dir that stores artifact file
201
+ const curWorkingDir = settings.cwd || srcDir;
202
+ settings = Object.assign({}, defaultCompilingSettings, settings);
203
+ const sourceContent = source.content !== undefined ? source.content : (0, fs_1.readFileSync)(sourcePath, 'utf8');
204
+ const maxBuffer = settings.stdout ? 1024 * 1024 * 100 : 1024 * 1024;
205
+ settings = Object.assign({}, defaultCompilingSettings, settings);
206
+ const cmd = settings2cmd(sourcePath, settings);
207
+ const output = (0, child_process_1.execSync)(cmd, {
208
+ input: sourceContent,
209
+ cwd: curWorkingDir,
210
+ timeout: settings.timeout,
211
+ maxBuffer: maxBuffer,
212
+ }).toString();
213
+ return handleCompilerOutput(sourcePath, settings, output);
214
+ }
215
+ exports.compile = compile;
216
+ function calcHexMd5(hex) {
217
+ const chex = hex.replace(/<([^>]+)>/g, '<>');
218
+ return (0, utils_1.md5)(chex);
219
+ }
220
+ function getHex(hex) {
221
+ return hex.replace(/<([^>]+)>/g, '');
222
+ }
223
+ function findDisableOpCode(hex) {
224
+ const script = bitcoinjs_lib_1.script.decompile(tools.fromHex(hex));
225
+ return script.find((chuck) => {
226
+ if (typeof chuck === 'number') {
227
+ return (0, bitcoinjs_lib_1.isOpSuccess)(chuck);
228
+ }
229
+ return false;
230
+ });
231
+ }
232
+ function handleCompilerOutput(sourcePath, settings, output) {
233
+ const srcDir = (0, path_1.dirname)(sourcePath);
234
+ const sourceFileName = (0, path_1.basename)(sourcePath);
235
+ const artifactsDir = settings.outputDir || srcDir;
236
+ const outputDir = toOutputDir(artifactsDir, sourcePath);
237
+ const outputFiles = {};
238
+ try {
239
+ // Because the output of the compiler on the win32 platform uses crlf as a newline, here we change \r\n to \n. make SYNTAX_ERR_REG、SEMANTIC_ERR_REG、IMPORT_ERR_REG work.
240
+ output = output.split(/\r?\n/g).join('\n');
241
+ const result = new CompileResult([], []);
242
+ const cwd = settings.cmdPrefix ? settings.cmdPrefix : (0, findCompiler_1.findCompiler)();
243
+ if (!cwd) {
244
+ throw new Error('No sCrypt compiler found');
245
+ }
246
+ result.compilerVersion = compilerVersion(cwd);
247
+ result.buildType = settings.buildType || BuildType.Release;
248
+ if (output.startsWith('Error:') || output.startsWith('Warning:')) {
249
+ Object.assign(result, getErrorsAndWarnings(output, srcDir, sourceFileName));
250
+ if (result.errors.length > 0) {
251
+ return result;
252
+ }
253
+ if (settings.stdout && result.warnings.length > 0) {
254
+ // stdout not allowed warnings
255
+ return result;
256
+ }
257
+ }
258
+ if (settings.stdout) {
259
+ const stdout = JSONbigAlways.parse(output);
260
+ parserAst(result, stdout.ast, srcDir, sourceFileName, sourcePath);
261
+ parserASM(result, stdout.asm, settings, srcDir, sourceFileName);
262
+ }
263
+ else {
264
+ if (settings.ast || settings.artifact) {
265
+ const outputFilePath = getOutputFilePath(outputDir, 'ast');
266
+ const astFile = outputFilePath.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
267
+ (0, fs_1.renameSync)(outputFilePath, astFile);
268
+ outputFiles['ast'] = astFile;
269
+ const ast = JSONbigAlways.parse((0, fs_1.readFileSync)(astFile, 'utf8'));
270
+ parserAst(result, ast, srcDir, sourceFileName, sourcePath);
271
+ }
272
+ if (settings.hex || settings.artifact) {
273
+ const outputFilePath = getOutputFilePath(outputDir, 'hex');
274
+ const hexFile = outputFilePath.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
275
+ (0, fs_1.renameSync)(outputFilePath, hexFile);
276
+ outputFiles['hex'] = hexFile;
277
+ result.hex = (0, fs_1.readFileSync)(hexFile, 'utf8');
278
+ result.md5 = calcHexMd5(result.hex);
279
+ }
280
+ if (settings.sourceMap) {
281
+ const outputFilePath = getOutputFilePath(outputDir, 'map');
282
+ if (settings.artifact) {
283
+ const dist = getOutputFilePath(artifactsDir, 'map');
284
+ const sourceMapFile = dist.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
285
+ (0, fs_1.renameSync)(outputFilePath, sourceMapFile);
286
+ result.sourceMapFile = (0, utils_1.path2uri)(sourceMapFile);
287
+ }
288
+ else {
289
+ const sourceMapFile = outputFilePath.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
290
+ (0, fs_1.renameSync)(outputFilePath, sourceMapFile);
291
+ outputFiles['map'] = sourceMapFile;
292
+ result.sourceMapFile = (0, utils_1.path2uri)(sourceMapFile);
293
+ }
294
+ }
295
+ if (settings.debug) {
296
+ const outputFilePath = getOutputFilePath(outputDir, 'dbg');
297
+ const dbgFile = outputFilePath.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
298
+ (0, fs_1.renameSync)(outputFilePath, dbgFile);
299
+ result.dbgFile = (0, utils_1.path2uri)(dbgFile);
300
+ }
301
+ // inject state type from transpiling result file `scrypt.index.json`
302
+ const indexFile = indexer_1.Indexer.queryIndexFile(sourcePath, process.cwd());
303
+ const pkgInfo = relinker_1.Relinker.getFilePackageInfo(sourcePath);
304
+ if (indexFile) {
305
+ const indexer = new indexer_1.Indexer(indexFile);
306
+ // set state type for libraries
307
+ result.library?.forEach((lib) => {
308
+ const stateType = indexer.symbolInfos.get(lib.name ? relinker_1.Relinker.getUnRenamedSymbol(lib.name) : undefined)?.stateType;
309
+ lib.stateType =
310
+ stateType &&
311
+ relinker_1.Relinker.getRenamedSymbol(stateType, pkgInfo.packageName, pkgInfo.packageVersion);
312
+ });
313
+ // set state type for contract
314
+ const stateType = indexer.symbolInfos.get(relinker_1.Relinker.getUnRenamedSymbol(result.contract))?.stateType;
315
+ result.stateType =
316
+ stateType &&
317
+ relinker_1.Relinker.getRenamedSymbol(stateType, pkgInfo.packageName, pkgInfo.packageVersion);
318
+ }
319
+ else {
320
+ throw new Error(`Cannot find \`scrypt.index.json\` file, run \`npm run build\` to generate it.`);
321
+ }
322
+ if (settings.artifact) {
323
+ const outputFilePath = getOutputFilePath(artifactsDir, 'artifact');
324
+ const artifactFile = outputFilePath.replace('stdin', (0, path_1.basename)(sourcePath, '.scrypt'));
325
+ const artifact = result.toArtifact();
326
+ (0, fs_1.writeFileSync)(artifactFile, JSON.stringify(artifact, (key, value) => {
327
+ if (key === 'file') {
328
+ return (0, path_1.relative)(artifactFile, value);
329
+ }
330
+ //ignore deprecated fields
331
+ if (key == 'sources' || key == 'sourceMap' || key === 'asm')
332
+ return undefined;
333
+ else
334
+ return value;
335
+ }, 2));
336
+ }
337
+ const indexer = new indexer_1.Indexer();
338
+ indexer.updateMd5(relinker_1.Relinker.getUnRenamedSymbol(result.contract), result.md5);
339
+ indexer.save();
340
+ }
341
+ return result;
342
+ }
343
+ finally {
344
+ doClean(settings, outputFiles, outputDir);
345
+ }
346
+ }
347
+ exports.handleCompilerOutput = handleCompilerOutput;
348
+ function compilerVersion(cwd) {
349
+ try {
350
+ const text = (0, child_process_1.execSync)(`"${cwd}" version`).toString();
351
+ const res = /Version:\s*([^\s]+)\s*/.exec(text);
352
+ if (res) {
353
+ return res[1];
354
+ }
355
+ }
356
+ catch (e) {
357
+ throw new Error(`compilerVersion fail when run: ${cwd} version: ${e.message}`);
358
+ }
359
+ return undefined;
360
+ }
361
+ exports.compilerVersion = compilerVersion;
362
+ function addSourceLocation(astRoot, basePath, curFileName) {
363
+ for (const fileName in astRoot) {
364
+ if (fileName === 'std') {
365
+ astRoot['std'] = _addSourceLocationProperty(astRoot['std'], 'std');
366
+ }
367
+ else {
368
+ const realFileName = fileName === 'stdin' ? curFileName : fileName;
369
+ const uri = (0, utils_1.path2uri)((0, path_1.join)(basePath, realFileName));
370
+ astRoot[uri] = _addSourceLocationProperty(astRoot[fileName], uri);
371
+ delete astRoot[fileName];
372
+ }
373
+ }
374
+ return astRoot;
375
+ }
376
+ function _addSourceLocationProperty(astObj, uri) {
377
+ if (!(typeof astObj === 'object')) {
378
+ return astObj;
379
+ }
380
+ for (const field in astObj) {
381
+ const value = astObj[field];
382
+ if (field === 'src') {
383
+ const matches = /:(\d+):(\d+):(\d+):(\d+)/.exec(value);
384
+ if (!matches) {
385
+ astObj.loc = null;
386
+ }
387
+ else {
388
+ astObj.loc = {
389
+ source: uri,
390
+ start: { line: parseInt(matches[1]), column: parseInt(matches[2]) },
391
+ end: { line: parseInt(matches[3]), column: parseInt(matches[4]) },
392
+ };
393
+ }
394
+ delete astObj['src'];
395
+ }
396
+ else if (typeof value === 'object') {
397
+ _addSourceLocationProperty(value, uri);
398
+ }
399
+ }
400
+ return astObj;
401
+ }
402
+ function getOutputFilePath(baseDir, target) {
403
+ if (target == 'hex') {
404
+ return (0, path_1.join)(baseDir, `stdin_${target}.txt`);
405
+ }
406
+ else if (target === 'map') {
407
+ return (0, path_1.join)(baseDir, `stdin.${target}.json`);
408
+ }
409
+ else if (target === 'dbg') {
410
+ return (0, path_1.join)(baseDir, `stdin.${target}.json`);
411
+ }
412
+ else if (target === 'artifact') {
413
+ return (0, path_1.join)(baseDir, 'stdin.json');
414
+ }
415
+ return (0, path_1.join)(baseDir, `stdin_${target}.json`);
416
+ }
417
+ function getFullFilePath(relativePath, baseDir, curFileName) {
418
+ if (relativePath.endsWith('stdin')) {
419
+ return (0, path_1.join)(baseDir, curFileName); // replace 'stdin' with real current compiling file name.
420
+ }
421
+ if (relativePath === 'std') {
422
+ return 'std'; //
423
+ }
424
+ return (0, path_1.join)(baseDir, relativePath);
425
+ }
426
+ exports.getFullFilePath = getFullFilePath;
427
+ function getConstructorDeclaration(mainContract) {
428
+ // explict constructor
429
+ if (mainContract['constructor']) {
430
+ return {
431
+ type: scrypt_ts_opcat_1.ABIEntityType.CONSTRUCTOR,
432
+ params: mainContract['constructor']['params'].map((p) => {
433
+ return { name: p['name'], type: p['type'] };
434
+ }),
435
+ };
436
+ }
437
+ else {
438
+ // implicit constructor
439
+ return {
440
+ type: scrypt_ts_opcat_1.ABIEntityType.CONSTRUCTOR,
441
+ params: mainContract['properties'].map((p) => {
442
+ return { name: p['name'].replace('this.', ''), type: p['type'] };
443
+ }),
444
+ };
445
+ }
446
+ }
447
+ function getStateProps(astRoot) {
448
+ const mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
449
+ if (mainContract && mainContract['properties']) {
450
+ return mainContract['properties']
451
+ .filter((p) => p.state)
452
+ .map((p) => {
453
+ return { name: p['name'].replace('this.', ''), type: p['type'] };
454
+ });
455
+ }
456
+ return [];
457
+ }
458
+ function getPublicFunctionDeclaration(mainContract) {
459
+ let pubIndex = 0;
460
+ const interfaces = mainContract['functions']
461
+ .filter((f) => f['visibility'] === 'Public')
462
+ .map((f) => {
463
+ const entity = {
464
+ type: scrypt_ts_opcat_1.ABIEntityType.FUNCTION,
465
+ name: f['name'],
466
+ index: f['nodeType'] === 'Constructor' ? undefined : pubIndex++,
467
+ params: f['params'].map((p) => {
468
+ return { name: p['name'], type: p['type'] };
469
+ }),
470
+ };
471
+ return entity;
472
+ });
473
+ return interfaces;
474
+ }
475
+ function getContractName(astRoot) {
476
+ const mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
477
+ if (!mainContract) {
478
+ return '';
479
+ }
480
+ return mainContract['name'] || '';
481
+ }
482
+ exports.getContractName = getContractName;
483
+ function shortGenericType(genericType) {
484
+ const m = genericType.match(/__SCRYPT_(\w+)__/);
485
+ if (m) {
486
+ return m[1];
487
+ }
488
+ return genericType;
489
+ }
490
+ /**
491
+ *
492
+ * @param astRoot AST root node after main contract compilation
493
+ * @param typeResolver a Type Resolver
494
+ * @returns All function ABIs defined by the main contract, including constructors
495
+ */
496
+ function getABIDeclaration(astRoot, typeResolver) {
497
+ const mainContract = astRoot['contracts'][astRoot['contracts'].length - 1];
498
+ if (!mainContract) {
499
+ return {
500
+ contract: '',
501
+ abi: [],
502
+ };
503
+ }
504
+ const interfaces = getPublicFunctionDeclaration(mainContract);
505
+ const constructorABI = getConstructorDeclaration(mainContract);
506
+ interfaces.push(constructorABI);
507
+ interfaces.forEach((abi) => {
508
+ abi.params = abi.params.map((param) => {
509
+ return Object.assign(param, {
510
+ type: typeResolver(param.type).finalType,
511
+ });
512
+ });
513
+ });
514
+ return {
515
+ contract: getContractName(astRoot),
516
+ abi: interfaces,
517
+ };
518
+ }
519
+ exports.getABIDeclaration = getABIDeclaration;
520
+ /**
521
+ *
522
+ * @param astRoot AST root node after main contract compilation
523
+ * @param dependencyAsts AST root node after all dependency contract compilation
524
+ * @returns all defined structures of the main contract and dependent contracts
525
+ */
526
+ function getStructDeclaration(astRoot, dependencyAsts) {
527
+ const allAst = [astRoot];
528
+ Object.keys(dependencyAsts).forEach((key) => {
529
+ allAst.push(dependencyAsts[key]);
530
+ });
531
+ return allAst
532
+ .map((ast) => {
533
+ return (ast['structs'] || []).map((s) => ({
534
+ name: s['name'],
535
+ params: s['fields'].map((p) => {
536
+ return { name: p['name'], type: p['type'] };
537
+ }),
538
+ genericTypes: s.genericTypes || [],
539
+ }));
540
+ })
541
+ .flat(1);
542
+ }
543
+ exports.getStructDeclaration = getStructDeclaration;
544
+ /**
545
+ *
546
+ * @param astRoot AST root node after main contract compilation
547
+ * @param dependencyAsts AST root node after all dependency contract compilation
548
+ * @returns all defined Library of the main contract and dependent contracts
549
+ */
550
+ function getLibraryDeclaration(astRoot, dependencyAsts) {
551
+ const allAst = [astRoot];
552
+ Object.keys(dependencyAsts).forEach((key) => {
553
+ if (key !== 'std') {
554
+ allAst.push(dependencyAsts[key]);
555
+ }
556
+ });
557
+ return allAst
558
+ .map((ast) => {
559
+ return (ast['contracts'] || [])
560
+ .filter((c) => c.nodeType == 'Library')
561
+ .map((c) => {
562
+ if (c['constructor']) {
563
+ return {
564
+ name: c.name,
565
+ params: c['constructor']['params'].map((p) => {
566
+ return { name: `ctor.${p['name']}`, type: p['type'] };
567
+ }),
568
+ properties: c['properties'].map((p) => {
569
+ return { name: p['name'], type: p['type'] };
570
+ }),
571
+ genericTypes: c.genericTypes || [],
572
+ };
573
+ }
574
+ else {
575
+ // implicit constructor
576
+ return {
577
+ name: c.name,
578
+ params: c['properties'].map((p) => {
579
+ return { name: p['name'], type: p['type'] };
580
+ }),
581
+ properties: c['properties'].map((p) => {
582
+ return { name: p['name'], type: p['type'] };
583
+ }),
584
+ genericTypes: c.genericTypes || [],
585
+ };
586
+ }
587
+ });
588
+ })
589
+ .flat(1);
590
+ }
591
+ exports.getLibraryDeclaration = getLibraryDeclaration;
592
+ function getContractDeclaration(astRoot, dependencyAsts) {
593
+ const allAst = [astRoot];
594
+ Object.keys(dependencyAsts).forEach((key) => {
595
+ if (key !== 'std') {
596
+ allAst.push(dependencyAsts[key]);
597
+ }
598
+ });
599
+ return allAst
600
+ .map((ast) => {
601
+ return (ast['contracts'] || [])
602
+ .filter((c) => c.nodeType == 'Contract')
603
+ .map((c) => {
604
+ if (c['constructor']) {
605
+ return {
606
+ name: c.name,
607
+ params: c['constructor']['params'].map((p) => {
608
+ return { name: `ctor.${p['name']}`, type: p['type'] };
609
+ }),
610
+ properties: c['properties'].map((p) => {
611
+ return { name: p['name'], type: p['type'] };
612
+ }),
613
+ genericTypes: c.genericTypes || [],
614
+ };
615
+ }
616
+ else {
617
+ // implicit constructor
618
+ return {
619
+ name: c.name,
620
+ params: c['properties'].map((p) => {
621
+ return { name: p['name'], type: p['type'] };
622
+ }),
623
+ properties: c['properties'].map((p) => {
624
+ return { name: p['name'], type: p['type'] };
625
+ }),
626
+ genericTypes: c.genericTypes || [],
627
+ };
628
+ }
629
+ });
630
+ })
631
+ .flat(1);
632
+ }
633
+ exports.getContractDeclaration = getContractDeclaration;
634
+ /**
635
+ *
636
+ * @param astRoot AST root node after main contract compilation
637
+ * @param dependencyAsts AST root node after all dependency contract compilation
638
+ * @returns all defined type aliaes of the main contract and dependent contracts
639
+ */
640
+ function getAliasDeclaration(astRoot, dependencyAsts) {
641
+ const allAst = [astRoot];
642
+ Object.keys(dependencyAsts).forEach((key) => {
643
+ allAst.push(dependencyAsts[key]);
644
+ });
645
+ return allAst
646
+ .map((ast) => {
647
+ return (ast['alias'] || []).map((s) => ({
648
+ name: s['alias'],
649
+ type: s['type'],
650
+ }));
651
+ })
652
+ .flat(1);
653
+ }
654
+ exports.getAliasDeclaration = getAliasDeclaration;
655
+ /**
656
+ *
657
+ * @param astRoot AST root node after main contract compilation
658
+ * @param dependencyAsts AST root node after all dependency contract compilation
659
+ * @returns all defined static const int literal of the main contract and dependent contracts
660
+ */
661
+ function getStaticDeclaration(astRoot, dependencyAsts) {
662
+ const allAst = [astRoot];
663
+ Object.keys(dependencyAsts).forEach((key) => {
664
+ allAst.push(dependencyAsts[key]);
665
+ });
666
+ return allAst
667
+ .map((ast) => {
668
+ return (ast['contracts'] || []).map((contract) => {
669
+ return (contract.statics || []).map((node) => {
670
+ return {
671
+ const: node.const,
672
+ name: `${contract.name}.${node.name}`,
673
+ type: node.type,
674
+ value: resolveConstValue(node),
675
+ };
676
+ });
677
+ });
678
+ })
679
+ .flat(Infinity)
680
+ .flat(1)
681
+ .filter((item) => item.const && item.value);
682
+ }
683
+ exports.getStaticDeclaration = getStaticDeclaration;
684
+ function getRelatedInformation(message, srcDir, sourceFileName) {
685
+ const relatedInformation = [];
686
+ let result;
687
+ while ((result = RELATED_INFORMATION_REG.exec(message))) {
688
+ const relatedFilePath = result.groups.filePath;
689
+ if (relatedFilePath === 'null')
690
+ continue;
691
+ const fullFilePath = getFullFilePath(relatedFilePath, srcDir, sourceFileName);
692
+ const line = parseInt(result.groups?.line || '-1');
693
+ const column = parseInt(result.groups?.column || '-1');
694
+ relatedInformation.push({
695
+ filePath: fullFilePath,
696
+ position: [
697
+ {
698
+ line: line,
699
+ column: column,
700
+ },
701
+ {
702
+ line: parseInt(result.groups?.line1 || '-1'),
703
+ column: parseInt(result.groups?.column1 || '-1'),
704
+ },
705
+ ],
706
+ message: '',
707
+ });
708
+ message = message.replace(/([^\s]+):(\d+):(\d+):(\d+):(\d+)/, '');
709
+ }
710
+ return {
711
+ relatedInformation,
712
+ message,
713
+ };
714
+ }
715
+ function getErrorsAndWarnings(output, srcDir, sourceFileName) {
716
+ const warnings = [...output.matchAll(WARNING_REG)].map((match) => {
717
+ const filePath = match.groups?.filePath || '';
718
+ const origin_message = match.groups?.message || '';
719
+ const { message, relatedInformation } = getRelatedInformation(origin_message, srcDir, sourceFileName);
720
+ return {
721
+ type: CompileErrorType.Warning,
722
+ filePath: getFullFilePath(filePath, srcDir, sourceFileName),
723
+ position: [
724
+ {
725
+ line: parseInt(match.groups?.line || '-1'),
726
+ column: parseInt(match.groups?.column || '-1'),
727
+ },
728
+ {
729
+ line: parseInt(match.groups?.line1 || '-1'),
730
+ column: parseInt(match.groups?.column1 || '-1'),
731
+ },
732
+ ],
733
+ message: message,
734
+ relatedInformation: relatedInformation,
735
+ };
736
+ });
737
+ const INTERNAL_ERR = output.match(INTERNAL_ERR_REG);
738
+ if (INTERNAL_ERR) {
739
+ const errors = [
740
+ {
741
+ type: CompileErrorType.InternalError,
742
+ filePath: getFullFilePath('stdin', srcDir, sourceFileName),
743
+ message: `Compiler internal error: ${INTERNAL_ERR.groups?.message || ''}`,
744
+ position: [
745
+ {
746
+ line: 1,
747
+ column: 1,
748
+ },
749
+ {
750
+ line: 1,
751
+ column: 1,
752
+ },
753
+ ],
754
+ relatedInformation: [],
755
+ },
756
+ ];
757
+ return new CompileResult(errors, warnings);
758
+ }
759
+ else if (output.includes('Syntax error:')) {
760
+ const syntaxErrors = [...output.matchAll(SYNTAX_ERR_REG)].map((match) => {
761
+ const filePath = match.groups?.filePath || '';
762
+ const unexpected = match.groups?.unexpected || '';
763
+ const expecting = match.groups?.expecting || '';
764
+ const origin_message = match.groups?.message || `unexpected ${unexpected}\nexpecting ${expecting}`;
765
+ const { message, relatedInformation } = getRelatedInformation(origin_message, srcDir, sourceFileName);
766
+ return {
767
+ type: CompileErrorType.SyntaxError,
768
+ filePath: getFullFilePath(filePath, srcDir, sourceFileName),
769
+ position: [
770
+ {
771
+ line: parseInt(match.groups?.line || '-1'),
772
+ column: parseInt(match.groups?.column || '-1'),
773
+ },
774
+ ],
775
+ message: message,
776
+ unexpected,
777
+ expecting,
778
+ relatedInformation: relatedInformation,
779
+ };
780
+ });
781
+ return new CompileResult(syntaxErrors, warnings);
782
+ }
783
+ else {
784
+ const semanticErrors = [...output.matchAll(SEMANTIC_ERR_REG)].map((match) => {
785
+ const origin_message = match.groups?.message || '';
786
+ const filePath = match.groups?.filePath || '';
787
+ const { message, relatedInformation } = getRelatedInformation(origin_message, srcDir, sourceFileName);
788
+ return {
789
+ type: CompileErrorType.SemanticError,
790
+ filePath: getFullFilePath(filePath, srcDir, sourceFileName),
791
+ position: [
792
+ {
793
+ line: parseInt(match.groups?.line || '-1'),
794
+ column: parseInt(match.groups?.column || '-1'),
795
+ },
796
+ {
797
+ line: parseInt(match.groups?.line1 || '-1'),
798
+ column: parseInt(match.groups?.column1 || '-1'),
799
+ },
800
+ ],
801
+ message: message,
802
+ relatedInformation: relatedInformation,
803
+ };
804
+ });
805
+ return new CompileResult(semanticErrors, warnings);
806
+ }
807
+ }
808
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
809
+ function resolveConstValue(node) {
810
+ if (node.expr.nodeType === 'IntLiteral') {
811
+ return node.expr.value.toString(10);
812
+ }
813
+ else if (node.type === 'int' && node.expr.nodeType === 'Variable') {
814
+ return node.expr.name;
815
+ }
816
+ else if (node.type === 'int' &&
817
+ node.expr.nodeType === 'BinaryExpr' &&
818
+ node.expr.name === 'Dot') {
819
+ return `${node.expr.lExpr.name}.${node.expr.rExpr.name}`;
820
+ }
821
+ return undefined;
822
+ }
823
+ function parserAst(result, ast, srcDir, sourceFileName, sourcePath) {
824
+ const allAst = addSourceLocation(ast, srcDir, sourceFileName);
825
+ const sourceUri = (0, utils_1.path2uri)(sourcePath);
826
+ result.file = sourcePath;
827
+ result.ast = allAst[sourceUri];
828
+ delete allAst[sourceUri];
829
+ result.dependencyAsts = allAst;
830
+ const alias = getAliasDeclaration(result.ast, allAst);
831
+ const structs = getStructDeclaration(result.ast, allAst);
832
+ const library = getLibraryDeclaration(result.ast, allAst);
833
+ const statics = getStaticDeclaration(result.ast, allAst);
834
+ result.contracts = getContractDeclaration(result.ast, allAst);
835
+ const typeResolver = (0, resolver_1.buildTypeResolver)(getContractName(result.ast), alias, structs, library, result.contracts, statics);
836
+ result.alias = alias.map((a) => ({
837
+ name: a.name,
838
+ type: typeResolver(a.type).finalType,
839
+ }));
840
+ result.structs = structs.map((a) => ({
841
+ name: a.name,
842
+ params: a.params.map((p) => ({ name: p.name, type: typeResolver(p.type).finalType })),
843
+ genericTypes: a.genericTypes.map((t) => shortGenericType(t)),
844
+ }));
845
+ result.library = library.map((a) => ({
846
+ name: a.name,
847
+ params: a.params.map((p) => ({ name: p.name, type: typeResolver(p.type).finalType })),
848
+ properties: a.properties.map((p) => ({ name: p.name, type: typeResolver(p.type).finalType })),
849
+ genericTypes: a.genericTypes.map((t) => shortGenericType(t)),
850
+ }));
851
+ result.statics = statics.map((s) => Object.assign({ ...s }, {
852
+ type: typeResolver(s.type).finalType,
853
+ }));
854
+ const { contract: name, abi } = getABIDeclaration(result.ast, typeResolver);
855
+ result.stateProps = getStateProps(result.ast).map((p) => ({
856
+ name: p.name,
857
+ type: typeResolver(p.type).finalType,
858
+ }));
859
+ result.abi = abi;
860
+ result.contract = name;
861
+ }
862
+ /**
863
+ * @deprecated use `--hex` when compiling
864
+ * @param result
865
+ * @param asmObj
866
+ * @param settings
867
+ * @param srcDir
868
+ * @param sourceFileName
869
+ */
870
+ function parserASM(result, asmObj, settings, srcDir, sourceFileName) {
871
+ const sources = asmObj['sources'];
872
+ if (settings.debug) {
873
+ Object.assign(result, {
874
+ file: result.file,
875
+ sources: asmObj['sources'].map((source) => getFullFilePath(source, srcDir, sourceFileName)),
876
+ sourceMap: asmObj['output'].map((item) => item.src),
877
+ });
878
+ }
879
+ result.hex = settings.hex ? asmObj['output'].map((item) => item.hex).join('') : '';
880
+ result.asm = asmObj['output'].map((item) => {
881
+ if (!settings.debug) {
882
+ return {
883
+ opcode: item.opcode,
884
+ };
885
+ }
886
+ const match = exports.SOURCE_REG.exec(item.src);
887
+ if (match && match.groups) {
888
+ const fileIndex = parseInt(match.groups.fileIndex);
889
+ let debugInfo;
890
+ const tagStr = match.groups.tagStr;
891
+ const m = /^(\w+)\.(\w+):(\d)(#(?<context>.+))?$/.exec(tagStr);
892
+ if (m && m.groups) {
893
+ debugInfo = {
894
+ contract: m[1],
895
+ func: m[2],
896
+ tag: m[3] == '0' ? DebugModeTag.FuncStart : DebugModeTag.FuncEnd,
897
+ context: m.groups.context,
898
+ };
899
+ }
900
+ else if (/loop:0/.test(tagStr)) {
901
+ debugInfo = {
902
+ contract: '',
903
+ func: '',
904
+ tag: DebugModeTag.LoopStart,
905
+ context: '',
906
+ };
907
+ }
908
+ const pos = sources[fileIndex]
909
+ ? {
910
+ file: sources[fileIndex]
911
+ ? getFullFilePath(sources[fileIndex], srcDir, sourceFileName)
912
+ : '',
913
+ line: sources[fileIndex] ? parseInt(match.groups.line) : -1,
914
+ endLine: sources[fileIndex] ? parseInt(match.groups.endLine) : -1,
915
+ column: sources[fileIndex] ? parseInt(match.groups.col) : -1,
916
+ endColumn: sources[fileIndex] ? parseInt(match.groups.endCol) : -1,
917
+ }
918
+ : undefined;
919
+ return {
920
+ opcode: item.opcode,
921
+ stack: item.stack,
922
+ topVars: item.topVars || [],
923
+ pos: pos,
924
+ debugInfo,
925
+ };
926
+ }
927
+ throw new Error('Compile Failed: Asm output parsing Error!');
928
+ });
929
+ if (settings.debug) {
930
+ result.autoTypedVars = asmObj['autoTypedVars'].map((item) => {
931
+ const match = exports.SOURCE_REG.exec(item.src);
932
+ let fileIndex = -1;
933
+ if (match && match.groups) {
934
+ fileIndex = parseInt(match.groups.fileIndex);
935
+ }
936
+ const pos = fileIndex > -1 && sources[fileIndex]
937
+ ? {
938
+ file: sources[fileIndex]
939
+ ? getFullFilePath(sources[fileIndex], srcDir, sourceFileName)
940
+ : '',
941
+ line: sources[fileIndex] ? parseInt(match.groups.line) : -1,
942
+ endLine: sources[fileIndex] ? parseInt(match.groups.endLine) : -1,
943
+ column: sources[fileIndex] ? parseInt(match.groups.col) : -1,
944
+ endColumn: sources[fileIndex] ? parseInt(match.groups.endCol) : -1,
945
+ }
946
+ : undefined;
947
+ return {
948
+ name: item.name,
949
+ type: item.type,
950
+ pos: pos,
951
+ };
952
+ });
953
+ }
954
+ }
955
+ function doClean(settings, outputFiles, outputDir) {
956
+ if (settings.stdout || settings.outputToFiles || settings.sourceMap) {
957
+ return;
958
+ }
959
+ try {
960
+ Object.keys(outputFiles).forEach((outputType) => {
961
+ const file = outputFiles[outputType];
962
+ if ((0, fs_1.existsSync)(file)) {
963
+ (0, fs_1.unlinkSync)(file);
964
+ }
965
+ });
966
+ (0, rimraf_1.rimrafSync)(outputDir);
967
+ }
968
+ catch (error) {
969
+ console.error('clean compiler output files failed!', error);
970
+ }
971
+ // console.log('compile time spent: ', Date.now() - st)
972
+ }
973
+ function compileContract(file, options) {
974
+ options = Object.assign({
975
+ out: (0, path_1.dirname)(file),
976
+ sourceMap: false,
977
+ artifact: false,
978
+ optimize: true,
979
+ }, options);
980
+ if (!(0, fs_1.existsSync)(file)) {
981
+ throw `file ${file} not exists!`;
982
+ }
983
+ if (!(0, fs_1.existsSync)(options.out)) {
984
+ (0, fs_1.mkdirSync)(options.out);
985
+ }
986
+ const result = compile({ path: file }, {
987
+ artifact: options.artifact,
988
+ outputDir: options.out,
989
+ sourceMap: options.sourceMap,
990
+ optimize: options.optimize,
991
+ cmdPrefix: (0, findCompiler_1.findCompiler)(),
992
+ });
993
+ return result;
994
+ }
995
+ exports.compileContract = compileContract;
996
+ function compileContractAsync(file, options) {
997
+ options = Object.assign({
998
+ out: (0, path_1.join)(__dirname, '..', 'out'),
999
+ sourceMap: false,
1000
+ artifact: false,
1001
+ optimize: true,
1002
+ }, options);
1003
+ if (!(0, fs_1.existsSync)(file)) {
1004
+ throw `file ${file} not exists!`;
1005
+ }
1006
+ if (!(0, fs_1.existsSync)(options.out)) {
1007
+ (0, fs_1.mkdirSync)(options.out);
1008
+ }
1009
+ return compileAsync({ path: file }, {
1010
+ artifact: options.artifact,
1011
+ outputDir: options.out,
1012
+ sourceMap: options.sourceMap,
1013
+ optimize: options.optimize,
1014
+ hex: true,
1015
+ cmdPrefix: (0, findCompiler_1.findCompiler)(),
1016
+ });
1017
+ }
1018
+ exports.compileContractAsync = compileContractAsync;
1019
+ //# sourceMappingURL=compilerWrapper.js.map