1/* @internal */ 2namespace ts { 3 export interface EmitHelperFactory { 4 getUnscopedHelperName(name: string): Identifier; 5 // TypeScript Helpers 6 createDecorateHelper(decoratorExpressions: readonly Expression[], target: Expression, memberName?: Expression, descriptor?: Expression): Expression; 7 createMetadataHelper(metadataKey: string, metadataValue: Expression): Expression; 8 createParamHelper(expression: Expression, parameterOffset: number): Expression; 9 // ES2018 Helpers 10 createAssignHelper(attributesSegments: readonly Expression[]): Expression; 11 createAwaitHelper(expression: Expression): Expression; 12 createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean): Expression; 13 createAsyncDelegatorHelper(expression: Expression): Expression; 14 createAsyncValuesHelper(expression: Expression): Expression; 15 // ES2018 Destructuring Helpers 16 createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression; 17 // ES2017 Helpers 18 createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block): Expression; 19 // ES2015 Helpers 20 createExtendsHelper(name: Identifier): Expression; 21 createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression): Expression; 22 createSpreadArrayHelper(to: Expression, from: Expression): Expression; 23 // ES2015 Destructuring Helpers 24 createValuesHelper(expression: Expression): Expression; 25 createReadHelper(iteratorRecord: Expression, count: number | undefined): Expression; 26 // ES2015 Generator Helpers 27 createGeneratorHelper(body: FunctionExpression): Expression; 28 // ES Module Helpers 29 createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined): Expression; 30 createImportStarHelper(expression: Expression): Expression; 31 createImportStarCallbackHelper(): Expression; 32 createImportDefaultHelper(expression: Expression): Expression; 33 createExportStarHelper(moduleExpression: Expression, exportsExpression?: Expression): Expression; 34 // Class Fields Helpers 35 createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier): Expression; 36 createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression): Expression; 37 } 38 39 export function createEmitHelperFactory(context: TransformationContext): EmitHelperFactory { 40 const factory = context.factory; 41 return { 42 getUnscopedHelperName, 43 // TypeScript Helpers 44 createDecorateHelper, 45 createMetadataHelper, 46 createParamHelper, 47 // ES2018 Helpers 48 createAssignHelper, 49 createAwaitHelper, 50 createAsyncGeneratorHelper, 51 createAsyncDelegatorHelper, 52 createAsyncValuesHelper, 53 // ES2018 Destructuring Helpers 54 createRestHelper, 55 // ES2017 Helpers 56 createAwaiterHelper, 57 // ES2015 Helpers 58 createExtendsHelper, 59 createTemplateObjectHelper, 60 createSpreadArrayHelper, 61 // ES2015 Destructuring Helpers 62 createValuesHelper, 63 createReadHelper, 64 // ES2015 Generator Helpers 65 createGeneratorHelper, 66 // ES Module Helpers 67 createCreateBindingHelper, 68 createImportStarHelper, 69 createImportStarCallbackHelper, 70 createImportDefaultHelper, 71 createExportStarHelper, 72 // Class Fields Helpers 73 createClassPrivateFieldGetHelper, 74 createClassPrivateFieldSetHelper, 75 }; 76 77 /** 78 * Gets an identifier for the name of an *unscoped* emit helper. 79 */ 80 function getUnscopedHelperName(name: string) { 81 return setEmitFlags(factory.createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode); 82 } 83 84 // TypeScript Helpers 85 86 function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression) { 87 context.requestEmitHelper(decorateHelper); 88 89 const argumentsArray: Expression[] = []; 90 argumentsArray.push(factory.createArrayLiteralExpression(decoratorExpressions, /*multiLine*/ true)); 91 argumentsArray.push(target); 92 if (memberName) { 93 argumentsArray.push(memberName); 94 if (descriptor) { 95 argumentsArray.push(descriptor); 96 } 97 } 98 99 return factory.createCallExpression( 100 getUnscopedHelperName("__decorate"), 101 /*typeArguments*/ undefined, 102 argumentsArray 103 ); 104 } 105 106 function createMetadataHelper(metadataKey: string, metadataValue: Expression) { 107 context.requestEmitHelper(metadataHelper); 108 return factory.createCallExpression( 109 getUnscopedHelperName("__metadata"), 110 /*typeArguments*/ undefined, 111 [ 112 factory.createStringLiteral(metadataKey), 113 metadataValue 114 ] 115 ); 116 } 117 118 function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) { 119 context.requestEmitHelper(paramHelper); 120 return setTextRange( 121 factory.createCallExpression( 122 getUnscopedHelperName("__param"), 123 /*typeArguments*/ undefined, 124 [ 125 factory.createNumericLiteral(parameterOffset + ""), 126 expression 127 ] 128 ), 129 location 130 ); 131 } 132 133 // ES2018 Helpers 134 135 function createAssignHelper(attributesSegments: Expression[]) { 136 if (context.getCompilerOptions().target! >= ScriptTarget.ES2015) { 137 return factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier("Object"), "assign"), 138 /*typeArguments*/ undefined, 139 attributesSegments); 140 } 141 context.requestEmitHelper(assignHelper); 142 return factory.createCallExpression( 143 getUnscopedHelperName("__assign"), 144 /*typeArguments*/ undefined, 145 attributesSegments 146 ); 147 } 148 149 function createAwaitHelper(expression: Expression) { 150 context.requestEmitHelper(awaitHelper); 151 return factory.createCallExpression(getUnscopedHelperName("__await"), /*typeArguments*/ undefined, [expression]); 152 } 153 154 function createAsyncGeneratorHelper(generatorFunc: FunctionExpression, hasLexicalThis: boolean) { 155 context.requestEmitHelper(awaitHelper); 156 context.requestEmitHelper(asyncGeneratorHelper); 157 158 // Mark this node as originally an async function 159 (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; 160 161 return factory.createCallExpression( 162 getUnscopedHelperName("__asyncGenerator"), 163 /*typeArguments*/ undefined, 164 [ 165 hasLexicalThis ? factory.createThis() : factory.createVoidZero(), 166 factory.createIdentifier("arguments"), 167 generatorFunc 168 ] 169 ); 170 } 171 172 function createAsyncDelegatorHelper(expression: Expression) { 173 context.requestEmitHelper(awaitHelper); 174 context.requestEmitHelper(asyncDelegator); 175 return factory.createCallExpression( 176 getUnscopedHelperName("__asyncDelegator"), 177 /*typeArguments*/ undefined, 178 [expression] 179 ); 180 } 181 182 function createAsyncValuesHelper(expression: Expression) { 183 context.requestEmitHelper(asyncValues); 184 return factory.createCallExpression( 185 getUnscopedHelperName("__asyncValues"), 186 /*typeArguments*/ undefined, 187 [expression] 188 ); 189 } 190 191 // ES2018 Destructuring Helpers 192 193 /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement 194 * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` 195 */ 196 function createRestHelper(value: Expression, elements: readonly BindingOrAssignmentElement[], computedTempVariables: readonly Expression[] | undefined, location: TextRange): Expression { 197 context.requestEmitHelper(restHelper); 198 const propertyNames: Expression[] = []; 199 let computedTempVariableOffset = 0; 200 for (let i = 0; i < elements.length - 1; i++) { 201 const propertyName = getPropertyNameOfBindingOrAssignmentElement(elements[i]); 202 if (propertyName) { 203 if (isComputedPropertyName(propertyName)) { 204 Debug.assertIsDefined(computedTempVariables, "Encountered computed property name but 'computedTempVariables' argument was not provided."); 205 const temp = computedTempVariables[computedTempVariableOffset]; 206 computedTempVariableOffset++; 207 // typeof _tmp === "symbol" ? _tmp : _tmp + "" 208 propertyNames.push( 209 factory.createConditionalExpression( 210 factory.createTypeCheck(temp, "symbol"), 211 /*questionToken*/ undefined, 212 temp, 213 /*colonToken*/ undefined, 214 factory.createAdd(temp, factory.createStringLiteral("")) 215 ) 216 ); 217 } 218 else { 219 propertyNames.push(factory.createStringLiteralFromNode(propertyName)); 220 } 221 } 222 } 223 return factory.createCallExpression( 224 getUnscopedHelperName("__rest"), 225 /*typeArguments*/ undefined, 226 [ 227 value, 228 setTextRange( 229 factory.createArrayLiteralExpression(propertyNames), 230 location 231 )] 232 ); 233 } 234 235 // ES2017 Helpers 236 237 function createAwaiterHelper(hasLexicalThis: boolean, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression | undefined, body: Block) { 238 context.requestEmitHelper(awaiterHelper); 239 240 const generatorFunc = factory.createFunctionExpression( 241 /*modifiers*/ undefined, 242 factory.createToken(SyntaxKind.AsteriskToken), 243 /*name*/ undefined, 244 /*typeParameters*/ undefined, 245 /*parameters*/ [], 246 /*type*/ undefined, 247 body 248 ); 249 250 // Mark this node as originally an async function 251 (generatorFunc.emitNode || (generatorFunc.emitNode = {} as EmitNode)).flags |= EmitFlags.AsyncFunctionBody | EmitFlags.ReuseTempVariableScope; 252 253 return factory.createCallExpression( 254 getUnscopedHelperName("__awaiter"), 255 /*typeArguments*/ undefined, 256 [ 257 hasLexicalThis ? factory.createThis() : factory.createVoidZero(), 258 hasLexicalArguments ? factory.createIdentifier("arguments") : factory.createVoidZero(), 259 promiseConstructor ? createExpressionFromEntityName(factory, promiseConstructor) : factory.createVoidZero(), 260 generatorFunc 261 ] 262 ); 263 } 264 265 // ES2015 Helpers 266 267 function createExtendsHelper(name: Identifier) { 268 context.requestEmitHelper(extendsHelper); 269 return factory.createCallExpression( 270 getUnscopedHelperName("__extends"), 271 /*typeArguments*/ undefined, 272 [name, factory.createUniqueName("_super", GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.FileLevel)] 273 ); 274 } 275 276 function createTemplateObjectHelper(cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) { 277 context.requestEmitHelper(templateObjectHelper); 278 return factory.createCallExpression( 279 getUnscopedHelperName("__makeTemplateObject"), 280 /*typeArguments*/ undefined, 281 [cooked, raw] 282 ); 283 } 284 285 function createSpreadArrayHelper(to: Expression, from: Expression) { 286 context.requestEmitHelper(spreadArrayHelper); 287 return factory.createCallExpression( 288 getUnscopedHelperName("__spreadArray"), 289 /*typeArguments*/ undefined, 290 [to, from] 291 ); 292 } 293 294 // ES2015 Destructuring Helpers 295 296 function createValuesHelper(expression: Expression) { 297 context.requestEmitHelper(valuesHelper); 298 return factory.createCallExpression( 299 getUnscopedHelperName("__values"), 300 /*typeArguments*/ undefined, 301 [expression] 302 ); 303 } 304 305 function createReadHelper(iteratorRecord: Expression, count: number | undefined) { 306 context.requestEmitHelper(readHelper); 307 return factory.createCallExpression( 308 getUnscopedHelperName("__read"), 309 /*typeArguments*/ undefined, 310 count !== undefined 311 ? [iteratorRecord, factory.createNumericLiteral(count + "")] 312 : [iteratorRecord] 313 ); 314 } 315 316 // ES2015 Generator Helpers 317 318 function createGeneratorHelper(body: FunctionExpression) { 319 context.requestEmitHelper(generatorHelper); 320 return factory.createCallExpression( 321 getUnscopedHelperName("__generator"), 322 /*typeArguments*/ undefined, 323 [factory.createThis(), body]); 324 } 325 326 // ES Module Helpers 327 328 function createCreateBindingHelper(module: Expression, inputName: Expression, outputName: Expression | undefined) { 329 context.requestEmitHelper(createBindingHelper); 330 return factory.createCallExpression( 331 getUnscopedHelperName("__createBinding"), 332 /*typeArguments*/ undefined, 333 [factory.createIdentifier("exports"), module, inputName, ...(outputName ? [outputName] : [])]); 334 } 335 336 function createImportStarHelper(expression: Expression) { 337 context.requestEmitHelper(importStarHelper); 338 return factory.createCallExpression( 339 getUnscopedHelperName("__importStar"), 340 /*typeArguments*/ undefined, 341 [expression] 342 ); 343 } 344 345 function createImportStarCallbackHelper() { 346 context.requestEmitHelper(importStarHelper); 347 return getUnscopedHelperName("__importStar"); 348 } 349 350 function createImportDefaultHelper(expression: Expression) { 351 context.requestEmitHelper(importDefaultHelper); 352 return factory.createCallExpression( 353 getUnscopedHelperName("__importDefault"), 354 /*typeArguments*/ undefined, 355 [expression] 356 ); 357 } 358 359 function createExportStarHelper(moduleExpression: Expression, exportsExpression: Expression = factory.createIdentifier("exports")) { 360 context.requestEmitHelper(exportStarHelper); 361 context.requestEmitHelper(createBindingHelper); 362 return factory.createCallExpression( 363 getUnscopedHelperName("__exportStar"), 364 /*typeArguments*/ undefined, 365 [moduleExpression, exportsExpression] 366 ); 367 } 368 369 // Class Fields Helpers 370 371 function createClassPrivateFieldGetHelper(receiver: Expression, privateField: Identifier) { 372 context.requestEmitHelper(classPrivateFieldGetHelper); 373 return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldGet"), /*typeArguments*/ undefined, [receiver, privateField]); 374 } 375 376 function createClassPrivateFieldSetHelper(receiver: Expression, privateField: Identifier, value: Expression) { 377 context.requestEmitHelper(classPrivateFieldSetHelper); 378 return factory.createCallExpression(getUnscopedHelperName("__classPrivateFieldSet"), /*typeArguments*/ undefined, [receiver, privateField, value]); 379 } 380 } 381 382 /* @internal */ 383 export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { 384 if (x === y) return Comparison.EqualTo; 385 if (x.priority === y.priority) return Comparison.EqualTo; 386 if (x.priority === undefined) return Comparison.GreaterThan; 387 if (y.priority === undefined) return Comparison.LessThan; 388 return compareValues(x.priority, y.priority); 389 } 390 391 /** 392 * @param input Template string input strings 393 * @param args Names which need to be made file-level unique 394 */ 395 export function helperString(input: TemplateStringsArray, ...args: string[]) { 396 return (uniqueName: EmitHelperUniqueNameCallback) => { 397 let result = ""; 398 for (let i = 0; i < args.length; i++) { 399 result += input[i]; 400 result += uniqueName(args[i]); 401 } 402 result += input[input.length - 1]; 403 return result; 404 }; 405 } 406 407 // TypeScript Helpers 408 409 export const decorateHelper: UnscopedEmitHelper = { 410 name: "typescript:decorate", 411 importName: "__decorate", 412 scoped: false, 413 priority: 2, 414 text: ` 415 var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 416 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 417 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 418 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 419 return c > 3 && r && Object.defineProperty(target, key, r), r; 420 };` 421 }; 422 423 export const metadataHelper: UnscopedEmitHelper = { 424 name: "typescript:metadata", 425 importName: "__metadata", 426 scoped: false, 427 priority: 3, 428 text: ` 429 var __metadata = (this && this.__metadata) || function (k, v) { 430 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 431 };` 432 }; 433 434 export const paramHelper: UnscopedEmitHelper = { 435 name: "typescript:param", 436 importName: "__param", 437 scoped: false, 438 priority: 4, 439 text: ` 440 var __param = (this && this.__param) || function (paramIndex, decorator) { 441 return function (target, key) { decorator(target, key, paramIndex); } 442 };` 443 }; 444 445 // ES2018 Helpers 446 447 export const assignHelper: UnscopedEmitHelper = { 448 name: "typescript:assign", 449 importName: "__assign", 450 scoped: false, 451 priority: 1, 452 text: ` 453 var __assign = (this && this.__assign) || function () { 454 __assign = Object.assign || function(t) { 455 for (var s, i = 1, n = arguments.length; i < n; i++) { 456 s = arguments[i]; 457 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) 458 t[p] = s[p]; 459 } 460 return t; 461 }; 462 return __assign.apply(this, arguments); 463 };` 464 }; 465 466 export const awaitHelper: UnscopedEmitHelper = { 467 name: "typescript:await", 468 importName: "__await", 469 scoped: false, 470 text: ` 471 var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }` 472 }; 473 474 export const asyncGeneratorHelper: UnscopedEmitHelper = { 475 name: "typescript:asyncGenerator", 476 importName: "__asyncGenerator", 477 scoped: false, 478 dependencies: [awaitHelper], 479 text: ` 480 var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { 481 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 482 var g = generator.apply(thisArg, _arguments || []), i, q = []; 483 return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; 484 function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } 485 function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } 486 function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } 487 function fulfill(value) { resume("next", value); } 488 function reject(value) { resume("throw", value); } 489 function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } 490 };` 491 }; 492 493 export const asyncDelegator: UnscopedEmitHelper = { 494 name: "typescript:asyncDelegator", 495 importName: "__asyncDelegator", 496 scoped: false, 497 dependencies: [awaitHelper], 498 text: ` 499 var __asyncDelegator = (this && this.__asyncDelegator) || function (o) { 500 var i, p; 501 return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; 502 function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; } 503 };` 504 }; 505 506 export const asyncValues: UnscopedEmitHelper = { 507 name: "typescript:asyncValues", 508 importName: "__asyncValues", 509 scoped: false, 510 text: ` 511 var __asyncValues = (this && this.__asyncValues) || function (o) { 512 if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); 513 var m = o[Symbol.asyncIterator], i; 514 return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); 515 function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } 516 function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } 517 };` 518 }; 519 520 // ES2018 Destructuring Helpers 521 522 export const restHelper: UnscopedEmitHelper = { 523 name: "typescript:rest", 524 importName: "__rest", 525 scoped: false, 526 text: ` 527 var __rest = (this && this.__rest) || function (s, e) { 528 var t = {}; 529 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) 530 t[p] = s[p]; 531 if (s != null && typeof Object.getOwnPropertySymbols === "function") 532 for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { 533 if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) 534 t[p[i]] = s[p[i]]; 535 } 536 return t; 537 };` 538 }; 539 540 // ES2017 Helpers 541 542 export const awaiterHelper: UnscopedEmitHelper = { 543 name: "typescript:awaiter", 544 importName: "__awaiter", 545 scoped: false, 546 priority: 5, 547 text: ` 548 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 549 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 550 return new (P || (P = Promise))(function (resolve, reject) { 551 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 552 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 553 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 554 step((generator = generator.apply(thisArg, _arguments || [])).next()); 555 }); 556 };` 557 }; 558 559 // ES2015 Helpers 560 561 export const extendsHelper: UnscopedEmitHelper = { 562 name: "typescript:extends", 563 importName: "__extends", 564 scoped: false, 565 priority: 0, 566 text: ` 567 var __extends = (this && this.__extends) || (function () { 568 var extendStatics = function (d, b) { 569 extendStatics = Object.setPrototypeOf || 570 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || 571 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; 572 return extendStatics(d, b); 573 }; 574 575 return function (d, b) { 576 if (typeof b !== "function" && b !== null) 577 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); 578 extendStatics(d, b); 579 function __() { this.constructor = d; } 580 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); 581 }; 582 })();` 583 }; 584 585 export const templateObjectHelper: UnscopedEmitHelper = { 586 name: "typescript:makeTemplateObject", 587 importName: "__makeTemplateObject", 588 scoped: false, 589 priority: 0, 590 text: ` 591 var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { 592 if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } 593 return cooked; 594 };` 595 }; 596 597 export const readHelper: UnscopedEmitHelper = { 598 name: "typescript:read", 599 importName: "__read", 600 scoped: false, 601 text: ` 602 var __read = (this && this.__read) || function (o, n) { 603 var m = typeof Symbol === "function" && o[Symbol.iterator]; 604 if (!m) return o; 605 var i = m.call(o), r, ar = [], e; 606 try { 607 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); 608 } 609 catch (error) { e = { error: error }; } 610 finally { 611 try { 612 if (r && !r.done && (m = i["return"])) m.call(i); 613 } 614 finally { if (e) throw e.error; } 615 } 616 return ar; 617 };` 618 }; 619 620 export const spreadArrayHelper: UnscopedEmitHelper = { 621 name: "typescript:spreadArray", 622 importName: "__spreadArray", 623 scoped: false, 624 text: ` 625 var __spreadArray = (this && this.__spreadArray) || function (to, from) { 626 for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) 627 to[j] = from[i]; 628 return to; 629 };` 630 }; 631 632 // ES2015 Destructuring Helpers 633 634 export const valuesHelper: UnscopedEmitHelper = { 635 name: "typescript:values", 636 importName: "__values", 637 scoped: false, 638 text: ` 639 var __values = (this && this.__values) || function(o) { 640 var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; 641 if (m) return m.call(o); 642 if (o && typeof o.length === "number") return { 643 next: function () { 644 if (o && i >= o.length) o = void 0; 645 return { value: o && o[i++], done: !o }; 646 } 647 }; 648 throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); 649 };` 650 }; 651 652 // ES2015 Generator Helpers 653 654 // The __generator helper is used by down-level transformations to emulate the runtime 655 // semantics of an ES2015 generator function. When called, this helper returns an 656 // object that implements the Iterator protocol, in that it has `next`, `return`, and 657 // `throw` methods that step through the generator when invoked. 658 // 659 // parameters: 660 // @param thisArg The value to use as the `this` binding for the transformed generator body. 661 // @param body A function that acts as the transformed generator body. 662 // 663 // variables: 664 // _ Persistent state for the generator that is shared between the helper and the 665 // generator body. The state object has the following members: 666 // sent() - A method that returns or throws the current completion value. 667 // label - The next point at which to resume evaluation of the generator body. 668 // trys - A stack of protected regions (try/catch/finally blocks). 669 // ops - A stack of pending instructions when inside of a finally block. 670 // f A value indicating whether the generator is executing. 671 // y An iterator to delegate for a yield*. 672 // t A temporary variable that holds one of the following values (note that these 673 // cases do not overlap): 674 // - The completion value when resuming from a `yield` or `yield*`. 675 // - The error value for a catch block. 676 // - The current protected region (array of try/catch/finally/end labels). 677 // - The verb (`next`, `throw`, or `return` method) to delegate to the expression 678 // of a `yield*`. 679 // - The result of evaluating the verb delegated to the expression of a `yield*`. 680 // 681 // functions: 682 // verb(n) Creates a bound callback to the `step` function for opcode `n`. 683 // step(op) Evaluates opcodes in a generator body until execution is suspended or 684 // completed. 685 // 686 // The __generator helper understands a limited set of instructions: 687 // 0: next(value?) - Start or resume the generator with the specified value. 688 // 1: throw(error) - Resume the generator with an exception. If the generator is 689 // suspended inside of one or more protected regions, evaluates 690 // any intervening finally blocks between the current label and 691 // the nearest catch block or function boundary. If uncaught, the 692 // exception is thrown to the caller. 693 // 2: return(value?) - Resume the generator as if with a return. If the generator is 694 // suspended inside of one or more protected regions, evaluates any 695 // intervening finally blocks. 696 // 3: break(label) - Jump to the specified label. If the label is outside of the 697 // current protected region, evaluates any intervening finally 698 // blocks. 699 // 4: yield(value?) - Yield execution to the caller with an optional value. When 700 // resumed, the generator will continue at the next label. 701 // 5: yield*(value) - Delegates evaluation to the supplied iterator. When 702 // delegation completes, the generator will continue at the next 703 // label. 704 // 6: catch(error) - Handles an exception thrown from within the generator body. If 705 // the current label is inside of one or more protected regions, 706 // evaluates any intervening finally blocks between the current 707 // label and the nearest catch block or function boundary. If 708 // uncaught, the exception is thrown to the caller. 709 // 7: endfinally - Ends a finally block, resuming the last instruction prior to 710 // entering a finally block. 711 // 712 // For examples of how these are used, see the comments in ./transformers/generators.ts 713 export const generatorHelper: UnscopedEmitHelper = { 714 name: "typescript:generator", 715 importName: "__generator", 716 scoped: false, 717 priority: 6, 718 text: ` 719 var __generator = (this && this.__generator) || function (thisArg, body) { 720 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 721 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; 722 function verb(n) { return function (v) { return step([n, v]); }; } 723 function step(op) { 724 if (f) throw new TypeError("Generator is already executing."); 725 while (_) try { 726 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; 727 if (y = 0, t) op = [op[0] & 2, t.value]; 728 switch (op[0]) { 729 case 0: case 1: t = op; break; 730 case 4: _.label++; return { value: op[1], done: false }; 731 case 5: _.label++; y = op[1]; op = [0]; continue; 732 case 7: op = _.ops.pop(); _.trys.pop(); continue; 733 default: 734 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } 735 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } 736 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } 737 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } 738 if (t[2]) _.ops.pop(); 739 _.trys.pop(); continue; 740 } 741 op = body.call(thisArg, _); 742 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } 743 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; 744 } 745 };` 746 }; 747 748 // ES Module Helpers 749 750 export const createBindingHelper: UnscopedEmitHelper = { 751 name: "typescript:commonjscreatebinding", 752 importName: "__createBinding", 753 scoped: false, 754 priority: 1, 755 text: ` 756 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 757 if (k2 === undefined) k2 = k; 758 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 759 }) : (function(o, m, k, k2) { 760 if (k2 === undefined) k2 = k; 761 o[k2] = m[k]; 762 }));` 763 }; 764 765 export const setModuleDefaultHelper: UnscopedEmitHelper = { 766 name: "typescript:commonjscreatevalue", 767 importName: "__setModuleDefault", 768 scoped: false, 769 priority: 1, 770 text: ` 771 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 772 Object.defineProperty(o, "default", { enumerable: true, value: v }); 773 }) : function(o, v) { 774 o["default"] = v; 775 });` 776 }; 777 778 // emit helper for `import * as Name from "foo"` 779 export const importStarHelper: UnscopedEmitHelper = { 780 name: "typescript:commonjsimportstar", 781 importName: "__importStar", 782 scoped: false, 783 dependencies: [createBindingHelper, setModuleDefaultHelper], 784 priority: 2, 785 text: ` 786 var __importStar = (this && this.__importStar) || function (mod) { 787 if (mod && mod.__esModule) return mod; 788 var result = {}; 789 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 790 __setModuleDefault(result, mod); 791 return result; 792 };` 793 }; 794 795 // emit helper for `import Name from "foo"` 796 export const importDefaultHelper: UnscopedEmitHelper = { 797 name: "typescript:commonjsimportdefault", 798 importName: "__importDefault", 799 scoped: false, 800 text: ` 801 var __importDefault = (this && this.__importDefault) || function (mod) { 802 return (mod && mod.__esModule) ? mod : { "default": mod }; 803 };` 804 }; 805 806 // emit output for the __export helper function 807 export const exportStarHelper: UnscopedEmitHelper = { 808 name: "typescript:export-star", 809 importName: "__exportStar", 810 scoped: false, 811 dependencies: [createBindingHelper], 812 priority: 2, 813 text: ` 814 var __exportStar = (this && this.__exportStar) || function(m, exports) { 815 for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); 816 };` 817 }; 818 819 // Class fields helpers 820 export const classPrivateFieldGetHelper: UnscopedEmitHelper = { 821 name: "typescript:classPrivateFieldGet", 822 importName: "__classPrivateFieldGet", 823 scoped: false, 824 text: ` 825 var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { 826 if (!privateMap.has(receiver)) { 827 throw new TypeError("attempted to get private field on non-instance"); 828 } 829 return privateMap.get(receiver); 830 };` 831 }; 832 833 export const classPrivateFieldSetHelper: UnscopedEmitHelper = { 834 name: "typescript:classPrivateFieldSet", 835 importName: "__classPrivateFieldSet", 836 scoped: false, 837 text: ` 838 var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, privateMap, value) { 839 if (!privateMap.has(receiver)) { 840 throw new TypeError("attempted to set private field on non-instance"); 841 } 842 privateMap.set(receiver, value); 843 return value; 844 };` 845 }; 846 847 let allUnscopedEmitHelpers: ReadonlyESMap<string, UnscopedEmitHelper> | undefined; 848 849 export function getAllUnscopedEmitHelpers() { 850 return allUnscopedEmitHelpers || (allUnscopedEmitHelpers = arrayToMap([ 851 decorateHelper, 852 metadataHelper, 853 paramHelper, 854 assignHelper, 855 awaitHelper, 856 asyncGeneratorHelper, 857 asyncDelegator, 858 asyncValues, 859 restHelper, 860 awaiterHelper, 861 extendsHelper, 862 templateObjectHelper, 863 spreadArrayHelper, 864 valuesHelper, 865 readHelper, 866 generatorHelper, 867 importStarHelper, 868 importDefaultHelper, 869 exportStarHelper, 870 classPrivateFieldGetHelper, 871 classPrivateFieldSetHelper, 872 createBindingHelper, 873 setModuleDefaultHelper 874 ], helper => helper.name)); 875 } 876 877 export const asyncSuperHelper: EmitHelper = { 878 name: "typescript:async-super", 879 scoped: true, 880 text: helperString` 881 const ${"_superIndex"} = name => super[name];` 882 }; 883 884 export const advancedAsyncSuperHelper: EmitHelper = { 885 name: "typescript:advanced-async-super", 886 scoped: true, 887 text: helperString` 888 const ${"_superIndex"} = (function (geti, seti) { 889 const cache = Object.create(null); 890 return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); 891 })(name => super[name], (name, value) => super[name] = value);` 892 }; 893 894 export function isCallToHelper(firstSegment: Expression, helperName: __String) { 895 return isCallExpression(firstSegment) 896 && isIdentifier(firstSegment.expression) 897 && (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName) 898 && firstSegment.expression.escapedText === helperName; 899 } 900}