Merge pull request #215 from sc-forks/emit

Emit coverage events.
pull/222/head
c-g-e-w-e-k-e- 7 years ago committed by GitHub
commit f5b16f924a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      lib/injector.js
  2. 21
      lib/instrumenter.js
  3. 200
      package-lock.json
  4. 4
      package.json
  5. 3
      test/conditional.js
  6. 3
      test/sources/cli/Face.sol
  7. 3
      test/sources/cli/PureView.sol
  8. 3
      test/sources/cli/TotallyPure.sol

@ -6,40 +6,40 @@ injector.callEvent = function injectCallEvent(contract, fileName, injectionPoint
const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1; const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1;
contract.runnableLines.push(linecount); contract.runnableLines.push(linecount);
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'__Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' + 'emit __Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'__FunctionCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.fnId + ');\n' + 'emit __FunctionCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.fnId + ');\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
(injection.openBracket ? '{' : '') + (injection.openBracket ? '{' : '') +
'__BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' + 'emit __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' +
(injection.comma ? ',' : ';') + (injection.comma ? ',' : ';') +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) { injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'else { __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' + 'else { emit __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
injector.callAssertPreEvent = function callAssertPreEvent(contract, fileName, injectionPoint, injection) { injector.callAssertPreEvent = function callAssertPreEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'__AssertPreCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' + 'emit __AssertPreCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
injector.callAssertPostEvent = function callAssertPostEvent(contract, fileName, injectionPoint, injection) { injector.callAssertPostEvent = function callAssertPostEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'__AssertPostCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' + 'emit __AssertPostCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ');\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };
@ -57,7 +57,7 @@ injector.literal = function injectLiteral(contract, fileName, injectionPoint, in
injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) { injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) + contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
' __StatementCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.statementId + ');\n' + 'emit __StatementCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.statementId + ');\n' +
contract.instrumented.slice(injectionPoint); contract.instrumented.slice(injectionPoint);
}; };

