| [9af201e] | 1 | /*
|
|---|
| 2 | MIT License http://www.opensource.org/licenses/mit-license.php
|
|---|
| 3 | Author Tobias Koppers @sokra
|
|---|
| 4 | */
|
|---|
| 5 | "use strict";
|
|---|
| 6 |
|
|---|
| 7 | class HookCodeFactory {
|
|---|
| 8 | constructor(config) {
|
|---|
| 9 | this.config = config;
|
|---|
| 10 | this.options = undefined;
|
|---|
| 11 | this._args = undefined;
|
|---|
| 12 | }
|
|---|
| 13 |
|
|---|
| 14 | create(options) {
|
|---|
| 15 | this.init(options);
|
|---|
| 16 | let fn;
|
|---|
| 17 | switch (options.type) {
|
|---|
| 18 | case "sync":
|
|---|
| 19 | fn = new Function(
|
|---|
| 20 | this.args(),
|
|---|
| 21 | `"use strict";\n${this.header()}${this.contentWithInterceptors({
|
|---|
| 22 | onError: (err) => `throw ${err};\n`,
|
|---|
| 23 | onResult: (result) => `return ${result};\n`,
|
|---|
| 24 | resultReturns: true,
|
|---|
| 25 | onDone: () => "",
|
|---|
| 26 | rethrowIfPossible: true
|
|---|
| 27 | })}`
|
|---|
| 28 | );
|
|---|
| 29 | break;
|
|---|
| 30 | case "async":
|
|---|
| 31 | fn = new Function(
|
|---|
| 32 | this.args({
|
|---|
| 33 | after: "_callback"
|
|---|
| 34 | }),
|
|---|
| 35 | `"use strict";\n${this.header()}${this.contentWithInterceptors({
|
|---|
| 36 | onError: (err) => `_callback(${err});\n`,
|
|---|
| 37 | onResult: (result) => `_callback(null, ${result});\n`,
|
|---|
| 38 | onDone: () => "_callback();\n"
|
|---|
| 39 | })}`
|
|---|
| 40 | );
|
|---|
| 41 | break;
|
|---|
| 42 | case "promise": {
|
|---|
| 43 | let errorHelperUsed = false;
|
|---|
| 44 | const content = this.contentWithInterceptors({
|
|---|
| 45 | onError: (err) => {
|
|---|
| 46 | errorHelperUsed = true;
|
|---|
| 47 | return `_error(${err});\n`;
|
|---|
| 48 | },
|
|---|
| 49 | onResult: (result) => `_resolve(${result});\n`,
|
|---|
| 50 | onDone: () => "_resolve();\n"
|
|---|
| 51 | });
|
|---|
| 52 | let code = "";
|
|---|
| 53 | code += '"use strict";\n';
|
|---|
| 54 | code += this.header();
|
|---|
| 55 | code += "return new Promise((function(_resolve, _reject) {\n";
|
|---|
| 56 | if (errorHelperUsed) {
|
|---|
| 57 | code += "var _sync = true;\n";
|
|---|
| 58 | code += "function _error(_err) {\n";
|
|---|
| 59 | code += "if(_sync)\n";
|
|---|
| 60 | code +=
|
|---|
| 61 | "_resolve(Promise.resolve().then((function() { throw _err; })));\n";
|
|---|
| 62 | code += "else\n";
|
|---|
| 63 | code += "_reject(_err);\n";
|
|---|
| 64 | code += "};\n";
|
|---|
| 65 | }
|
|---|
| 66 | code += content;
|
|---|
| 67 | if (errorHelperUsed) {
|
|---|
| 68 | code += "_sync = false;\n";
|
|---|
| 69 | }
|
|---|
| 70 | code += "}));\n";
|
|---|
| 71 | fn = new Function(this.args(), code);
|
|---|
| 72 | break;
|
|---|
| 73 | }
|
|---|
| 74 | }
|
|---|
| 75 | this.deinit();
|
|---|
| 76 | return fn;
|
|---|
| 77 | }
|
|---|
| 78 |
|
|---|
| 79 | setup(instance, options) {
|
|---|
| 80 | const { taps } = options;
|
|---|
| 81 | const { length } = taps;
|
|---|
| 82 | const fns = Array.from({ length });
|
|---|
| 83 | for (let i = 0; i < length; i++) {
|
|---|
| 84 | fns[i] = taps[i].fn;
|
|---|
| 85 | }
|
|---|
| 86 | instance._x = fns;
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | /**
|
|---|
| 90 | * @param {{ type: "sync" | "promise" | "async", taps: Array<Tap>, interceptors: Array<Interceptor> }} options
|
|---|
| 91 | */
|
|---|
| 92 | init(options) {
|
|---|
| 93 | this.options = options;
|
|---|
| 94 | // `_args` is only read (length / join / [0]) - never mutated - so we
|
|---|
| 95 | // can share the caller's array directly instead of paying for a copy
|
|---|
| 96 | // on every compile.
|
|---|
| 97 | this._args = options.args;
|
|---|
| 98 | this._joinedArgs = undefined;
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | deinit() {
|
|---|
| 102 | this.options = undefined;
|
|---|
| 103 | this._args = undefined;
|
|---|
| 104 | this._joinedArgs = undefined;
|
|---|
| 105 | }
|
|---|
| 106 |
|
|---|
| 107 | contentWithInterceptors(options) {
|
|---|
| 108 | if (this.options.interceptors.length > 0) {
|
|---|
| 109 | const { onError, onResult, onDone } = options;
|
|---|
| 110 | let code = "";
|
|---|
| 111 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 112 | const interceptor = this.options.interceptors[i];
|
|---|
| 113 | if (interceptor.call) {
|
|---|
| 114 | code += `${this.getInterceptor(i)}.call(${this.args({
|
|---|
| 115 | before: interceptor.context ? "_context" : undefined
|
|---|
| 116 | })});\n`;
|
|---|
| 117 | }
|
|---|
| 118 | }
|
|---|
| 119 | code += this.content(
|
|---|
| 120 | Object.assign(options, {
|
|---|
| 121 | onError:
|
|---|
| 122 | onError &&
|
|---|
| 123 | ((err) => {
|
|---|
| 124 | let code = "";
|
|---|
| 125 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 126 | const interceptor = this.options.interceptors[i];
|
|---|
| 127 | if (interceptor.error) {
|
|---|
| 128 | code += `${this.getInterceptor(i)}.error(${err});\n`;
|
|---|
| 129 | }
|
|---|
| 130 | }
|
|---|
| 131 | code += onError(err);
|
|---|
| 132 | return code;
|
|---|
| 133 | }),
|
|---|
| 134 | onResult:
|
|---|
| 135 | onResult &&
|
|---|
| 136 | ((result) => {
|
|---|
| 137 | let code = "";
|
|---|
| 138 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 139 | const interceptor = this.options.interceptors[i];
|
|---|
| 140 | if (interceptor.result) {
|
|---|
| 141 | code += `${this.getInterceptor(i)}.result(${result});\n`;
|
|---|
| 142 | }
|
|---|
| 143 | }
|
|---|
| 144 | code += onResult(result);
|
|---|
| 145 | return code;
|
|---|
| 146 | }),
|
|---|
| 147 | onDone:
|
|---|
| 148 | onDone &&
|
|---|
| 149 | (() => {
|
|---|
| 150 | let code = "";
|
|---|
| 151 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 152 | const interceptor = this.options.interceptors[i];
|
|---|
| 153 | if (interceptor.done) {
|
|---|
| 154 | code += `${this.getInterceptor(i)}.done();\n`;
|
|---|
| 155 | }
|
|---|
| 156 | }
|
|---|
| 157 | code += onDone();
|
|---|
| 158 | return code;
|
|---|
| 159 | })
|
|---|
| 160 | })
|
|---|
| 161 | );
|
|---|
| 162 | return code;
|
|---|
| 163 | }
|
|---|
| 164 | return this.content(options);
|
|---|
| 165 | }
|
|---|
| 166 |
|
|---|
| 167 | header() {
|
|---|
| 168 | let code = "";
|
|---|
| 169 | code += this.needContext() ? "var _context = {};\n" : "var _context;\n";
|
|---|
| 170 | code += "var _x = this._x;\n";
|
|---|
| 171 | if (this.options.interceptors.length > 0) {
|
|---|
| 172 | code += "var _taps = this.taps;\n";
|
|---|
| 173 | code += "var _interceptors = this.interceptors;\n";
|
|---|
| 174 | }
|
|---|
| 175 | return code;
|
|---|
| 176 | }
|
|---|
| 177 |
|
|---|
| 178 | needContext() {
|
|---|
| 179 | const { taps } = this.options;
|
|---|
| 180 | for (let i = 0; i < taps.length; i++) {
|
|---|
| 181 | if (taps[i].context) return true;
|
|---|
| 182 | }
|
|---|
| 183 | return false;
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | callTap(tapIndex, { onError, onResult, onDone, rethrowIfPossible }) {
|
|---|
| 187 | let code = "";
|
|---|
| 188 | let hasTapCached = false;
|
|---|
| 189 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 190 | const interceptor = this.options.interceptors[i];
|
|---|
| 191 | if (interceptor.tap) {
|
|---|
| 192 | if (!hasTapCached) {
|
|---|
| 193 | code += `var _tap${tapIndex} = ${this.getTap(tapIndex)};\n`;
|
|---|
| 194 | hasTapCached = true;
|
|---|
| 195 | }
|
|---|
| 196 | code += `${this.getInterceptor(i)}.tap(${
|
|---|
| 197 | interceptor.context ? "_context, " : ""
|
|---|
| 198 | }_tap${tapIndex});\n`;
|
|---|
| 199 | }
|
|---|
| 200 | }
|
|---|
| 201 | code += `var _fn${tapIndex} = ${this.getTapFn(tapIndex)};\n`;
|
|---|
| 202 | const tap = this.options.taps[tapIndex];
|
|---|
| 203 | switch (tap.type) {
|
|---|
| 204 | case "sync":
|
|---|
| 205 | if (!rethrowIfPossible) {
|
|---|
| 206 | code += `var _hasError${tapIndex} = false;\n`;
|
|---|
| 207 | code += "try {\n";
|
|---|
| 208 | }
|
|---|
| 209 | if (onResult) {
|
|---|
| 210 | code += `var _result${tapIndex} = _fn${tapIndex}(${this.args({
|
|---|
| 211 | before: tap.context ? "_context" : undefined
|
|---|
| 212 | })});\n`;
|
|---|
| 213 | } else {
|
|---|
| 214 | code += `_fn${tapIndex}(${this.args({
|
|---|
| 215 | before: tap.context ? "_context" : undefined
|
|---|
| 216 | })});\n`;
|
|---|
| 217 | }
|
|---|
| 218 | if (!rethrowIfPossible) {
|
|---|
| 219 | code += "} catch(_err) {\n";
|
|---|
| 220 | code += `_hasError${tapIndex} = true;\n`;
|
|---|
| 221 | code += onError("_err");
|
|---|
| 222 | code += "}\n";
|
|---|
| 223 | code += `if(!_hasError${tapIndex}) {\n`;
|
|---|
| 224 | }
|
|---|
| 225 | if (onResult) {
|
|---|
| 226 | code += onResult(`_result${tapIndex}`);
|
|---|
| 227 | }
|
|---|
| 228 | if (onDone) {
|
|---|
| 229 | code += onDone();
|
|---|
| 230 | }
|
|---|
| 231 | if (!rethrowIfPossible) {
|
|---|
| 232 | code += "}\n";
|
|---|
| 233 | }
|
|---|
| 234 | break;
|
|---|
| 235 | case "async": {
|
|---|
| 236 | let cbCode = "";
|
|---|
| 237 | cbCode += onResult
|
|---|
| 238 | ? `(function(_err${tapIndex}, _result${tapIndex}) {\n`
|
|---|
| 239 | : `(function(_err${tapIndex}) {\n`;
|
|---|
| 240 | cbCode += `if(_err${tapIndex}) {\n`;
|
|---|
| 241 | cbCode += onError(`_err${tapIndex}`);
|
|---|
| 242 | cbCode += "} else {\n";
|
|---|
| 243 | if (onResult) {
|
|---|
| 244 | cbCode += onResult(`_result${tapIndex}`);
|
|---|
| 245 | }
|
|---|
| 246 | if (onDone) {
|
|---|
| 247 | cbCode += onDone();
|
|---|
| 248 | }
|
|---|
| 249 | cbCode += "}\n";
|
|---|
| 250 | cbCode += "})";
|
|---|
| 251 | code += `_fn${tapIndex}(${this.args({
|
|---|
| 252 | before: tap.context ? "_context" : undefined,
|
|---|
| 253 | after: cbCode
|
|---|
| 254 | })});\n`;
|
|---|
| 255 | break;
|
|---|
| 256 | }
|
|---|
| 257 | case "promise":
|
|---|
| 258 | code += `var _hasResult${tapIndex} = false;\n`;
|
|---|
| 259 | code += `var _promise${tapIndex} = _fn${tapIndex}(${this.args({
|
|---|
| 260 | before: tap.context ? "_context" : undefined
|
|---|
| 261 | })});\n`;
|
|---|
| 262 | code += `if (!_promise${tapIndex} || !_promise${tapIndex}.then)\n`;
|
|---|
| 263 | code += ` throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise${tapIndex} + ')');\n`;
|
|---|
| 264 | code += `_promise${tapIndex}.then((function(_result${tapIndex}) {\n`;
|
|---|
| 265 | code += `_hasResult${tapIndex} = true;\n`;
|
|---|
| 266 | if (onResult) {
|
|---|
| 267 | code += onResult(`_result${tapIndex}`);
|
|---|
| 268 | }
|
|---|
| 269 | if (onDone) {
|
|---|
| 270 | code += onDone();
|
|---|
| 271 | }
|
|---|
| 272 | code += `}), function(_err${tapIndex}) {\n`;
|
|---|
| 273 | code += `if(_hasResult${tapIndex}) throw _err${tapIndex};\n`;
|
|---|
| 274 | code += onError(
|
|---|
| 275 | `!_err${tapIndex} ? new Error('Tap function (tapPromise) rejects "' + _err${tapIndex} + '" value') : _err${tapIndex}`
|
|---|
| 276 | );
|
|---|
| 277 | code += "});\n";
|
|---|
| 278 | break;
|
|---|
| 279 | }
|
|---|
| 280 | return code;
|
|---|
| 281 | }
|
|---|
| 282 |
|
|---|
| 283 | callTapsSeries({
|
|---|
| 284 | onError,
|
|---|
| 285 | onResult,
|
|---|
| 286 | resultReturns,
|
|---|
| 287 | onDone,
|
|---|
| 288 | doneReturns,
|
|---|
| 289 | rethrowIfPossible
|
|---|
| 290 | }) {
|
|---|
| 291 | const { taps } = this.options;
|
|---|
| 292 | const tapsLength = taps.length;
|
|---|
| 293 | if (tapsLength === 0) return onDone();
|
|---|
| 294 | // Inlined findIndex to avoid the callback allocation.
|
|---|
| 295 | let firstAsync = -1;
|
|---|
| 296 | for (let i = 0; i < tapsLength; i++) {
|
|---|
| 297 | if (taps[i].type !== "sync") {
|
|---|
| 298 | firstAsync = i;
|
|---|
| 299 | break;
|
|---|
| 300 | }
|
|---|
| 301 | }
|
|---|
| 302 | const somethingReturns = resultReturns || doneReturns;
|
|---|
| 303 | // doneBreak doesn't depend on the loop variable - hoist to allocate once.
|
|---|
| 304 | const doneBreak = (skipDone) => {
|
|---|
| 305 | if (skipDone) return "";
|
|---|
| 306 | return onDone();
|
|---|
| 307 | };
|
|---|
| 308 | let code = "";
|
|---|
| 309 | let current = onDone;
|
|---|
| 310 | let unrollCounter = 0;
|
|---|
| 311 | for (let j = tapsLength - 1; j >= 0; j--) {
|
|---|
| 312 | const i = j;
|
|---|
| 313 | const unroll =
|
|---|
| 314 | current !== onDone && (taps[i].type !== "sync" || unrollCounter++ > 20);
|
|---|
| 315 | if (unroll) {
|
|---|
| 316 | unrollCounter = 0;
|
|---|
| 317 | code += `function _next${i}() {\n`;
|
|---|
| 318 | code += current();
|
|---|
| 319 | code += "}\n";
|
|---|
| 320 | current = () => `${somethingReturns ? "return " : ""}_next${i}();\n`;
|
|---|
| 321 | }
|
|---|
| 322 | const done = current;
|
|---|
| 323 | const content = this.callTap(i, {
|
|---|
| 324 | onError: (error) => onError(i, error, done, doneBreak),
|
|---|
| 325 | onResult:
|
|---|
| 326 | onResult && ((result) => onResult(i, result, done, doneBreak)),
|
|---|
| 327 | onDone: !onResult && done,
|
|---|
| 328 | rethrowIfPossible:
|
|---|
| 329 | rethrowIfPossible && (firstAsync < 0 || i < firstAsync)
|
|---|
| 330 | });
|
|---|
| 331 | current = () => content;
|
|---|
| 332 | }
|
|---|
| 333 | code += current();
|
|---|
| 334 | return code;
|
|---|
| 335 | }
|
|---|
| 336 |
|
|---|
| 337 | callTapsLooping({ onError, onDone, rethrowIfPossible }) {
|
|---|
| 338 | if (this.options.taps.length === 0) return onDone();
|
|---|
| 339 | const syncOnly = this.options.taps.every((t) => t.type === "sync");
|
|---|
| 340 | let code = "";
|
|---|
| 341 | if (!syncOnly) {
|
|---|
| 342 | code += "var _looper = (function() {\n";
|
|---|
| 343 | code += "var _loopAsync = false;\n";
|
|---|
| 344 | }
|
|---|
| 345 | code += "var _loop;\n";
|
|---|
| 346 | code += "do {\n";
|
|---|
| 347 | code += "_loop = false;\n";
|
|---|
| 348 | for (let i = 0; i < this.options.interceptors.length; i++) {
|
|---|
| 349 | const interceptor = this.options.interceptors[i];
|
|---|
| 350 | if (interceptor.loop) {
|
|---|
| 351 | code += `${this.getInterceptor(i)}.loop(${this.args({
|
|---|
| 352 | before: interceptor.context ? "_context" : undefined
|
|---|
| 353 | })});\n`;
|
|---|
| 354 | }
|
|---|
| 355 | }
|
|---|
| 356 | code += this.callTapsSeries({
|
|---|
| 357 | onError,
|
|---|
| 358 | onResult: (i, result, next, doneBreak) => {
|
|---|
| 359 | let code = "";
|
|---|
| 360 | code += `if(${result} !== undefined) {\n`;
|
|---|
| 361 | code += "_loop = true;\n";
|
|---|
| 362 | if (!syncOnly) code += "if(_loopAsync) _looper();\n";
|
|---|
| 363 | code += doneBreak(true);
|
|---|
| 364 | code += "} else {\n";
|
|---|
| 365 | code += next();
|
|---|
| 366 | code += "}\n";
|
|---|
| 367 | return code;
|
|---|
| 368 | },
|
|---|
| 369 | onDone:
|
|---|
| 370 | onDone &&
|
|---|
| 371 | (() => {
|
|---|
| 372 | let code = "";
|
|---|
| 373 | code += "if(!_loop) {\n";
|
|---|
| 374 | code += onDone();
|
|---|
| 375 | code += "}\n";
|
|---|
| 376 | return code;
|
|---|
| 377 | }),
|
|---|
| 378 | rethrowIfPossible: rethrowIfPossible && syncOnly
|
|---|
| 379 | });
|
|---|
| 380 | code += "} while(_loop);\n";
|
|---|
| 381 | if (!syncOnly) {
|
|---|
| 382 | code += "_loopAsync = true;\n";
|
|---|
| 383 | code += "});\n";
|
|---|
| 384 | code += "_looper();\n";
|
|---|
| 385 | }
|
|---|
| 386 | return code;
|
|---|
| 387 | }
|
|---|
| 388 |
|
|---|
| 389 | callTapsParallel({
|
|---|
| 390 | onError,
|
|---|
| 391 | onResult,
|
|---|
| 392 | onDone,
|
|---|
| 393 | rethrowIfPossible,
|
|---|
| 394 | onTap = (i, run) => run()
|
|---|
| 395 | }) {
|
|---|
| 396 | const { taps } = this.options;
|
|---|
| 397 | const tapsLength = taps.length;
|
|---|
| 398 | if (tapsLength <= 1) {
|
|---|
| 399 | return this.callTapsSeries({
|
|---|
| 400 | onError,
|
|---|
| 401 | onResult,
|
|---|
| 402 | onDone,
|
|---|
| 403 | rethrowIfPossible
|
|---|
| 404 | });
|
|---|
| 405 | }
|
|---|
| 406 | // done and doneBreak don't depend on the loop variable - hoist them
|
|---|
| 407 | // so they're allocated once per compile instead of once per tap.
|
|---|
| 408 | const done = () => {
|
|---|
| 409 | if (onDone) return "if(--_counter === 0) _done();\n";
|
|---|
| 410 | return "--_counter;";
|
|---|
| 411 | };
|
|---|
| 412 | const doneBreak = (skipDone) => {
|
|---|
| 413 | if (skipDone || !onDone) return "_counter = 0;\n";
|
|---|
| 414 | return "_counter = 0;\n_done();\n";
|
|---|
| 415 | };
|
|---|
| 416 | let code = "";
|
|---|
| 417 | code += "do {\n";
|
|---|
| 418 | code += `var _counter = ${tapsLength};\n`;
|
|---|
| 419 | if (onDone) {
|
|---|
| 420 | code += "var _done = (function() {\n";
|
|---|
| 421 | code += onDone();
|
|---|
| 422 | code += "});\n";
|
|---|
| 423 | }
|
|---|
| 424 | for (let i = 0; i < tapsLength; i++) {
|
|---|
| 425 | code += "if(_counter <= 0) break;\n";
|
|---|
| 426 | code += onTap(
|
|---|
| 427 | i,
|
|---|
| 428 | () =>
|
|---|
| 429 | this.callTap(i, {
|
|---|
| 430 | onError: (error) => {
|
|---|
| 431 | let code = "";
|
|---|
| 432 | code += "if(_counter > 0) {\n";
|
|---|
| 433 | code += onError(i, error, done, doneBreak);
|
|---|
| 434 | code += "}\n";
|
|---|
| 435 | return code;
|
|---|
| 436 | },
|
|---|
| 437 | onResult:
|
|---|
| 438 | onResult &&
|
|---|
| 439 | ((result) => {
|
|---|
| 440 | let code = "";
|
|---|
| 441 | code += "if(_counter > 0) {\n";
|
|---|
| 442 | code += onResult(i, result, done, doneBreak);
|
|---|
| 443 | code += "}\n";
|
|---|
| 444 | return code;
|
|---|
| 445 | }),
|
|---|
| 446 | onDone: !onResult && (() => done()),
|
|---|
| 447 | rethrowIfPossible
|
|---|
| 448 | }),
|
|---|
| 449 | done,
|
|---|
| 450 | doneBreak
|
|---|
| 451 | );
|
|---|
| 452 | }
|
|---|
| 453 | code += "} while(false);\n";
|
|---|
| 454 | return code;
|
|---|
| 455 | }
|
|---|
| 456 |
|
|---|
| 457 | args({ before, after } = {}) {
|
|---|
| 458 | // Hot during code generation. Join `_args` once and cache the result,
|
|---|
| 459 | // then build the customized variants via string concat instead of
|
|---|
| 460 | // allocating temporary `[before, ...allArgs]` / `[...allArgs, after]`
|
|---|
| 461 | // arrays and re-joining.
|
|---|
| 462 | let joined = this._joinedArgs;
|
|---|
| 463 | if (joined === undefined) {
|
|---|
| 464 | joined = this._args.length === 0 ? "" : this._args.join(", ");
|
|---|
| 465 | this._joinedArgs = joined;
|
|---|
| 466 | }
|
|---|
| 467 | if (!before && !after) return joined;
|
|---|
| 468 | if (joined.length === 0) {
|
|---|
| 469 | if (before && after) return `${before}, ${after}`;
|
|---|
| 470 | return before || after;
|
|---|
| 471 | }
|
|---|
| 472 | if (before && after) return `${before}, ${joined}, ${after}`;
|
|---|
| 473 | if (before) return `${before}, ${joined}`;
|
|---|
| 474 | return `${joined}, ${after}`;
|
|---|
| 475 | }
|
|---|
| 476 |
|
|---|
| 477 | getTapFn(idx) {
|
|---|
| 478 | return `_x[${idx}]`;
|
|---|
| 479 | }
|
|---|
| 480 |
|
|---|
| 481 | getTap(idx) {
|
|---|
| 482 | return `_taps[${idx}]`;
|
|---|
| 483 | }
|
|---|
| 484 |
|
|---|
| 485 | getInterceptor(idx) {
|
|---|
| 486 | return `_interceptors[${idx}]`;
|
|---|
| 487 | }
|
|---|
| 488 | }
|
|---|
| 489 |
|
|---|
| 490 | module.exports = HookCodeFactory;
|
|---|