• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / js-slang / 17161360280

22 Aug 2025 05:04PM UTC coverage: 77.439% (-1.1%) from 78.56%
17161360280

Pull #1813

github

web-flow
Merge 3531197b0 into 20b0a35b6
Pull Request #1813: Remove infinite loop detector

2746 of 3843 branches covered (71.45%)

Branch coverage included in aggregate %.

8193 of 10283 relevant lines covered (79.68%)

162956.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.59
/src/utils/ast/astCreator.ts
1
import type es from 'estree'
2

3
import {
4
  AllowedDeclarations,
5
  type BlockExpression,
6
  type FunctionDeclarationExpression,
7
  type Node,
8
  type StatementSequence
9
} from '../../types'
10

11
export const locationDummyNode = (line: number, column: number, source: string | null) =>
72✔
12
  literal('Dummy', { start: { line, column }, end: { line, column }, source })
54,546,768✔
13

14
export const identifier = (name: string, loc?: es.SourceLocation | null): es.Identifier => ({
364,018✔
15
  type: 'Identifier',
16
  name,
17
  loc
18
})
19

20
export const importDeclaration = (
72✔
21
  source: string,
22
  specifiers: es.ImportDeclaration['specifiers'],
23
  loc?: es.SourceLocation | null
24
): es.ImportDeclaration => ({
30✔
25
  type: 'ImportDeclaration',
26
  source: literal(source),
27
  specifiers,
28
  loc
29
})
30

31
export const importSpecifier = (
72✔
32
  importedName: string,
33
  localName: string,
34
  loc?: es.SourceLocation | null
35
): es.ImportSpecifier => ({
44✔
36
  type: 'ImportSpecifier',
37
  imported: identifier(importedName),
38
  local: identifier(localName),
39
  loc
40
})
41

42
export const importDefaultSpecifier = (
72✔
43
  localName: string,
44
  loc?: es.SourceLocation | null
45
): es.ImportDefaultSpecifier => ({
6✔
46
  type: 'ImportDefaultSpecifier',
47
  local: identifier(localName),
48
  loc
49
})
50

51
export const importNamespaceSpecifier = (
72✔
52
  localName: string,
53
  loc?: es.SourceLocation | null
54
): es.ImportNamespaceSpecifier => ({
1✔
55
  type: 'ImportNamespaceSpecifier',
56
  local: identifier(localName),
57
  loc
58
})
59

60
export const literal = (
72✔
61
  value: string | number | boolean | null,
62
  loc?: es.SourceLocation | null
63
): es.Literal => ({
55,583,311✔
64
  type: 'Literal',
65
  value,
66
  loc
67
})
68

69
export const memberExpression = (
72✔
70
  object: es.Expression,
71
  property: string | number
72
): es.MemberExpression => ({
76,865✔
73
  type: 'MemberExpression',
74
  object,
75
  computed: typeof property === 'number',
76
  optional: false,
77
  property: typeof property === 'number' ? literal(property) : identifier(property)
76,865!
78
})
79

80
export const declaration = (
72✔
81
  name: string,
82
  kind: AllowedDeclarations,
83
  init: es.Expression,
84
  loc?: es.SourceLocation | null
85
) =>
86
  variableDeclaration(
57,429✔
87
    [
88
      {
89
        type: 'VariableDeclarator',
90
        id: identifier(name),
91
        init
92
      }
93
    ],
94
    kind,
95
    loc
96
  )
97

98
export const constantDeclaration = (
72✔
99
  name: string,
100
  init: es.Expression,
101
  loc?: es.SourceLocation | null
102
) => declaration(name, 'const', init, loc)
57,429✔
103

104
export const callExpression = (
72✔
105
  callee: es.Expression,
106
  args: (es.Expression | es.SpreadElement)[],
107
  loc?: es.SourceLocation | null
108
): es.CallExpression => ({
81,221✔
109
  type: 'CallExpression',
110
  callee,
111
  arguments: args,
112
  optional: false,
113
  loc
114
})
115

116
export const expressionStatement = (expression: es.Expression): es.ExpressionStatement => ({
1,596✔
117
  type: 'ExpressionStatement',
118
  expression
119
})
120

121
export const blockArrowFunction = (
72✔
122
  params: es.Identifier[],
123
  body: es.Statement[] | es.BlockStatement | es.Expression,
124
  loc?: es.SourceLocation | null
125
): es.ArrowFunctionExpression => ({
52,257✔
126
  type: 'ArrowFunctionExpression',
127
  expression: false,
128
  generator: false,
129
  params,
130
  body: Array.isArray(body) ? blockStatement(body) : body,
52,257!
131
  loc
132
})
133

