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

source-academy / js-slang / 12904208937

22 Jan 2025 08:32AM UTC coverage: 81.63% (-0.02%) from 81.654%
12904208937

Pull #1630

github

web-flow
Merge aa16b5a7d into 8ead9f26e
Pull Request #1630: Upgrade gl to v8, Prettier to v3

3654 of 4864 branches covered (75.12%)

Branch coverage included in aggregate %.

63 of 84 new or added lines in 13 files covered. (75.0%)

7 existing lines in 3 files now uncovered.

11499 of 13699 relevant lines covered (83.94%)

140593.93 hits per line

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

69.7
/src/errors/errors.ts
1
/* tslint:disable: max-classes-per-file */
2
/* tslint:disable:max-line-length */
3
import { baseGenerator, generate } from 'astring'
79✔
4
import * as es from 'estree'
5

6
import { UNKNOWN_LOCATION } from '../constants'
79✔
7
import { ErrorSeverity, ErrorType, Node, SourceError, Value } from '../types'
79✔
8
import { stringify } from '../utils/stringify'
79✔
9
import { RuntimeSourceError } from './runtimeSourceError'
79✔
10

11
//Wrap build-in function error in SourceError
12
export class BuiltInFunctionError extends RuntimeSourceError {
79✔
13
  constructor(private explanation: String) {
2✔
14
    super(undefined)
2✔
15
    this.explanation = explanation
2✔
16
  }
17

18
  public explain() {
19
    return `${this.explanation}`
2✔
20
  }
21

22
  public elaborate() {
23
    return this.explain()
×
24
  }
25
}
26

27
export class InterruptedError extends RuntimeSourceError {
79✔
28
  constructor(node: Node) {
29
    super(node)
×
30
  }
31

32
  public explain() {
33
    return 'Execution aborted by user.'
×
34
  }
35

36
  public elaborate() {
37
    return 'TODO'
×
38
  }
39
}
40

41
export class ExceptionError implements SourceError {
79✔
42
  public type = ErrorType.RUNTIME
149✔
43
  public severity = ErrorSeverity.ERROR
149✔
44
  public location: es.SourceLocation
45

46
  constructor(
47
    public error: Error,
149✔
48
    location?: es.SourceLocation | null
49
  ) {
50
    this.location = location ?? UNKNOWN_LOCATION
149✔
51
  }
52

53
  public explain() {
54
    return this.error.toString()
167✔
55
  }
56

57
  public elaborate() {
58
    return 'TODO'
28✔
59
  }
60
}
61

62
export class MaximumStackLimitExceeded extends RuntimeSourceError {
79✔
63
  public static MAX_CALLS_TO_SHOW = 3
79✔
64

65
  private customGenerator = {
15✔
66
    ...baseGenerator,
67
    CallExpression(node: any, state: any) {
68
      state.write(generate(node.callee))
45✔
69
      state.write('(')
45✔
70
      const argsRepr = node.arguments.map((arg: any) => stringify(arg.value))
51✔
71
      state.write(argsRepr.join(', '))
45✔
72
      state.write(')')
45✔
73
    }
74
  }
75

76
  constructor(
77
    node: Node,
78
    private calls: es.CallExpression[]
15✔
79
  ) {
80
    super(node)
15✔
81
  }
82

83
  public explain() {
84
    const repr = (call: es.CallExpression) => generate(call, { generator: this.customGenerator })
45✔
85
    return (
15✔
86
      'Maximum call stack size exceeded\n  ' + this.calls.map(call => repr(call) + '..').join('  ')
45✔
87
    )
88
  }
89

90
  public elaborate() {
91
    return 'TODO'
×
92
  }
93
}
94

95
export class CallingNonFunctionValue extends RuntimeSourceError {
79✔
96
  constructor(
97
    private callee: Value,
56✔
98
    private node: Node
56✔
99
  ) {
100
    super(node)
56✔
101
  }
102

103
  public explain() {
104
    return `Calling non-function value ${stringify(this.callee)}.`
56✔
105
  }
106

107
  public elaborate() {
108
    const calleeVal = this.callee
24✔
109
    const calleeStr = stringify(calleeVal)
24✔
110
    let argStr = ''
24✔
111

112
    const callArgs = (this.node as es.CallExpression).arguments
24✔
113

114
    argStr = callArgs.map(generate).join(', ')
24✔
115

116
    const elabStr = `Because ${calleeStr} is not a function, you cannot run ${calleeStr}(${argStr}).`
24✔
117
    const multStr = `If you were planning to perform multiplication by ${calleeStr}, you need to use the * operator.`
24✔
118

119
    if (Number.isFinite(calleeVal)) {
24✔
120
      return `${elabStr} ${multStr}`
4✔
121
    } else {
122
      return elabStr
20✔
123
    }
124
  }
125
}
126

127
export class UndefinedVariable extends RuntimeSourceError {
79✔
128
  constructor(
129
    public name: string,
261✔
130
    node: Node
131
  ) {
132
    super(node)
261✔
133
  }
134

135
  public explain() {
136
    return `Name ${this.name} not declared.`
31✔
137
  }
138

139
  public elaborate() {
140
    return `Before you can read the value of ${this.name}, you need to declare it as a variable or a constant. You can do this using the let or const keywords.`
4✔
141
  }
142
}
143

