Skip to content

Commit 95b099a

Browse files
committed
Begin transition to solidity-parser-antlr
1 parent cf95ea1 commit 95b099a

File tree

8 files changed

+91
-89
lines changed

8 files changed

+91
-89
lines changed

lib/instrumentSolidity.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const SolidityParser = require('solidity-parser-sc');
2+
const SolidityParserAntlr = require('solidity-parser-antlr');
23
const preprocessor = require('./preprocessor');
34
const injector = require('./injector');
45
const parse = require('./parse');
@@ -20,7 +21,7 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
2021
contract.injectionPoints = {};
2122

2223
// First, we run over the original contract to get the source mapping.
23-
let ast = SolidityParser.parse(contract.source);
24+
let ast = SolidityParserAntlr.parse(contract.source, {range: true});
2425
parse[ast.type](contract, ast);
2526
const retValue = JSON.parse(JSON.stringify(contract));
2627

@@ -36,12 +37,10 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
3637

3738
contract.preprocessed = preprocessor.run(contract.source);
3839
contract.instrumented = contract.preprocessed;
39-
40-
ast = SolidityParser.parse(contract.preprocessed);
41-
42-
const contractStatement = ast.body.filter(node => (node.type === 'ContractStatement' ||
43-
node.type === 'LibraryStatement' ||
44-
node.type === 'InterfaceStatement'));
40+
ast = SolidityParserAntlr.parse(contract.preprocessed, {range: true});
41+
const contractStatement = ast.children.filter(node => (node.type === 'ContractDefinition' ||
42+
node.type === 'LibraryDefinition' ||
43+
node.type === 'InterfaceDefinition'));
4544
contract.contractName = contractStatement[0].name;
4645

4746
parse[ast.type](contract, ast);

