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

Siubaak / sval / 14771539826

01 May 2025 07:10AM UTC coverage: 73.748% (+8.3%) from 65.487%
14771539826

push

github

Siubaak
[update] rollup -> vite

753 of 922 branches covered (81.67%)

Branch coverage included in aggregate %.

60 of 60 new or added lines in 12 files covered. (100.0%)

358 existing lines in 15 files now uncovered.

2545 of 3550 relevant lines covered (71.69%)

932.53 hits per line

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

57.71
/src/evaluate/declaration.ts
1
import { NOINIT, DEADZONE, PRIVATE, IMPORT, EXPORTS } from '../share/const.ts'
1✔
2
import { define, getDptor, assign, hasOwn } from '../share/util.ts'
1✔
3
import { pattern, createFunc, createClass } from './helper.ts'
1✔
4
import { BlockStatement } from './statement.ts'
1✔
5
import { VarKind } from '../scope/variable.ts'
6
import Scope from '../scope/index.ts'
1✔
7
import evaluate from './index.ts'
1✔
8
import * as acorn from 'acorn'
9

10
export function* FunctionDeclaration(
1✔
11
  node: acorn.FunctionDeclaration,
3✔
12
  scope: Scope
3✔
13
): IterableIterator<any> {
3✔
14
  scope.func(node.id.name, createFunc(node, scope))
3✔
15
}
3✔
16

17
export interface VariableDeclarationOptions {
18
  hoist?: boolean
19
  onlyBlock?: boolean
20
  feed?: any
21
}
22

23
export function* VariableDeclaration(
1✔
24
  node: acorn.VariableDeclaration,
175✔
25
  scope: Scope,
175✔
26
  options: VariableDeclarationOptions = {},
175✔
27
) {
175✔
28
  for (let i = 0; i < node.declarations.length; i++) {
175✔
29
    yield* VariableDeclarator(node.declarations[i], scope, assign({ kind: node.kind }, options))
186✔
30
  }
186✔
31
}
175✔
32

33
export interface VariableDeclaratorOptions {
34
  kind?: VarKind
35
}
36

37
export function* VariableDeclarator(
1✔
38
  node: acorn.VariableDeclarator,
186✔
39
  scope: Scope,
186✔
40
  options: VariableDeclaratorOptions & VariableDeclarationOptions = {},
186✔
41
) {
186✔
42
  const { kind = 'var', hoist = false, onlyBlock = false, feed } = options
186✔
43
  if (hoist) {
186✔
44
    if (onlyBlock || kind === 'var') {
75✔
45
      if (node.id.type === 'Identifier') {
55✔
46
        scope[kind](node.id.name, onlyBlock ? DEADZONE : kind === 'var' ? NOINIT : undefined)
46✔
47
      } else {
55✔
48
        yield* pattern(node.id, scope, { kind, hoist, onlyBlock })
9✔
49
      }
9✔
50
    }
55✔
51
  } else {
183✔
52
    const hasFeed = 'feed' in options
111✔
53
    const value = hasFeed ? feed : yield* evaluate(node.init, scope)
111✔
54
    if (node.id.type === 'Identifier') {
111✔
55
      const name = node.id.name
102✔
56
      if (kind === 'var' && !node.init && !hasFeed) {
102✔
57
        scope.var(name, NOINIT)
5✔
58
      } else {
102✔
59
        scope[kind](name, value)
97✔
60
      }
97✔
61
      if (
102✔
62
        node.init
102✔
63
        && ['ClassExpression', 'FunctionExpression', 'ArrowFunctionExpression']
41✔
64
          .indexOf(node.init.type) !== -1
41✔
65
        && !value.name
9✔
66
      ) {
102✔
67
        define(value, 'name', {
9✔
68
          value: name,
9✔
69
          configurable: true
9✔
70
        })
9✔
71
      }
9✔
72
    } else {
111✔
73
      yield* pattern(node.id, scope, { kind, feed: value })
9✔
74
    }
9✔
75
  }
111✔
76
}
186✔
77