144
export class UnassignedVariable extends RuntimeSourceError {
79✔
145
  constructor(
146
    public name: string,
15✔
147
    node: Node
148
  ) {
149
    super(node)
15✔
150
  }
151

152
  public explain() {
153
    return `Name ${this.name} declared later in current scope but not yet assigned`
15✔
154
  }
155

156
  public elaborate() {
157
    return `If you're trying to access the value of ${this.name} from an outer scope, please rename the inner ${this.name}. An easy way to avoid this issue in future would be to avoid declaring any variables or constants with the name ${this.name} in the same scope.`
1✔
158
  }
159
}
160

161
export class InvalidNumberOfArguments extends RuntimeSourceError {
79✔
162
  private calleeStr: string
163

164
  constructor(
165
    node: Node,
166
    private expected: number,
61✔
167
    private got: number,
61✔
168
    private hasVarArgs = false
61✔
169
  ) {
170
    super(node)
61✔
171
    this.calleeStr = generate((node as es.CallExpression).callee)
61✔
172
  }
173

174
  public explain() {
175
    return `Expected ${this.expected} ${this.hasVarArgs ? 'or more ' : ''}arguments, but got ${
61✔
176
      this.got
177
    }.`
178
  }
179

180
  public elaborate() {
181
    const calleeStr = this.calleeStr
15✔
182
    const pluralS = this.expected === 1 ? '' : 's'
15✔
183

184
    return `Try calling function ${calleeStr} again, but with ${this.expected} argument${pluralS} instead. Remember that arguments are separated by a ',' (comma).`
15✔
185
  }
186
}
187

188
export class VariableRedeclaration extends RuntimeSourceError {
79✔
189
  constructor(
NEW
190
    private node: Node,
×
NEW
191
    private name: string,
×
NEW
192
    private writable?: boolean
×
193
  ) {
UNCOV
194
    super(node)
×
195
  }
196

197
  public explain() {
198
    return `Redeclaring name ${this.name}.`
×
199
  }
200

201
  public elaborate() {
202
    if (this.writable === true) {
×
203
      const elabStr = `Since ${this.name} has already been declared, you can assign a value to it without re-declaring.`
×
204

205
      let initStr = ''
×
206

207
      if (this.node.type === 'FunctionDeclaration') {
×
208
        initStr =
×
209
          '(' + (this.node as es.FunctionDeclaration).params.map(generate).join(',') + ') => {...'
210
      } else if (this.node.type === 'VariableDeclaration') {
×
211
        initStr = generate((this.node as es.VariableDeclaration).declarations[0].init)
×
212
      }
213

214
      return `${elabStr} As such, you can just do\n\n\t${this.name} = ${initStr};\n`
×
215
    } else if (this.writable === false) {
×
216
      return `You will need to declare another variable, as ${this.name} is read-only.`
×
217
    } else {
218
      return ''
×
219
    }
220
  }
221
}
222

223
export class ConstAssignment extends RuntimeSourceError {
79✔
224
  constructor(
225
    node: Node,
226
    private name: string
13✔
227
  ) {
228
    super(node)
13✔
229
  }
230

231
  public explain() {
232
    return `Cannot assign new value to constant ${this.name}.`
13✔
233
  }
234

235
  public elaborate() {
236
    return `As ${this.name} was declared as a constant, its value cannot be changed. You will have to declare a new variable.`
4✔
237
  }
238
}
239

240
export class GetPropertyError extends RuntimeSourceError {
79✔
241
  constructor(
242
    node: Node,
NEW
243
    private obj: Value,
×
NEW
244
    private prop: string
×
245
  ) {
UNCOV
246
    super(node)
×
247
  }
248

249
  public explain() {
250
    return `Cannot read property ${this.prop} of ${stringify(this.obj)}.`
×
251
  }
252

253
  public elaborate() {
254
    return 'TODO'
×
255
  }
256
}
257

258
export class GetInheritedPropertyError extends RuntimeSourceError {
79✔
259
  public type = ErrorType.RUNTIME
2✔
260
  public severity = ErrorSeverity.ERROR
2✔
261
  public location: es.SourceLocation
262

263
  constructor(
264
    node: Node,
265
    private obj: Value,
2✔
266
    private prop: string
2✔
267
  ) {
268
    super(node)
2✔
269
    this.location = node.loc ?? UNKNOWN_LOCATION
2!
270
  }
271

272
  public explain() {
273
    return `Cannot read inherited property ${this.prop} of ${stringify(this.obj)}.`
2✔
274
  }
275

276
  public elaborate() {
277
    return 'TODO'
×
278
  }
279
}
280

281
export class SetPropertyError extends RuntimeSourceError {
79✔
282
  constructor(
283
    node: Node,
NEW
284
    private obj: Value,
×
NEW
285
    private prop: string
×
286
  ) {
UNCOV
287
    super(node)
×
288
  }
289

290
  public explain() {
291
    return `Cannot assign property ${this.prop} of ${stringify(this.obj)}.`
×
292
  }
293

294
  public elaborate() {
295
    return 'TODO'
×
296
  }
297
}
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