134
export const functionExpression = (
72✔
135
  params: es.Pattern[],
136
  body: es.Statement[] | es.BlockStatement,
137
  loc?: es.SourceLocation | null,
138
  id?: es.Identifier
139
): es.FunctionExpression => ({
×
140
  type: 'FunctionExpression',
141
  id: id ?? null,
×
142
  async: false,
143
  generator: false,
144
  params,
145
  body: Array.isArray(body) ? blockStatement(body) : body,
×
146
  loc
147
})
148

149
export const blockStatement = (
72✔
150
  body: es.Statement[],
151
  loc?: es.SourceLocation | null
152
): es.BlockStatement => ({
3,476✔
153
  type: 'BlockStatement',
154
  body,
155
  loc
156
})
157

158
export const statementSequence = (
72✔
159
  body: es.Statement[],
160
  loc?: es.SourceLocation | null
161
): StatementSequence => ({
266,938✔
162
  type: 'StatementSequence',
163
  body,
164
  loc
165
})
166

167
export const program = (body: es.Statement[]): es.Program => ({
99✔
168
  type: 'Program',
169
  sourceType: 'module',
170
  body
171
})
172

173
export const returnStatement = (
72✔
174
  argument: es.Expression,
175
  loc?: es.SourceLocation | null
176
): es.ReturnStatement => ({
1,349✔
177
  type: 'ReturnStatement',
178
  argument,
179
  loc
180
})
181

182
export const property = (key: string, value: es.Expression): es.Property => ({
173,087✔
183
  type: 'Property',
184
  method: false,
185
  shorthand: false,
186
  computed: false,
187
  key: identifier(key),
188
  value,
189
  kind: 'init'
190
})
191

192
export const objectExpression = (properties: es.Property[]): es.ObjectExpression => ({
31,016✔
193
  type: 'ObjectExpression',
194
  properties
195
})
196

197
export const mutateToCallExpression = (
72✔
198
  node: Node,
199
  callee: es.Expression,
200
  args: es.Expression[]
201
) => {
202
  node.type = 'CallExpression'
28,637✔
203
  node = node as es.CallExpression
28,637✔
204
  node.callee = callee
28,637✔
205
  node.arguments = args
28,637✔
206
}
207

208
export const mutateToAssignmentExpression = (
72✔
209
  node: Node,
210
  left: es.Pattern,
211
  right: es.Expression
212
) => {
213
  node.type = 'AssignmentExpression'
×
214
  node = node as es.AssignmentExpression
×
215
  node.operator = '='
×
216
  node.left = left
×
217
  node.right = right
×
218
}
219

220
export const mutateToExpressionStatement = (node: Node, expr: es.Expression) => {
72✔
221
  node.type = 'ExpressionStatement'
×
222
  node = node as es.ExpressionStatement
×
223
  node.expression = expr
×
224
}
225

226
export const mutateToReturnStatement = (node: Node, expr: es.Expression) => {
72✔
227
  node.type = 'ReturnStatement'
×
228
  node = node as es.ReturnStatement
×
229
  node.argument = expr
×
230
}
231

232
export const mutateToMemberExpression = (node: Node, obj: es.Expression, prop: es.Expression) => {
72✔
233
  node.type = 'MemberExpression'
×
234
  node = node as es.MemberExpression
×
235
  node.object = obj
×
236
  node.property = prop
×
237
  node.computed = false
×
238
}
239

240
export const logicalExpression = (
72✔
241
  operator: es.LogicalOperator,
242
  left: es.Expression,
243
  right: es.Expression,
244
  loc?: es.SourceLocation | null
245
): es.LogicalExpression => ({
2,570✔
246
  type: 'LogicalExpression',
247
  operator,
248
  left,
249
  right,
250
  loc
251
})
252

253
export const mutateToConditionalExpression = (
72✔
254
  node: Node,
255
  test: es.Expression,
256
  consequent: es.Expression,
257
  alternate: es.Expression
258
) => {
259
  node.type = 'ConditionalExpression'
×
260
  node = node as es.ConditionalExpression
×
261
  node.test = test
×
262
  node.consequent = consequent
×
263
  node.alternate = alternate
×
264
}
265

266
export const conditionalExpression = (
72✔
267
  test: es.Expression,
268
  consequent: es.Expression,
269
  alternate: es.Expression,
270
  loc?: es.SourceLocation | null
271
): es.ConditionalExpression => ({
21,847✔
272
  type: 'ConditionalExpression',
273
  test,
274
  consequent,
275
  alternate,
276
  loc
277
})
278

