mirror of https://github.com/embarklabs/embark.git
Linting things
This commit is contained in:
parent
22d809ba22
commit
0ec3ff0ddc
|
@ -186,7 +186,7 @@
|
||||||
"no-unmodified-loop-condition": "error",
|
"no-unmodified-loop-condition": "error",
|
||||||
"no-unneeded-ternary": "error",
|
"no-unneeded-ternary": "error",
|
||||||
"no-unused-expressions": "error",
|
"no-unused-expressions": "error",
|
||||||
"no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
|
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_"}],
|
||||||
"no-use-before-define": "off",
|
"no-use-before-define": "off",
|
||||||
"no-useless-call": "off",
|
"no-useless-call": "off",
|
||||||
"no-useless-computed-key": "error",
|
"no-useless-computed-key": "error",
|
||||||
|
|
|
@ -23,23 +23,21 @@ class ContractSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceMapToLocations(sourceMap) {
|
sourceMapToLocations(sourceMap) {
|
||||||
var [offset, length, ..._rest] = sourceMap.split(":").map((val) => {
|
var [offset, length, ..._] = sourceMap.split(":").map((val) => {
|
||||||
return parseInt(val, 10);
|
return parseInt(val, 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
var locations = {};
|
var locations = {};
|
||||||
|
|
||||||
for(var i = 0; i < this.lineCount; i++) {
|
for(let i = 0; i < this.lineCount; i++) {
|
||||||
if(this.lineOffsets[i+1] <= offset)
|
if(this.lineOffsets[i+1] <= offset) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
locations.start = {line: i, column: offset - this.lineOffsets[i]};
|
locations.start = {line: i, column: offset - this.lineOffsets[i]};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i = locations.start.line; i < this.lineCount; i++) {
|
for(var i = locations.start.line; i < this.lineCount; i++) {
|
||||||
if(this.lineOffsets[i+1] <= offset + length)
|
if(this.lineOffsets[i+1] <= offset + length) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
locations.end = {line: i, column: ((offset + length) - this.lineOffsets[i])};
|
locations.end = {line: i, column: ((offset + length) - this.lineOffsets[i])};
|
||||||
break;
|
break;
|
||||||
|
@ -81,7 +79,7 @@ class ContractSource {
|
||||||
instruction: instruction,
|
instruction: instruction,
|
||||||
sourceMap: sourceMaps[instructions],
|
sourceMap: sourceMaps[instructions],
|
||||||
seen: false
|
seen: false
|
||||||
}
|
};
|
||||||
|
|
||||||
pc += length;
|
pc += length;
|
||||||
instructions++;
|
instructions++;
|
||||||
|
@ -90,9 +88,9 @@ class ContractSource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*eslint complexity: ["error", 27]*/
|
||||||
generateCodeCoverage(trace) {
|
generateCodeCoverage(trace) {
|
||||||
if(!this.ast || !this.contractBytecode)
|
if(!this.ast || !this.contractBytecode) throw new Error('Error generating coverage: solc output was not assigned');
|
||||||
throw new Error('Error generating coverage: solc output was not assigned');
|
|
||||||
|
|
||||||
var coverage = {
|
var coverage = {
|
||||||
code: this.body.split("\n"),
|
code: this.body.split("\n"),
|
||||||
|
@ -103,18 +101,15 @@ class ContractSource {
|
||||||
f: {},
|
f: {},
|
||||||
fnMap: {},
|
fnMap: {},
|
||||||
statementMap: {},
|
statementMap: {},
|
||||||
branchMap: {},
|
branchMap: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var nodesRequiringVisiting = [this.ast];
|
var nodesRequiringVisiting = [this.ast];
|
||||||
var nodeStack = [];
|
|
||||||
var sourceMapToNodeType = {};
|
var sourceMapToNodeType = {};
|
||||||
|
|
||||||
do {
|
do {
|
||||||
var node = nodesRequiringVisiting.pop();
|
var node = nodesRequiringVisiting.pop();
|
||||||
|
if(!node) continue;
|
||||||
if(!node)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var children = [];
|
var children = [];
|
||||||
var markLocations = [];
|
var markLocations = [];
|
||||||
|
@ -152,18 +147,15 @@ class ContractSource {
|
||||||
|
|
||||||
markLocations = [location, trueBranchLocation, falseBranchLocation];
|
markLocations = [location, trueBranchLocation, falseBranchLocation];
|
||||||
|
|
||||||
if(node.trueBody.statements[0])
|
if(node.trueBody.statements[0]) {
|
||||||
node.trueBody.statements[0]._parent = {type: 'b', id: node.id, idx: 0}
|
node.trueBody.statements[0]._parent = {type: 'b', id: node.id, idx: 0};
|
||||||
|
}
|
||||||
|
|
||||||
if(node.falseBody && node.falseBody.statements[0])
|
if(node.falseBody && node.falseBody.statements[0]) {
|
||||||
node.falseBody.statements[0]._parent = {type: 'b', id: node.id, idx: 1}
|
node.falseBody.statements[0]._parent = {type: 'b', id: node.id, idx: 1};
|
||||||
|
}
|
||||||
sourceMapToNodeType[node.src] = [{
|
|
||||||
type: 'b',
|
|
||||||
id: node.id,
|
|
||||||
body: {loc: location},
|
|
||||||
}]
|
|
||||||
|
|
||||||
|
sourceMapToNodeType[node.src] = [{type: 'b', id: node.id, body: {loc: location}}];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'BinaryOperation':
|
case 'BinaryOperation':
|
||||||
|
@ -175,12 +167,13 @@ class ContractSource {
|
||||||
// return "body". We don't `break` here on purpose so it can share the
|
// return "body". We don't `break` here on purpose so it can share the
|
||||||
// same logic below.
|
// same logic below.
|
||||||
node.src = node.expression.src;
|
node.src = node.expression.src;
|
||||||
|
// falls through
|
||||||
|
|
||||||
case 'Assignment':
|
case 'Assignment':
|
||||||
case 'ExpressionStatement':
|
case 'ExpressionStatement':
|
||||||
coverage.s[node.id] = 0;
|
coverage.s[node.id] = 0;
|
||||||
|
|
||||||
var location = this.sourceMapToLocations(node.src);
|
location = this.sourceMapToLocations(node.src);
|
||||||
coverage.statementMap[node.id] = location;
|
coverage.statementMap[node.id] = location;
|
||||||
|
|
||||||
if(!sourceMapToNodeType[node.src]) sourceMapToNodeType[node.src] = [];
|
if(!sourceMapToNodeType[node.src]) sourceMapToNodeType[node.src] = [];
|
||||||
|
@ -188,7 +181,7 @@ class ContractSource {
|
||||||
type: 's',
|
type: 's',
|
||||||
id: node.id,
|
id: node.id,
|
||||||
body: {loc: coverage.statementMap[node.id]},
|
body: {loc: coverage.statementMap[node.id]},
|
||||||
parent: node._parent,
|
parent: node._parent
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,21 +210,17 @@ class ContractSource {
|
||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
var fnName = node.isConstructor ? "(constructor)" : node.name;
|
var fnName = node.isConstructor ? "(constructor)" : node.name;
|
||||||
var location = this.sourceMapToLocations(functionDefinitionSourceMap);
|
location = this.sourceMapToLocations(functionDefinitionSourceMap);
|
||||||
|
|
||||||
coverage.f[node.id] = 0;
|
coverage.f[node.id] = 0;
|
||||||
coverage.fnMap[node.id] = {
|
coverage.fnMap[node.id] = {
|
||||||
name: fnName,
|
name: fnName,
|
||||||
line: location.start.line,
|
line: location.start.line,
|
||||||
loc: location,
|
loc: location
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record function positions.
|
// Record function positions.
|
||||||
sourceMapToNodeType[node.src] = [{
|
sourceMapToNodeType[node.src] = [{type: 'f', id: node.id, body: coverage.fnMap[node.id]}];
|
||||||
type: 'f',
|
|
||||||
id: node.id,
|
|
||||||
body: coverage.fnMap[node.id],
|
|
||||||
}];
|
|
||||||
|
|
||||||
if(node.body) children = node.body.statements;
|
if(node.body) children = node.body.statements;
|
||||||
markLocations = [location];
|
markLocations = [location];
|
||||||
|
@ -266,17 +255,15 @@ class ContractSource {
|
||||||
contractMatches = false;
|
contractMatches = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
if(!contractMatches) break;
|
if(!contractMatches) break;
|
||||||
|
|
||||||
trace.structLogs.forEach((step) => {
|
trace.structLogs.forEach((step) => {
|
||||||
var step = bytecode[step.pc];
|
step = bytecode[step.pc];
|
||||||
|
if(!step.sourceMap || step.sourceMap == '') return;
|
||||||
|
|
||||||
if(!step.sourceMap || step.sourceMap == '')
|
var nodes = sourceMapToNodeType[step.sourceMap];
|
||||||
return;
|
|
||||||
|
|
||||||
var nodes = sourceMapToNodeType[step.sourceMap] ;
|
|
||||||
|
|
||||||
if(!nodes) return;
|
if(!nodes) return;
|
||||||
|
|
||||||
|
@ -291,16 +278,17 @@ class ContractSource {
|
||||||
recordedLineHit = true;
|
recordedLineHit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node.type != 'b')
|
if(node.type != 'b') coverage[node.type][node.id]++;
|
||||||
coverage[node.type][node.id]++;
|
|
||||||
|
|
||||||
if(!node.parent)
|
if(!node.parent) return;
|
||||||
return;
|
|
||||||
|
|
||||||
switch(node.parent.type) {
|
switch(node.parent.type) {
|
||||||
case 'b':
|
case 'b':
|
||||||
coverage.b[node.parent.id][node.parent.idx]++;
|
coverage.b[node.parent.id][node.parent.idx]++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// do nothing
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -310,9 +298,7 @@ class ContractSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
_instructionLength(instruction) {
|
_instructionLength(instruction) {
|
||||||
if(instruction.indexOf('PUSH') == -1)
|
if(instruction.indexOf('PUSH') == -1) return 1;
|
||||||
return 1;
|
|
||||||
|
|
||||||
return parseInt(instruction.match(/PUSH(\d+)/m)[1], 10) + 1;
|
return parseInt(instruction.match(/PUSH(\d+)/m)[1], 10) + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ class ContractSources {
|
||||||
// No 'break' statement here on purpose, as it shares
|
// No 'break' statement here on purpose, as it shares
|
||||||
// the logic below.
|
// the logic below.
|
||||||
files = [files];
|
files = [files];
|
||||||
|
// falls through
|
||||||
|
|
||||||
case '[object Array]':
|
case '[object Array]':
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
|
@ -31,6 +32,9 @@ class ContractSources {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error(`Don't know how to initialize with ${Object.prototype.toString.call(files)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,10 +52,7 @@ class ContractSources {
|
||||||
for(var file in output.contracts) {
|
for(var file in output.contracts) {
|
||||||
var basename = path.basename(file);
|
var basename = path.basename(file);
|
||||||
var contractSource = this.files[basename];
|
var contractSource = this.files[basename];
|
||||||
if(!contractSource){
|
if(!contractSource) continue;
|
||||||
continue; // TODO CHECK THIS LOGIC
|
|
||||||
throw new Error(`Can't attribute output to ${file}: file has not been read in.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
contractSource.parseSolcOutput(output.sources[file], output.contracts[file]);
|
contractSource.parseSolcOutput(output.sources[file], output.contracts[file]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,15 +45,23 @@ class CodeCoverage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async runSolc(receipt) {
|
async runSolc(receipt) {
|
||||||
var block = await web3.eth.getBlock(receipt.number);
|
let block = await web3.eth.getBlock(receipt.number);
|
||||||
for(var i in block.transactions) {
|
if(block.transactions.length == 0) return;
|
||||||
|
|
||||||
|
let requests = [];
|
||||||
|
for(let i in block.transactions) {
|
||||||
var txHash = block.transactions[i];
|
var txHash = block.transactions[i];
|
||||||
|
|
||||||
if(this.seenTransactions[txHash]) return;
|
if(this.seenTransactions[txHash]) return;
|
||||||
|
|
||||||
this.seenTransactions[txHash] = true;
|
this.seenTransactions[txHash] = true;
|
||||||
var trace = await web3.debug.traceTransaction(txHash, {});
|
requests.push(web3.debug.traceTransaction(txHash, {}));
|
||||||
var cov = this.contractSources.generateCodeCoverage(trace);
|
}
|
||||||
|
|
||||||
|
let traces = await Promise.all(requests);
|
||||||
|
|
||||||
|
for(let i in traces) {
|
||||||
|
var cov = this.contractSources.generateCodeCoverage(traces[i]);
|
||||||
this.coverageReport = cov;
|
this.coverageReport = cov;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
class SourceMap {
|
class SourceMap {
|
||||||
constructor(sourceMapStringOrOffset, length, id) {
|
constructor(sourceMapStringOrOffset, length, id) {
|
||||||
if(typeof sourceMapStringOrOffset == 'string') {
|
if(typeof sourceMapStringOrOffset == 'string') {
|
||||||
var [offset, length, id, ..._rest] = sourceMapStringOrOffset.split(":");
|
let [offset, length, id, ..._rest] = sourceMapStringOrOffset.split(":");
|
||||||
|
|
||||||
this.offset = parseInt(offset, 10);
|
this.offset = parseInt(offset, 10);
|
||||||
this.length = parseInt(length, 10);
|
this.length = parseInt(length, 10);
|
||||||
|
|
|
@ -97,7 +97,6 @@ class Solidity {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
output.errors = []; // TODO REMOVE THIS
|
|
||||||
if (output.errors) {
|
if (output.errors) {
|
||||||
for (let i=0; i<output.errors.length; i++) {
|
for (let i=0; i<output.errors.length; i++) {
|
||||||
if (output.errors[i].type === 'Warning') {
|
if (output.errors[i].type === 'Warning') {
|
||||||
|
|
Loading…
Reference in New Issue