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