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

source-academy / js-slang / 13645552196

04 Mar 2025 03:23AM UTC coverage: 81.126%. Remained the same
13645552196

Pull #1742

github

web-flow
Merge 694cb981e into e35223ffb
Pull Request #1742: Rewrite: Stepper

3440 of 4608 branches covered (74.65%)

Branch coverage included in aggregate %.

10762 of 12898 relevant lines covered (83.44%)

143030.0 hits per line

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

14.29
/src/utils/statementSeqTransform.ts
1
import * as es from 'estree'
2

3
import { Node, StatementSequence } from '../types'
4
import * as ast from './ast/astCreator'
74✔
5
function hasDeclarations(node: es.BlockStatement | es.Program): boolean {
6
  for (const statement of node.body) {
1,029✔
7
    if (statement.type === 'VariableDeclaration' || statement.type === 'FunctionDeclaration') {
1,064✔
8
      return true
847✔
9
    }
10
  }
11
  return false
182✔
12
}
13

14
function hasImportDeclarations(node: es.Program): boolean {
15
  for (const statement of node.body) {
182✔
16
    if (statement.type === 'ImportDeclaration') {
205!
17
      return true
×
18
    }
19
  }
20
  return false
182✔
21
}
22

23
type NodeTransformer = (node: Node) => Node
24

25
type ASTTransformers = Map<string, NodeTransformer>
26

