1- const sha1 = require ( "sha1" ) ;
21const web3Utils = require ( "web3-utils" ) ;
32
43class Injector {
54 constructor ( ) {
65 this . hashCounter = 0 ;
7- this . definitionCounter = 0 ;
86 }
97
10- /**
11- * Generates solidity statement to inject for line, stmt, branch, fn 'events'
12- * @param {String } memoryVariable
13- * @param {String } hash hash key to an instrumentationData entry (see _getHash)
14- * @param {String } type instrumentation type, e.g. line, statement
15- // @return {String } ex: _sc_82e0891[0] = bytes32(0xdc08...08ed1); /* function */
16- _getInjectable ( memoryVariable , hash , type ) {
17- return `${ memoryVariable } [0] = bytes32(${ hash } ); /* ${ type } */ \n` ;
8+ _split ( contract , injectionPoint ) {
9+ return {
10+ start : contract . instrumented . slice ( 0 , injectionPoint ) ,
11+ end : contract . instrumented . slice ( injectionPoint )
12+ }
13+ }
14+
15+ _getInjectable ( fileName , hash , type ) {
16+ return `${ this . _getMethodIdentifier ( fileName ) } (${ hash } ); /* ${ type } */ \n` ;
1817 }
1918
2019 _getHash ( fileName ) {
2120 this . hashCounter ++ ;
2221 return web3Utils . keccak256 ( `${ fileName } :${ this . hashCounter } ` ) ;
2322 }
2423
24+ _getMethodIdentifier ( fileName ) {
25+ return `coverage_${ web3Utils . keccak256 ( fileName ) . slice ( 0 , 10 ) } `
26+ }
27+
28+ _getInjectionComponents ( contract , injectionPoint , fileName , type ) {
29+ const { start, end } = this . _split ( contract , injectionPoint ) ;
30+ const hash = this . _getHash ( fileName )
31+ const injectable = this . _getInjectable ( fileName , hash , type ) ;
32+
33+ return {
34+ start : start ,
35+ end : end ,
36+ hash : hash ,
37+ injectable : injectable
38+ }
39+ }
40+
2541 /**
2642 * Generates a solidity statement injection. Declared once per fn.
2743 * Definition is the same for every fn in file.
2844 * @param {String } fileName
2945 * @return {String } ex: bytes32[1] memory _sc_82e0891
3046 */
31- _getMemoryVariableDefinition ( fileName ) {
32- this . definitionCounter ++ ;
33- return `\nbytes32[1] memory _sc_${ sha1 ( fileName ) . slice ( 0 , 7 ) } ;\n` ;
34- }
35-
36- _getMemoryVariableAssignment ( fileName ) {
37- return `\n_sc_${ sha1 ( fileName ) . slice ( 0 , 7 ) } ` ;
47+ _getHashMethodDefinition ( fileName ) {
48+ const hash = web3Utils . keccak256 ( fileName ) . slice ( 0 , 10 ) ;
49+ const method = this . _getMethodIdentifier ( fileName ) ;
50+ return `\nfunction ${ method } (bytes32 c__${ hash } ) public pure {}\n` ;
3851 }
3952
40-
4153 injectLine ( contract , fileName , injectionPoint , injection , instrumentation ) {
4254 const type = 'line' ;
43- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
44- const end = contract . instrumented . slice ( injectionPoint ) ;
55+ const { start, end } = this . _split ( contract , injectionPoint ) ;
4556
4657 const newLines = start . match ( / \n / g) ;
4758 const linecount = ( newLines || [ ] ) . length + 1 ;
4859 contract . runnableLines . push ( linecount ) ;
4960
50- const hash = this . _getHash ( fileName ) ;
51- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
52- const injectable = this . _getInjectable ( memoryVariable , hash , type )
61+ const hash = this . _getHash ( fileName )
62+ const injectable = this . _getInjectable ( fileName , hash , type ) ;
5363
5464 instrumentation [ hash ] = {
5565 id : linecount ,
@@ -63,12 +73,13 @@ class Injector {
6373
6474 injectStatement ( contract , fileName , injectionPoint , injection , instrumentation ) {
6575 const type = 'statement' ;
66- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
67- const end = contract . instrumented . slice ( injectionPoint ) ;
6876
69- const hash = this . _getHash ( fileName ) ;
70- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
71- const injectable = this . _getInjectable ( memoryVariable , hash , type )
77+ const {
78+ start,
79+ end,
80+ hash,
81+ injectable
82+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
7283
7384 instrumentation [ hash ] = {
7485 id : injection . statementId ,
@@ -82,13 +93,13 @@ class Injector {
8293
8394 injectFunction ( contract , fileName , injectionPoint , injection , instrumentation ) {
8495 const type = 'function' ;
85- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
86- const end = contract . instrumented . slice ( injectionPoint ) ;
8796
88- const hash = this . _getHash ( fileName ) ;
89- const memoryVariableDefinition = this . _getMemoryVariableDefinition ( fileName ) ;
90- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
91- const injectable = this . _getInjectable ( memoryVariable , hash , type ) ;
97+ const {
98+ start,
99+ end,
100+ hash,
101+ injectable
102+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
92103
93104 instrumentation [ hash ] = {
94105 id : injection . fnId ,
@@ -97,17 +108,18 @@ class Injector {
97108 hits : 0
98109 }
99110
100- contract . instrumented = `${ start } ${ memoryVariableDefinition } ${ injectable } ${ end } ` ;
111+ contract . instrumented = `${ start } ${ injectable } ${ end } ` ;
101112 }
102113
103114 injectBranch ( contract , fileName , injectionPoint , injection , instrumentation ) {
104115 const type = 'branch' ;
105- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
106- const end = contract . instrumented . slice ( injectionPoint ) ;
107116
108- const hash = this . _getHash ( fileName ) ;
109- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
110- const injectable = this . _getInjectable ( memoryVariable , hash , type ) ;
117+ const {
118+ start,
119+ end,
120+ hash,
121+ injectable
122+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
111123
112124 instrumentation [ hash ] = {
113125 id : injection . branchId ,
@@ -122,12 +134,13 @@ class Injector {
122134
123135 injectEmptyBranch ( contract , fileName , injectionPoint , injection , instrumentation ) {
124136 const type = 'branch' ;
125- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
126- const end = contract . instrumented . slice ( injectionPoint ) ;
127137
128- const hash = this . _getHash ( fileName ) ;
129- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
130- const injectable = this . _getInjectable ( memoryVariable , hash , type ) ;
138+ const {
139+ start,
140+ end,
141+ hash,
142+ injectable
143+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
131144
132145 instrumentation [ hash ] = {
133146 id : injection . branchId ,
@@ -142,12 +155,13 @@ class Injector {
142155
143156 injectAssertPre ( contract , fileName , injectionPoint , injection , instrumentation ) {
144157 const type = 'assertPre' ;
145- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
146- const end = contract . instrumented . slice ( injectionPoint ) ;
147158
148- const hash = this . _getHash ( fileName ) ;
149- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
150- const injectable = this . _getInjectable ( memoryVariable , hash , type ) ;
159+ const {
160+ start,
161+ end,
162+ hash,
163+ injectable
164+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
151165
152166 instrumentation [ hash ] = {
153167 id : injection . branchId ,
@@ -161,12 +175,13 @@ class Injector {
161175
162176 injectAssertPost ( contract , fileName , injectionPoint , injection , instrumentation ) {
163177 const type = 'assertPost' ;
164- const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
165- const end = contract . instrumented . slice ( injectionPoint ) ;
166178
167- const hash = this . _getHash ( fileName ) ;
168- const memoryVariable = this . _getMemoryVariableAssignment ( fileName ) ;
169- const injectable = this . _getInjectable ( memoryVariable , hash , type ) ;
179+ const {
180+ start,
181+ end,
182+ hash,
183+ injectable
184+ } = this . _getInjectionComponents ( contract , injectionPoint , fileName , type ) ;
170185
171186 instrumentation [ hash ] = {
172187 id : injection . branchId ,
@@ -177,6 +192,12 @@ class Injector {
177192
178193 contract . instrumented = `${ start } ${ injectable } ${ end } ` ;
179194 }
195+
196+ injectHashMethod ( contract , fileName , injectionPoint , injection , instrumentation ) {
197+ const start = contract . instrumented . slice ( 0 , injectionPoint ) ;
198+ const end = contract . instrumented . slice ( injectionPoint ) ;
199+ contract . instrumented = `${ start } ${ this . _getHashMethodDefinition ( fileName ) } ${ end } ` ;
200+ }
180201} ;
181202
182203module . exports = Injector ;
0 commit comments