78
export function* ClassDeclaration(
1✔
UNCOV
79
  node: acorn.ClassDeclaration,
×
UNCOV
80
  scope: Scope
×
UNCOV
81
): IterableIterator<any> {
×
82
  scope.func(node.id.name, yield* createClass(node, scope))
×
UNCOV
83
}
×
84

85
export interface ClassOptions {
86
  klass?: any,
87
  superClass?: (...args: any[]) => void
88
}
89

90
export function* ClassBody(node: acorn.ClassBody, scope: Scope, options: ClassOptions = {}) {
1✔
91
  const { klass, superClass } = options
×
92

93
  for (let i = 0; i < node.body.length; i++) {
×
94
    const def = node.body[i]
×
95
    if (def.type === 'MethodDefinition') {
×
96
      yield* MethodDefinition(def, scope, { klass, superClass })
×
97
    } else if (def.type === 'PropertyDefinition' && def.static) {
×
98
      yield* PropertyDefinition(def, scope, { klass, superClass })
×
99
    } else if (def.type === 'StaticBlock') {
×
100
      yield* StaticBlock(def, scope, { klass, superClass })
×
UNCOV
101
    }
×
UNCOV
102
  }
×
UNCOV
103
}
×
104

105
export function* MethodDefinition(node: acorn.MethodDefinition, scope: Scope, options: ClassOptions = {}) {
1✔
106
  const { klass, superClass } = options
×
107

UNCOV
108
  let key: string
×
109
  let priv: boolean = false
×
110

111
  if (node.computed) {
×
112
    key = yield* evaluate(node.key, scope)
×
113
  } else if (node.key.type === 'Identifier') {
×
114
    key = node.key.name
×
115
  } else if (node.key.type === 'PrivateIdentifier') {
×
116
    key = node.key.name
×
117
    priv = true
×
UNCOV
118
  } else {
×
119
    throw new SyntaxError('Unexpected token')
×
UNCOV
120
  }
×
121

122
  let obj = node.static ? klass : klass.prototype
×
123

124
  if (priv) {
×
125
    if (!obj[PRIVATE]) {
×
126
      define(obj, PRIVATE, { value: {} })
×
UNCOV
127
    }
×
128
    obj = obj[PRIVATE]
×
UNCOV
129
  }
×
130

131
  const value = createFunc(node.value, scope, { superClass })
×
132

133
  switch (node.kind) {
×
UNCOV
134
    case 'constructor':
×
135
      break
×
UNCOV
136
    case 'method':
×
137
      define(obj, key, {
×
UNCOV
138
        value,
×
UNCOV
139
        writable: true,
×
UNCOV
140
        configurable: true,
×
UNCOV
141
      })
×
142
      break
×
UNCOV
143
    case 'get': {
×
144
      const oriDptor = getDptor(obj, key)
×
145
      define(obj, key, {
×
UNCOV
146
        get: value,
×
UNCOV
147
        set: oriDptor && oriDptor.set,
×
UNCOV
148
        configurable: true,
×
UNCOV
149
      })
×
150
      break
×
UNCOV
151
    }
×
UNCOV
152
    case 'set': {
×
153
      const oriDptor = getDptor(obj, key)
×
154
      define(obj, key, {
×
UNCOV
155
        get: oriDptor && oriDptor.get,
×
UNCOV
156
        set: value,
×
UNCOV
157
        configurable: true,
×
UNCOV
158
      })
×
159
      break
×
UNCOV
160
    }
×
UNCOV
161
    default:
×
162
      throw new SyntaxError('Unexpected token')
×
UNCOV
163
  } 
×
UNCOV
164
}
×
165

