UNPKG

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