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

source-academy / js-slang / 22701253621

05 Mar 2026 03:44AM UTC coverage: 75.716% (-0.9%) from 76.655%
22701253621

Pull #1907

github

web-flow
Merge 6fd6773cc into 4dd96b380
Pull Request #1907: Scm remove

3139 of 4310 branches covered (72.83%)

Branch coverage included in aggregate %.

7 of 7 new or added lines in 5 files covered. (100.0%)

10 existing lines in 4 files now uncovered.

6299 of 8155 relevant lines covered (77.24%)

176525.65 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!
UNCOV
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 => {
39
    node.elements = node.elements.map(x => (x ? transform(x) : null))
×
40
    return node
×
41
  },
42
  ArrowFunctionExpression: node => {
43
    node.params = node.params.map(transform)
×
44
    node.body = transform(node.body)
×
45
    return node
×
46
  },
47
  AssignmentExpression: ['left', 'right'],
48
  BinaryExpression: ['left', 'right'],
49
  BlockStatement: node => {
50
    node.body = node.body.map(transform)
×
51
    if (hasNoDeclarations(node.body)) {
×
52
      return ast.statementSequence(node.body, node.loc)
×
53
    } else {
54
      return node
×
55
    }
56
  },
57
  BreakStatement: 'label',
58
  CallExpression: node => {
59
    node.callee = transform(node.callee)
×
60
    node.arguments = node.arguments.map(transform)
×
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) {
×
69
      node.declaration = transform(node.declaration)
×
70
    }
71
    node.specifiers = node.specifiers.map(x => transform(x))
×
72
    if (node.source) {
×
73
      transform(node.source)
×
74
    }
75
    return node
×
76
  },
77
  ExportSpecifier: ['exported', 'local'],
78
  ExpressionStatement: 'expression',
79
  ForStatement: ['body', 'init', 'test', 'update'],
80
  FunctionDeclaration: node => {
81
    node.params = node.params.map(transform)
×
82
    node.body = transform(node.body)
×
83
    if (node.id) {
×
84
      node.id = transform(node.id)
×
85
    }
86
    return node
×
87
  },
88
  FunctionExpression: node => {
89
    if (node.id) {
×
90
      node.id = transform(node.id)
×
91
    }
92
    node.params = node.params.map(transform)
×
93
    node.body = transform(node.body)
×
94
    return node
×
95
  },
96
  IfStatement: ['alternate', 'consequent', 'test'],
97
  ImportDeclaration: node => {
98
    node.specifiers = node.specifiers.map(transform)
×
99
    node.source = transform(node.source)
×
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 => {
108
    node.arguments = node.arguments.map(transform)
×
109
    return node
×
110
  },
111
  ObjectExpression: node => {
112
    node.properties = node.properties.map(transform)
×
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 => {
127
    node.body = node.body.map(transform)
×
128
    return node
×
129
  },
130
  ThrowStatement: 'argument',
131
  TryStatement: ['block', 'finalizer', 'handler'],
132
  UnaryExpression: 'argument',
133
  VariableDeclarator: ['id', 'init'],
134
  VariableDeclaration: node => {
135
    node.declarations = node.declarations.map(transform)
×
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':
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

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
155
    node[prop!] = transform(node[prop])
×
156
  }
157

158
  return node
×
159
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc