diff --git a/lib/parse.js b/lib/parse.js index 146e184..3d561fb 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -55,8 +55,21 @@ parse.ContractOrLibraryStatement = function(contract, expression) { // We need to define a method to pass coverage hashes into at top of each contract. // This lets us get a fresh stack for the hash and avoid stack-too-deep errors. if (expression.kind !== 'interface'){ - const start = expression.range[0]; - const end = contract.instrumented.slice(expression.range[0]).indexOf('{') + 1; + let start = 0; + + // It's possible a base contract will have constructor string arg + // which contains an open curly brace. Skip ahead pass the bases... + if (expression.baseContracts && expression.baseContracts.length){ + for (let base of expression.baseContracts ){ + if (base.range[1] > start){ + start = base.range[1]; + } + } + } else { + start = expression.range[0]; + } + + const end = contract.instrumented.slice(start).indexOf('{') + 1; const loc = start + end;; (contract.injectionPoints[loc]) diff --git a/test/units/statements.js b/test/units/statements.js index cd0fbc7..808ec32 100644 --- a/test/units/statements.js +++ b/test/units/statements.js @@ -23,6 +23,11 @@ describe('generic statements', () => { util.report(info.solcOutput.errors); }) + it('should compile a base contract contructor with a string arg containing "{"', ()=> { + const info = util.instrumentAndCompile('statements/interpolation'); + util.report(info.solcOutput.errors); + }) + it('should instrument a single statement (first line of function)', () => { const info = util.instrumentAndCompile('statements/single'); util.report(info.solcOutput.errors);