From a9b575d470505e61d43bcb65e3c229ea8a51c534 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 8 Apr 2018 18:47:07 -0700 Subject: [PATCH 1/3] Emit coverage events. Bump solc to 0.4.21, Truffle to 4.1.5 --- lib/injector.js | 14 +-- lib/instrumenter.js | 6 + package-lock.json | 200 ++++++++++--------------------- package.json | 4 +- test/conditional.js | 3 +- test/sources/cli/Face.sol | 3 +- test/sources/cli/PureView.sol | 3 +- test/sources/cli/TotallyPure.sol | 3 +- 8 files changed, 86 insertions(+), 150 deletions(-) diff --git a/lib/injector.js b/lib/injector.js index 4105768..6e7306f 100644 --- a/lib/injector.js +++ b/lib/injector.js @@ -6,40 +6,40 @@ injector.callEvent = function injectCallEvent(contract, fileName, injectionPoint const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1; contract.runnableLines.push(linecount); contract.instrumented = contract.instrumented.slice(0, injectionPoint) + - '__Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' + + 'emit __Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' + contract.instrumented.slice(injectionPoint); }; injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { 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); }; injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) { contract.instrumented = contract.instrumented.slice(0, injectionPoint) + (injection.openBracket ? '{' : '') + - '__BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' + + 'emit __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' + (injection.comma ? ',' : ';') + contract.instrumented.slice(injectionPoint); }; injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) { 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); }; injector.callAssertPreEvent = function callAssertPreEvent(contract, fileName, injectionPoint, injection) { 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); }; injector.callAssertPostEvent = function callAssertPostEvent(contract, fileName, injectionPoint, injection) { 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); }; @@ -57,7 +57,7 @@ injector.literal = function injectLiteral(contract, fileName, injectionPoint, in injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) { 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); }; diff --git a/lib/instrumenter.js b/lib/instrumenter.js index 13f2033..a7db9e3 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -46,6 +46,12 @@ instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpre }; instrumenter.instrumentConditionalExpression = function instrumentConditionalExpression(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 :/ + // 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; diff --git a/package-lock.json b/package-lock.json index ba5c99a..65650a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5341,9 +5341,9 @@ "integrity": "sha1-Q66MQZ/TrAVqBfip0fsQIs1B7MI=" }, "solc": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.17.tgz", - "integrity": "sha512-39Tmo2r+qclwW7ooLXMLzMSxmoGtHy3/p2sDKdA9NM/+MRtzLm/AFKj4BY2Cocg3gwkfJzKTEx6X0wiI4fIZ/A==", + "version": "0.4.21", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.4.21.tgz", + "integrity": "sha512-8lJmimVjOG9AJOQRWS2ph4rSctPMsPGZ4H360HLs5iI+euUlt7iAvUxSLeFZZzwk0kas4Qta7HmlMXNU3yYwhw==", "dev": true, "requires": { "fs-extra": "0.30.0", @@ -5351,63 +5351,6 @@ "require-from-string": "1.2.1", "semver": "5.5.0", "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": { @@ -5827,84 +5770,14 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, "truffle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.0.1.tgz", - "integrity": "sha512-PybO+GMq3AvsfCWfEx4sbuaJlDL19iR8Ff20cO0TtP599N5JbMLlhwlffvVInPgFjP+F11vjSOYj3hT8fONs5A==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/truffle/-/truffle-4.1.5.tgz", + "integrity": "sha512-6sOVFQ0xNbb52MMWf0nHxv0FiXWPTV+OIbq1B0+I5F3sIS8JJ7pM1+o7chbs+oO/CLqbbC6ggXJqFWzIWaiaQg==", "dev": true, "requires": { "mocha": "3.5.3", "original-require": "1.0.1", - "solc": "0.4.18" - }, - "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" - } - } + "solc": "0.4.21" } }, "tunnel-agent": { @@ -6569,6 +6442,65 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "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": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.0.5.tgz", diff --git a/package.json b/package.json index 10c953b..f96355b 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "merkle-patricia-tree": "~2.1.2", "mocha": "^3.1.0", "request": "^2.81.0", - "solc": "0.4.17", - "truffle": "4.0.1" + "solc": "0.4.21", + "truffle": "4.1.5" } } diff --git a/test/conditional.js b/test/conditional.js index 21ad227..8b8da61 100644 --- a/test/conditional.js +++ b/test/conditional.js @@ -7,13 +7,14 @@ const CoverageMap = require('./../lib/coverageMap'); const vm = require('./util/vm'); const assert = require('assert'); -describe('conditional statements', () => { +describe.skip('conditional statements', () => { const filePath = path.resolve('./test.sol'); const pathPrefix = './'; it('should cover a conditional that reaches the consequent (same-line)', done => { const contract = util.getCode('conditional/sameline-consequent.sol'); const info = getInstrumentedVersion(contract, filePath); + console.log(info.contract) const coverage = new CoverageMap(); coverage.addContract(info, filePath); diff --git a/test/sources/cli/Face.sol b/test/sources/cli/Face.sol index 1b95f0c..47b5030 100644 --- a/test/sources/cli/Face.sol +++ b/test/sources/cli/Face.sol @@ -1,5 +1,4 @@ -pragma experimental "v0.5.0"; -//pragma solidity ^0.4.17; +pragma solidity ^0.4.21; interface Face { function stare(uint a, uint b) external; diff --git a/test/sources/cli/PureView.sol b/test/sources/cli/PureView.sol index 6ff075c..f8debcd 100644 --- a/test/sources/cli/PureView.sol +++ b/test/sources/cli/PureView.sol @@ -1,5 +1,4 @@ -pragma experimental "v0.5.0"; -//pragma solidity ^0.4.17; +pragma solidity ^0.4.21; contract PureView { diff --git a/test/sources/cli/TotallyPure.sol b/test/sources/cli/TotallyPure.sol index eb7fb4d..1d0eeee 100644 --- a/test/sources/cli/TotallyPure.sol +++ b/test/sources/cli/TotallyPure.sol @@ -1,5 +1,4 @@ -pragma experimental "v0.5.0"; -//pragma solidity ^0.4.17; +pragma solidity ^0.4.21; import "./../assets/Face.sol"; import "./../assets/PureView.sol"; From 339b881e718e2200633122c18e427c224c09bb40 Mon Sep 17 00:00:00 2001 From: cgewecke Date: Sun, 8 Apr 2018 19:00:17 -0700 Subject: [PATCH 2/3] Comment out conditional code (for coveralls) --- lib/instrumenter.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/instrumenter.js b/lib/instrumenter.js index a7db9e3..cc2c424 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -52,7 +52,8 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp // Very sad, this is the coolest thing in here. return; // ---------------------------------------------------------------------------------------------- - contract.branchId += 1; + + /*contract.branchId += 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; @@ -107,7 +108,7 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp }); createOrAppendInjectionPoint(contract, expression.alternate.end, { type: 'closeParen', - }); + });*/ }; instrumenter.instrumentStatement = function instrumentStatement(contract, expression) { From 1b79bb54a818c50f6fa71015c21c9749ca91af7b Mon Sep 17 00:00:00 2001 From: cgewecke Date: Wed, 11 Apr 2018 07:48:09 -0700 Subject: [PATCH 3/3] Comment out assignment instrumentation logic --- lib/instrumenter.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/instrumenter.js b/lib/instrumenter.js index cc2c424..eafc897 100644 --- a/lib/instrumenter.js +++ b/lib/instrumenter.js @@ -19,9 +19,15 @@ instrumenter.prePosition = function prePosition(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 right - if (expression.right.type === 'ConditionalExpression') { + /*if (expression.right.type === 'ConditionalExpression') { if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') { // Then we need to go from bytes32 varname = (conditional expression) // to bytes32 varname; (,varname) = (conditional expression) @@ -42,7 +48,7 @@ instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpre console.log(err, contract, expression.left); process.exit(); } - } + }*/ }; instrumenter.instrumentConditionalExpression = function instrumentConditionalExpression(contract, expression) {