• 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

22.08
/src/utils/statementSeqTransform.ts
1
import type es from 'estree';
2
import type { Node, NodeTypeToNode } from '../types';
3
import * as ast from './ast/astCreator';
4
import { hasNoDeclarations } from './ast/helpers';
5

6
function hasImportDeclarations(node: es.Program): boolean {
7
  for (const statement of node.body) {
836✔
8
    if (statement.type === 'ImportDeclaration') {
19,813!
NEW
9
      return true;
×
10
    }
11
  }
12
  return false;
836✔
13
}
14

15
/**
16
 * Utility type for getting all the keys of a ControlItem that have values
17
 * that are assignable to Nodes
18
 */
19
type GetNodeKeys<T extends Node> = {
20
  [K in keyof T as T[K] extends Node | null | undefined ? K : never]: K;
21
};
22
/**
23
 * Extracts all the keys of a ControlItem that have values that are assignable to Nodes
24
 * as a union
25
 */
26
type KeysOfNodeProperties<T extends Node> = GetNodeKeys<T>[keyof GetNodeKeys<T>];
27

28
type NodeTransformer<T extends Node> =
29
  | KeysOfNodeProperties<T>
30
  | KeysOfNodeProperties<T>[]
31
  | ((node: T) => Node);
32

33
type NodeTransformers = {
34
  [K in Node['type']]?: NodeTransformer<NodeTypeToNode<K>>;
35
};
36

37
const transformers: NodeTransformers = {
65✔
38
  ArrayExpression: node => {
NEW
39
    node.elements = node.elements.map(x => (x ? transform(x) : null));
×
NEW
40
    return node;
×
41
  },
42
  ArrowFunctionExpression: node => {
NEW
43
    node.params = node.params.map(transform);
×
NEW
44
    node.body = transform(node.body);
×
NEW
45
    return node;
×
46
  },
47
  AssignmentExpression: ['left', 'right'],
48
  BinaryExpression: ['left', 'right'],
49
  BlockStatement: node => {
NEW
50
    node.body = node.body.map(transform);
×
51
    if (hasNoDeclarations(node.body)) {
×
NEW
52
      return ast.statementSequence(node.body, node.loc);
×
53
    } else {
NEW
54
      return node;
×
55
    }
56
  },
57
  BreakStatement: 'label',
58
  CallExpression: node => {
NEW
59
    node.callee = transform(node.callee);
×
NEW
60
    node.arguments = node.arguments.map(transform);
×
NEW
61
    return node;
×
62
  },
63
  ClassDeclaration: ['body', 'id', 'superClass'],
64
  ConditionalExpression: ['alternate', 'consequent', 'test'],
65
  ContinueStatement: 'label',
66
  ExportDefaultDeclaration: 'declaration',
67
  ExportNamedDeclaration: node => {
68
    if (node.declaration) {
×
NEW
69
      node.declaration = transform(node.declaration);
×
70
    }
NEW
71
    node.specifiers = node.specifiers.map(x => transform(x));
×
72
    if (node.source) {
×
NEW
73
      transform(node.source);
×
74
    }
NEW
75
    return node;
×
76
  },
77
  ExportSpecifier: ['exported', 'local'],
78
  ExpressionStatement: 'expression',
79
  ForStatement: ['body', 'init', 'test', 'update'],
80
  FunctionDeclaration: node => {
NEW
81
    node.params = node.params.map(transform);
×
NEW
82
    node.body = transform(node.body);
×
83
    if (node.id) {
×
NEW
84
      node.id = transform(node.id);
×
85
    }
NEW
86
    return node;
×
87
  },
88
  FunctionExpression: node => {
89
    if (node.id) {
×
NEW
90
      node.id = transform(node.id);
×
91
    }
NEW
92
    node.params = node.params.map(transform);
×
NEW
93
    node.body = transform(node.body);
×
NEW
94
    return node;
×
95
  },
96
  IfStatement: ['alternate', 'consequent', 'test'],
97
  ImportDeclaration: node => {
NEW
98
    node.specifiers = node.specifiers.map(transform);
×
NEW
99
    node.source = transform(node.source);
×
NEW
100
    return node;
×
101
  },
102
  ImportDefaultSpecifier: 'local',
103
  ImportSpecifier: ['imported', 'local'],
104
  LogicalExpression: ['left', 'right'],
105
  MemberExpression: ['object', 'property'],
106
  MethodDefinition: ['key', 'value'],
107
  NewExpression: node => {
NEW
108
    node.arguments = node.arguments.map(transform);
×
NEW
109
    return node;
×
110
  },
111
  ObjectExpression: node => {
NEW
112
    node.properties = node.properties.map(transform);
×
NEW
113
    return node;
×
114
  },
115
  Program: node => {
116
    if (!hasNoDeclarations(node.body) && !hasImportDeclarations(node)) {
923✔
117
      return ast.statementSequence(node.body as es.Statement[], node.loc);
836✔
118
    } else {
119
      return node;
87✔
120
    }
121
  },
122
  Property: ['key', 'value'],
123
  RestElement: 'argument',
124
  ReturnStatement: 'argument',
125
  SpreadElement: 'argument',
126
  StatementSequence: node => {
NEW
127
    node.body = node.body.map(transform);
×
NEW
128
    return node;
×
129
  },
130
  ThrowStatement: 'argument',
131
  TryStatement: ['block', 'finalizer', 'handler'],
132
  UnaryExpression: 'argument',
133
  VariableDeclarator: ['id', 'init'],
134
  VariableDeclaration: node => {
NEW
135
    node.declarations = node.declarations.map(transform);
×
NEW
136
    return node;
×
137
  },
138
  WhileStatement: ['body', 'test'],
139
};
140

141
export function transform<NodeType extends Node>(node: NodeType): NodeType {
142
  const transformer = transformers[node.type];
923✔
143

144
  switch (typeof transformer) {
923!
145
    case 'undefined':
NEW
146
      return node;
×
147
    case 'function':
148
      // @ts-expect-error Node type gets narrowed to never
149
      return transformer(node) as NodeType;
923✔
150
  }
151

NEW
152
  const properties = typeof transformer === 'string' ? [transformer] : transformer;
×
153
  for (const prop of properties) {
923✔
154
    // @ts-expect-error Weird typescript shennenigans going on here don't mind this
NEW
155
    node[prop!] = transform(node[prop]);
×
156
  }
157

NEW
158
  return node;
×
159
}
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