166
export function* PropertyDefinition(node: acorn.PropertyDefinition, scope: Scope, options: ClassOptions = {}) {
1✔
167
  const { klass, superClass } = options
×
168

UNCOV
169
  let key: string
×
170
  let priv: boolean = false
×
171

172
  if (node.computed) {
×
173
    key = yield* evaluate(node.key, scope)
×
174
  } else if (node.key.type === 'Identifier') {
×
175
    key = node.key.name
×
176
  } else if (node.key.type === 'PrivateIdentifier') {
×
177
    key = node.key.name
×
178
    priv = true
×
UNCOV
179
  } else {
×
180
    throw new SyntaxError('Unexpected token')
×
UNCOV
181
  }
×
182

183
  const subScope: Scope = new Scope(scope, true)
×
184
  subScope.const('this', klass)
×
185

186
  let obj = klass
×
187

188
  if (priv) {
×
189
    if (!obj[PRIVATE]) {
×
190
      define(obj, PRIVATE, { value: {} })
×
UNCOV
191
    }
×
192
    obj = obj[PRIVATE]
×
UNCOV
193
  }
×
194

195
  if (!node.value) {
×
196
    obj[key] = undefined
×
197
  } else if (node.value.type === 'FunctionExpression' || node.value.type === 'ArrowFunctionExpression') {
×
198
    obj[key] = createFunc(node.value, subScope, { superClass })
×
UNCOV
199
  } else {
×
200
    obj[key] = yield* evaluate(node.value, subScope)
×
UNCOV
201
  }
×
UNCOV
202
}
×
203

204
export function* StaticBlock(node: acorn.StaticBlock, scope: Scope, options: ClassOptions = {}) {
1✔
205
  const { klass } = options
×
206

207
  const subScope: Scope = new Scope(scope, true)
×
208
  subScope.const('this', klass)
×
209

210
  return yield* BlockStatement(node, subScope, { invasived: true })
×
UNCOV
211
}
×
212

213
export function* ImportDeclaration(node: acorn.ImportDeclaration, scope: Scope) {
1✔
214
  const globalScope = scope.global()
7✔
215

216
  const module = globalScope.find(IMPORT + node.source.value)
7✔
217
  let value: any
7✔
218
  if (module) {
7✔
219
    const result = module.get()
7✔
220
    if (result) {
7✔
221
      if (typeof result === 'function') {
7✔
222
        value = result()
2✔
223
      } else if (typeof result === 'object') {
7✔
224
        value = result
5✔
225
      }
5✔
226
    }
7✔
227
  }
7✔
228

229
  if (!value || typeof value !== 'object') {
7!
230
    throw new TypeError(`Failed to resolve module specifier "${node.source.value}"`)
×
UNCOV
231
  }
×
232

233
  for (let i = 0; i < node.specifiers.length; i++) {
7✔
234
    const spec = node.specifiers[i]
8✔
235
    let name: string
8✔
236
    if (spec.type === 'ImportSpecifier') {
8✔
237
      name = spec.imported.type === 'Identifier'
1✔
238
        ? spec.imported.name : spec.imported.value as string
1!
239
    } else if (spec.type === 'ImportDefaultSpecifier') {
8✔
240
      name = 'default'
6✔
241
    } else if (spec.type === 'ImportNamespaceSpecifier') {
7✔
242
      name = '*'
1✔
243
    }
1✔
244
    if (name !== '*' && !hasOwn(value, name)) {
8✔
245
      throw new SyntaxError(`The requested module "${node.source.value}" does not provide an export named "${name}"`)
×
UNCOV
246
    }
×
247
    scope.var(spec.local.name, name === '*' ? assign({}, value) : value[name])
8✔
248
  }
8✔
249
}
7✔
250

251
export function* ExportDefaultDeclaration(node: acorn.ExportDefaultDeclaration, scope: Scope) {
1✔
252
  const globalScope = scope.global()
×
253

UNCOV
254
  let value: any
×
255
  if (node.declaration.type === 'FunctionDeclaration') {
×
256
    value = createFunc(node.declaration, scope)
×
257
    scope.func(node.declaration.id.name, value)
×
258
  } else if (node.declaration.type === 'ClassDeclaration') {
×
259
    value = yield* createClass(node.declaration, scope)
×
260
    scope.func(node.declaration.id.name, value)
×
UNCOV
261
  } else {
×
262
    value = yield* evaluate(node.declaration, scope)
×
UNCOV
263
  }
×
264

265
  const variable = globalScope.find(EXPORTS)
×
266
  if (variable) {
×
267
    const exports = variable.get()
×
268
    if (exports && typeof exports === 'object') {
×
269
      exports.default = value
×
UNCOV
270
    }
×
UNCOV
271
  }
×
UNCOV
272
}
×
273

