as-test 1.1.2 → 1.1.4

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);
@@ -157,8 +264,7 @@ export class CoverageTransform extends Visitor {
157
264
  this.globalStatements.push(registerStmt);
158
265
  }
159
266
  }
160
- visitFunctionDeclaration(node, isDefault) {
161
- super.visitFunctionDeclaration(node, isDefault);
267
+ visitFunctionDeclaration(node) {
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
  }
@@ -217,42 +329,14 @@ export class CoverageTransform extends Visitor {
217
329
  if (ifTrue &&
218
330
  ifTrue.kind !== 31 &&
219
331
  !isBuiltinStatement(ifTrue)) {
220
- const trueLc = getLineCol(ifTrue);
221
- const point = new CoverPoint();
222
- point.line = trueLc?.line;
223
- point.column = trueLc?.column;
224
- point.file = path;
225
- point.type = CoverType.Expression;
226
- point.hash = hash(point);
227
- const replacer = new RangeTransform(ifTrue);
228
- const registerStmt = createRegisterStatement(point);
229
- replacer.visit(registerStmt);
230
- const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifTrue)], ifTrue.range);
231
- replacer.visit(coverStmt);
232
- coverStmt.statements.push(ifTrue);
233
- node.ifTrue = coverStmt;
234
- this.globalStatements.push(registerStmt);
332
+ node.ifTrue = this.instrumentStatementBody(path, ifTrue, "IfBranch");
235
333
  visitIfTrue = true;
236
334
  visitIfFalse = !!ifFalse;
237
335
  }
238
336
  if (ifFalse &&
239
337
  ifFalse.kind !== 31 &&
240
338
  !isBuiltinStatement(ifFalse)) {
241
- const falseLc = getLineCol(ifFalse);
242
- const point = new CoverPoint();
243
- point.line = falseLc?.line;
244
- point.column = falseLc?.column;
245
- point.file = path;
246
- point.type = CoverType.Expression;
247
- point.hash = hash(point);
248
- const replacer = new RangeTransform(ifFalse);
249
- const registerStmt = createRegisterStatement(point);
250
- replacer.visit(registerStmt);
251
- const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifFalse)], ifFalse.range);
252
- replacer.visit(coverStmt);
253
- coverStmt.statements.push(ifFalse);
254
- node.ifFalse = coverStmt;
255
- this.globalStatements.push(registerStmt);
339
+ node.ifFalse = this.instrumentStatementBody(path, ifFalse, "IfBranch");
256
340
  visitIfTrue = true;
257
341
  visitIfFalse = true;
258
342
  }
@@ -289,7 +373,8 @@ export class CoverageTransform extends Visitor {
289
373
  point.line = trueLc?.line;
290
374
  point.column = trueLc?.column;
291
375
  point.file = path;
292
- point.type = CoverType.Expression;
376
+ point.type = "Ternary";
377
+ this.assignParentMetadata(point);
293
378
  point.hash = hash(point);
294
379
  const replacer = new RangeTransform(trueExpression);
295
380
  const registerStmt = createRegisterStatement(point);
@@ -307,7 +392,8 @@ export class CoverageTransform extends Visitor {
307
392
  point.line = falseLc?.line;
308
393
  point.column = falseLc?.column;
309
394
  point.file = path;
310
- point.type = CoverType.Expression;
395
+ point.type = "Ternary";
396
+ this.assignParentMetadata(point);
311
397
  point.hash = hash(point);
312
398
  const replacer = new RangeTransform(falseExpression);
313
399
  const registerStmt = createRegisterStatement(point);
@@ -319,6 +405,72 @@ export class CoverageTransform extends Visitor {
319
405
  }
320
406
  }
321
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
+ }
322
474
  visitSwitchCase(node) {
323
475
  if (node.visited)
324
476
  return;
@@ -329,7 +481,8 @@ export class CoverageTransform extends Visitor {
329
481
  point.line = caseLc?.line;
330
482
  point.column = caseLc?.column;
331
483
  point.file = path;
332
- point.type = CoverType.Block;
484
+ point.type = "SwitchCase";
485
+ this.assignParentMetadata(point);
333
486
  point.hash = hash(point);
334
487
  const replacer = new RangeTransform(node);
335
488
  const registerStmt = createRegisterStatement(point);
@@ -354,7 +507,8 @@ export class CoverageTransform extends Visitor {
354
507
  point.line = blockLc?.line;
355
508
  point.column = blockLc?.column;
356
509
  point.file = path;
357
- point.type = CoverType.Block;
510
+ point.type = "Block";
511
+ this.assignParentMetadata(point);
358
512
  point.hash = hash(point);
359
513
  const replacer = new RangeTransform(node);
360
514
  const registerStmt = createRegisterStatement(point);
@@ -413,6 +567,11 @@ function getExpressionName(node) {
413
567
  return null;
414
568
  }
415
569
  }
570
+ function getNodeName(node) {
571
+ if (!node)
572
+ return null;
573
+ return getExpressionName(node);
574
+ }
416
575
  function djb2Hash(str) {
417
576
  const points = Array.from(str);
418
577
  let h = 5381;
@@ -444,7 +603,7 @@ function getLineCol(node) {
444
603
  };
445
604
  }
446
605
  function createRegisterStatement(point) {
447
- 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})`);
448
607
  }
449
608
  function createCoverStatement(hashValue, ref) {
450
609
  return Node.createExpressionStatement(createCoverCallExpression(hashValue, ref));
@@ -455,16 +614,6 @@ function createCoverExpression(hashValue, replacement, ref) {
455
614
  function createCoverCallExpression(hashValue, ref) {
456
615
  return Node.createCallExpression(Node.createIdentifierExpression("__COVER", ref.range), null, [Node.createStringLiteralExpression(hashValue, ref.range)], ref.range);
457
616
  }
458
- function coverTypeToString(type) {
459
- switch (type) {
460
- case CoverType.Function:
461
- return "Function";
462
- case CoverType.Expression:
463
- return "Expression";
464
- default:
465
- return "Block";
466
- }
467
- }
468
617
  function asStringLiteral(value) {
469
618
  return JSON.stringify(value);
470
619
  }