remove engine dependency; use api

This commit is contained in:
Iuri Matias 2018-07-30 14:33:01 -04:00
parent 3a15804fda
commit 77dd5b4944
2 changed files with 108 additions and 76 deletions

View File

@ -24,6 +24,10 @@ class ContractsManager {
cb(self.compileError, self.listContracts()); cb(self.compileError, self.listContracts());
}); });
self.events.setCommandHandler('contracts:dependencies', (cb) => {
cb(self.compileError, self.contractDependencies);
});
self.events.setCommandHandler("contracts:contract", (contractName, cb) => { self.events.setCommandHandler("contracts:contract", (contractName, cb) => {
cb(self.getContract(contractName)); cb(self.getContract(contractName));
}); });

View File

@ -1,3 +1,4 @@
const async = require('async');
const Viz = require('viz.js'); const Viz = require('viz.js');
const fs = require('fs'); const fs = require('fs');
@ -13,95 +14,119 @@ class GraphGenerator {
} }
generate(options) { generate(options) {
const self = this;
let id = 0; let id = 0;
let contractString = ""; let contractString = "";
let relationshipString = ""; let relationshipString = "";
let idMapping = {}; let idMapping = {};
let contractInheritance = {}; let contractInheritance = {};
let contracts = {};
let contractsDependencies = {};
for (let contract in this.engine.contractsManager.contracts) { async.waterfall([
if(options.skipUndeployed && !this.engine.contractsManager.contracts[contract].deploy) continue; function getContractList(next) {
self.events.request('contracts:list', (err, _contracts) => {
contracts = _contracts;
next();
});
},
function getContractsDependencies(next) {
self.events.request('contracts:dependencies', (err, _contractsDependencies) => {
contractsDependencies = _contractsDependencies;
next();
});
},
function (next) {
for (let contract of contracts) {
if (options.skipUndeployed && !contract.deploy) continue;
id++; id++;
idMapping[contract] = id; idMapping[contract.className] = id;
let contractLabel = ""; let contractLabel = "";
contractLabel += `${contract}`; contractLabel += `${contract.className}`;
let tooltip = contract; let tooltip = contract.className;
if(this.engine.contractsManager.contracts[contract].instanceOf !== undefined && if (contract.instanceOf !== undefined && contracts[contract.instanceOf] !== undefined) {
this.engine.contractsManager.contracts[this.engine.contractsManager.contracts[contract].instanceOf] !== undefined){ contractInheritance[contract.className] = contract.instanceOf;
contractInheritance[contract] = this.engine.contractsManager.contracts[contract].instanceOf; contractLabel += ": " + contract.instanceOf;
contractLabel += ": " + this.engine.contractsManager.contracts[contract].instanceOf; tooltip += " instance of " + contract.instanceOf;
tooltip += " instance of " + this.engine.contractsManager.contracts[contract].instanceOf; } else {
} else { if (!(options.skipFunctions === true && options.skipEvents === true)) contractLabel += "|";
if(!(options.skipFunctions === true && options.skipEvents === true)) contractLabel += "|";
for(let i = 0; i < this.engine.contractsManager.contracts[contract].abiDefinition.length; i++){ for (let i = 0; i < contract.abiDefinition.length; i++) {
let abiDef = this.engine.contractsManager.contracts[contract].abiDefinition[i]; let abiDef = contract.abiDefinition[i];
if(abiDef.type == 'event' && options.skipEvents) continue; if (abiDef.type == 'event' && options.skipEvents) continue;
if(['constructor', 'fallback'].indexOf(abiDef.type) > -1 && options.skipFunctions) continue; if (['constructor', 'fallback'].indexOf(abiDef.type) > -1 && options.skipFunctions) continue;
switch(abiDef.type){ switch(abiDef.type){
case 'fallback': case 'fallback':
contractLabel += "«fallback»()\\l"; contractLabel += "«fallback»()\\l";
break; break;
case 'constructor': case 'constructor':
contractLabel += "«constructor»("; contractLabel += "«constructor»(";
abiDef.inputs.forEach(function(elem, index){ abiDef.inputs.forEach(function(elem, index){
contractLabel += (index == 0 ? "" : ", ") + elem.type; contractLabel += (index == 0 ? "" : ", ") + elem.type;
}); });
contractLabel += ")\\l"; contractLabel += ")\\l";
break; break;
case 'event': case 'event':
contractLabel += "«event»" + abiDef.name + "("; contractLabel += "«event»" + abiDef.name + "(";
abiDef.inputs.forEach(function(elem, index){ abiDef.inputs.forEach(function(elem, index){
contractLabel += (index == 0 ? "" : ", ") + elem.type; contractLabel += (index == 0 ? "" : ", ") + elem.type;
}); });
contractLabel += ")\\l"; contractLabel += ")\\l";
break; break;
default: break; default: break;
}
}
let fHashes = contract.functionHashes;
if (fHashes != {} && fHashes != undefined && !options.skipFunctions){
for (let method in contract.functionHashes){
contractLabel += method + '\\l';
}
}
} }
}
let fHashes = this.engine.contractsManager.contracts[contract].functionHashes; let others = '';
if(fHashes != {} && fHashes != undefined && !options.skipFunctions){ if (!contract.deploy){
for(let method in this.engine.contractsManager.contracts[contract].functionHashes){ others = 'fontcolor="#c3c3c3", color="#a0a0a0"';
contractLabel += method + '\\l'; tooltip += " (not deployed)";
} }
contractString += `${id}[label = "{${contractLabel}}", tooltip="${tooltip}", fillcolor=gray95, ${others}]\n`;
} }
} next();
},
let others = ''; function (next) {
if(!this.engine.contractsManager.contracts[contract].deploy){ for (let c in contractsDependencies) {
others = 'fontcolor="#c3c3c3", color="#a0a0a0"'; let contractDependencies = Array.from(new Set(contractsDependencies[c]));
tooltip += " (not deployed)"; contractDependencies.forEach((d) => {
} if (idMapping[c] !== undefined && idMapping[d] !== undefined) {
if ((options.skipUndeployed && contracts[c].deploy && contracts[d].deploy) || !options.skipUndeployed) {
contractString += `${id}[label = "{${contractLabel}}", tooltip="${tooltip}", fillcolor=gray95, ${others}]\n`; relationshipString += `${idMapping[d]}->${idMapping[c]}[constraint=true, arrowtail=diamond, tooltip="${c} uses ${d}"]\n`;
}
} }
});
for (let c in this.engine.contractsManager.contractDependencies){
let contractDependencies = Array.from(new Set(this.engine.contractsManager.contractDependencies[c]));
contractDependencies.forEach((d) => {
if(idMapping[c] !== undefined && idMapping[d] !== undefined){
if((options.skipUndeployed && this.engine.contractsManager.contracts[c].deploy && this.engine.contractsManager.contracts[d].deploy) || !options.skipUndeployed){
relationshipString += `${idMapping[d]}->${idMapping[c]}[constraint=true, arrowtail=diamond, tooltip="${c} uses ${d}"]\n`;
}
} }
}); next();
} },
function (next) {
for (let c in contractInheritance){
if(options.skipUndeployed && !contracts[contractInheritance[c]].deploy) continue;
for (let c in contractInheritance){ relationshipString += `${idMapping[contractInheritance[c]]}->${idMapping[c]}[tooltip="${c} instance of ${contractInheritance[c]}"]\n`;
if(options.skipUndeployed && !this.engine.contractsManager.contracts[contractInheritance[c]].deploy) continue; }
console.log("-----");
relationshipString += `${idMapping[contractInheritance[c]]}->${idMapping[c]}[tooltip="${c} instance of ${contractInheritance[c]}"]\n`; console.log(relationshipString);
} console.log("-----");
next();
let dot = ` },
function (next) {
let dot = `
digraph Contracts { digraph Contracts {
node[shape=record,style=filled] node[shape=record,style=filled]
edge[dir=back, arrowtail=empty] edge[dir=back, arrowtail=empty]
@ -109,15 +134,18 @@ class GraphGenerator {
${relationshipString} ${relationshipString}
}`; }`;
let svg = Viz(dot); console.log(dot);
let svg = Viz(dot);
let filename = "diagram.svg"; let filename = "diagram.svg";
fs.writeFileSync(filename, svg, (err) => { fs.writeFileSync(filename, svg, (err) => {
if (err) throw err; if (err) throw err;
next();
});
}
], function(_err, _result) {
}); });
} }
} }