Skip to content

Commit d1762a0

Browse files
committed
refactor code generation
1 parent 32d34cd commit d1762a0

15 files changed

+146
-152
lines changed

lib/contracts/code_generator.js

Lines changed: 41 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
const ejs = require('ejs');
2+
const Templates = {
3+
utils: require('./code_templates/utils.js.ejs'),
4+
vanilla_contract: require('./code_templates/vanilla-contract.js.ejs'),
5+
embarkjs_contract: require('./code_templates/embarkjs-contract.js.ejs'),
6+
exec_when_ready: require('./code_templates/exec-when-ready.js.ejs'),
7+
load_manager: require('./code_templates/load-manager.js.ejs'),
8+
define_when_env_loaded: require('./code_templates/define-when-env-loaded.js.ejs'),
9+
main_context: require('./code_templates/main-context.js.ejs'),
10+
define_web3_simple: require('./code_templates/define-web3-simple.js.ejs'),
11+
web3_connector: require('./code_templates/web3-connector.js.ejs'),
12+
do_when_loaded: require('./code_templates/do-when-loaded.js.ejs'),
13+
exec_when_env_loaded: require('./code_templates/exec-when-env-loaded.js.ejs')
14+
}
15+
116
class CodeGenerator {
217
constructor(options) {
318
this.blockchainConfig = options.blockchainConfig || {};
@@ -51,64 +66,11 @@ class CodeGenerator {
5166
return "";
5267
}
5368

54-
result += "\nfunction __reduce(arr, memo, iteratee, cb) {";
55-
result += "\n if (typeof cb !== 'function') {";
56-
result += "\n if (typeof memo === 'function' && typeof iteratee === 'function') {";
57-
result += "\n cb = iteratee;";
58-
result += "\n iteratee = memo;";
59-
result += "\n memo = [];";
60-
result += "\n } else {";
61-
result += "\n throw new TypeError('expected callback to be a function');";
62-
result += "\n }";
63-
result += "\n }";
64-
result += "\n";
65-
result += "\n if (!Array.isArray(arr)) {";
66-
result += "\n cb(new TypeError('expected an array'));";
67-
result += "\n return;";
68-
result += "\n }";
69-
result += "\n";
70-
result += "\n if (typeof iteratee !== 'function') {";
71-
result += "\n cb(new TypeError('expected iteratee to be a function'));";
72-
result += "\n return;";
73-
result += "\n }";
74-
result += "\n";
75-
result += "\n (function next(i, acc) {";
76-
result += "\n if (i === arr.length) {";
77-
result += "\n cb(null, acc);";
78-
result += "\n return;";
79-
result += "\n }";
80-
result += "\n";
81-
result += "\n iteratee(acc, arr[i], function(err, val) {";
82-
result += "\n if (err) {";
83-
result += "\n cb(err);";
84-
result += "\n return;";
85-
result += "\n }";
86-
result += "\n next(i + 1, val);";
87-
result += "\n });";
88-
result += "\n })(0, memo);";
89-
result += "\n};";
90-
91-
let mainContext = "";
92-
if (isDeployment) {
93-
mainContext = "__mainContext.";
94-
result += "\nvar __mainContext = __mainContext || this;";
95-
} else {
96-
result += "\nvar __mainContext = __mainContext || this;";
97-
mainContext = "__mainContext.";
98-
}
99-
100-
result += "\n" + mainContext + "__LoadManager = function() { this.list = []; this.done = false; }";
101-
result += "\n" + mainContext + "__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } }";
102-
result += "\n" + mainContext + "__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) }";
103-
result += "\n" + mainContext + "__loadManagerInstance = new " + mainContext + "__LoadManager();";
69+
result += Templates.utils();
10470

105-
result += "\nvar whenEnvIsLoaded = function(cb) {";
106-
result += "\n if (typeof document !== 'undefined' && document !== null) {";
107-
result += "\n document.addEventListener('DOMContentLoaded', cb);";
108-
result += "\n } else {";
109-
result += "\n cb();";
110-
result += "\n }";
111-
result += "\n}";
71+
result += Templates.main_context();
72+
result += Templates.load_manager();
73+
result += Templates.define_when_env_loaded();
11274

11375
if (this.plugins) {
11476
providerPlugins = this.plugins.getPluginsFor('clientWeb3Provider');
@@ -119,50 +81,18 @@ result += "\n";
11981
result += plugin.generateProvider(self) + "\n";
12082
});
12183
} else {
122-
result += "\nwhenEnvIsLoaded(function(){" + mainContext + "__loadManagerInstance.doFirst(function(done) {\n";
12384

124-
result += "\nif (typeof window !== 'undefined') { window.web3 = undefined; }";
85+
let web3Load;
12586

12687
if (isDeployment) {
12788
let connection = "http://" + this.contractsConfig.deployment.host + ":" + this.contractsConfig.deployment.port;
128-
result += '\n\tweb3 = new Web3(new Web3.providers.HttpProvider("' + connection + '"));';
129-
result += '\n\tdone();';
89+
web3Load = Templates.define_web3_simple({url: connection, done: 'done();'});
13090
} else {
131-
132-
let connectionCode = "";
133-
connectionCode += "\n__reduce([";
134-
connectionCode += this.contractsConfig.dappConnection.map((x) => '"' + x + '"').join(',');
135-
connectionCode += "], function(prev, value, next) {";
136-
137-
connectionCode += "\nif (prev === false) {";
138-
connectionCode += "\n return next(null, false);";
139-
connectionCode += "\n}";
140-
141-
connectionCode += "\n if (value === '$WEB3' && (typeof web3 !== 'undefined' && typeof Web3 !== 'undefined')) {";
142-
connectionCode += '\n\tweb3 = new Web3(web3.currentProvider);';
143-
connectionCode += "\n } else if (value !== '$WEB3' && (typeof Web3 !== 'undefined' && ((typeof web3 === 'undefined') || (typeof web3 !== 'undefined' && (!web3.isConnected || (web3.isConnected && !web3.isConnected())))))) {";
144-
145-
connectionCode += "\n\tweb3 = new Web3(new Web3.providers.HttpProvider(value));";
146-
147-
connectionCode += "\n}";
148-
149-
connectionCode += "\nelse if (value === '$WEB3') {";
150-
connectionCode += "\n\treturn next(null, '');";
151-
connectionCode += "\n}";
152-
153-
connectionCode += "\nweb3.eth.getAccounts(function(err, account) { if(err) { next(null, true) } else { next(null, false) }})";
154-
155-
connectionCode += "\n}, function(err, _result) {";
156-
connectionCode += "\nweb3.eth.getAccounts(function(err, accounts) {;";
157-
connectionCode += "\nweb3.eth.defaultAccount = accounts[0];";
158-
connectionCode += '\ndone();';
159-
connectionCode += "\n});";
160-
connectionCode += "\n});";
161-
162-
result += connectionCode;
91+
let connectionList = "[" + this.contractsConfig.dappConnection.map((x) => '"' + x + '"').join(',') + "]";
92+
web3Load = Templates.web3_connector({connectionList: connectionList, done: 'done();'});
16393
}
16494

165-
result += '\n})})';
95+
result += Templates.do_when_loaded({block: web3Load});
16696
}
16797

