@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.
- package/dist/compile/compilerWrapper.d.ts +203 -0
- package/dist/compile/compilerWrapper.d.ts.map +1 -0
- package/dist/compile/compilerWrapper.js +1019 -0
- package/dist/compile/compilerWrapper.js.map +1 -0
- package/dist/compile/findCompiler.d.ts +3 -0
- package/dist/compile/findCompiler.d.ts.map +1 -0
- package/dist/compile/findCompiler.js +102 -0
- package/dist/compile/findCompiler.js.map +1 -0
- package/dist/compile/getBinary.d.ts +3 -0
- package/dist/compile/getBinary.d.ts.map +1 -0
- package/dist/compile/getBinary.js +94 -0
- package/dist/compile/getBinary.js.map +1 -0
- package/dist/debug.d.ts +25 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +110 -0
- package/dist/debug.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +52 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +189 -0
- package/dist/indexer.js.map +1 -0
- package/dist/relinker.d.ts +44 -0
- package/dist/relinker.d.ts.map +1 -0
- package/dist/relinker.js +321 -0
- package/dist/relinker.js.map +1 -0
- package/dist/resolver.d.ts +3 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +280 -0
- package/dist/resolver.js.map +1 -0
- package/dist/scryptParser.d.ts +31 -0
- package/dist/scryptParser.d.ts.map +1 -0
- package/dist/scryptParser.js +372 -0
- package/dist/scryptParser.js.map +1 -0
- package/dist/snippets.d.ts +39 -0
- package/dist/snippets.d.ts.map +1 -0
- package/dist/snippets.js +54 -0
- package/dist/snippets.js.map +1 -0
- package/dist/transpiler.d.ts +314 -0
- package/dist/transpiler.d.ts.map +1 -0
- package/dist/transpiler.js +4239 -0
- package/dist/transpiler.js.map +1 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +31 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +23 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +352 -0
- package/dist/utils.js.map +1 -0
- 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
|