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

source-academy / js-slang / 23995741899

05 Apr 2026 06:14AM UTC coverage: 77.093% (+0.002%) from 77.091%
23995741899

push

github

web-flow
Upgrade to TypeScript 6 and Prettier improvements (#1936)

* Upgrade TypeScript to v6

* Fix import source

* Fix tsconfig

* Fix preexisting type errors

* Remove scm-slang

* Bump node types

* Fix tsconfig

* Fix node types specifier

* Enable trailing commas

* Enable semicolons

* Check and commit files with changed line numbers

* Update Yarn to 4.13.0

* Remove unneeded sicp package deps

3112 of 4282 branches covered (72.68%)

Branch coverage included in aggregate %.

3761 of 5218 new or added lines in 152 files covered. (72.08%)

26 existing lines in 9 files now uncovered.

7136 of 9011 relevant lines covered (79.19%)

175254.05 hits per line

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

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

3
import type { AllowedDeclarations, Node, StatementSequence } from '../../types';
4

5
export const locationDummyNode = (line: number, column: number, source: string | null) =>
65✔
6
  literal('Dummy', { start: { line, column }, end: { line, column }, source });
56,963,294✔
7

8
export const identifier = (name: string, loc?: es.SourceLocation | null): es.Identifier => ({
359,364✔
9
  type: 'Identifier',
10
  name,
11
  loc,
12
});
13

14
export const importDeclaration = (
65✔
15
  source: string,
16
  specifiers: es.ImportDeclaration['specifiers'],
17
  loc?: es.SourceLocation | null,
18
): es.ImportDeclaration => ({
25✔
19
  type: 'ImportDeclaration',
20
  source: literal(source),
21
  specifiers,
22
  loc,
23
});
24

25
export const importSpecifier = (
65✔
26
  importedName: string,
27
  localName: string,
28
  loc?: es.SourceLocation | null,
29
): es.ImportSpecifier => ({
39✔
30
  type: 'ImportSpecifier',
31
  imported: identifier(importedName),
32
  local: identifier(localName),
33
  loc,
34
});
35

36
export const importDefaultSpecifier = (
65✔
37
  localName: string,
38
  loc?: es.SourceLocation | null,
39
): es.ImportDefaultSpecifier => ({
6✔
40
  type: 'ImportDefaultSpecifier',
41
  local: identifier(localName),
42
  loc,
43
});
44

45
export const importNamespaceSpecifier = (
65✔
46
  localName: string,
47
  loc?: es.SourceLocation | null,
48
): es.ImportNamespaceSpecifier => ({
1✔
49
  type: 'ImportNamespaceSpecifier',
50
  local: identifier(localName),
51
  loc,
52
});
53

54
export const literal = (
65✔
55
  value: string | number | boolean | null,
56
  loc?: es.SourceLocation | null,
57
): es.Literal => ({
57,995,071✔
58
  type: 'Literal',
59
  value,
60
  loc,
61
});
62

63
export const memberExpression = (
65✔
64
  object: es.Expression,
65
  property: string | number,
66
): es.MemberExpression => ({
76,135✔
67
  type: 'MemberExpression',
68
  object,
69
  computed: typeof property === 'number',
70
  optional: false,
71
  property: typeof property === 'number' ? literal(property) : identifier(property),
76,135!
72
});
73

74
export const declaration = (
65✔
75
  name: string,
76
  kind: AllowedDeclarations,
77
  init: es.Expression,
78
  loc?: es.SourceLocation | null,
79
) =>
80
  variableDeclaration(
57,064✔
81
    [
82
      {
83
        type: 'VariableDeclarator',
84
        id: identifier(name),
85
        init,
86
      },
87
    ],
88
    kind,
89
    loc,
90
  );
91

92
export const constantDeclaration = (
65✔
93
  name: string,
94
  init: es.Expression,
95
  loc?: es.SourceLocation | null,
96
) => declaration(name, 'const', init, loc);
57,064✔
97

98
export const callExpression = (
65✔
99
  callee: es.Expression,
100
  args: (es.Expression | es.SpreadElement)[],
101
  loc?: es.SourceLocation | null,
102
): es.CallExpression => ({
79,046✔
103
  type: 'CallExpression',
104
  callee,
105
  arguments: args,
106
  optional: false,
107
  loc,
108
});
109

110
export const expressionStatement = (expression: es.Expression): es.ExpressionStatement => ({
1,582✔
111
  type: 'ExpressionStatement',
112
  expression,
113
});
114

115
export const blockArrowFunction = (
65✔
116
  params: es.Identifier[],
117
  body: es.Statement[] | es.BlockStatement | es.Expression,
118
  loc?: es.SourceLocation | null,
119
): es.ArrowFunctionExpression => ({
51,273✔
120
  type: 'ArrowFunctionExpression',
121
  expression: false,
122
  generator: false,
123
  params,
124
  body: Array.isArray(body) ? blockStatement(body) : body,
51,273!
125
  loc,
126
});
127

128
export const functionExpression = (
65✔
129
  params: es.Pattern[],
130
  body: es.Statement[] | es.BlockStatement,
131
  loc?: es.SourceLocation | null,
132
  id?: es.Identifier,
133
): es.FunctionExpression => ({
×
134
  type: 'FunctionExpression',
135
  id: id ?? null,
×
136
  async: false,
137
  generator: false,
138
  params,
139
  body: Array.isArray(body) ? blockStatement(body) : body,
×
140
  loc,
141
});
142

143
export const blockStatement = (
65✔
144
  body: es.Statement[],
145
  loc?: es.SourceLocation | null,
146
): es.BlockStatement => ({
2,677✔
147
  type: 'BlockStatement',
148
  body,
149
  loc,
150
});
151

152
export const statementSequence = (
65✔
153
  body: es.Statement[],
154
  loc?: es.SourceLocation | null,
155
): StatementSequence => ({
267,573✔
156
  type: 'StatementSequence',
157
  body,
158
  loc,
159
});
160

161
export const program = (body: es.Statement[]): es.Program => ({
99✔
162
  type: 'Program',
163
  sourceType: 'module',
164
  body,
165
});
166

167
export const returnStatement = (
65✔
168
  argument: es.Expression,
169
  loc?: es.SourceLocation | null,
170
): es.ReturnStatement => ({
561✔
171
  type: 'ReturnStatement',
172
  argument,
173
  loc,
174
});
175

176
export const property = (key: string, value: es.Expression): es.Property => ({
171,067✔
177
  type: 'Property',
178
  method: false,
179
  shorthand: false,
180
  computed: false,
181
  key: identifier(key),
182
  value,
183
  kind: 'init',
184
});
185

186
export const objectExpression = (properties: es.Property[]): es.ObjectExpression => ({
30,656✔
187
  type: 'ObjectExpression',
188
  properties,
189
});
190

191
export const mutateToCallExpression = (
65✔
192
  node: Node,
193
  callee: es.Expression,
194
  args: es.Expression[],
195
) => {
196
  node.type = 'CallExpression';
28,307✔
197
  node = node as es.CallExpression;
28,307✔
198
  node.callee = callee;
28,307✔
199
  node.arguments = args;
28,307✔
200
};
201

202
export const mutateToAssignmentExpression = (
65✔
203
  node: Node,
204
  left: es.Pattern,
205
  right: es.Expression,
206
) => {
NEW
207
  node.type = 'AssignmentExpression';
×
NEW
208
  node = node as es.AssignmentExpression;
×
NEW
209
  node.operator = '=';
×
NEW
210
  node.left = left;
×
NEW
211
  node.right = right;
×
212
};
213

214
export const mutateToExpressionStatement = (node: Node, expr: es.Expression) => {
65✔
NEW
215
  node.type = 'ExpressionStatement';
×
NEW
216
  node = node as es.ExpressionStatement;
×
NEW
217
  node.expression = expr;
×
218
};
219

220
export const mutateToReturnStatement = (node: Node, expr: es.Expression) => {
65✔
NEW
221
  node.type = 'ReturnStatement';
×
NEW
222
  node = node as es.ReturnStatement;
×
NEW
223
  node.argument = expr;
×
224
};
225

226
export const mutateToMemberExpression = (node: Node, obj: es.Expression, prop: es.Expression) => {
65✔
NEW
227
  node.type = 'MemberExpression';
×
NEW
228
  node = node as es.MemberExpression;
×
NEW
229
  node.object = obj;
×
NEW
230
  node.property = prop;
×
NEW
231
  node.computed = false;
×
232
};
233

234
export const logicalExpression = (
65✔
235
  operator: es.LogicalOperator,
236
  left: es.Expression,
237
  right: es.Expression,
238
  loc?: es.SourceLocation | null,
239
): es.LogicalExpression => ({
2,538✔
240
  type: 'LogicalExpression',
241
  operator,
242
  left,
243
  right,
244
  loc,
245
});
246

247
export const mutateToConditionalExpression = (
65✔
248
  node: Node,
249
  test: es.Expression,
250
  consequent: es.Expression,
251
  alternate: es.Expression,
252
) => {
NEW
253
  node.type = 'ConditionalExpression';
×
NEW
254
  node = node as es.ConditionalExpression;
×
NEW
255
  node.test = test;
×
NEW
256
  node.consequent = consequent;
×
NEW
257
  node.alternate = alternate;
×
258
};
259

260
export const conditionalExpression = (
65✔
261
  test: es.Expression,
262
  consequent: es.Expression,
263
  alternate: es.Expression,
264
  loc?: es.SourceLocation | null,
265
): es.ConditionalExpression => ({
21,709✔
266
  type: 'ConditionalExpression',
267
  test,
268
  consequent,
269
  alternate,
270
  loc,
271
});
272

273
export const arrayExpression = (elements: es.Expression[]): es.ArrayExpression => ({
21,951✔
274
  type: 'ArrayExpression',
275
  elements,
276
});
277

278
export const assignmentExpression = (
65✔
279
  left: es.Identifier | es.MemberExpression,
280
  right: es.Expression,
281
  loc?: es.SourceLocation | null,
282
): es.AssignmentExpression => ({
1,143✔
283
  type: 'AssignmentExpression',
284
  operator: '=',
285
  left,
286
  right,
287
  loc,
288
});
289

290
export const binaryExpression = (
65✔
291
  operator: es.BinaryOperator,
292
  left: es.Expression,
293
  right: es.Expression,
294
  loc?: es.SourceLocation | null,
295
): es.BinaryExpression => ({
×
296
  type: 'BinaryExpression',
297
  operator,
298
  left,
299
  right,
300
  loc,
301
});
302

303
export const unaryExpression = (
65✔
304
  operator: es.UnaryOperator,
305
  argument: es.Expression,
306
  loc?: es.SourceLocation | null,
307
): es.UnaryExpression => ({
×
308
  type: 'UnaryExpression',
309
  operator,
310
  prefix: true,
311
  argument,
312
  loc,
313
});
314

315
// primitive: undefined is a possible value
316
export const primitive = (value: any): es.Expression => {
65✔
317
  return value === undefined ? identifier('undefined') : literal(value);
610,586✔
318
};
319

320
export const functionDeclaration = (
65✔
321
  id: es.Identifier,
322
  params: es.Pattern[],
323
  body: es.BlockStatement,
324
  loc?: es.SourceLocation | null,
325
): es.FunctionDeclaration => ({
32✔
326
  type: 'FunctionDeclaration',
327
  id,
328
  params,
329
  body,
330
  loc,
331
});
332

333
export const arrowFunctionExpression = (
65✔
334
  params: es.Pattern[],
335
  body: es.Expression | es.BlockStatement,
336
  loc?: es.SourceLocation | null,
337
): es.ArrowFunctionExpression => ({
806✔
338
  type: 'ArrowFunctionExpression',
339
  expression: body.type !== 'BlockStatement',
340
  generator: false,
341
  params,
342
  body,
343
  loc,
344
});
345

346
export const variableDeclaration = (
65✔
347
  declarations: es.VariableDeclarator[],
348
  kind: es.VariableDeclaration['kind'] = 'const',
57,738✔
349
  loc?: es.SourceLocation | null,
350
): es.VariableDeclaration => ({
57,738✔
351
  type: 'VariableDeclaration',
352
  kind,
353
  declarations,
354
  loc,
355
});
356

357
export const variableDeclarator = (
65✔
358
  id: es.Pattern,
359
  init: es.Expression,
360
  loc?: es.SourceLocation | null,
361
): es.VariableDeclarator => ({
674✔
362
  type: 'VariableDeclarator',
363
  id,
364
  init,
365
  loc,
366
});
367

368
export const ifStatement = (
65✔
369
  test: es.Expression,
370
  consequent: es.BlockStatement,
371
  alternate: es.Statement,
372
  loc?: es.SourceLocation | null,
373
): es.IfStatement => ({
×
374
  type: 'IfStatement',
375
  test,
376
  consequent,
377
  alternate,
378
  loc,
379
});
380

381
export const whileStatement = (
65✔
382
  body: es.BlockStatement,
383
  test: es.Expression,
384
  loc?: es.SourceLocation | null,
385
): es.WhileStatement => ({
×
386
  type: 'WhileStatement',
387
  test,
388
  body,
389
  loc,
390
});
391

392
export const forStatement = (
65✔
393
  init: es.VariableDeclaration | es.Expression,
394
  test: es.Expression,
395
  update: es.Expression,
396
  body: es.Statement,
397
  loc?: es.SourceLocation | null,
398
): es.ForStatement => ({
337✔
399
  type: 'ForStatement',
400
  init,
401
  test,
402
  update,
403
  body,
404
  loc,
405
});
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