27
const transformers: ASTTransformers = new Map<string, NodeTransformer>([
74✔
28
  [
29
    'Program',
30
    (node: es.Program) => {
31
      if (hasDeclarations(node) || hasImportDeclarations(node)) {
1,029✔
32
        return node
847✔
33
      } else {
34
        return ast.statementSequence(node.body as es.Statement[], node.loc)
182✔
35
      }
36
    }
37
  ],
38

39
  [
40
    'BlockStatement',
41
    (node: es.BlockStatement) => {
42
      node.body = node.body.map(x => transform(x))
×
43
      if (hasDeclarations(node)) {
×
44
        return node
×
45
      } else {
46
        return ast.statementSequence(node.body, node.loc)
×
47
      }
48
    }
49
  ],
50

51
  [
52
    'StatementSequence',
53
    (node: StatementSequence) => {
54
      node.body = node.body.map(x => transform(x))
×
55
      return node
×
56
    }
57
  ],
58

59
  [
60
    'ExpressionStatement',
61
    (node: es.ExpressionStatement) => {
62
      node.expression = transform(node.expression)
×
63
      return node
×
64
    }
65
  ],
66

67
  [
68
    'IfStatement',
69
    (node: es.IfStatement) => {
70
      node.test = transform(node.test)
×
71
      node.consequent = transform(node.consequent)
×
72
      if (node.alternate) {
×
73
        node.alternate = transform(node.alternate)
×
74
      }
75
      return node
×
76
    }
77
  ],
78

79
  [
80
    'FunctionDeclaration',
81
    (node: es.FunctionDeclaration) => {
82
      node.params = node.params.map(x => transform(x))
×
83
      node.body = transform(node.body)
×
84
      if (node.id) {
×
85
        node.id = transform(node.id)
×
86
      }
87
      return node
×
88
    }
89
  ],
90

91
  [
92
    'VariableDeclarator',
93
    (node: es.VariableDeclarator) => {
94
      node.id = transform(node.id)
×
95
      if (node.init) {
×
96
        node.init = transform(node.init)
×
97
      }
98
      return node
×
99
    }
100
  ],
101

102
  [
103
    'VariableDeclaration',
104
    (node: es.VariableDeclaration) => {
105
      node.declarations = node.declarations.map(x => transform(x))
×
106
      return node
×
107
    }
108
  ],
109

110
  [
111
    'ReturnStatement',
112
    (node: es.ReturnStatement) => {
113
      if (node.argument) {
×
114
        node.argument = transform(node.argument)
×
115
      }
116
      return node
×
117
    }
118
  ],
119

120
  [
121
    'CallExpression',
122
    (node: es.SimpleCallExpression) => {
123
      node.callee = transform(node.callee)
×
124
      node.arguments = node.arguments.map(x => transform(x))
×
125
      return node
×
126
    }
127
  ],
128

129
  [
130
    'UnaryExpression',
131
    (node: es.UnaryExpression) => {
132
      node.argument = transform(node.argument)
×
133
      return node
×
134
    }
135
  ],
136

137
  [
138
    'BinaryExpression',
139
    (node: es.BinaryExpression) => {
140
      node.left = transform(node.left)
×
141
      node.right = transform(node.right)
×
142
      return node
×
143
    }
144
  ],
145

146
  [
147
    'LogicalExpression',
148
    (node: es.LogicalExpression) => {
149
      node.left = transform(node.left)
×
150
      node.right = transform(node.right)
×
151
      return node
×
152
    }
153
  ],
154

155
  [
156
    'ConditionalExpression',
157
    (node: es.ConditionalExpression) => {
158
      node.test = transform(node.test)
×
159
      node.consequent = transform(node.consequent)
×
160
      node.alternate = transform(node.alternate)
×
161
      return node
×
162
    }
163
  ],
164

165
  [
166
    'ArrowFunctionExpression',
167
    (node: es.ArrowFunctionExpression) => {
168
      node.params = node.params.map(x => transform(x))
×
169
      node.body = transform(node.body)
×
170
      return node
×
171
    }
172
  ],
173

174
  [
175
    'Identifier',
176
    (node: es.Identifier) => {
177
      return node
×
178
    }
179
  ],
180

181
  [
182
    'Literal',
183
    (node: es.Literal) => {
184
      return node
×
185
    }
186
  ],
187

188
  [
189
    'ArrayExpression',
190
    (node: es.ArrayExpression) => {
191
      node.elements = node.elements.map(x => (x ? transform(x) : null))
×
192
      return node
×
193
    }
194
  ],
195

196
  [
197
    'AssignmentExpression',
198
    (node: es.AssignmentExpression) => {
199
      node.left = transform(node.left)
×
200
      node.right = transform(node.right)
×
201
      return node
×
202
    }
203
  ],
204

205
  [
206
    'ForStatement',
207
    (node: es.ForStatement) => {
208
      if (node.init) {
×
209
        node.init = transform(node.init)
×
210
      }
211
      if (node.test) {
×
212
        node.test = transform(node.test)
×
213
      }
214
      if (node.update) {
×
215
        node.update = transform(node.update)
×
216
      }
217
      node.body = transform(node.body)
×
218
      return node
×
219
    }
220
  ],
221

222
  [
223
    'WhileStatement',
224
    (node: es.WhileStatement) => {
225
      node.test = transform(node.test)
×
226
      node.body = transform(node.body)
×
227
      return node
×
228
    }
229
  ],
230

231
  [
232
    'BreakStatement',
233
    (node: es.BreakStatement) => {
234
      if (node.label) {
×
235
        node.label = transform(node.label)
×
236
      }
237
      return node
×
238
    }
239
  ],
240

241
  [
242
    'ContinueStatement',
243
    (node: es.ContinueStatement) => {
244
      if (node.label) {
×
245
        node.label = transform(node.label)
×
246
      }
247
      return node
×
248
    }
249
  ],
250

251
  [
252
    'ObjectExpression',
253
    (node: es.ObjectExpression) => {
254
      node.properties = node.properties.map(x => transform(x))
×
255
      return node
×
256
    }
257
  ],
258

259
  [
260
    'MemberExpression',
261
    (node: es.MemberExpression) => {
262
      node.object = transform(node.object)
×
263
      node.property = transform(node.property)
×
264
      return node
×
265
    }
266
  ],
267

268
  [
269
    'Property',
270
    (node: es.Property) => {
271
      node.key = transform(node.key)
×
272
      node.value = transform(node.value)
×
273
      return node
×
274
    }
275
  ],
276

277
  [
278
    'ImportDeclaration',
279
    (node: es.ImportDeclaration) => {
280
      node.specifiers = node.specifiers.map(x => transform(x))
×
281
      node.source = transform(node.source)
×
282
      return node
×
283
    }
284
  ],
285

286
  [
287
    'ImportSpecifier',
288
    (node: es.ImportSpecifier) => {
289
      node.local = transform(node.local)
×
290
      node.imported = transform(node.imported)
×
291
      return node
×
292
    }
293
  ],
294

295
  [
296
    'ImportDefaultSpecifier',
297
    (node: es.ImportDefaultSpecifier) => {
298
      node.local = transform(node.local)
×
299
      return node
×
300
    }
301
  ],
302

303
  [
304
    'ExportNamedDeclaration',
305
    (node: es.ExportNamedDeclaration) => {
306
      if (node.declaration) {
×
307
        node.declaration = transform(node.declaration)
×
308
      }
309
      node.specifiers = node.specifiers.map(x => transform(x))
×
310
      if (node.source) {
×
311
        transform(node.source)
×
312
      }
313
      return node
×
314
    }
315
  ],
316

317
  [
318
    'ExportDefaultDeclaration',
319
    (node: es.ExportDefaultDeclaration) => {
320
      node.declaration = transform(node.declaration)
×
321
      return node
×
322
    }
323
  ],
324

325
  [
326
    'ExportSpecifier',
327
    (node: es.ExportSpecifier) => {
328
      node.local = transform(node.local)
×
329
      node.exported = transform(node.exported)
×
330
      return node
×
331
    }
332
  ],
333

334
  [
335
    'ClassDeclaration',
336
    (node: es.ClassDeclaration) => {
337
      if (node.id) {
×
338
        node.id = transform(node.id)
×
339
      }
340
      if (node.superClass) {
×
341
        node.superClass = transform(node.superClass)
×
342
      }
343
      node.body = transform(node.body)
×
344
      return node
×
345
    }
346
  ],
347

348
  [
349
    'NewExpression',
350
    (node: es.NewExpression) => {
351
      node.arguments = node.arguments.map(x => transform(x))
×
352
      return node
×
353
    }
354
  ],
355

356
  [
357
    'MethodDefinition',
358
    (node: es.MethodDefinition) => {
359
      node.key = transform(node.key)
×
360
      node.value = transform(node.value)
×
361
      return node
×
362
    }
363
  ],
364

365
  [
366
    'FunctionExpression',
367
    (node: es.FunctionExpression) => {
368
      if (node.id) {
×
369
        node.id = transform(node.id)
×
370
      }
371
      node.params = node.params.map(x => transform(x))
×
372
      node.body = transform(node.body)
×
373
      return node
×
374
    }
375
  ],
376

377
  [
378
    'ThisExpression',
379
    (_node: es.ThisExpression) => {
380
      return _node
×
381
    }
382
  ],
383

384
  [
385
    'Super',
386
    (_node: es.Super) => {
387
      return _node
×
388
    }
389
  ],
390

391
  [
392
    'TryStatement',
393
    (node: es.TryStatement) => {
394
      node.block = transform(node.block)
×
395
      if (node.handler) {
×
396
        node.handler = transform(node.handler)
×
397
      }
398
      if (node.finalizer) {
×
399
        node.finalizer = transform(node.finalizer)
×
400
      }
401
      return node
×
402
    }
403
  ],
404
  [
405
    'ThrowStatement',
406
    (node: es.ThrowStatement) => {
407
      node.argument = transform(node.argument)
×
408
      return node
×
409
    }
410
  ],
411
  [
412
    'SpreadElement',
413
    (node: es.SpreadElement) => {
414
      node.argument = transform(node.argument)
×
415
      return node
×
416
    }
417
  ],
418
  [
419
    'RestElement',
420
    (node: es.RestElement) => {
421
      node.argument = transform(node.argument)
×
422
      return node
×
423
    }
424
  ]
425
])
426

427
export function transform<NodeType extends Node>(node: NodeType): NodeType {
74✔
428
  if (transformers.has(node.type)) {
1,029!
429
    const transformer = transformers.get(node.type) as (n: NodeType) => NodeType
1,029✔
430
    const transformed = transformer(node)
1,029✔
431
    return transformed
1,029✔
432
  } else {
433
    return node
×
434
  }
435
}
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

© 2026 Coveralls, Inc