279
export const arrayExpression = (elements: es.Expression[]): es.ArrayExpression => ({
22,211✔
280
  type: 'ArrayExpression',
281
  elements
282
})
283

284
export const assignmentExpression = (
72✔
285
  left: es.Identifier | es.MemberExpression,
286
  right: es.Expression,
287
  loc?: es.SourceLocation | null
288
): es.AssignmentExpression => ({
1,150✔
289
  type: 'AssignmentExpression',
290
  operator: '=',
291
  left,
292
  right,
293
  loc
294
})
295

296
export const binaryExpression = (
72✔
297
  operator: es.BinaryOperator,
298
  left: es.Expression,
299
  right: es.Expression,
300
  loc?: es.SourceLocation | null
301
): es.BinaryExpression => ({
×
302
  type: 'BinaryExpression',
303
  operator,
304
  left,
305
  right,
306
  loc
307
})
308

309
export const unaryExpression = (
72✔
310
  operator: es.UnaryOperator,
311
  argument: es.Expression,
312
  loc?: es.SourceLocation | null
313
): es.UnaryExpression => ({
×
314
  type: 'UnaryExpression',
315
  operator,
316
  prefix: true,
317
  argument,
318
  loc
319
})
320

321
// primitive: undefined is a possible value
322
export const primitive = (value: any): es.Expression => {
72✔
323
  return value === undefined ? identifier('undefined') : literal(value)
610,591✔
324
}
325

326
export const functionDeclarationExpression = (
72✔
327
  id: es.Identifier,
328
  params: es.Pattern[],
329
  body: es.BlockStatement,
330
  loc?: es.SourceLocation | null
331
): FunctionDeclarationExpression => ({
×
332
  type: 'FunctionExpression',
333
  id,
334
  params,
335
  body,
336
  loc
337
})
338

339
export const functionDeclaration = (
72✔
340
  id: es.Identifier,
341
  params: es.Pattern[],
342
  body: es.BlockStatement,
343
  loc?: es.SourceLocation | null
344
): es.FunctionDeclaration => ({
32✔
345
  type: 'FunctionDeclaration',
346
  id,
347
  params,
348
  body,
349
  loc
350
})
351

352
export const blockExpression = (
72✔
353
  body: es.Statement[],
354
  loc?: es.SourceLocation | null
355
): BlockExpression => ({
×
356
  type: 'BlockExpression',
357
  body,
358
  loc
359
})
360

361
export const arrowFunctionExpression = (
72✔
362
  params: es.Pattern[],
363
  body: es.Expression | es.BlockStatement,
364
  loc?: es.SourceLocation | null
365
): es.ArrowFunctionExpression => ({
813✔
366
  type: 'ArrowFunctionExpression',
367
  expression: body.type !== 'BlockStatement',
368
  generator: false,
369
  params,
370
  body,
371
  loc
372
})
373

374
export const variableDeclaration = (
72✔
375
  declarations: es.VariableDeclarator[],
376
  kind: es.VariableDeclaration['kind'] = 'const',
×
377
  loc?: es.SourceLocation | null
378
): es.VariableDeclaration => ({
58,103✔
379
  type: 'VariableDeclaration',
380
  kind,
381
  declarations,
382
  loc
383
})
384

385
export const variableDeclarator = (
72✔
386
  id: es.Pattern,
387
  init: es.Expression,
388
  loc?: es.SourceLocation | null
389
): es.VariableDeclarator => ({
674✔
390
  type: 'VariableDeclarator',
391
  id,
392
  init,
393
  loc
394
})
395

396
export const ifStatement = (
72✔
397
  test: es.Expression,
398
  consequent: es.BlockStatement,
399
  alternate: es.Statement,
400
  loc?: es.SourceLocation | null
401
): es.IfStatement => ({
×
402
  type: 'IfStatement',
403
  test,
404
  consequent,
405
  alternate,
406
  loc
407
})
408

409
export const whileStatement = (
72✔
410
  body: es.BlockStatement,
411
  test: es.Expression,
412
  loc?: es.SourceLocation | null
413
): es.WhileStatement => ({
×
414
  type: 'WhileStatement',
415
  test,
416
  body,
417
  loc
418
})
419

420
export const forStatement = (
72✔
421
  init: es.VariableDeclaration | es.Expression,
422
  test: es.Expression,
423
  update: es.Expression,
424
  body: es.Statement,
425
  loc?: es.SourceLocation | null
426
): es.ForStatement => ({
337✔
427
  type: 'ForStatement',
428
  init,
429
  test,
430
  update,
431
  body,
432
  loc
433
})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc