|
13 | 13 | const { |
14 | 14 | ArrayBufferIsView, |
15 | 15 | ArrayPrototypeIncludes, |
16 | | - ArrayPrototypePush, |
17 | 16 | ArrayPrototypeSort, |
18 | 17 | MathPow, |
19 | 18 | MathTrunc, |
@@ -67,37 +66,7 @@ function toNumber(value, opts = kEmptyObject) { |
67 | 66 | } |
68 | 67 | } |
69 | 68 |
|
70 | | -function type(V) { |
71 | | - if (V === null) |
72 | | - return 'Null'; |
73 | | - |
74 | | - switch (typeof V) { |
75 | | - case 'undefined': |
76 | | - return 'Undefined'; |
77 | | - case 'boolean': |
78 | | - return 'Boolean'; |
79 | | - case 'number': |
80 | | - return 'Number'; |
81 | | - case 'string': |
82 | | - return 'String'; |
83 | | - case 'symbol': |
84 | | - return 'Symbol'; |
85 | | - case 'bigint': |
86 | | - return 'BigInt'; |
87 | | - case 'object': // Fall through |
88 | | - case 'function': // Fall through |
89 | | - default: |
90 | | - // Per ES spec, typeof returns an implementation-defined value that is not |
91 | | - // any of the existing ones for uncallable non-standard exotic objects. |
92 | | - // Yet Type() which the Web IDL spec depends on returns Object for such |
93 | | - // cases. So treat the default case as an object. |
94 | | - return 'Object'; |
95 | | - } |
96 | | -} |
97 | | - |
98 | 69 | // Fast check for the WebIDL Object type: a non-null object or a function. |
99 | | -// Equivalent to `type(V) === 'Object'` but avoids allocating and comparing |
100 | | -// the intermediate string tag on hot paths. |
101 | 70 | function isObjectType(V) { |
102 | 71 | return V !== null && (typeof V === 'object' || typeof V === 'function'); |
103 | 72 | } |
@@ -271,61 +240,59 @@ function createDictionaryConverter(name, dictionaries) { |
271 | 240 | if (member.required) { |
272 | 241 | hasRequiredKey = true; |
273 | 242 | } |
274 | | - ArrayPrototypePush(allMembers, member); |
| 243 | + allMembers[i] = member; |
275 | 244 | } |
276 | 245 | ArrayPrototypeSort(allMembers, (a, b) => { |
277 | 246 | if (a.key === b.key) { |
278 | 247 | return 0; |
279 | 248 | } |
280 | 249 | return a.key < b.key ? -1 : 1; |
281 | 250 | }); |
| 251 | + const membersLength = allMembers.length; |
282 | 252 |
|
283 | 253 | return function(V, opts = kEmptyObject) { |
284 | | - const typeV = type(V); |
285 | | - switch (typeV) { |
286 | | - case 'Undefined': |
287 | | - case 'Null': |
288 | | - case 'Object': |
289 | | - break; |
290 | | - default: |
291 | | - throw makeException( |
292 | | - 'can not be converted to a dictionary', |
293 | | - opts); |
| 254 | + let isNullish; |
| 255 | + if (V === undefined || V === null) { |
| 256 | + isNullish = true; |
| 257 | + } else if (typeof V === 'object' || typeof V === 'function') { |
| 258 | + isNullish = false; |
| 259 | + } else { |
| 260 | + throw makeException( |
| 261 | + 'can not be converted to a dictionary', |
| 262 | + opts); |
294 | 263 | } |
295 | | - const esDict = V; |
| 264 | + |
296 | 265 | const idlDict = {}; |
297 | 266 |
|
298 | 267 | // Fast path null and undefined. |
299 | | - if (V == null && !hasRequiredKey) { |
| 268 | + if (isNullish && !hasRequiredKey) { |
300 | 269 | return idlDict; |
301 | 270 | } |
302 | 271 |
|
303 | | - for (let i = 0; i < allMembers.length; i++) { |
| 272 | + const prefix = opts.prefix; |
| 273 | + const outerContext = opts.context; |
| 274 | + |
| 275 | + for (let i = 0; i < membersLength; i++) { |
304 | 276 | const member = allMembers[i]; |
305 | 277 | const key = member.key; |
306 | 278 |
|
307 | | - let esMemberValue; |
308 | | - if (typeV === 'Undefined' || typeV === 'Null') { |
309 | | - esMemberValue = undefined; |
310 | | - } else { |
311 | | - esMemberValue = esDict[key]; |
312 | | - } |
| 279 | + const esMemberValue = isNullish ? undefined : V[key]; |
313 | 280 |
|
314 | 281 | if (esMemberValue !== undefined) { |
315 | | - const context = `'${key}' of '${name}'${ |
316 | | - opts.context ? ` (${opts.context})` : '' |
317 | | - }`; |
| 282 | + const context = outerContext ? |
| 283 | + `'${key}' of '${name}' (${outerContext})` : |
| 284 | + `'${key}' of '${name}'`; |
318 | 285 | const idlMemberValue = member.converter(esMemberValue, { |
319 | 286 | __proto__: null, |
320 | | - prefix: opts.prefix, |
| 287 | + prefix, |
321 | 288 | context, |
322 | 289 | }); |
323 | | - member.validator?.(idlMemberValue, esDict); |
| 290 | + member.validator?.(idlMemberValue, V); |
324 | 291 | setOwnProperty(idlDict, key, idlMemberValue); |
325 | 292 | } else if (member.required) { |
326 | 293 | throw makeException( |
327 | 294 | `can not be converted to '${name}' because '${key}' is required in '${name}'.`, |
328 | | - { __proto__: null, prefix: opts.prefix, context: opts.context, code: 'ERR_MISSING_OPTION' }); |
| 295 | + { __proto__: null, prefix, context: outerContext, code: 'ERR_MISSING_OPTION' }); |
329 | 296 | } |
330 | 297 | } |
331 | 298 |
|
|
0 commit comments