@ -19,9 +19,15 @@ instrumenter.prePosition = function prePosition(expression) {
}; };
instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpression(contract, expression) { instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpression(contract, expression) {
// This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword.
// Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/
return;
// --------------------------------------------------------------------------------------------
// The only time we instrument an assignment expression is if there's a conditional expression on // The only time we instrument an assignment expression is if there's a conditional expression on
// the right // the right
if (expression.right.type === 'ConditionalExpression') { /*if (expression.right.type === 'ConditionalExpression') {
if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') { if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') {
// Then we need to go from bytes32 varname = (conditional expression) // Then we need to go from bytes32 varname = (conditional expression)
// to bytes32 varname; (,varname) = (conditional expression) // to bytes32 varname; (,varname) = (conditional expression)
@ -42,11 +48,18 @@ instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpre
console.log(err, contract, expression.left); console.log(err, contract, expression.left);
process.exit(); process.exit();
} }
} }*/
}; };
instrumenter.instrumentConditionalExpression = function instrumentConditionalExpression(contract, expression) { instrumenter.instrumentConditionalExpression = function instrumentConditionalExpression(contract, expression) {
contract.branchId += 1; // ----------------------------------------------------------------------------------------------
// This is suspended for 0.5.0 which tries to accomodate the new `emit` keyword.
// Solc is not allowing us to use the construction `emit SomeEvent()` within the parens :/
// Very sad, this is the coolest thing in here.
return;
// ----------------------------------------------------------------------------------------------
/*contract.branchId += 1;
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1; const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1;
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1; const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1;
@ -101,7 +114,7 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp
}); });
createOrAppendInjectionPoint(contract, expression.alternate.end, { createOrAppendInjectionPoint(contract, expression.alternate.end, {
type: 'closeParen', type: 'closeParen',
}); });*/
}; };
instrumenter.instrumentStatement = function instrumentStatement(contract, expression) { instrumenter.instrumentStatement = function instrumentStatement(contract, expression) {

200
package-lock.json generated

@ -5341,9 +5341,9 @@
"integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=" "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI="
}, },
"solc": { "solc": {
"version": "0.4.17", "version": "0.4.21",
"resolved": "https://registry.npmjs.org/solc/-/solc-0.4.17.tgz", "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.21.tgz",
"integrity": "sha512-39Tmo2r+qclwW7ooLXMLzMSxmoGtHy3/p2sDKdA9NM/+MRtzLm/AFKj4BY2Cocg3gwkfJzKTEx6X0wiI4fIZ/A==", "integrity": "sha512-8lJmimVjOG9AJOQRWS2ph4rSctPMsPGZ4H360HLs5iI+euUlt7iAvUxSLeFZZzwk0kas4Qta7HmlMXNU3yYwhw==",
"dev": true, "dev": true,
"requires": { "requires": {
"fs-extra": "0.30.0", "fs-extra": "0.30.0",
@ -5351,63 +5351,6 @@
"require-from-string": "1.2.1", "require-from-string": "1.2.1",
"semver": "5.5.0", "semver": "5.5.0",
"yargs": "4.8.1" "yargs": "4.8.1"
},
"dependencies": {
"camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
"dev": true
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"dev": true,
"requires": {
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wrap-ansi": "2.1.0"
}
},
"window-size": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
"integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
"dev": true
},
"yargs": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
"integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
"dev": true,
"requires": {
"cliui": "3.2.0",
"decamelize": "1.2.0",
"get-caller-file": "1.0.2",
"lodash.assign": "4.2.0",
"os-locale": "1.4.0",
"read-pkg-up": "1.0.1",
"require-directory": "2.1.1",
"require-main-filename": "1.0.1",
"set-blocking": "2.0.0",
"string-width": "1.0.2",
"which-module": "1.0.0",
"window-size": "0.2.0",
"y18n": "3.2.1",
"yargs-parser": "2.4.1"
}
},
"yargs-parser": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
"integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
"dev": true,
"requires": {
"camelcase": "3.0.0",
"lodash.assign": "4.2.0"
}
}
} }
}, },
"solidity-parser-sc": { "solidity-parser-sc": {
@ -5827,84 +5770,14 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM="
}, },
"truffle": { "truffle": {
"version": "4.0.1", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/truffle/-/truffle-4.0.1.tgz", "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.5.tgz",
"integrity": "sha512-PybO+GMq3AvsfCWfEx4sbuaJlDL19iR8Ff20cO0TtP599N5JbMLlhwlffvVInPgFjP+F11vjSOYj3hT8fONs5A==", "integrity": "sha512-6sOVFQ0xNbb52MMWf0nHxv0FiXWPTV+OIbq1B0+I5F3sIS8JJ7pM1+o7chbs+oO/CLqbbC6ggXJqFWzIWaiaQg==",
"dev": true, "dev": true,
"requires": { "requires": {
"mocha": "3.5.3", "mocha": "3.5.3",
"original-require": "1.0.1", "original-require": "1.0.1",
"solc": "0.4.18" "solc": "0.4.21"
},
"dependencies": {
"camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
"dev": true
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"dev": true,
"requires": {
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wrap-ansi": "2.1.0"
}
},
"solc": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/solc/-/solc-0.4.18.tgz",
"integrity": "sha512-Kq+O3PNF9Pfq7fB+lDYAuoqRdghLmZyfngsg0h1Hj38NKAeVHeGPOGeZasn5KqdPeCzbMFvaGyTySxzGv6aXCg==",
"dev": true,
"requires": {
"fs-extra": "0.30.0",
"memorystream": "0.3.1",
"require-from-string": "1.2.1",
"semver": "5.5.0",
"yargs": "4.8.1"
}
},
"window-size": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
"integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
"dev": true
},
"yargs": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
"integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
"dev": true,
"requires": {
"cliui": "3.2.0",
"decamelize": "1.2.0",
"get-caller-file": "1.0.2",
"lodash.assign": "4.2.0",
"os-locale": "1.4.0",
"read-pkg-up": "1.0.1",
"require-directory": "2.1.1",
"require-main-filename": "1.0.1",
"set-blocking": "2.0.0",
"string-width": "1.0.2",
"which-module": "1.0.0",
"window-size": "0.2.0",
"y18n": "3.2.1",
"yargs-parser": "2.4.1"
}
},
"yargs-parser": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
"integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
"dev": true,
"requires": {
"camelcase": "3.0.0",
"lodash.assign": "4.2.0"
}
}
} }
}, },
"tunnel-agent": { "tunnel-agent": {
@ -6569,6 +6442,65 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
}, },
"yargs": {
"version": "4.8.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz",
"integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=",
"dev": true,
"requires": {
"cliui": "3.2.0",
"decamelize": "1.2.0",
"get-caller-file": "1.0.2",
"lodash.assign": "4.2.0",
"os-locale": "1.4.0",
"read-pkg-up": "1.0.1",
"require-directory": "2.1.1",
"require-main-filename": "1.0.1",
"set-blocking": "2.0.0",
"string-width": "1.0.2",
"which-module": "1.0.0",
"window-size": "0.2.0",
"y18n": "3.2.1",
"yargs-parser": "2.4.1"
},
"dependencies": {
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"dev": true,
"requires": {
"string-width": "1.0.2",
"strip-ansi": "3.0.1",
"wrap-ansi": "2.1.0"
}
},
"window-size": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz",
"integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=",
"dev": true
}
}
},
"yargs-parser": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz",
"integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=",
"dev": true,
"requires": {
"camelcase": "3.0.0",
"lodash.assign": "4.2.0"
},
"dependencies": {
"camelcase": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
"integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
"dev": true
}
}
},
"yeoman-environment": { "yeoman-environment": {
"version": "2.0.5", "version": "2.0.5",
"resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.5.tgz", "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.5.tgz",

@ -44,7 +44,7 @@
"merkle-patricia-tree": "~2.1.2", "merkle-patricia-tree": "~2.1.2",
"mocha": "^3.1.0", "mocha": "^3.1.0",
"request": "^2.81.0", "request": "^2.81.0",
"solc": "0.4.17", "solc": "0.4.21",
"truffle": "4.0.1" "truffle": "4.1.5"
} }
} }

