* Shared core for the callHooksFor* helpers. Takes `args` as an already * collected array so the public wrappers each allocate it once instead of * re-collecting it through several rest-parameter layers (hot per identifier). * @template T * @template R * @param {HookMap<SyncBailHook<T, R>>
(hookMap, info, fallback, defined, args)
| 4513 | * @returns {R | undefined} result of hook |
| 4514 | */ |
| 4515 | _callHooksForInfo(hookMap, info, fallback, defined, args) { |
| 4516 | /** @type {string} */ |
| 4517 | let name; |
| 4518 | if (typeof info === "string") { |
| 4519 | name = info; |
| 4520 | } else { |
| 4521 | if (!(info instanceof VariableInfo)) { |
| 4522 | if (defined !== undefined) { |
| 4523 | return defined(); |
| 4524 | } |
| 4525 | return; |
| 4526 | } |
| 4527 | let tagInfo = info.tagInfo; |
| 4528 | while (tagInfo !== undefined) { |
| 4529 | const hook = hookMap.get(tagInfo.tag); |
| 4530 | if (hook !== undefined) { |
| 4531 | this.currentTagData = tagInfo.data; |
| 4532 | const result = hook.call(...args); |
| 4533 | this.currentTagData = undefined; |
| 4534 | if (result !== undefined) return result; |
| 4535 | } |
| 4536 | tagInfo = tagInfo.next; |
| 4537 | } |
| 4538 | if (!info.isFree() && !info.isTagged()) { |
| 4539 | if (defined !== undefined) { |
| 4540 | return defined(); |
| 4541 | } |
| 4542 | return; |
| 4543 | } |
| 4544 | name = /** @type {string} */ (info.name); |
| 4545 | } |
| 4546 | const hook = hookMap.get(name); |
| 4547 | if (hook !== undefined) { |
| 4548 | const result = hook.call(...args); |
| 4549 | if (result !== undefined) return result; |
| 4550 | } |
| 4551 | if (fallback !== undefined) { |
| 4552 | return fallback(name); |
| 4553 | } |
| 4554 | } |
| 4555 | |
| 4556 | /** |
| 4557 | * Call hooks for name with fallback. |
no test coverage detected