|
|
|
@ -14,7 +14,7 @@ function createOrAppendInjectionPoint(contract, key, value) { |
|
|
|
|
instrumenter.prePosition = function prePosition(expression) { |
|
|
|
|
if (expression.right.type === 'ConditionalExpression' && |
|
|
|
|
expression.left.type === 'MemberExpression') { |
|
|
|
|
expression.start -= 2; |
|
|
|
|
expression.range[0] -= 2; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -31,15 +31,15 @@ instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpre |
|
|
|
|
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)
|
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.end, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.range[1], { |
|
|
|
|
type: 'literal', string: '; (,' + expression.left.name + ')', |
|
|
|
|
}); |
|
|
|
|
instrumenter.instrumentConditionalExpression(contract, expression.right); |
|
|
|
|
} else if (expression.left.type === 'MemberExpression') { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.range[0], { |
|
|
|
|
type: 'literal', string: '(,', |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.end, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.left.range[1], { |
|
|
|
|
type: 'literal', string: ')', |
|
|
|
|
}); |
|
|
|
|
instrumenter.instrumentConditionalExpression(contract, expression.right); |
|
|
|
@ -61,12 +61,12 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp |
|
|
|
|
|
|
|
|
|
/*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; |
|
|
|
|
const consequentStartCol = startcol + (contract, expression.consequent.start - expression.start); |
|
|
|
|
const consequentEndCol = consequentStartCol + (contract, expression.consequent.end - expression.consequent.start); |
|
|
|
|
const alternateStartCol = startcol + (contract, expression.alternate.start - expression.start); |
|
|
|
|
const alternateEndCol = alternateStartCol + (contract, expression.alternate.end - expression.alternate.start); |
|
|
|
|
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; |
|
|
|
|
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; |
|
|
|
|
const consequentStartCol = startcol + (contract, expression.trueBody.range[0] - expression.range[0]); |
|
|
|
|
const consequentEndCol = consequentStartCol + (contract, expression.trueBody.range[1] - expression.trueBody.range[0]); |
|
|
|
|
const alternateStartCol = startcol + (contract, expression.falseBody.range[0] - expression.range[0]); |
|
|
|
|
const alternateEndCol = alternateStartCol + (contract, expression.falseBody.range[1] - expression.falseBody.range[0]); |
|
|
|
|
// NB locations for conditional branches in istanbul are length 1 and associated with the : and ?.
|
|
|
|
|
contract.branchMap[contract.branchId] = { |
|
|
|
|
line: startline, |
|
|
|
@ -95,24 +95,24 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Wrap the consequent
|
|
|
|
|
createOrAppendInjectionPoint(contract, expression.consequent.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { |
|
|
|
|
type: 'openParen', |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.consequent.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], { |
|
|
|
|
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 0, |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.consequent.end, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.trueBody.range[1], { |
|
|
|
|
type: 'closeParen', |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Wrap the alternate
|
|
|
|
|
createOrAppendInjectionPoint(contract, expression.alternate.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { |
|
|
|
|
type: 'openParen', |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.alternate.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], { |
|
|
|
|
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 1, |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.alternate.end, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.falseBody.range[1], { |
|
|
|
|
type: 'closeParen', |
|
|
|
|
});*/ |
|
|
|
|
}; |
|
|
|
@ -120,14 +120,14 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp |
|
|
|
|
instrumenter.instrumentStatement = function instrumentStatement(contract, expression) { |
|
|
|
|
contract.statementId += 1; |
|
|
|
|
// We need to work out the lines and columns the expression starts and ends
|
|
|
|
|
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 expressionContent = contract.instrumented.slice(expression.start, expression.end); |
|
|
|
|
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; |
|
|
|
|
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; |
|
|
|
|
const expressionContent = contract.instrumented.slice(expression.range[0], expression.range[1] + 1); |
|
|
|
|
|
|
|
|
|
const endline = startline + (contract, expressionContent.match('/\n/g') || []).length; |
|
|
|
|
let endcol; |
|
|
|
|
if (expressionContent.lastIndexOf('\n') >= 0) { |
|
|
|
|
endcol = contract.instrumented.slice(expressionContent.lastIndexOf('\n'), expression.end).length - 1; |
|
|
|
|
endcol = contract.instrumented.slice(expressionContent.lastIndexOf('\n'), expression.range[1]).length; |
|
|
|
|
} else { |
|
|
|
|
endcol = startcol + (contract, expressionContent.length - 1); |
|
|
|
|
} |
|
|
|
@ -139,15 +139,15 @@ instrumenter.instrumentStatement = function instrumentStatement(contract, expres |
|
|
|
|
line: endline, column: endcol, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.range[0], { |
|
|
|
|
type: 'statement', statementId: contract.statementId, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
instrumenter.instrumentLine = function instrumentLine(contract, expression) { |
|
|
|
|
// what's the position of the most recent newline?
|
|
|
|
|
const startchar = expression.start; |
|
|
|
|
const endchar = expression.end; |
|
|
|
|
const startchar = expression.range[0]; |
|
|
|
|
const endchar = expression.range[1] + 1; |
|
|
|
|
const lastNewLine = contract.instrumented.slice(0, startchar).lastIndexOf('\n'); |
|
|
|
|
const nextNewLine = startchar + contract.instrumented.slice(startchar).indexOf('\n'); |
|
|
|
|
const contractSnipped = contract.instrumented.slice(lastNewLine, nextNewLine); |
|
|
|
@ -160,7 +160,7 @@ instrumenter.instrumentLine = function instrumentLine(contract, expression) { |
|
|
|
|
}); |
|
|
|
|
} else if (contract.instrumented.slice(lastNewLine, startchar).replace('{', '').trim().length === 0 && |
|
|
|
|
contract.instrumented.slice(endchar, nextNewLine).replace(/[;}]/g, '').trim().length === 0) { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.range[0], { |
|
|
|
|
type: 'callEvent', |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
@ -169,11 +169,11 @@ instrumenter.instrumentLine = function instrumentLine(contract, expression) { |
|
|
|
|
|
|
|
|
|
instrumenter.instrumentFunctionDeclaration = function instrumentFunctionDeclaration(contract, expression) { |
|
|
|
|
contract.fnId += 1; |
|
|
|
|
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1; |
|
|
|
|
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; |
|
|
|
|
// We need to work out the lines and columns the function declaration starts and ends
|
|
|
|
|
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1; |
|
|
|
|
const endlineDelta = contract.instrumented.slice(expression.start).indexOf('{'); |
|
|
|
|
const functionDefinition = contract.instrumented.slice(expression.start, expression.start + endlineDelta); |
|
|
|
|
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; |
|
|
|
|
const endlineDelta = contract.instrumented.slice(expression.range[0]).indexOf('{'); |
|
|
|
|
const functionDefinition = contract.instrumented.slice(expression.range[0], expression.range[0] + endlineDelta); |
|
|
|
|
const endline = startline + (functionDefinition.match(/\n/g) || []).length; |
|
|
|
|
const endcol = functionDefinition.length - functionDefinition.lastIndexOf('\n'); |
|
|
|
|
contract.fnMap[contract.fnId] = { |
|
|
|
@ -188,15 +188,15 @@ instrumenter.instrumentFunctionDeclaration = function instrumentFunctionDeclarat |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.start + endlineDelta + 1, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.range[0] + endlineDelta + 1, { |
|
|
|
|
type: 'callFunctionEvent', fnId: contract.fnId, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
instrumenter.addNewBranch = function addNewBranch(contract, expression) { |
|
|
|
|
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; |
|
|
|
|
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1; |
|
|
|
|
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1; |
|
|
|
|
// NB locations for if branches in istanbul are zero length and associated with the start of the if.
|
|
|
|
|
contract.branchMap[contract.branchId] = { |
|
|
|
|
line: startline, |
|
|
|
@ -221,31 +221,31 @@ instrumenter.addNewBranch = function addNewBranch(contract, expression) { |
|
|
|
|
|
|
|
|
|
instrumenter.instrumentAssertOrRequire = function instrumentAssertOrRequire(contract, expression) { |
|
|
|
|
instrumenter.addNewBranch(contract, expression); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.start, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.range[0], { |
|
|
|
|
type: 'callAssertPreEvent', branchId: contract.branchId, |
|
|
|
|
}); |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.end + 1, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.range[1] + 2, { |
|
|
|
|
type: 'callAssertPostEvent', branchId: contract.branchId, |
|
|
|
|
}); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
instrumenter.instrumentIfStatement = function instrumentIfStatement(contract, expression) { |
|
|
|
|
instrumenter.addNewBranch(contract, expression); |
|
|
|
|
if (expression.consequent.type === 'BlockStatement') { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.consequent.start + 1, { |
|
|
|
|
if (expression.trueBody.type === 'Block') { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.trueBody.range[0] + 1, { |
|
|
|
|
type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 0, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
if (expression.alternate && expression.alternate.type === 'IfStatement') { |
|
|
|
|
if (expression.falseBody && expression.falseBody.type === 'IfStatement') { |
|
|
|
|
// Do nothing - we must be pre-preprocessor, so don't bother instrumenting -
|
|
|
|
|
// when we're actually instrumenting, this will never happen (we've wrapped it in
|
|
|
|
|
// a block statement)
|
|
|
|
|
} else if (expression.alternate && expression.alternate.type === 'BlockStatement') { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.alternate.start + 1, { |
|
|
|
|
} else if (expression.falseBody && expression.falseBody.type === 'Block') { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.falseBody.range[0] + 1, { |
|
|
|
|
type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 1, |
|
|
|
|
}); |
|
|
|
|
} else { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.consequent.end, { |
|
|
|
|
createOrAppendInjectionPoint(contract, expression.trueBody.range[1] + 1, { |
|
|
|
|
type: 'callEmptyBranchEvent', branchId: contract.branchId, locationIdx: 1, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|