16898
return result;
@@ -179,20 +109,11 @@ result += "\n";
179109
for (let className in this.contractsManager.contracts) {
180110
let contract = this.contractsManager.contracts[className];
181111
let abi = JSON.stringify(contract.abiDefinition);
182-
result += "\n" + className + "Abi = " + abi + ";";
183-
result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);";
184-
result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');";
112+
result += Templates.vanilla_contract({className: className, abi: abi, contract: contract});
185113
}
186114
return result;
187115
}
188116

189-
let mainContext = "";
190-
if (isDeployment) {
191-
mainContext = "__mainContext.";
192-
} else {
193-
mainContext = "__mainContext.";
194-
}
195-
196117
if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
197118
return "";
198119
}
@@ -212,28 +133,16 @@ result += "\n";
212133
let abi = JSON.stringify(contract.abiDefinition);
213134
let gasEstimates = JSON.stringify(contract.gasEstimates);
214135

215-
// TODO: refactor this
216-
//result += "\nif (whenEnvIsLoaded === undefined) {";
217-
//result += "\n var whenEnvIsLoaded = function(cb) {";
218-
//result += "\n if (typeof document !== 'undefined' && document !== null) {";
219-
//result += "\n document.addEventListener('DOMContentLoaded', cb);";
220-
//result += "\n } else {";
221-
//result += "\n cb();";
222-
//result += "\n }";
223-
//result += "\n }";
224-
//result += "\n}";
225-
226-
result += "\n" + mainContext + "__loadManagerInstance.execWhenReady(function() {";
227-
result += "\nif (typeof window !== 'undefined') { window." + className + " = undefined; }";
136+
let block = "";
137+
228138
if (useEmbarkJS) {
229139
let contractAddress = contract.deployedAddress ? ("'" + contract.deployedAddress + "'") : "undefined";
230-
result += "\n" + mainContext + "" + className + " = new EmbarkJS.Contract({abi: " + abi + ", address: " + contractAddress + ", code: '" + contract.code + "', gasEstimates: " + gasEstimates + "});";
140+
block += Templates.embarkjs_contract({className: className, abi: abi, contract: contract, contractAddress: contractAddress, gasEstimates: gasEstimates});
231141
} else {
232-
result += "\n" + className + "Abi = " + abi + ";";
233-
result += "\n" + className + "Contract = web3.eth.contract(" + className + "Abi);";
234-
result += "\n" + className + " = " + className + "Contract.at('" + contract.deployedAddress + "');";
142+
block += Templates.vanilla_contract({className: className, abi: abi, contract: contract});
235143
}
236-
result += '\n});';
144+
result += Templates.exec_when_ready({block: block});
145+
237146
}
238147
}
239148

@@ -247,19 +156,8 @@ result += "\n";
247156
if (!useEmbarkJS || self.storageConfig === {}) return "";
248157