@ -7,13 +7,14 @@ const CoverageMap = require('./../lib/coverageMap');
const vm = require('./util/vm'); const vm = require('./util/vm');
const assert = require('assert'); const assert = require('assert');
describe('conditional statements', () => { describe.skip('conditional statements', () => {
const filePath = path.resolve('./test.sol'); const filePath = path.resolve('./test.sol');
const pathPrefix = './'; const pathPrefix = './';
it('should cover a conditional that reaches the consequent (same-line)', done => { it('should cover a conditional that reaches the consequent (same-line)', done => {
const contract = util.getCode('conditional/sameline-consequent.sol'); const contract = util.getCode('conditional/sameline-consequent.sol');
const info = getInstrumentedVersion(contract, filePath); const info = getInstrumentedVersion(contract, filePath);
console.log(info.contract)
const coverage = new CoverageMap(); const coverage = new CoverageMap();
coverage.addContract(info, filePath); coverage.addContract(info, filePath);

@ -1,5 +1,4 @@
pragma experimental "v0.5.0"; pragma solidity ^0.4.21;
//pragma solidity ^0.4.17;
interface Face { interface Face {
function stare(uint a, uint b) external; function stare(uint a, uint b) external;

@ -1,5 +1,4 @@
pragma experimental "v0.5.0"; pragma solidity ^0.4.21;
//pragma solidity ^0.4.17;
contract PureView { contract PureView {

@ -1,5 +1,4 @@
pragma experimental "v0.5.0"; pragma solidity ^0.4.21;
//pragma solidity ^0.4.17;
import "./../assets/Face.sol"; import "./../assets/Face.sol";
import "./../assets/PureView.sol"; import "./../assets/PureView.sol";

Loading…
Cancel
Save