as-test 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,625 +1,588 @@
1
1
  import { Transform } from "assemblyscript/dist/transform.js";
2
2
  import {
3
- Parser,
4
- Source,
5
- SourceKind,
6
- Statement,
7
- Token,
8
-
9
- BinaryExpression,
10
- CommaExpression,
11
- ParenthesizedExpression,
12
- ParameterNode,
13
- BlockStatement,
14
- ExpressionStatement,
15
- FunctionDeclaration,
16
- IfStatement,
17
- MethodDeclaration,
18
- ReturnStatement,
19
- SwitchCase,
20
- TernaryExpression,
21
- NodeKind,
22
- ArrowKind,
23
- Node,
24
- ObjectLiteralExpression,
25
- Tokenizer
3
+ Parser,
4
+ Source,
5
+ SourceKind,
6
+ Statement,
7
+ Token,
8
+ BinaryExpression,
9
+ CommaExpression,
10
+ ParenthesizedExpression,
11
+ ParameterNode,
12
+ BlockStatement,
13
+ ExpressionStatement,
14
+ FunctionDeclaration,
15
+ IfStatement,
16
+ MethodDeclaration,
17
+ ReturnStatement,
18
+ SwitchCase,
19
+ TernaryExpression,
20
+ NodeKind,
21
+ ArrowKind,
22
+ Node,
23
+ Tokenizer,
26
24
  } from "assemblyscript/dist/assemblyscript.js";
27
25
 
28
26
  import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
29
27
  import { isStdlib } from "visitor-as/dist/utils.js";
30
28
  import { RangeTransform } from "visitor-as/dist/transformRange.js";
31
29
 
32
- let ENABLED = false;
33
-
34
30
  enum CoverType {
35
- Function,
36
- Expression,
37
- Block
31
+ Function,
32
+ Expression,
33
+ Block,
38
34
  }
39
35
 
40
36
  class CoverPoint {
41
- public file: string = "";
42
- public hash: string = "";
43
- public line: number = 0;
44
- public column: number = 0;
45
- public type!: CoverType;
46
- public executed: boolean = false;
37
+ public file: string = "";
38
+ public hash: string = "";
39
+ public line: number = 0;
40
+ public column: number = 0;
41
+ public type!: CoverType;
42
+ public executed: boolean = false;
47
43
  }
48
44
 