249158
if (self.storageConfig.provider === 'ipfs' && self.storageConfig.enabled === true) {
250-
// TODO: make this more readable
251-
252-
result += "\nvar whenEnvIsLoaded = function(cb) {";
253-
result += "\n if (typeof document !== 'undefined' && document !== null) {";
254-
result += "\n document.addEventListener('DOMContentLoaded', cb);";
255-
result += "\n } else {";
256-
result += "\n cb();";
257-
result += "\n }";
258-
result += "\n}";
259-
260-
result += "\nwhenEnvIsLoaded(function() {\n";
261-
result += "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "', getUrl: '" + self.storageConfig.getUrl + "'});";
262-
result += '\n})';
159+
let block = "\nEmbarkJS.Storage.setProvider('" + self.storageConfig.provider + "', {server: '" + self.storageConfig.host + "', port: '" + self.storageConfig.port + "', getUrl: '" + self.storageConfig.getUrl + "'});";
160+
result += Templates.define_when_env_loaded({block: block});
263161
}
264162

265163
return result;
@@ -271,26 +169,20 @@ result += "\n";
271169

272170
if (!useEmbarkJS || self.communicationConfig === {}) return "";
273171

274-
result += "\nvar whenEnvIsLoaded = function(cb) {";
275-
result += "\n if (typeof document !== 'undefined' && document !== null) {";
276-
result += "\n document.addEventListener('DOMContentLoaded', cb);";
277-
result += "\n } else {";
278-
result += "\n cb();";
279-
result += "\n }";
280-
result += "\n}";
172+
// TODO: don't repeat this twice; should have 'requirements' generator first
173+
result += Templates.define_when_env_loaded();
281174

175+
let block;
282176
if (self.communicationConfig.provider === 'whisper' && self.communicationConfig.enabled === true) {
283-
result += "\nwhenEnvIsLoaded(function() {\n";
284-
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
285-
result += '\n})';
177+
block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
178+
result += Templates.define_when_env_loaded({block: block});
286179
} else if (self.communicationConfig.provider === 'orbit' && self.communicationConfig.enabled === true) {
287-
result += "\nwhenEnvIsLoaded(function() {\n";
288180
if (self.communicationConfig.host === undefined && self.communicationConfig.port === undefined) {
289-
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
181+
block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "');";
290182
} else {
291-
result += "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});";
183+
block = "\nEmbarkJS.Messages.setProvider('" + self.communicationConfig.provider + "', {server: '" + self.communicationConfig.host + "', port: '" + self.communicationConfig.port + "'});";
292184
}
293-
result += '\n})';
185+
result += Templates.define_when_env_loaded({block: block});
294186
}
295187

296188
return result;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__mainContext.web3 = undefined;
2+
web3 = new Web3(new Web3.providers.HttpProvider("<%- url -%>'"));
3+
<%- done %>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
var whenEnvIsLoaded = function(cb) {
2+
if (typeof document !== 'undefined' && document !== null) {
3+
document.addEventListener('DOMContentLoaded', cb);
4+
} else {
5+
cb();
6+
}
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
whenEnvIsLoaded(function(){
2+
__mainContext.__loadManagerInstance.doFirst(function(done) {
3+
<%- block %>
4+
})
5+
});
6+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__mainContext.<%- className %> = new EmbarkJS.Contract({abi: <%- abi %>, address: <%- contractAddress %>, code: '<%- contract.code %>', gasEstimates: <%- gasEstimates %>});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
whenEnvIsLoaded(function() {
2+
<%- block %>
3+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
__mainContext.__loadManagerInstance.execWhenReady(function() {
2+
<%- block %>
3+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
__mainContext.__LoadManager = function() { this.list = []; this.done = false; }
2+
__mainContext.__LoadManager.prototype.execWhenReady = function(cb) { if (this.done) { cb(); } else { this.list.push(cb) } }
3+
__mainContext.__LoadManager.prototype.doFirst = function(todo) { var self = this; todo(function() { self.done = true; self.list.map((x) => x.apply()) }) }
4+
__mainContext.__loadManagerInstance = new __mainContext.__LoadManager();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
var __mainContext = __mainContext || this;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
function __reduce(arr, memo, iteratee, cb) {
2+
if (typeof cb !== 'function') {
3+
if (typeof memo === 'function' && typeof iteratee === 'function') {
4+
cb = iteratee;
5+
iteratee = memo;
6+
memo = [];
7+
} else {
8+
throw new TypeError('expected callback to be a function');
9+
}
10+
}
11+
12+
if (!Array.isArray(arr)) {
13+
cb(new TypeError('expected an array'));
14+
return;
15+
}
16+
17+
if (typeof iteratee !== 'function') {
18+
cb(new TypeError('expected iteratee to be a function'));
19+
return;
20+
}
21+
22+
(function next(i, acc) {
23+
if (i === arr.length) {
24+
cb(null, acc);
25+
return;
26+
}
27+
28+
iteratee(acc, arr[i], function(err, val) {
29+
if (err) {
30+
cb(err);
31+
return;
32+
}
33+
next(i + 1, val);
34+
});
35+
})(0, memo);
36+
};

0 commit comments

Comments
 (0)