UNPKG

8.77 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6var fileSystem_1 = __importDefault(require("./fileSystem"));
7var async_1 = __importDefault(require("async"));
8var path_1 = __importDefault(require("path"));
9var RemixCompiler = require('remix-solidity').Compiler;
10function regexIndexOf(inputString, regex, startpos) {
11 if (startpos === void 0) { startpos = 0; }
12 var indexOf = inputString.substring(startpos).search(regex);
13 return (indexOf >= 0) ? (indexOf + (startpos)) : indexOf;
14}
15function writeTestAccountsContract(accounts) {
16 var testAccountContract = require('../sol/tests_accounts.sol.js');
17 var body = "address[" + accounts.length + "] memory accounts;";
18 if (!accounts.length)
19 body += ';';
20 else {
21 accounts.map(function (address, index) {
22 body += "\naccounts[" + index + "] = " + address + ";\n";
23 });
24 }
25 return testAccountContract.replace('>accounts<', body);
26}
27/**
28 * @dev Check if path includes name of a remix test file
29 * @param path file path to check
30 */
31function isRemixTestFile(path) {
32 return ['tests.sol', 'remix_tests.sol', 'remix_accounts.sol'].some(function (name) { return path.includes(name); });
33}
34/**
35 * @dev Process file to prepare sources object to be passed in solc compiler input
36 *
37 * See: https://solidity.readthedocs.io/en/latest/using-the-compiler.html#input-description
38 *
39 * @param filePath path of file to process
40 * @param sources existing 'sources' object in which keys are the "global" names of the source files and
41 * value is object containing content of corresponding file with under key 'content'
42 * @param isRoot True, If file is a root test contract file which is getting processed, not an imported file
43 */
44function processFile(filePath, sources, isRoot) {
45 if (isRoot === void 0) { isRoot = false; }
46 var importRegEx = /import ['"](.+?)['"];/g;
47 var group = null;
48 var isFileAlreadyInSources = Object.keys(sources).includes(filePath);
49 // Return if file is a remix test file or already processed
50 if (isRemixTestFile(filePath) || isFileAlreadyInSources)
51 return;
52 var content = fileSystem_1.default.readFileSync(filePath, { encoding: 'utf-8' });
53 var testFileImportRegEx = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm;
54 // import 'remix_tests.sol', if file is a root test contract file and doesn't already have it
55 if (isRoot && filePath.endsWith('_test.sol') && regexIndexOf(content, testFileImportRegEx) < 0) {
56 var includeTestLibs = '\nimport \'remix_tests.sol\';\n';
57 content = includeTestLibs.concat(content);
58 }
59 sources[filePath] = { content: content };
60 importRegEx.exec(''); // Resetting state of RegEx
61 // Process each 'import' in file content
62 while (group = importRegEx.exec(content)) {
63 var importedFile = group[1];
64 var importedFilePath = path_1.default.join(path_1.default.dirname(filePath), importedFile);
65 processFile(importedFilePath, sources);
66 }
67}
68var userAgent = (typeof (navigator) !== 'undefined') && navigator.userAgent ? navigator.userAgent.toLowerCase() : '-';
69var isBrowser = !(typeof (window) === 'undefined' || userAgent.indexOf(' electron/') > -1);
70/**
71 * @dev Compile file or files before running tests (used for CLI execution)
72 * @param filename Name of file
73 * @param isDirectory True, if path is a directory
74 * @param opts Options
75 * @param cb Callback
76 *
77 * TODO: replace this with remix's own compiler code
78 */
79function compileFileOrFiles(filename, isDirectory, opts, cb) {
80 var compiler;
81 var accounts = opts.accounts || [];
82 var sources = {
83 'tests.sol': { content: require('../sol/tests.sol.js') },
84 'remix_tests.sol': { content: require('../sol/tests.sol.js') },
85 'remix_accounts.sol': { content: writeTestAccountsContract(accounts) }
86 };
87 var filepath = (isDirectory ? filename : path_1.default.dirname(filename));
88 try {
89 if (!isDirectory && fileSystem_1.default.existsSync(filename)) {
90 if (filename.split('.').pop() === 'sol') {
91 processFile(filename, sources, true);
92 }
93 else {
94 throw new Error('Not a solidity file');
95 }
96 }
97 else {
98 // walkSync only if it is a directory
99 fileSystem_1.default.walkSync(filepath, function (foundpath) {
100 // only process .sol files
101 if (foundpath.split('.').pop() === 'sol') {
102 processFile(foundpath, sources, true);
103 }
104 });
105 }
106 }
107 catch (e) {
108 throw e;
109 }
110 finally {
111 async_1.default.waterfall([
112 function loadCompiler(next) {
113 compiler = new RemixCompiler();
114 compiler.onInternalCompilerLoaded();
115 // compiler.event.register('compilerLoaded', this, function (version) {
116 next();
117 // });
118 },
119 function doCompilation(next) {
120 // @ts-ignore
121 compiler.event.register('compilationFinished', this, function (success, data, source) {
122 next(null, data);
123 });
124 compiler.compile(sources, filepath);
125 }
126 ], function (err, result) {
127 var error = [];
128 if (result.error)
129 error.push(result.error);
130 var errors = (result.errors || error).filter(function (e) { return e.type === 'Error' || e.severity === 'error'; });
131 if (errors.length > 0) {
132 if (!isBrowser)
133 require('signale').fatal(errors);
134 return cb(errors);
135 }
136 cb(err, result.contracts, result.sources); //return callback with contract details & ASTs
137 });
138 }
139}
140exports.compileFileOrFiles = compileFileOrFiles;
141/**
142 * @dev Compile contract source before running tests (used for IDE tests execution)
143 * @param sources sources
144 * @param compilerConfig current compiler configuration
145 * @param importFileCb Import file callback
146 * @param opts Options
147 * @param cb Callback
148 */
149function compileContractSources(sources, compilerConfig, importFileCb, opts, cb) {
150 var compiler, filepath;
151 var accounts = opts.accounts || [];
152 // Iterate over sources keys. Inject test libraries. Inject test library import statements.
153 if (!('remix_tests.sol' in sources) && !('tests.sol' in sources)) {
154 sources['tests.sol'] = { content: require('../sol/tests.sol.js') };
155 sources['remix_tests.sol'] = { content: require('../sol/tests.sol.js') };
156 sources['remix_accounts.sol'] = { content: writeTestAccountsContract(accounts) };
157 }
158 var testFileImportRegEx = /^(import)\s['"](remix_tests.sol|tests.sol)['"];/gm;
159 var includeTestLibs = '\nimport \'remix_tests.sol\';\n';
160 for (var file in sources) {
161 var c = sources[file].content;
162 if (file.endsWith('_test.sol') && c && regexIndexOf(c, testFileImportRegEx) < 0) {
163 sources[file].content = includeTestLibs.concat(c);
164 }
165 }
166 async_1.default.waterfall([
167 function loadCompiler(next) {
168 var currentCompilerUrl = compilerConfig.currentCompilerUrl, evmVersion = compilerConfig.evmVersion, optimize = compilerConfig.optimize, usingWorker = compilerConfig.usingWorker;
169 compiler = new RemixCompiler(importFileCb);
170 compiler.set('evmVersion', evmVersion);
171 compiler.set('optimize', optimize);
172 compiler.loadVersion(usingWorker, currentCompilerUrl);
173 // @ts-ignore
174 compiler.event.register('compilerLoaded', this, function (version) {
175 next();
176 });
177 },
178 function doCompilation(next) {
179 // @ts-ignore
180 compiler.event.register('compilationFinished', this, function (success, data, source) {
181 next(null, data);
182 });
183 compiler.compile(sources, filepath);
184 }
185 ], function (err, result) {
186 var error = [];
187 if (result.error)
188 error.push(result.error);
189 var errors = (result.errors || error).filter(function (e) { return e.type === 'Error' || e.severity === 'error'; });
190 if (errors.length > 0) {
191 if (!isBrowser)
192 require('signale').fatal(errors);
193 return cb(errors);
194 }
195 cb(err, result.contracts, result.sources); // return callback with contract details & ASTs
196 });
197}
198exports.compileContractSources = compileContractSources;
199//# sourceMappingURL=compiler.js.map
\No newline at end of file