49
45
  class CoverageTransform extends BaseVisitor {
50
- public mustImport: boolean = false;
51
- public points: Map<string, CoverPoint> = new Map<string, CoverPoint>();
52
- public globalStatements: Statement[] = [];
53
- visitBinaryExpression(node: BinaryExpression): void {
54
- super.visitBinaryExpression(node);
55
- // @ts-ignore
56
- if (node.visited) return;
57
- // @ts-ignore
58
- node.visited = true;
59
- const path = node.range.source.normalizedPath;
60
-
61
- switch (node.operator) {
62
- case Token.Bar_Bar:
63
- case Token.Ampersand_Ampersand: {
64
- const right = node.right;
65
- const rightLc = getLineCol(node);
46
+ public mustImport: boolean = false;
47
+ public points: Map<string, CoverPoint> = new Map<string, CoverPoint>();
48
+ public globalStatements: Statement[] = [];
49
+ visitBinaryExpression(node: BinaryExpression): void {
50
+ super.visitBinaryExpression(node);
51
+ // @ts-ignore
52
+ if (node.visited) return;
53
+ // @ts-ignore
54
+ node.visited = true;
55
+ const path = node.range.source.normalizedPath;
56
+
57
+ switch (node.operator) {
58
+ case Token.Bar_Bar:
59
+ case Token.Ampersand_Ampersand: {
60
+ const right = node.right;
61
+ const rightLc = getLineCol(node);
66
62
 
67
- const point = new CoverPoint();
68
- point.line = rightLc?.line!;
69
- point.column = rightLc?.column!;
70
- point.file = path;
71
- point.type = CoverType.Expression;
72
-
73
- point.hash = hash(point);
63
+ const point = new CoverPoint();
64
+ point.line = rightLc?.line!;
65
+ point.column = rightLc?.column!;
66
+ point.file = path;
67
+ point.type = CoverType.Expression;
74
68
 
69
+ point.hash = hash(point);
75
70
 
76
- const replacer = new RangeTransform(node);
77
- const registerStmt = SimpleParser.parseTopLevelStatement(
78
- `__REGISTER({
71
+ const replacer = new RangeTransform(node);
72
+ const registerStmt = SimpleParser.parseTopLevelStatement(
73
+ `__REGISTER({
79
74
  file: "${point.file}",
80
75
  hash: "${point.hash}",
81
76
  line: ${point.line},
82
77
  column: ${point.column},
83
78
  type: "Expression",
84
79
  executed: false
85
- });`
86
- );
87
- replacer.visit(registerStmt);
80
+ });`,
81
+ );
82
+ replacer.visit(registerStmt);
88
83
 
89
- let coverExpression = SimpleParser.parseExpression(
90
- `(__COVER("${point.hash}"), $$REPLACE_ME)`
91
- ) as ParenthesizedExpression;
92
- replacer.visit(coverExpression);
84
+ let coverExpression = SimpleParser.parseExpression(
85
+ `(__COVER("${point.hash}"), $$REPLACE_ME)`,
86
+ ) as ParenthesizedExpression;
87
+ replacer.visit(coverExpression);
93
88
 
94
- (coverExpression.expression as CommaExpression).expressions[1] = right;
89
+ (coverExpression.expression as CommaExpression).expressions[1] = right;
95
90
 
96
- node.right = coverExpression;
91
+ node.right = coverExpression;
97
92
 
98
- this.globalStatements.push(registerStmt);
93
+ this.globalStatements.push(registerStmt);
99
94
 
100
- break;
101
- }
102
- }
95
+ break;
96
+ }
103
97
  }
104
- visitMethodDeclaration(node: MethodDeclaration): void {
105
- super.visitMethodDeclaration(node);
106
- // @ts-ignore
107
- if (node.visited) return;
108
- // @ts-ignore
109
- node.visited = true;
110
- if (node.body) {
111
- // @ts-ignore
112
- if (node.body.visited) return;
113
- // @ts-ignore
114
- node.body.visited = true;
115
- const path = node.range.source.normalizedPath;
116
- const funcLc = getLineCol(node);
117
-
118
- const point = new CoverPoint();
119
- point.line = funcLc?.line!;
120
- point.column = funcLc?.column!;
121
- point.file = path;
122
- point.type = CoverType.Function;
123
-
124
- point.hash = hash(point);
125
-
126
-
127
- const replacer = new RangeTransform(node);
128
- const registerStmt = SimpleParser.parseTopLevelStatement(
129
- `__REGISTER({
98
+ }
99
+ visitMethodDeclaration(node: MethodDeclaration): void {
100
+ super.visitMethodDeclaration(node);
101
+ // @ts-ignore
102
+ if (node.visited) return;
103
+ // @ts-ignore
104
+ node.visited = true;
105
+ if (node.body) {
106
+ // @ts-ignore
107
+ if (node.body.visited) return;
108
+ // @ts-ignore
109
+ node.body.visited = true;
110
+ const path = node.range.source.normalizedPath;
111
+ const funcLc = getLineCol(node);
112
+
113
+ const point = new CoverPoint();
114
+ point.line = funcLc?.line!;
115
+ point.column = funcLc?.column!;
116
+ point.file = path;
117
+ point.type = CoverType.Function;
118
+
119
+ point.hash = hash(point);
120
+
121
+ const replacer = new RangeTransform(node);
122
+ const registerStmt = SimpleParser.parseTopLevelStatement(
123
+ `__REGISTER({
130
124
  file: "${point.file}",
131
125
  hash: "${point.hash}",
132
126
  line: ${point.line},
133
127
  column: ${point.column},
134
128
  type: "Function",
135
129
  executed: false
136
- })`
137
- );
138
- replacer.visit(registerStmt);
130
+ })`,
131
+ );
132
+ replacer.visit(registerStmt);
139
133
 
140
- const coverStmt = SimpleParser.parseStatement(
141
- `__COVER("${point.hash}")`,
142
- true
143
- );
144
- replacer.visit(coverStmt);
134
+ const coverStmt = SimpleParser.parseStatement(
135
+ `__COVER("${point.hash}")`,
136
+ true,
137
+ );
138
+ replacer.visit(coverStmt);
145
139
 
146
- const bodyBlock = node.body as BlockStatement;
147
- bodyBlock.statements.unshift(coverStmt);
140
+ const bodyBlock = node.body as BlockStatement;
141
+ bodyBlock.statements.unshift(coverStmt);
148
142
 
149
- this.globalStatements.push(registerStmt);
150
- }
143
+ this.globalStatements.push(registerStmt);
151
144
  }
152
- visitParameter(node: ParameterNode): void {
153
- // @ts-ignore
154
- if (node.visited) return;
155
- // @ts-ignore
156
- node.visited = true;
157
- const path = node.range.source.normalizedPath;
158
- if (node.initializer) {
159
- // @ts-ignore
160
- if (node.initializer.visited) return;
161
- // @ts-ignore
162
- node.initializer.visited = true;
163
- super.visitParameter(node);
164
- const paramLc = getLineCol(node.initializer);
165
-
166
- const point = new CoverPoint();
167
- point.line = paramLc?.line!;
168
- point.column = paramLc?.column!;
169
- point.file = path;
170
- point.type = CoverType.Expression;
171
-
172
- point.hash = hash(point);
173
-
174
-
175
- const replacer = new RangeTransform(node);
176
- const registerStmt = SimpleParser.parseTopLevelStatement(
177
- `__REGISTER({
145
+ }
146
+ visitParameter(node: ParameterNode): void {
147
+ // @ts-ignore
148
+ if (node.visited) return;
149
+ // @ts-ignore
150
+ node.visited = true;
151
+ const path = node.range.source.normalizedPath;
152
+ if (node.initializer) {
153
+ // @ts-ignore
154
+ if (node.initializer.visited) return;
155
+ // @ts-ignore
156
+ node.initializer.visited = true;
157
+ super.visitParameter(node);
158
+ const paramLc = getLineCol(node.initializer);
159
+
160
+ const point = new CoverPoint();
161
+ point.line = paramLc?.line!;
162
+ point.column = paramLc?.column!;
163
+ point.file = path;
164
+ point.type = CoverType.Expression;
165
+
166
+ point.hash = hash(point);
167
+
168
+ const replacer = new RangeTransform(node);
169
+ const registerStmt = SimpleParser.parseTopLevelStatement(
170
+ `__REGISTER({
178
171
  file: "${point.file}",
179
172
  hash: "${point.hash}",
180
173
  line: ${point.line},
181
174
  column: ${point.column},
182
175
  type: "Expression",
183
176
  executed: false
184
- })`
185
- );
186
- replacer.visit(registerStmt);
177
+ })`,
178
+ );
179
+ replacer.visit(registerStmt);
187
180
 
188
- const coverExpression = SimpleParser.parseExpression(
189
- `(__COVER("${point.hash}"), $$REPLACE_ME)`
190
- ) as ParenthesizedExpression;
191
- replacer.visit(coverExpression);
181
+ const coverExpression = SimpleParser.parseExpression(
182
+ `(__COVER("${point.hash}"), $$REPLACE_ME)`,
183
+ ) as ParenthesizedExpression;
184
+ replacer.visit(coverExpression);
192
185
 
193
- (coverExpression.expression as CommaExpression).expressions[1] = node.initializer;
186
+ (coverExpression.expression as CommaExpression).expressions[1] =
187
+ node.initializer;
194
188
 
195
- node.initializer = coverExpression;
189
+ node.initializer = coverExpression;
196
190
 
197
- this.globalStatements.push(registerStmt);
198
- }
191
+ this.globalStatements.push(registerStmt);
199
192
  }
200
- visitFunctionDeclaration(node: FunctionDeclaration, isDefault?: boolean | undefined): void {
201
- super.visitFunctionDeclaration(node, isDefault);
202
- // @ts-ignore
203
- if (node.visited) return;
204
- // @ts-ignore
205
- node.visited = true;
206
- if (node.body) {
207
- // @ts-ignore
208
- if (node.body.visited) return;
209
- // @ts-ignore
210
- node.body.visited = true;
211
-
212
- const path = node.range.source.normalizedPath;
213
- const funcLc = getLineCol(node);
214
- const point = new CoverPoint();
215
- point.line = funcLc?.line!;
216
- point.column = funcLc?.column!;
217
- point.file = path;
218
- point.type = CoverType.Function;
219
-
220
- point.hash = hash(point);
221
-
222
-
223
- const replacer = new RangeTransform(node);
224
- const registerStmt = SimpleParser.parseTopLevelStatement(
225
- `__REGISTER({
193
+ }
194
+ visitFunctionDeclaration(
195
+ node: FunctionDeclaration,
196
+ isDefault?: boolean | undefined,
197
+ ): void {
198
+ super.visitFunctionDeclaration(node, isDefault);
199
+ // @ts-ignore
200
+ if (node.visited) return;
201
+ // @ts-ignore
202
+ node.visited = true;
203
+ if (node.body) {
204
+ // @ts-ignore
205
+ if (node.body.visited) return;
206
+ // @ts-ignore
207
+ node.body.visited = true;
208
+
209
+ const path = node.range.source.normalizedPath;
210
+ const funcLc = getLineCol(node);
211
+ const point = new CoverPoint();
212
+ point.line = funcLc?.line!;
213
+ point.column = funcLc?.column!;
214
+ point.file = path;
215
+ point.type = CoverType.Function;
216
+
217
+ point.hash = hash(point);
218
+
219
+ const replacer = new RangeTransform(node);
220
+ const registerStmt = SimpleParser.parseTopLevelStatement(
221
+ `__REGISTER({
226
222
  file: "${point.file}",
227
223
  hash: "${point.hash}",
228
224
  line: ${point.line},
229
225
  column: ${point.column},
230
226
  type: "Function",
231
227
  executed: false
232
- })`
233
- );
234
- replacer.visit(registerStmt);
228
+ })`,
229
+ );
230
+ replacer.visit(registerStmt);
235
231
 
236
- this.globalStatements.push(registerStmt);
232
+ this.globalStatements.push(registerStmt);
237
233
 
238
- if (node.body.kind === NodeKind.Export) {
239
- const coverStmt = SimpleParser.parseStatement(`{
234
+ if (node.body.kind === NodeKind.Export) {
235
+ const coverStmt = SimpleParser.parseStatement(`{
240
236
  __COVER("${point.hash}")
241
237
  return $$REPLACE_ME
242
238
  }`) as BlockStatement;
243
- replacer.visit(coverStmt);
244
-
245
- const bodyReturn = coverStmt.statements[1] as ReturnStatement;
246
- const body = node.body as ExpressionStatement;
247
- node.arrowKind = ArrowKind.Single;
248
- bodyReturn.value = body.expression;
249
- node.body = body;
250
- } else {
251
- const coverStmt = SimpleParser.parseStatement(
252
- `__COVER("${point.hash}")`,
253
- true
254
- );
255
- replacer.visit(coverStmt);
256
-
257
- if (node.body instanceof BlockStatement) {
258
- node.body.statements.unshift(coverStmt);
259
- console.log(node)
260
- } else if (node.body instanceof ExpressionStatement) {
261
- const expression = (node.body as ExpressionStatement).expression;
262
- node.body = Node.createBlockStatement([
263
- Node.createReturnStatement(
264
- expression,
265
- expression.range
266
- )],
267
- expression.range
268
- );
269
-
270
- const bodyBlock = node.body as BlockStatement;
271
- bodyBlock.statements.unshift(coverStmt);
272
- }
273
- }
239
+ replacer.visit(coverStmt);
240
+
241
+ const bodyReturn = coverStmt.statements[1] as ReturnStatement;
242
+ const body = node.body as ExpressionStatement;
243
+ node.arrowKind = ArrowKind.Single;
244
+ bodyReturn.value = body.expression;
245
+ node.body = body;
246
+ } else {
247
+ const coverStmt = SimpleParser.parseStatement(
248
+ `__COVER("${point.hash}")`,
249
+ true,
250
+ );
251
+ replacer.visit(coverStmt);
252
+
253
+ if (node.body instanceof BlockStatement) {
254
+ node.body.statements.unshift(coverStmt);
255
+ console.log(node);
256
+ } else if (node.body instanceof ExpressionStatement) {
257
+ const expression = (node.body as ExpressionStatement).expression;
258
+ node.body = Node.createBlockStatement(
259
+ [Node.createReturnStatement(expression, expression.range)],
260
+ expression.range,
261
+ );
262
+
263
+ const bodyBlock = node.body as BlockStatement;
264
+ bodyBlock.statements.unshift(coverStmt);
274
265
  }
266
+ }
275
267
  }
276
- visitIfStatement(node: IfStatement): void {
277
- // @ts-ignore
278
- if (node.visited) return;
279
- // @ts-ignore
280
- node.visited = true;
281
- let visitIfTrue = false;
282
- let visitIfFalse = false;
268
+ }
269
+ visitIfStatement(node: IfStatement): void {
270
+ // @ts-ignore
271
+ if (node.visited) return;
272
+ // @ts-ignore
273
+ node.visited = true;
274
+ let visitIfTrue = false;
275
+ let visitIfFalse = false;
283
276
 
284
- const ifTrue = node.ifTrue;
285
- const ifFalse = node.ifFalse;
277
+ const ifTrue = node.ifTrue;
278
+ const ifFalse = node.ifFalse;
286
279
 
287
- const path = node.range.source.normalizedPath;
280
+ const path = node.range.source.normalizedPath;
288
281
 
289
- if (ifTrue.kind !== NodeKind.Block) {
290
- const trueLc = getLineCol(ifTrue);
291
- const point = new CoverPoint();
282
+ if (ifTrue.kind !== NodeKind.Block) {
283
+ const trueLc = getLineCol(ifTrue);
284
+ const point = new CoverPoint();
292
285
 
293
- point.line = trueLc?.line!;
294
- point.column = trueLc?.column!;
295
- point.file = path;
296
- point.type = CoverType.Expression;
286
+ point.line = trueLc?.line!;
287
+ point.column = trueLc?.column!;
288
+ point.file = path;
289
+ point.type = CoverType.Expression;
297
290
 
298
- point.hash = hash(point);
291
+ point.hash = hash(point);
299
292
 
293
+ const replacer = new RangeTransform(ifTrue);
300
294
 
301
- const replacer = new RangeTransform(ifTrue);
302
-
303
- const registerStmt = SimpleParser.parseTopLevelStatement(
304
- `__REGISTER({
295
+ const registerStmt = SimpleParser.parseTopLevelStatement(
296
+ `__REGISTER({
305
297
  file: "${point.file}",
306
298
  hash: "${point.hash}",
307
299
  line: ${point.line},
308
300
  column: ${point.column},
309
301
  type: "Expression",
310
302
  executed: false
311
- })`
312
- );
313
- replacer.visit(registerStmt);
314
-
315
- const coverStmt = SimpleParser.parseStatement(
316
- `{__COVER("${point.hash}")};`,
317
- true
318
- ) as BlockStatement;
319
- replacer.visit(coverStmt);
303
+ })`,
304
+ );
305
+ replacer.visit(registerStmt);
320
306
 
321
- coverStmt.statements.push(ifTrue);
322
- node.ifTrue = coverStmt;
307
+ const coverStmt = SimpleParser.parseStatement(
308
+ `{__COVER("${point.hash}")};`,
309
+ true,
310
+ ) as BlockStatement;
311
+ replacer.visit(coverStmt);
323
312
 
324
- this.globalStatements.push(registerStmt);
313
+ coverStmt.statements.push(ifTrue);
314
+ node.ifTrue = coverStmt;
325
315
 
326
- visitIfTrue = true;
327
- visitIfFalse = !!ifFalse;
328
- }
316
+ this.globalStatements.push(registerStmt);
329
317
 
330
- if (ifFalse && ifFalse.kind !== NodeKind.Block) {
331
- const falseLc = getLineCol(ifFalse);
332
- const point = new CoverPoint();
318
+ visitIfTrue = true;
319
+ visitIfFalse = !!ifFalse;
320
+ }
333
321
 
334
- point.line = falseLc?.line!;
335
- point.column = falseLc?.column!;
336
- point.file = path;
337
- point.type = CoverType.Expression;
322
+ if (ifFalse && ifFalse.kind !== NodeKind.Block) {
323
+ const falseLc = getLineCol(ifFalse);
324
+ const point = new CoverPoint();
338
325
 
339
- point.hash = hash(point);
326
+ point.line = falseLc?.line!;
327
+ point.column = falseLc?.column!;
328
+ point.file = path;
329
+ point.type = CoverType.Expression;
340
330
 
331
+ point.hash = hash(point);
341
332
 
342
- const replacer = new RangeTransform(ifTrue);
333
+ const replacer = new RangeTransform(ifTrue);
343
334
 
344
- const registerStmt = SimpleParser.parseTopLevelStatement(
345
- `__REGISTER({
335
+ const registerStmt = SimpleParser.parseTopLevelStatement(
336
+ `__REGISTER({
346
337
  file: "${point.file}",
347
338
  hash: "${point.hash}",
348
339
  line: ${point.line},
349
340
  column: ${point.column},
350
341
  type: "Expression",
351
342
  executed: false
352
- })`
353
- );
354
- replacer.visit(registerStmt);
343
+ })`,
344
+ );
345
+ replacer.visit(registerStmt);
355
346
 
356
- const coverStmt = SimpleParser.parseStatement(
357
- `{__COVER("${point.hash}")};`,
358
- true
359
- ) as BlockStatement;
360
- replacer.visit(coverStmt);
347
+ const coverStmt = SimpleParser.parseStatement(
348
+ `{__COVER("${point.hash}")};`,
349
+ true,
350
+ ) as BlockStatement;
351
+ replacer.visit(coverStmt);
361
352
 
362
- coverStmt.statements.push(ifFalse);
363
- node.ifFalse = coverStmt;
353
+ coverStmt.statements.push(ifFalse);
354
+ node.ifFalse = coverStmt;
364
355
 
365
- this.globalStatements.push(registerStmt);
356
+ this.globalStatements.push(registerStmt);
366
357
 
367
- visitIfTrue = true;
368
- visitIfFalse = true;
369
- }
370
- if (visitIfTrue || visitIfFalse) {
371
- if (visitIfTrue) {
372
- // @ts-ignore
373
- if (ifTrue.visited) return;
374
- // @ts-ignore
375
- ifTrue.visited = true;
376
- this._visit(ifTrue);
377
- }
378
- if (visitIfFalse) {
379
- // @ts-ignore
380
- if (ifFalse.visited) return;
381
- // @ts-ignore
382
- ifFalse.visited = true;
383
- this._visit(ifFalse!);
384
- }
385
- } else {
386
- super.visitIfStatement(node);
387
- }
358
+ visitIfTrue = true;
359
+ visitIfFalse = true;
388
360
  }
389
- visitTernaryExpression(node: TernaryExpression): void {
361
+ if (visitIfTrue || visitIfFalse) {
362
+ if (visitIfTrue) {
390
363
  // @ts-ignore
391
- if (node.visited) return;
364
+ if (ifTrue.visited) return;
392
365
  // @ts-ignore
393
- node.visited = true;
394
- super.visitTernaryExpression(node);
395
-
396
- const trueExpression = node.ifThen;
397
- const falseExpression = node.ifElse;
398
-
399
- const path = node.range.source.normalizedPath;
400
- {
401
- const trueLc = getLineCol(trueExpression);
402
- const point = new CoverPoint();
403
- point.line = trueLc?.line!;
404
- point.column = trueLc?.column!;
405
- point.file = path;
406
- point.type = CoverType.Expression;
407
-
408
- point.hash = hash(point);
409
-
410
-
411
- const replacer = new RangeTransform(trueExpression);
412
-
413
- const registerStmt = SimpleParser.parseTopLevelStatement(
414
- `__REGISTER({
366
+ ifTrue.visited = true;
367
+ this._visit(ifTrue);
368
+ }
369
+ if (visitIfFalse) {
370
+ // @ts-ignore
371
+ if (ifFalse.visited) return;
372
+ // @ts-ignore
373
+ ifFalse.visited = true;
374
+ this._visit(ifFalse!);
375
+ }
376
+ } else {
377
+ super.visitIfStatement(node);
378
+ }
379
+ }
380
+ visitTernaryExpression(node: TernaryExpression): void {
381
+ // @ts-ignore
382
+ if (node.visited) return;
383
+ // @ts-ignore
384
+ node.visited = true;
385
+ super.visitTernaryExpression(node);
386
+
387
+ const trueExpression = node.ifThen;
388
+ const falseExpression = node.ifElse;
389
+
390
+ const path = node.range.source.normalizedPath;
391
+ {
392
+ const trueLc = getLineCol(trueExpression);
393
+ const point = new CoverPoint();
394
+ point.line = trueLc?.line!;
395
+ point.column = trueLc?.column!;
396
+ point.file = path;
397
+ point.type = CoverType.Expression;
398
+
399
+ point.hash = hash(point);
400
+
401
+ const replacer = new RangeTransform(trueExpression);
402
+
403
+ const registerStmt = SimpleParser.parseTopLevelStatement(
404
+ `__REGISTER({
415
405
  file: "${point.file}",
416
406
  hash: "${point.hash}",
417
407
  line: ${point.line},
418
408
  column: ${point.column},
419
409
  type: "Expression",
420
410
  executed: false
421
- })`
422
- );
423
- replacer.visit(registerStmt);
424
-
425
- const coverExpression = SimpleParser.parseExpression(
426
- `(__COVER("${point.hash}"), $$REPLACE_ME)`
427
- ) as ParenthesizedExpression;
428
- replacer.visit(coverExpression);
411
+ })`,
412
+ );
413
+ replacer.visit(registerStmt);
429
414
 
430
- (coverExpression.expression as CommaExpression).expressions[1] = trueExpression;
431
- node.ifThen = coverExpression;
415
+ const coverExpression = SimpleParser.parseExpression(
416
+ `(__COVER("${point.hash}"), $$REPLACE_ME)`,
417
+ ) as ParenthesizedExpression;
418
+ replacer.visit(coverExpression);
432
419
 
433
- this.globalStatements.push(registerStmt);
434
- }
435
- {
436
- const falseLc = getLineCol(falseExpression);
437
- const point = new CoverPoint();
438
- point.line = falseLc?.line!;
439
- point.column = falseLc?.column!;
440
- point.file = path;
441
- point.type = CoverType.Expression;
420
+ (coverExpression.expression as CommaExpression).expressions[1] =
421
+ trueExpression;
422
+ node.ifThen = coverExpression;
442
423
 
443
- point.hash = hash(point);
424
+ this.globalStatements.push(registerStmt);
425
+ }
426
+ {
427
+ const falseLc = getLineCol(falseExpression);
428
+ const point = new CoverPoint();
429
+ point.line = falseLc?.line!;
430
+ point.column = falseLc?.column!;
431
+ point.file = path;
432
+ point.type = CoverType.Expression;
444
433
 
434
+ point.hash = hash(point);
445
435
 
446
- const replacer = new RangeTransform(falseExpression);
436
+ const replacer = new RangeTransform(falseExpression);
447
437
 
448
- const registerStmt = SimpleParser.parseTopLevelStatement(
449
- `__REGISTER({
438
+ const registerStmt = SimpleParser.parseTopLevelStatement(
439
+ `__REGISTER({
450
440
  file: "${point.file}",
451
441
  hash: "${point.hash}",
452
442
  line: ${point.line},
453
443
  column: ${point.column},
454
444
  type: "Expression",
455
445
  executed: false
456
- })`
457
- );
458
- replacer.visit(registerStmt);
459
-
460
- const coverExpression = SimpleParser.parseExpression(
461
- `(__COVER("${point.hash}"), $$REPLACE_ME)`
462
- ) as ParenthesizedExpression;
463
- replacer.visit(coverExpression);
464
-
465
- (coverExpression.expression as CommaExpression).expressions[1] = falseExpression;
466
- node.ifElse = coverExpression;
467
- this.globalStatements.push(registerStmt);
468
- }
446
+ })`,
447
+ );
448
+ replacer.visit(registerStmt);
449
+
450
+ const coverExpression = SimpleParser.parseExpression(
451
+ `(__COVER("${point.hash}"), $$REPLACE_ME)`,
452
+ ) as ParenthesizedExpression;
453
+ replacer.visit(coverExpression);
454
+
455
+ (coverExpression.expression as CommaExpression).expressions[1] =
456
+ falseExpression;
457
+ node.ifElse = coverExpression;
458
+ this.globalStatements.push(registerStmt);
469
459
  }
470
- visitSwitchCase(node: SwitchCase): void {
471
- // @ts-ignore
472
- if (node.visited) return;
473
- // @ts-ignore
474
- node.visited = true;
475
- const path = node.range.source.normalizedPath;
476
- const caseLc = getLineCol(node);
477
-
478
- const point = new CoverPoint();
479
- point.line = caseLc?.line!;
480
- point.column = caseLc?.column!;
481
- point.file = path;
482
- point.type = CoverType.Block;
483
-
484
- point.hash = hash(point);
485
-
486
-
487
- const replacer = new RangeTransform(node);
488
-
489
- const registerStmt = SimpleParser.parseTopLevelStatement(
490
- `__REGISTER({
460
+ }
461
+ visitSwitchCase(node: SwitchCase): void {
462
+ // @ts-ignore
463
+ if (node.visited) return;
464
+ // @ts-ignore
465
+ node.visited = true;
466
+ const path = node.range.source.normalizedPath;
467
+ const caseLc = getLineCol(node);
468
+
469
+ const point = new CoverPoint();
470
+ point.line = caseLc?.line!;
471
+ point.column = caseLc?.column!;
472
+ point.file = path;
473
+ point.type = CoverType.Block;
474
+
475
+ point.hash = hash(point);
476
+
477
+ const replacer = new RangeTransform(node);
478
+
479
+ const registerStmt = SimpleParser.parseTopLevelStatement(
480
+ `__REGISTER({
491
481
  file: "${point.file}",
492
482
  hash: "${point.hash}",
493
483
  line: ${point.line},
494
484
  column: ${point.column},
495
485
  type: "Block",
496
486
  executed: false
497
- })`
498
- );
499
- replacer.visit(registerStmt);
500
-
501
- const coverStmt = SimpleParser.parseStatement(
502
- `__COVER("${point.hash}")`
503
- );
504
- replacer.visit(coverStmt);
505
-
506
- this.globalStatements.push(registerStmt);
507
- super.visitSwitchCase(node);
508
- node.statements.unshift(coverStmt);
509
- }
510
- visitBlockStatement(node: BlockStatement): void {
511
- // @ts-ignore
512
- if (node.visited) return;
513
- // @ts-ignore
514
- node.visited = true;
515
- const path = node.range.source.normalizedPath;
516
-
517
- const blockLc = getLineCol(node);
518
-
519
- const point = new CoverPoint();
520
- point.line = blockLc?.line!;
521
- point.column = blockLc?.column!;
522
- point.file = path;
523
- point.type = CoverType.Block;
524
-
525
- point.hash = hash(point);
526
-
527
-
528
- const replacer = new RangeTransform(node);
529
-
530
- const registerStmt = SimpleParser.parseTopLevelStatement(
531
- `__REGISTER({
487
+ })`,
488
+ );
489
+ replacer.visit(registerStmt);
490
+
491
+ const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`);
492
+ replacer.visit(coverStmt);
493
+
494
+ this.globalStatements.push(registerStmt);
495
+ super.visitSwitchCase(node);
496
+ node.statements.unshift(coverStmt);
497
+ }
498
+ visitBlockStatement(node: BlockStatement): void {
499
+ // @ts-ignore
500
+ if (node.visited) return;
501
+ // @ts-ignore
502
+ node.visited = true;
503
+ const path = node.range.source.normalizedPath;
504
+
505
+ const blockLc = getLineCol(node);
506
+
507
+ const point = new CoverPoint();
508
+ point.line = blockLc?.line!;
509
+ point.column = blockLc?.column!;
510
+ point.file = path;
511
+ point.type = CoverType.Block;
512
+
513
+ point.hash = hash(point);
514
+
515
+ const replacer = new RangeTransform(node);
516
+
517
+ const registerStmt = SimpleParser.parseTopLevelStatement(
518
+ `__REGISTER({
532
519
  file: "${point.file}",
533
520
  hash: "${point.hash}",
534
521
  line: ${point.line},
535
522
  column: ${point.column},
536
523
  type: "Block",
537
524
  executed: false
538
- })`
539
- );
540
- replacer.visit(registerStmt);
541
-
542
- const coverStmt = SimpleParser.parseStatement(
543
- `__COVER("${point.hash}")`
544
- );
545
- replacer.visit(coverStmt);
546
-
547
- this.globalStatements.push(registerStmt);
548
- super.visitBlockStatement(node);
549
- node.statements.unshift(coverStmt);
550
- }
551
- visitSource(node: Source): void {
552
- super.visitSource(node);
553
- }
554
- }
555
-
556
- class CoverageFinder extends BaseVisitor {
557
- visitObjectLiteralExpression(node: ObjectLiteralExpression): void {
558
- for (let i = 0; i < node.names.length; i++) {
559
- const name = node.names[i]!;
560
- if (name.text === "coverage") {
561
- const v = node.values[i]!;
562
- if (v.kind === NodeKind.True) {
563
- ENABLED = true;
564
- }
565
- }
566
- }
567
- }
525
+ })`,
526
+ );
527
+ replacer.visit(registerStmt);
528
+
529
+ const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`);
530
+ replacer.visit(coverStmt);
531
+
532
+ this.globalStatements.push(registerStmt);
533
+ super.visitBlockStatement(node);
534
+ node.statements.unshift(coverStmt);
535
+ }
536
+ visitSource(node: Source): void {
537
+ super.visitSource(node);
538
+ }
568
539
  }
569
540
 
570
541
  export default class Transformer extends Transform {
571
- // Trigger the transform after parse.
572
- afterParse(parser: Parser): void {
573
- for (const source of parser.sources) {
574
- if (source.sourceKind === SourceKind.UserEntry) {
575
- const transform = new CoverageFinder();
576
- transform.visit(source);
577
- }
542
+ // Trigger the transform after parse.
543
+ afterParse(parser: Parser): void {
544
+ // Create new transform
545
+ const transformer = new CoverageTransform();
546
+
547
+ // Sort the sources so that user scripts are visited last
548
+ const sources = parser.sources
549
+ .filter((source) => !isStdlib(source))
550
+ .sort((_a, _b) => {
551
+ const a = _a.internalPath;
552
+ const b = _b.internalPath;
553
+ if (a[0] === "~" && b[0] !== "~") {
554
+ return -1;
555
+ } else if (a[0] !== "~" && b[0] === "~") {
556
+ return 1;
557
+ } else {
558
+ return 0;
578
559
  }
579
- if (!ENABLED) return;
580
-
581
- // Create new transform
582
- const transformer = new CoverageTransform();
583
-
584
- // Sort the sources so that user scripts are visited last
585
- const sources = parser.sources
586
- .filter((source) => !isStdlib(source))
587
- .sort((_a, _b) => {
588
- const a = _a.internalPath;
589
- const b = _b.internalPath;
590
- if (a[0] === "~" && b[0] !== "~") {
591
- return -1;
592
- } else if (a[0] !== "~" && b[0] === "~") {
593
- return 1;
594
- } else {
595
- return 0;
596
- }
597
- });
598
-
599
- // Loop over every source
600
- for (const source of sources) {
601
- if (source.isLibrary) continue;
602
- if (source.simplePath === "coverage") continue;
603
- // Ignore all lib and std. Visit everything else.
604
- if (!isStdlib(source)) {
605
- transformer.visit(source);
606
- if (transformer.globalStatements.length) {
607
- source.statements.unshift(...transformer.globalStatements);
608
- const tokenizer = new Tokenizer(
609
- new Source(
610
- SourceKind.User,
611
- source.normalizedPath,
612
- "import { __REGISTER, __COVER } from \"as-test/assembly/coverage\";"
613
- )
614
- );
615
- parser.currentSource = tokenizer.source;
616
- source.statements.unshift(parser.parseTopLevelStatement(tokenizer)!);
617
- parser.currentSource = source;
618
- }
619
- }
620
- transformer.globalStatements = [];
560
+ });
561
+
562
+ // Loop over every source
563
+ for (const source of sources) {
564
+ if (source.isLibrary) continue;
565
+ if (source.simplePath === "coverage") continue;
566
+ // Ignore all lib and std. Visit everything else.
567
+ if (!isStdlib(source)) {
568
+ transformer.visit(source);
569
+ if (transformer.globalStatements.length) {
570
+ source.statements.unshift(...transformer.globalStatements);
571
+ const tokenizer = new Tokenizer(
572
+ new Source(
573
+ SourceKind.User,
574
+ source.normalizedPath,
575
+ 'import { __REGISTER, __COVER } from "as-test/assembly/coverage";',
576
+ ),
577
+ );
578
+ parser.currentSource = tokenizer.source;
579
+ source.statements.unshift(parser.parseTopLevelStatement(tokenizer)!);
580
+ parser.currentSource = source;
621
581
  }
582
+ }
583
+ transformer.globalStatements = [];
622
584
  }
585
+ }
623
586
  }
624
587
 
625
588
  /**
@@ -630,32 +593,37 @@ export default class Transformer extends Transform {
630
593
  * @returns {number} The hash of the string
631
594
  */
632
595
  function djb2Hash(str: string): number {
633
- const points = Array.from(str);
634
- let h = 5381;
635
- for (let p = 0; p < points.length; p++)
636
- // h = (h * 31 + c) | 0;
637
- h = ((h << 5) - h + points[p]!.codePointAt(0)!) | 0;
638
- return h;
596
+ const points = Array.from(str);
597
+ let h = 5381;
598
+ for (let p = 0; p < points.length; p++)
599
+ // h = (h * 31 + c) | 0;
600
+ h = ((h << 5) - h + points[p]!.codePointAt(0)!) | 0;
601
+ return h;
639
602
  }
640
603
 
641
604
  function hash(point: CoverPoint): string {
642
- const hsh = djb2Hash(point.file + point.line.toString() + point.column.toString() + point.type.toString());
643
- if (hsh < 0) {
644
- const out = hsh.toString(16);
645
- return "3" + out.slice(1);
646
- } else {
647
- return hsh.toString(16);
648
- }
605
+ const hsh = djb2Hash(
606
+ point.file +
607
+ point.line.toString() +
608
+ point.column.toString() +
609
+ point.type.toString(),
610
+ );
611
+ if (hsh < 0) {
612
+ const out = hsh.toString(16);
613
+ return "3" + out.slice(1);
614
+ } else {
615
+ return hsh.toString(16);
616
+ }
649
617
  }
650
618
 
651
619
  class LineColumn {
652
- public line!: number;
653
- public column!: number;
620
+ public line!: number;
621
+ public column!: number;
654
622
  }
655
623
 
656
624
  function getLineCol(node: Node): LineColumn {
657
- return {
658
- line: node.range.source.lineAt(node.range.start),
659
- column: node.range.source.columnAt()
660
- }
661
- }
625
+ return {
626
+ line: node.range.source.lineAt(node.range.start),
627
+ column: node.range.source.columnAt(),
628
+ };
629
+ }