274
export function* ExportNamedDeclaration(node: acorn.ExportNamedDeclaration, scope: Scope) {
1✔
275
  const globalScope = scope.global()
3✔
276

277
  if (node.declaration) {
3✔
278
    if (node.declaration.type === 'FunctionDeclaration') {
2✔
279
      const value = createFunc(node.declaration, scope)
1✔
280
      scope.func(node.declaration.id.name, value)
1✔
281
      const variable = globalScope.find(EXPORTS)
1✔
282
      if (variable) {
1✔
283
        const exports = variable.get()
1✔
284
        if (exports && typeof exports === 'object') {
1✔
285
          exports[node.declaration.id.name] = value
1✔
286
        }
1✔
287
      }
1✔
288
    } else if (node.declaration.type === 'ClassDeclaration') {
1!
289
      const value = yield* createClass(node.declaration, scope)
×
290
      scope.func(node.declaration.id.name, value)
×
291
      const variable = globalScope.find(EXPORTS)
×
292
      if (variable) {
×
293
        const exports = variable.get()
×
294
        if (exports && typeof exports === 'object') {
×
295
          exports[node.declaration.id.name] = value
×
UNCOV
296
        }
×
UNCOV
297
      }
×
298
    } else if (node.declaration.type === 'VariableDeclaration') {
1✔
299
      yield* VariableDeclaration(node.declaration, scope)
1✔
300
      const variable = globalScope.find(EXPORTS)
1✔
301
      if (variable) {
1✔
302
        const exports = variable.get()
1✔
303
        if (exports && typeof exports === 'object') {
1✔
304
          for (let i = 0; i < node.declaration.declarations.length; i++) {
1✔
305
            const name = (node.declaration.declarations[i].id as acorn.Identifier).name
2✔
306
            const item = scope.find(name)
2✔
307
            if (item) {
2✔
308
              exports[name] = item.get()
2✔
309
            }
2✔
310
          }
2✔
311
        }
1✔
312
      }
1✔
313
    }
1✔
314
  } else if (node.specifiers) {
3✔
315
    const variable = globalScope.find(EXPORTS)
1✔
316
    if (variable) {
1✔
317
      const exports = variable.get()
1✔
318
      if (exports && typeof exports === 'object') {
1✔
319
        for (let i = 0; i < node.specifiers.length; i++) {
1✔
320
          const spec = node.specifiers[i]
1✔
321
          const name = spec.local.type === 'Identifier'
1✔
322
            ? spec.local.name : spec.local.value as string
1!
323
          const item = scope.find(name)
1✔
324
          if (item) {
1✔
325
            exports[
1✔
326
              spec.exported.type === 'Identifier'
1✔
327
                ? spec.exported.name : spec.exported.value as string
1!
328
            ] = item.get()
1✔
329
          }
1✔
330
        }
1✔
331
      }
1✔
332
    }
1✔
333
  }
1✔
334
}
3✔
335

336
export function* ExportAllDeclaration(node: acorn.ExportAllDeclaration, scope: Scope) {
1✔
337
  const globalScope = scope.global()
1✔
338

339
  const module = globalScope.find(IMPORT + node.source.value)
1✔
340
  let value: any
1✔
341
  if (module) {
1✔
342
    const result = module.get()
1✔
343
    if (result) {
1✔
344
      if (typeof result === 'function') {
1✔
345
        value = result()
1✔
346
      } else if (typeof result === 'object') {
1!
347
        value = result
×
UNCOV
348
      }
×
349
    }
1✔
350
  }
1✔
351

352
  if (!value || typeof value !== 'object') {
1!
353
    throw new TypeError(`Failed to resolve module specifier "${node.source.value}"`)
×
UNCOV
354
  }
×
355

356
  const variable = globalScope.find(EXPORTS)
1✔
357
  if (variable) {
1✔
358
    const exports = variable.get()
1✔
359
    if (exports && typeof exports === 'object') {
1✔
360
      assign(exports, value)
1✔
361
    }
1✔
362
  }
1✔
363
}
1✔
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