as-test 1.1.1 → 1.1.3

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.
@@ -2,12 +2,6 @@ import { BlockStatement, ExpressionStatement, Node, } from "assemblyscript/dist/
2
2
  import { RangeTransform } from "./range.js";
3
3
  import { isStdlib, SimpleParser } from "./util.js";
4
4
  import { Visitor } from "./visitor.js";
5
- var CoverType;
6
- (function (CoverType) {
7
- CoverType[CoverType["Function"] = 0] = "Function";
8
- CoverType[CoverType["Expression"] = 1] = "Expression";
9
- CoverType[CoverType["Block"] = 2] = "Block";
10
- })(CoverType || (CoverType = {}));
11
5
  const COVERAGE_IGNORED_CALLS = new Set([
12
6
  "beforeAll",
13
7
  "afterAll",
@@ -50,13 +44,106 @@ class CoverPoint {
50
44
  hash = "";
51
45
  line = 0;
52
46
  column = 0;
53
- type;
47
+ type = "Expression";
54
48
  executed = false;
49
+ parentHash = "";
50
+ scopeKind = "";
51
+ scopeName = "";
52
+ depth = 0;
55
53
  }
56
54
  export class CoverageTransform extends Visitor {
57
55
  mustImport = false;
58
56
  points = new Map();
59
57
  globalStatements = [];
58
+ scopeStack = [];
59
+ getCurrentScope() {
60
+ return this.scopeStack.length
61
+ ? this.scopeStack[this.scopeStack.length - 1]
62
+ : null;
63
+ }
64
+ withScope(point, callback) {
65
+ this.scopeStack.push(point);
66
+ try {
67
+ callback();
68
+ }
69
+ finally {
70
+ this.scopeStack.pop();
71
+ }
72
+ }
73
+ assignParentMetadata(point) {
74
+ const currentScope = this.getCurrentScope();
75
+ if (!currentScope)
76
+ return;
77
+ point.parentHash = currentScope.hash;
78
+ point.scopeKind = currentScope.scopeKind;
79
+ point.scopeName = currentScope.scopeName;
80
+ point.depth = currentScope.depth + 1;
81
+ }
82
+ assignScopeMetadata(point, scopeKind, scopeName = null) {
83
+ point.scopeKind = scopeKind;
84
+ point.scopeName = scopeName ?? "";
85
+ }
86
+ createFunctionPoint(path, node, scopeKind, scopeName = null) {
87
+ const funcLc = getLineCol(node);
88
+ const point = new CoverPoint();
89
+ point.line = funcLc?.line;
90
+ point.column = funcLc?.column;
91
+ point.file = path;
92
+ point.type = scopeKind;
93
+ this.assignParentMetadata(point);
94
+ this.assignScopeMetadata(point, scopeKind, scopeName);
95
+ point.hash = hash(point);
96
+ return point;
97
+ }
98
+ createPoint(path, node, type) {
99
+ const lc = getLineCol(node);
100
+ const point = new CoverPoint();
101
+ point.line = lc?.line;
102
+ point.column = lc?.column;
103
+ point.file = path;
104
+ point.type = type;
105
+ this.assignParentMetadata(point);
106
+ point.hash = hash(point);
107
+ return point;
108
+ }
109
+ instrumentStatementBody(path, node, type) {
110
+ const point = this.createPoint(path, node, type);
111
+ const replacer = new RangeTransform(node);
112
+ const registerStmt = createRegisterStatement(point);
113
+ replacer.visit(registerStmt);
114
+ const coverStmt = createCoverStatement(point.hash, node);
115
+ replacer.visit(coverStmt);
116
+ this.globalStatements.push(registerStmt);
117
+ if (node.kind == 31) {
118
+ const block = node;
119
+ block.statements.unshift(coverStmt);
120
+ return block;
121
+ }
122
+ const coverBlock = Node.createBlockStatement([coverStmt], node.range);
123
+ replacer.visit(coverBlock);
124
+ coverBlock.statements.push(node);
125
+ return coverBlock;
126
+ }
127
+ isAssignmentOperator(operator) {
128
+ switch (operator) {
129
+ case 101:
130
+ case 102:
131
+ case 103:
132
+ case 104:
133
+ case 105:
134
+ case 106:
135
+ case 107:
136
+ case 108:
137
+ case 109:
138
+ case 110:
139
+ case 111:
140
+ case 112:
141
+ case 113:
142
+ return true;
143
+ default:
144
+ return false;
145
+ }
146
+ }
60
147
  visitCallExpression(node) {
61
148
  const callName = getCallName(node);
62
149
  if (callName && COVERAGE_IGNORED_CALLS.has(callName)) {
@@ -89,7 +176,8 @@ export class CoverageTransform extends Visitor {
89
176
  point.line = rightLc?.line;
90
177
  point.column = rightLc?.column;
91
178
  point.file = path;
92
- point.type = CoverType.Expression;
179
+ point.type = "LogicalBranch";
180
+ this.assignParentMetadata(point);
93
181
  point.hash = hash(point);
94
182
  const replacer = new RangeTransform(node);
95
183
  const registerStmt = createRegisterStatement(point);
@@ -100,10 +188,25 @@ export class CoverageTransform extends Visitor {
100
188
  this.globalStatements.push(registerStmt);
101
189
  break;
102
190
  }
191
+ default: {
192
+ if (!this.isAssignmentOperator(node.operator))
193
+ break;
194
+ const right = node.right;
195
+ if (isBuiltinCallExpression(right))
196
+ break;
197
+ const point = this.createPoint(path, right, "Assignment");
198
+ const replacer = new RangeTransform(node);
199
+ const registerStmt = createRegisterStatement(point);
200
+ replacer.visit(registerStmt);
201
+ const coverExpression = createCoverExpression(point.hash, right, node);
202
+ replacer.visit(coverExpression);
203
+ node.right = coverExpression;
204
+ this.globalStatements.push(registerStmt);
205
+ break;
206
+ }
103
207
  }
104
208
  }
105
209
  visitMethodDeclaration(node) {
106
- super.visitMethodDeclaration(node);
107
210
  if (node.visited)
108
211
  return;
109
212
  node.visited = true;
@@ -112,13 +215,9 @@ export class CoverageTransform extends Visitor {
112
215
  return;
113
216
  node.body.visited = true;
114
217
  const path = node.range.source.normalizedPath;
115
- const funcLc = getLineCol(node);
116
- const point = new CoverPoint();
117
- point.line = funcLc?.line;
118
- point.column = funcLc?.column;
119
- point.file = path;
120
- point.type = CoverType.Function;
121
- point.hash = hash(point);
218
+ const methodName = getNodeName(node.name);
219
+ const scopeKind = methodName == "constructor" ? "Constructor" : "Method";
220
+ const point = this.createFunctionPoint(path, node, scopeKind, methodName);
122
221
  const replacer = new RangeTransform(node);
123
222
  const registerStmt = createRegisterStatement(point);
124
223
  replacer.visit(registerStmt);
@@ -127,6 +226,13 @@ export class CoverageTransform extends Visitor {
127
226
  const bodyBlock = node.body;
128
227
  bodyBlock.statements.unshift(coverStmt);
129
228
  this.globalStatements.push(registerStmt);
229
+ this.withScope(point, () => {
230
+ this.visit(node.name, node);
231
+ this.visit(node.typeParameters, node);
232
+ this.visit(node.signature, node);
233
+ this.visit(node.decorators, node);
234
+ this.visit(bodyBlock.statements, bodyBlock);
235
+ });
130
236
  }
131
237
  }
132
238
  visitParameter(node) {
@@ -146,7 +252,8 @@ export class CoverageTransform extends Visitor {
146
252
  point.line = paramLc?.line;
147
253
  point.column = paramLc?.column;
148
254
  point.file = path;
149
- point.type = CoverType.Expression;
255
+ point.type = "DefaultValue";
256
+ this.assignParentMetadata(point);
150
257
  point.hash = hash(point);
151
258
  const replacer = new RangeTransform(node);
152
259
  const registerStmt = createRegisterStatement(point);
@@ -158,7 +265,6 @@ export class CoverageTransform extends Visitor {
158
265
  }
159
266
  }
160
267
  visitFunctionDeclaration(node, isDefault) {
161
- super.visitFunctionDeclaration(node, isDefault);
162
268
  if (node.visited)
163
269
  return;
164
270
  node.visited = true;
@@ -167,13 +273,7 @@ export class CoverageTransform extends Visitor {
167
273
  return;
168
274
  node.body.visited = true;
169
275
  const path = node.range.source.normalizedPath;
170
- const funcLc = getLineCol(node);
171
- const point = new CoverPoint();
172
- point.line = funcLc?.line;
173
- point.column = funcLc?.column;
174
- point.file = path;
175
- point.type = CoverType.Function;
176
- point.hash = hash(point);
276
+ const point = this.createFunctionPoint(path, node, "Function", node.name?.text ?? null);
177
277
  const replacer = new RangeTransform(node);
178
278
  const registerStmt = createRegisterStatement(point);
179
279
  replacer.visit(registerStmt);
@@ -202,6 +302,18 @@ export class CoverageTransform extends Visitor {
202
302
  const bodyBlock = node.body;
203
303
  bodyBlock.statements.unshift(coverStmt);
204
304
  }
305
+ this.withScope(point, () => {
306
+ this.visit(node.name, node);
307
+ this.visit(node.decorators, node);
308
+ this.visit(node.typeParameters, node);
309
+ this.visit(node.signature, node);
310
+ if (node.body instanceof BlockStatement) {
311
+ this.visit(node.body.statements, node.body);
312
+ }
313
+ else {
314
+ this.visit(node.body, node);
315
+ }
316
+ });
205
317
  }
206
318
  }
207
319
  }
@@ -214,43 +326,17 @@ export class CoverageTransform extends Visitor {
214
326
  const ifTrue = node.ifTrue;
215
327
  const ifFalse = node.ifFalse;
216
328
  const path = node.range.source.normalizedPath;
217
- if (ifTrue.kind !== 31 && !isBuiltinStatement(ifTrue)) {
218
- const trueLc = getLineCol(ifTrue);
219
- const point = new CoverPoint();
220
- point.line = trueLc?.line;
221
- point.column = trueLc?.column;
222
- point.file = path;
223
- point.type = CoverType.Expression;
224
- point.hash = hash(point);
225
- const replacer = new RangeTransform(ifTrue);
226
- const registerStmt = createRegisterStatement(point);
227
- replacer.visit(registerStmt);
228
- const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifTrue)], ifTrue.range);
229
- replacer.visit(coverStmt);
230
- coverStmt.statements.push(ifTrue);
231
- node.ifTrue = coverStmt;
232
- this.globalStatements.push(registerStmt);
329
+ if (ifTrue &&
330
+ ifTrue.kind !== 31 &&
331
+ !isBuiltinStatement(ifTrue)) {
332
+ node.ifTrue = this.instrumentStatementBody(path, ifTrue, "IfBranch");
233
333
  visitIfTrue = true;
234
334
  visitIfFalse = !!ifFalse;
235
335
  }
236
336
  if (ifFalse &&
237
337
  ifFalse.kind !== 31 &&
238
338
  !isBuiltinStatement(ifFalse)) {
239
- const falseLc = getLineCol(ifFalse);
240
- const point = new CoverPoint();
241
- point.line = falseLc?.line;
242
- point.column = falseLc?.column;
243
- point.file = path;
244
- point.type = CoverType.Expression;
245
- point.hash = hash(point);
246
- const replacer = new RangeTransform(ifFalse);
247
- const registerStmt = createRegisterStatement(point);
248
- replacer.visit(registerStmt);
249
- const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifFalse)], ifFalse.range);
250
- replacer.visit(coverStmt);
251
- coverStmt.statements.push(ifFalse);
252
- node.ifFalse = coverStmt;
253
- this.globalStatements.push(registerStmt);
339
+ node.ifFalse = this.instrumentStatementBody(path, ifFalse, "IfBranch");
254
340
  visitIfTrue = true;
255
341
  visitIfFalse = true;
256
342
  }
@@ -287,7 +373,8 @@ export class CoverageTransform extends Visitor {
287
373
  point.line = trueLc?.line;
288
374
  point.column = trueLc?.column;
289
375
  point.file = path;
290
- point.type = CoverType.Expression;
376
+ point.type = "Ternary";
377
+ this.assignParentMetadata(point);
291
378
  point.hash = hash(point);
292
379
  const replacer = new RangeTransform(trueExpression);
293
380
  const registerStmt = createRegisterStatement(point);
@@ -305,7 +392,8 @@ export class CoverageTransform extends Visitor {
305
392
  point.line = falseLc?.line;
306
393
  point.column = falseLc?.column;
307
394
  point.file = path;
308
- point.type = CoverType.Expression;
395
+ point.type = "Ternary";
396
+ this.assignParentMetadata(point);
309
397
  point.hash = hash(point);
310
398
  const replacer = new RangeTransform(falseExpression);
311
399
  const registerStmt = createRegisterStatement(point);
@@ -317,6 +405,72 @@ export class CoverageTransform extends Visitor {
317
405
  }
318
406
  }
319
407
  }
408
+ visitForStatement(node) {
409
+ if (node.visited)
410
+ return;
411
+ node.visited = true;
412
+ const path = node.range.source.normalizedPath;
413
+ node.body = this.instrumentStatementBody(path, node.body, "Loop");
414
+ super.visitForStatement(node);
415
+ }
416
+ visitForOfStatement(node) {
417
+ if (node.visited)
418
+ return;
419
+ node.visited = true;
420
+ const path = node.range.source.normalizedPath;
421
+ node.body = this.instrumentStatementBody(path, node.body, "Loop");
422
+ super.visitForOfStatement(node);
423
+ }
424
+ visitWhileStatement(node) {
425
+ if (node.visited)
426
+ return;
427
+ node.visited = true;
428
+ const path = node.range.source.normalizedPath;
429
+ node.body = this.instrumentStatementBody(path, node.body, "Loop");
430
+ super.visitWhileStatement(node);
431
+ }
432
+ visitDoStatement(node) {
433
+ if (node.visited)
434
+ return;
435
+ node.visited = true;
436
+ const path = node.range.source.normalizedPath;
437
+ node.body = this.instrumentStatementBody(path, node.body, "Loop");
438
+ super.visitDoStatement(node);
439
+ }
440
+ visitReturnStatement(node) {
441
+ if (node.visited)
442
+ return;
443
+ node.visited = true;
444
+ super.visitReturnStatement(node);
445
+ if (!node.value || isBuiltinCallExpression(node.value))
446
+ return;
447
+ const path = node.range.source.normalizedPath;
448
+ const point = this.createPoint(path, node.value, "Return");
449
+ const replacer = new RangeTransform(node);
450
+ const registerStmt = createRegisterStatement(point);
451
+ replacer.visit(registerStmt);
452
+ const coverExpression = createCoverExpression(point.hash, node.value, node);
453
+ replacer.visit(coverExpression);
454
+ node.value = coverExpression;
455
+ this.globalStatements.push(registerStmt);
456
+ }
457
+ visitThrowStatement(node) {
458
+ if (node.visited)
459
+ return;
460
+ node.visited = true;
461
+ super.visitThrowStatement(node);
462
+ if (!node.value || isBuiltinCallExpression(node.value))
463
+ return;
464
+ const path = node.range.source.normalizedPath;
465
+ const point = this.createPoint(path, node.value, "Throw");
466
+ const replacer = new RangeTransform(node);
467
+ const registerStmt = createRegisterStatement(point);
468
+ replacer.visit(registerStmt);
469
+ const coverExpression = createCoverExpression(point.hash, node.value, node);
470
+ replacer.visit(coverExpression);
471
+ node.value = coverExpression;
472
+ this.globalStatements.push(registerStmt);
473
+ }
320
474
  visitSwitchCase(node) {
321
475
  if (node.visited)
322
476
  return;
@@ -327,7 +481,8 @@ export class CoverageTransform extends Visitor {
327
481
  point.line = caseLc?.line;
328
482
  point.column = caseLc?.column;
329
483
  point.file = path;
330
- point.type = CoverType.Block;
484
+ point.type = "SwitchCase";
485
+ this.assignParentMetadata(point);
331
486
  point.hash = hash(point);
332
487
  const replacer = new RangeTransform(node);
333
488
  const registerStmt = createRegisterStatement(point);
@@ -352,7 +507,8 @@ export class CoverageTransform extends Visitor {
352
507
  point.line = blockLc?.line;
353
508
  point.column = blockLc?.column;
354
509
  point.file = path;
355
- point.type = CoverType.Block;
510
+ point.type = "Block";
511
+ this.assignParentMetadata(point);
356
512
  point.hash = hash(point);
357
513
  const replacer = new RangeTransform(node);
358
514
  const registerStmt = createRegisterStatement(point);
@@ -411,6 +567,11 @@ function getExpressionName(node) {
411
567
  return null;
412
568
  }
413
569
  }
570
+ function getNodeName(node) {
571
+ if (!node)
572
+ return null;
573
+ return getExpressionName(node);
574
+ }
414
575
  function djb2Hash(str) {
415
576
  const points = Array.from(str);
416
577
  let h = 5381;
@@ -442,7 +603,7 @@ function getLineCol(node) {
442
603
  };
443
604
  }
444
605
  function createRegisterStatement(point) {
445
- return SimpleParser.parseTopLevelStatement(`__REGISTER_RAW(${asStringLiteral(point.file)}, ${asStringLiteral(point.hash)}, ${point.line}, ${point.column}, ${asStringLiteral(coverTypeToString(point.type))})`);
606
+ return SimpleParser.parseTopLevelStatement(`__REGISTER_RAW(${asStringLiteral(point.file)}, ${asStringLiteral(point.hash)}, ${point.line}, ${point.column}, ${asStringLiteral(point.type)}, ${asStringLiteral(point.parentHash)}, ${asStringLiteral(point.scopeKind)}, ${asStringLiteral(point.scopeName)}, ${point.depth})`);
446
607
  }
447
608
  function createCoverStatement(hashValue, ref) {
448
609
  return Node.createExpressionStatement(createCoverCallExpression(hashValue, ref));
@@ -453,16 +614,6 @@ function createCoverExpression(hashValue, replacement, ref) {
453
614
  function createCoverCallExpression(hashValue, ref) {
454
615
  return Node.createCallExpression(Node.createIdentifierExpression("__COVER", ref.range), null, [Node.createStringLiteralExpression(hashValue, ref.range)], ref.range);
455
616
  }
456
- function coverTypeToString(type) {
457
- switch (type) {
458
- case CoverType.Function:
459
- return "Function";
460
- case CoverType.Expression:
461
- return "Expression";
462
- default:
463
- return "Block";
464
- }
465
- }
466
617
  function asStringLiteral(value) {
467
618
  return JSON.stringify(value);
468
619
  }