Accommodate async nature of solidity-parser-antlr

leapdao
Alex 6 years ago
parent ee58167e81
commit 9b5d9ffc66
  1. 14
      lib/preprocessor.js
  2. 23
      test/if.js
  3. 21
      test/sources/if/if-elseif-else.sol

@ -50,28 +50,29 @@ module.exports.run = function r(contract) {
try {
const ast = SolidityParser.parse(contract, { range: true });
keepRunning = false;
blocksToWrap = [];
SolidityParser.visit(ast, {
IfStatement: function(node) {
if (node.trueBody.type !== 'Block') {
contract = blockWrap(contract, node.trueBody);
blocksToWrap.push(node.trueBody);
keepRunning = true;
return false;
} else if (node.falseBody && node.falseBody.type !== 'Block'){
contract = blockWrap(contract, node.falseBody);
blocksToWrap.push(node.falseBody);
keepRunning = true;
return false;
}
},
ForStatement: function(node){
if (node.body.type !== 'Block'){
contract = blockWrap(contract, node.body);
blocksToWrap.push(node.body);
keepRunning = true;
return false;
}
},
WhileStatement: function(node){
if (node.body.type !== 'Block'){
contract = blockWrap(contract, node.body);
blocksToWrap.push(node.body);
keepRunning = true;
return false;
}
@ -84,6 +85,11 @@ module.exports.run = function r(contract) {
}
}
})
// Returning 'false' only stops going any deeper in that particular branch of the tree, but other branches
// continue.
// So we apply the blocks we found in reverse order to avoid extra characters messing things up.
blocksToWrap.sort((a,b) => a.range[0] < b.range[0]);
blocksToWrap.forEach(block => contract = blockWrap(contract, block))
} catch (err) {
contract = err;
keepRunning = false;

@ -208,4 +208,27 @@ describe('if, else, and else if statements', () => {
done();
}).catch(done);
});
it('should cover if-elseif-else statements that are at the same depth as each other', done => {
const contract = util.getCode('if/if-elseif-else.sol');
const info = getInstrumentedVersion(contract, filePath);
const coverage = new CoverageMap();
coverage.addContract(info, filePath);
vm.execute(info.contract, 'a', [2, 3, 3]).then(events => {
const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {
5: 1, 6: 0, 8: 1, 10: 0, 13: 1, 14: 0, 16: 1, 18: 0,
});
assert.deepEqual(mapping[filePath].b, {
1: [0, 1], 2: [1, 0], 3: [0, 1], 4: [1, 0]
});
assert.deepEqual(mapping[filePath].s, {
1: 1, 2: 0, 3: 1, 4: 1, 5: 0, 6: 1, 7: 0, 8: 1, 9: 1, 10: 0,
});
assert.deepEqual(mapping[filePath].f, {
1: 1,
});
done();
}).catch(done);
});
});

@ -0,0 +1,21 @@
pragma solidity ^0.5.0;
contract Test {
function a(uint x,uint y, uint z) public {
if (x == y) {
z = 0;
} else if (x == 2) {
z = 1;
} else {
z = 2;
}
if (x == y) {
z = 0;
} else if (x == 2) {
z = 1;
} else {
z = 2;
}
}
}
Loading…
Cancel
Save