lib/instrumenter.js

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function createOrAppendInjectionPoint(contract, key, value) {
1414
instrumenter.prePosition = function prePosition(expression) {
1515
if (expression.right.type === 'ConditionalExpression' &&
1616
expression.left.type === 'MemberExpression') {
17-
expression.start -= 2;
17+
expression.range[0] -= 2;
1818
}
1919
};
2020

@@ -31,15 +31,15 @@ instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpre
3131
if (expression.left.type === 'DeclarativeExpression' || expression.left.type === 'Identifier') {
3232
// Then we need to go from bytes32 varname = (conditional expression)
3333
// to bytes32 varname; (,varname) = (conditional expression)
34-
createOrAppendInjectionPoint(contract, expression.left.end, {
34+
createOrAppendInjectionPoint(contract, expression.left.range[1], {
3535
type: 'literal', string: '; (,' + expression.left.name + ')',
3636
});
3737
instrumenter.instrumentConditionalExpression(contract, expression.right);
3838
} else if (expression.left.type === 'MemberExpression') {
39-
createOrAppendInjectionPoint(contract, expression.left.start, {
39+
createOrAppendInjectionPoint(contract, expression.left.range[0], {
4040
type: 'literal', string: '(,',
4141
});
42-
createOrAppendInjectionPoint(contract, expression.left.end, {
42+
createOrAppendInjectionPoint(contract, expression.left.range[1], {
4343
type: 'literal', string: ')',
4444
});
4545
instrumenter.instrumentConditionalExpression(contract, expression.right);
@@ -61,12 +61,12 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp
6161

6262
/*contract.branchId += 1;
6363
64-
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1;
65-
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1;
66-
const consequentStartCol = startcol + (contract, expression.consequent.start - expression.start);
67-
const consequentEndCol = consequentStartCol + (contract, expression.consequent.end - expression.consequent.start);
68-
const alternateStartCol = startcol + (contract, expression.alternate.start - expression.start);
69-
const alternateEndCol = alternateStartCol + (contract, expression.alternate.end - expression.alternate.start);
64+
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1;
65+
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1;
66+
const consequentStartCol = startcol + (contract, expression.trueBody.range[0] - expression.range[0]);
67+
const consequentEndCol = consequentStartCol + (contract, expression.trueBody.range[1] - expression.trueBody.range[0]);
68+
const alternateStartCol = startcol + (contract, expression.falseBody.range[0] - expression.range[0]);
69+
const alternateEndCol = alternateStartCol + (contract, expression.falseBody.range[1] - expression.falseBody.range[0]);
7070
// NB locations for conditional branches in istanbul are length 1 and associated with the : and ?.
7171
contract.branchMap[contract.branchId] = {
7272
line: startline,
@@ -95,39 +95,39 @@ instrumenter.instrumentConditionalExpression = function instrumentConditionalExp
9595
9696
9797
// Wrap the consequent
98-
createOrAppendInjectionPoint(contract, expression.consequent.start, {
98+
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], {
9999
type: 'openParen',
100100
});
101-
createOrAppendInjectionPoint(contract, expression.consequent.start, {
101+
createOrAppendInjectionPoint(contract, expression.trueBody.range[0], {
102102
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 0,
103103
});
104-
createOrAppendInjectionPoint(contract, expression.consequent.end, {
104+
createOrAppendInjectionPoint(contract, expression.trueBody.range[1], {
105105
type: 'closeParen',
106106
});
107107
108108
// Wrap the alternate
109-
createOrAppendInjectionPoint(contract, expression.alternate.start, {
109+
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], {
110110
type: 'openParen',
111111
});
112-
createOrAppendInjectionPoint(contract, expression.alternate.start, {
112+
createOrAppendInjectionPoint(contract, expression.falseBody.range[0], {
113113
type: 'callBranchEvent', comma: true, branchId: contract.branchId, locationIdx: 1,
114114
});
115-
createOrAppendInjectionPoint(contract, expression.alternate.end, {
115+
createOrAppendInjectionPoint(contract, expression.falseBody.range[1], {
116116
type: 'closeParen',
117117
});*/
118118
};
119119

120120
instrumenter.instrumentStatement = function instrumentStatement(contract, expression) {
121121
contract.statementId += 1;
122122
// We need to work out the lines and columns the expression starts and ends
123-
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1;
124-
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1;
125-
const expressionContent = contract.instrumented.slice(expression.start, expression.end);
123+
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1;
124+
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1;
125+
const expressionContent = contract.instrumented.slice(expression.range[0], expression.range[1] + 1);
126126

127127
const endline = startline + (contract, expressionContent.match('/\n/g') || []).length;
128128
let endcol;
129129
if (expressionContent.lastIndexOf('\n') >= 0) {
130-
endcol = contract.instrumented.slice(expressionContent.lastIndexOf('\n'), expression.end).length - 1;
130+
endcol = contract.instrumented.slice(expressionContent.lastIndexOf('\n'), expression.range[1]).length;
131131
} else {
132132
endcol = startcol + (contract, expressionContent.length - 1);
133133
}
@@ -139,15 +139,15 @@ instrumenter.instrumentStatement = function instrumentStatement(contract, expres
139139
line: endline, column: endcol,
140140
},
141141
};
142-
createOrAppendInjectionPoint(contract, expression.start, {
142+
createOrAppendInjectionPoint(contract, expression.range[0], {
143143
type: 'statement', statementId: contract.statementId,
144144
});
145145
};
146146

147147
instrumenter.instrumentLine = function instrumentLine(contract, expression) {
148148
// what's the position of the most recent newline?
149-
const startchar = expression.start;
150-
const endchar = expression.end;
149+
const startchar = expression.range[0];
150+
const endchar = expression.range[1] + 1;
151151
const lastNewLine = contract.instrumented.slice(0, startchar).lastIndexOf('\n');
152152
const nextNewLine = startchar + contract.instrumented.slice(startchar).indexOf('\n');
153153
const contractSnipped = contract.instrumented.slice(lastNewLine, nextNewLine);
@@ -160,7 +160,7 @@ instrumenter.instrumentLine = function instrumentLine(contract, expression) {
160160
});
161161
} else if (contract.instrumented.slice(lastNewLine, startchar).replace('{', '').trim().length === 0 &&
162162
contract.instrumented.slice(endchar, nextNewLine).replace(/[;}]/g, '').trim().length === 0) {
163-
createOrAppendInjectionPoint(contract, expression.start, {
163+
createOrAppendInjectionPoint(contract, expression.range[0], {
164164
type: 'callEvent',
165165
});
166166
}
@@ -169,11 +169,11 @@ instrumenter.instrumentLine = function instrumentLine(contract, expression) {
169169

170170
instrumenter.instrumentFunctionDeclaration = function instrumentFunctionDeclaration(contract, expression) {
171171
contract.fnId += 1;
172-
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1;
172+
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1;
173173
// We need to work out the lines and columns the function declaration starts and ends
174-
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1;
175-
const endlineDelta = contract.instrumented.slice(expression.start).indexOf('{');
176-
const functionDefinition = contract.instrumented.slice(expression.start, expression.start + endlineDelta);
174+
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1;
175+
const endlineDelta = contract.instrumented.slice(expression.range[0]).indexOf('{');
176+
const functionDefinition = contract.instrumented.slice(expression.range[0], expression.range[0] + endlineDelta);
177177
const endline = startline + (functionDefinition.match(/\n/g) || []).length;
178178
const endcol = functionDefinition.length - functionDefinition.lastIndexOf('\n');
179179
contract.fnMap[contract.fnId] = {
@@ -188,15 +188,15 @@ instrumenter.instrumentFunctionDeclaration = function instrumentFunctionDeclarat
188188
},
189189
},
190190
};
191-
createOrAppendInjectionPoint(contract, expression.start + endlineDelta + 1, {
191+
createOrAppendInjectionPoint(contract, expression.range[0] + endlineDelta + 1, {
192192
type: 'callFunctionEvent', fnId: contract.fnId,
193193
});
194194
};
195195

196196
instrumenter.addNewBranch = function addNewBranch(contract, expression) {
197197
contract.branchId += 1;
198-
const startline = (contract.instrumented.slice(0, expression.start).match(/\n/g) || []).length + 1;
199-
const startcol = expression.start - contract.instrumented.slice(0, expression.start).lastIndexOf('\n') - 1;
198+
const startline = (contract.instrumented.slice(0, expression.range[0]).match(/\n/g) || []).length + 1;
199+
const startcol = expression.range[0] - contract.instrumented.slice(0, expression.range[0]).lastIndexOf('\n') - 1;
200200
// NB locations for if branches in istanbul are zero length and associated with the start of the if.
201201
contract.branchMap[contract.branchId] = {
202202
line: startline,
@@ -221,31 +221,31 @@ instrumenter.addNewBranch = function addNewBranch(contract, expression) {
221221

222222
instrumenter.instrumentAssertOrRequire = function instrumentAssertOrRequire(contract, expression) {
223223
instrumenter.addNewBranch(contract, expression);
224-
createOrAppendInjectionPoint(contract, expression.start, {
224+
createOrAppendInjectionPoint(contract, expression.range[0], {
225225
type: 'callAssertPreEvent', branchId: contract.branchId,
226226
});
227-
createOrAppendInjectionPoint(contract, expression.end + 1, {
227+
createOrAppendInjectionPoint(contract, expression.range[1] + 2, {
228228
type: 'callAssertPostEvent', branchId: contract.branchId,
229229
});
230230
};
231231

232232
instrumenter.instrumentIfStatement = function instrumentIfStatement(contract, expression) {
233233
instrumenter.addNewBranch(contract, expression);
234-
if (expression.consequent.type === 'BlockStatement') {
235-
createOrAppendInjectionPoint(contract, expression.consequent.start + 1, {
234+
if (expression.trueBody.type === 'Block') {
235+
createOrAppendInjectionPoint(contract, expression.trueBody.range[0] + 1, {
236236
type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 0,
237237
});
238238
}
239-
if (expression.alternate && expression.alternate.type === 'IfStatement') {
239+
if (expression.falseBody && expression.falseBody.type === 'IfStatement') {
240240
// Do nothing - we must be pre-preprocessor, so don't bother instrumenting -
241241
// when we're actually instrumenting, this will never happen (we've wrapped it in
242242
// a block statement)
243-
} else if (expression.alternate && expression.alternate.type === 'BlockStatement') {
244-
createOrAppendInjectionPoint(contract, expression.alternate.start + 1, {
243+
} else if (expression.falseBody && expression.falseBody.type === 'Block') {
244+
createOrAppendInjectionPoint(contract, expression.falseBody.range[0] + 1, {
245245
type: 'callBranchEvent', branchId: contract.branchId, locationIdx: 1,
246246
});
247247
} else {
248-
createOrAppendInjectionPoint(contract, expression.consequent.end, {
248+
createOrAppendInjectionPoint(contract, expression.trueBody.range[1] + 1, {
249249
type: 'callEmptyBranchEvent', branchId: contract.branchId, locationIdx: 1,
250250
});
251251
}

0 commit comments

Comments
 (0)