| 1 |
|
|---|
| 2 |
|
|---|
| 3 | const HELPERS = {
|
|---|
| 4 | require: `
|
|---|
| 5 | import {createRequire as CREATE_REQUIRE_NAME} from "module";
|
|---|
| 6 | const require = CREATE_REQUIRE_NAME(import.meta.url);
|
|---|
| 7 | `,
|
|---|
| 8 | interopRequireWildcard: `
|
|---|
| 9 | function interopRequireWildcard(obj) {
|
|---|
| 10 | if (obj && obj.__esModule) {
|
|---|
| 11 | return obj;
|
|---|
| 12 | } else {
|
|---|
| 13 | var newObj = {};
|
|---|
| 14 | if (obj != null) {
|
|---|
| 15 | for (var key in obj) {
|
|---|
| 16 | if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|---|
| 17 | newObj[key] = obj[key];
|
|---|
| 18 | }
|
|---|
| 19 | }
|
|---|
| 20 | }
|
|---|
| 21 | newObj.default = obj;
|
|---|
| 22 | return newObj;
|
|---|
| 23 | }
|
|---|
| 24 | }
|
|---|
| 25 | `,
|
|---|
| 26 | interopRequireDefault: `
|
|---|
| 27 | function interopRequireDefault(obj) {
|
|---|
| 28 | return obj && obj.__esModule ? obj : { default: obj };
|
|---|
| 29 | }
|
|---|
| 30 | `,
|
|---|
| 31 | createNamedExportFrom: `
|
|---|
| 32 | function createNamedExportFrom(obj, localName, importedName) {
|
|---|
| 33 | Object.defineProperty(exports, localName, {enumerable: true, configurable: true, get: () => obj[importedName]});
|
|---|
| 34 | }
|
|---|
| 35 | `,
|
|---|
| 36 | // Note that TypeScript and Babel do this differently; TypeScript does a simple existence
|
|---|
| 37 | // check in the exports object and does a plain assignment, whereas Babel uses
|
|---|
| 38 | // defineProperty and builds an object of explicitly-exported names so that star exports can
|
|---|
| 39 | // always take lower precedence. For now, we do the easier TypeScript thing.
|
|---|
| 40 | createStarExport: `
|
|---|
| 41 | function createStarExport(obj) {
|
|---|
| 42 | Object.keys(obj)
|
|---|
| 43 | .filter((key) => key !== "default" && key !== "__esModule")
|
|---|
| 44 | .forEach((key) => {
|
|---|
| 45 | if (exports.hasOwnProperty(key)) {
|
|---|
| 46 | return;
|
|---|
| 47 | }
|
|---|
| 48 | Object.defineProperty(exports, key, {enumerable: true, configurable: true, get: () => obj[key]});
|
|---|
| 49 | });
|
|---|
| 50 | }
|
|---|
| 51 | `,
|
|---|
| 52 | nullishCoalesce: `
|
|---|
| 53 | function nullishCoalesce(lhs, rhsFn) {
|
|---|
| 54 | if (lhs != null) {
|
|---|
| 55 | return lhs;
|
|---|
| 56 | } else {
|
|---|
| 57 | return rhsFn();
|
|---|
| 58 | }
|
|---|
| 59 | }
|
|---|
| 60 | `,
|
|---|
| 61 | asyncNullishCoalesce: `
|
|---|
| 62 | async function asyncNullishCoalesce(lhs, rhsFn) {
|
|---|
| 63 | if (lhs != null) {
|
|---|
| 64 | return lhs;
|
|---|
| 65 | } else {
|
|---|
| 66 | return await rhsFn();
|
|---|
| 67 | }
|
|---|
| 68 | }
|
|---|
| 69 | `,
|
|---|
| 70 | optionalChain: `
|
|---|
| 71 | function optionalChain(ops) {
|
|---|
| 72 | let lastAccessLHS = undefined;
|
|---|
| 73 | let value = ops[0];
|
|---|
| 74 | let i = 1;
|
|---|
| 75 | while (i < ops.length) {
|
|---|
| 76 | const op = ops[i];
|
|---|
| 77 | const fn = ops[i + 1];
|
|---|
| 78 | i += 2;
|
|---|
| 79 | if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
|
|---|
| 80 | return undefined;
|
|---|
| 81 | }
|
|---|
| 82 | if (op === 'access' || op === 'optionalAccess') {
|
|---|
| 83 | lastAccessLHS = value;
|
|---|
| 84 | value = fn(value);
|
|---|
| 85 | } else if (op === 'call' || op === 'optionalCall') {
|
|---|
| 86 | value = fn((...args) => value.call(lastAccessLHS, ...args));
|
|---|
| 87 | lastAccessLHS = undefined;
|
|---|
| 88 | }
|
|---|
| 89 | }
|
|---|
| 90 | return value;
|
|---|
| 91 | }
|
|---|
| 92 | `,
|
|---|
| 93 | asyncOptionalChain: `
|
|---|
| 94 | async function asyncOptionalChain(ops) {
|
|---|
| 95 | let lastAccessLHS = undefined;
|
|---|
| 96 | let value = ops[0];
|
|---|
| 97 | let i = 1;
|
|---|
| 98 | while (i < ops.length) {
|
|---|
| 99 | const op = ops[i];
|
|---|
| 100 | const fn = ops[i + 1];
|
|---|
| 101 | i += 2;
|
|---|
| 102 | if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
|
|---|
| 103 | return undefined;
|
|---|
| 104 | }
|
|---|
| 105 | if (op === 'access' || op === 'optionalAccess') {
|
|---|
| 106 | lastAccessLHS = value;
|
|---|
| 107 | value = await fn(value);
|
|---|
| 108 | } else if (op === 'call' || op === 'optionalCall') {
|
|---|
| 109 | value = await fn((...args) => value.call(lastAccessLHS, ...args));
|
|---|
| 110 | lastAccessLHS = undefined;
|
|---|
| 111 | }
|
|---|
| 112 | }
|
|---|
| 113 | return value;
|
|---|
| 114 | }
|
|---|
| 115 | `,
|
|---|
| 116 | optionalChainDelete: `
|
|---|
| 117 | function optionalChainDelete(ops) {
|
|---|
| 118 | const result = OPTIONAL_CHAIN_NAME(ops);
|
|---|
| 119 | return result == null ? true : result;
|
|---|
| 120 | }
|
|---|
| 121 | `,
|
|---|
| 122 | asyncOptionalChainDelete: `
|
|---|
| 123 | async function asyncOptionalChainDelete(ops) {
|
|---|
| 124 | const result = await ASYNC_OPTIONAL_CHAIN_NAME(ops);
|
|---|
| 125 | return result == null ? true : result;
|
|---|
| 126 | }
|
|---|
| 127 | `,
|
|---|
| 128 | };
|
|---|
| 129 |
|
|---|
| 130 | export class HelperManager {
|
|---|
| 131 | __init() {this.helperNames = {}}
|
|---|
| 132 | __init2() {this.createRequireName = null}
|
|---|
| 133 | constructor( nameManager) {;this.nameManager = nameManager;HelperManager.prototype.__init.call(this);HelperManager.prototype.__init2.call(this);}
|
|---|
| 134 |
|
|---|
| 135 | getHelperName(baseName) {
|
|---|
| 136 | let helperName = this.helperNames[baseName];
|
|---|
| 137 | if (helperName) {
|
|---|
| 138 | return helperName;
|
|---|
| 139 | }
|
|---|
| 140 | helperName = this.nameManager.claimFreeName(`_${baseName}`);
|
|---|
| 141 | this.helperNames[baseName] = helperName;
|
|---|
| 142 | return helperName;
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | emitHelpers() {
|
|---|
| 146 | let resultCode = "";
|
|---|
| 147 | if (this.helperNames.optionalChainDelete) {
|
|---|
| 148 | this.getHelperName("optionalChain");
|
|---|
| 149 | }
|
|---|
| 150 | if (this.helperNames.asyncOptionalChainDelete) {
|
|---|
| 151 | this.getHelperName("asyncOptionalChain");
|
|---|
| 152 | }
|
|---|
| 153 | for (const [baseName, helperCodeTemplate] of Object.entries(HELPERS)) {
|
|---|
| 154 | const helperName = this.helperNames[baseName];
|
|---|
| 155 | let helperCode = helperCodeTemplate;
|
|---|
| 156 | if (baseName === "optionalChainDelete") {
|
|---|
| 157 | helperCode = helperCode.replace("OPTIONAL_CHAIN_NAME", this.helperNames.optionalChain);
|
|---|
| 158 | } else if (baseName === "asyncOptionalChainDelete") {
|
|---|
| 159 | helperCode = helperCode.replace(
|
|---|
| 160 | "ASYNC_OPTIONAL_CHAIN_NAME",
|
|---|
| 161 | this.helperNames.asyncOptionalChain,
|
|---|
| 162 | );
|
|---|
| 163 | } else if (baseName === "require") {
|
|---|
| 164 | if (this.createRequireName === null) {
|
|---|
| 165 | this.createRequireName = this.nameManager.claimFreeName("_createRequire");
|
|---|
| 166 | }
|
|---|
| 167 | helperCode = helperCode.replace(/CREATE_REQUIRE_NAME/g, this.createRequireName);
|
|---|
| 168 | }
|
|---|
| 169 | if (helperName) {
|
|---|
| 170 | resultCode += " ";
|
|---|
| 171 | resultCode += helperCode.replace(baseName, helperName).replace(/\s+/g, " ").trim();
|
|---|
| 172 | }
|
|---|
| 173 | }
|
|---|
| 174 | return resultCode;
|
|---|
| 175 | }
|
|---|
| 176 | }
|
|---|