|
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 | } |
@@ -251,61 +220,59 @@ function createDictionaryConverter(name, dictionaries) { |
251 | 220 | if (member.required) { |
252 | 221 | hasRequiredKey = true; |
253 | 222 | } |
254 | | - ArrayPrototypePush(allMembers, member); |
| 223 | + allMembers[i] = member; |
255 | 224 | } |
256 | 225 | ArrayPrototypeSort(allMembers, (a, b) => { |
257 | 226 | if (a.key === b.key) { |
258 | 227 | return 0; |
259 | 228 | } |
260 | 229 | return a.key < b.key ? -1 : 1; |
261 | 230 | }); |
| 231 | + const membersLength = allMembers.length; |
262 | 232 |
|
263 | 233 | return function(V, opts = kEmptyObject) { |
264 | | - const typeV = type(V); |
265 | | - switch (typeV) { |
266 | | - case 'Undefined': |
267 | | - case 'Null': |
268 | | - case 'Object': |
269 | | - break; |
270 | | - default: |
271 | | - throw makeException( |
272 | | - 'can not be converted to a dictionary', |
273 | | - opts); |
| 234 | + let isNullish; |
| 235 | + if (V === undefined || V === null) { |
| 236 | + isNullish = true; |
| 237 | + } else if (typeof V === 'object' || typeof V === 'function') { |
| 238 | + isNullish = false; |
| 239 | + } else { |
| 240 | + throw makeException( |
| 241 | + 'can not be converted to a dictionary', |
| 242 | + opts); |
274 | 243 | } |
275 | | - const esDict = V; |
| 244 | + |
276 | 245 | const idlDict = {}; |
277 | 246 |
|
278 | 247 | // Fast path null and undefined. |
279 | | - if (V == null && !hasRequiredKey) { |
| 248 | + if (isNullish && !hasRequiredKey) { |
280 | 249 | return idlDict; |
281 | 250 | } |
282 | 251 |
|
283 | | - for (let i = 0; i < allMembers.length; i++) { |
| 252 | + const prefix = opts.prefix; |
| 253 | + const outerContext = opts.context; |
| 254 | + |
| 255 | + for (let i = 0; i < membersLength; i++) { |
284 | 256 | const member = allMembers[i]; |
285 | 257 | const key = member.key; |
286 | 258 |
|
287 | | - let esMemberValue; |
288 | | - if (typeV === 'Undefined' || typeV === 'Null') { |
289 | | - esMemberValue = undefined; |
290 | | - } else { |
291 | | - esMemberValue = esDict[key]; |
292 | | - } |
| 259 | + const esMemberValue = isNullish ? undefined : V[key]; |
293 | 260 |
|
294 | 261 | if (esMemberValue !== undefined) { |
295 | | - const context = `'${key}' of '${name}'${ |
296 | | - opts.context ? ` (${opts.context})` : '' |
297 | | - }`; |
| 262 | + const context = outerContext ? |
| 263 | + `'${key}' of '${name}' (${outerContext})` : |
| 264 | + `'${key}' of '${name}'`; |
298 | 265 | const idlMemberValue = member.converter(esMemberValue, { |
299 | 266 | __proto__: null, |
300 | | - prefix: opts.prefix, |
| 267 | + prefix, |
301 | 268 | context, |
302 | 269 | }); |
303 | | - member.validator?.(idlMemberValue, esDict); |
| 270 | + member.validator?.(idlMemberValue, V); |
304 | 271 | setOwnProperty(idlDict, key, idlMemberValue); |
305 | 272 | } else if (member.required) { |
306 | 273 | throw makeException( |
307 | 274 | `can not be converted to '${name}' because '${key}' is required in '${name}'.`, |
308 | | - { __proto__: null, prefix: opts.prefix, context: opts.context, code: 'ERR_MISSING_OPTION' }); |
| 275 | + { __proto__: null, prefix, context: outerContext, code: 'ERR_MISSING_OPTION' }); |
309 | 276 | } |
310 | 277 | } |
311 | 278 |
|
|
0 commit comments