fields.js 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.buildCheckInRHS = buildCheckInRHS;
  6. exports.buildFieldsInitNodes = buildFieldsInitNodes;
  7. exports.buildPrivateNamesMap = buildPrivateNamesMap;
  8. exports.buildPrivateNamesNodes = buildPrivateNamesNodes;
  9. exports.privateNameVisitorFactory = privateNameVisitorFactory;
  10. exports.transformPrivateNamesUsage = transformPrivateNamesUsage;
  11. var _core = require("@babel/core");
  12. var _traverse = require("@babel/traverse");
  13. var _helperReplaceSupers = require("@babel/helper-replace-supers");
  14. var _helperMemberExpressionToFunctions = require("@babel/helper-member-expression-to-functions");
  15. var _helperOptimiseCallExpression = require("@babel/helper-optimise-call-expression");
  16. var _helperAnnotateAsPure = require("@babel/helper-annotate-as-pure");
  17. var _helperSkipTransparentExpressionWrappers = require("@babel/helper-skip-transparent-expression-wrappers");
  18. var ts = require("./typescript.js");
  19. {
  20. var newHelpers = file => {
  21. ;
  22. return file.availableHelper("classPrivateFieldGet2");
  23. };
  24. }
  25. function buildPrivateNamesMap(className, privateFieldsAsSymbolsOrProperties, props, file) {
  26. const privateNamesMap = new Map();
  27. let classBrandId;
  28. for (const prop of props) {
  29. if (prop.isPrivate()) {
  30. const {
  31. name
  32. } = prop.node.key.id;
  33. let update = privateNamesMap.get(name);
  34. if (!update) {
  35. const isMethod = !prop.isProperty();
  36. const isStatic = prop.node.static;
  37. let initAdded = false;
  38. let id;
  39. if (!privateFieldsAsSymbolsOrProperties && newHelpers(file) && isMethod && !isStatic) {
  40. var _classBrandId;
  41. initAdded = !!classBrandId;
  42. (_classBrandId = classBrandId) != null ? _classBrandId : classBrandId = prop.scope.generateUidIdentifier(`${className}_brand`);
  43. id = classBrandId;
  44. } else {
  45. id = prop.scope.generateUidIdentifier(name);
  46. }
  47. update = {
  48. id,
  49. static: isStatic,
  50. method: isMethod,
  51. initAdded
  52. };
  53. privateNamesMap.set(name, update);
  54. }
  55. if (prop.isClassPrivateMethod()) {
  56. if (prop.node.kind === "get") {
  57. const {
  58. body
  59. } = prop.node.body;
  60. let $;
  61. if (body.length === 1 && _core.types.isReturnStatement($ = body[0]) && _core.types.isCallExpression($ = $.argument) && $.arguments.length === 1 && _core.types.isThisExpression($.arguments[0]) && _core.types.isIdentifier($ = $.callee)) {
  62. update.getId = _core.types.cloneNode($);
  63. update.getterDeclared = true;
  64. } else {
  65. update.getId = prop.scope.generateUidIdentifier(`get_${name}`);
  66. }
  67. } else if (prop.node.kind === "set") {
  68. const {
  69. params
  70. } = prop.node;
  71. const {
  72. body
  73. } = prop.node.body;
  74. let $;
  75. if (body.length === 1 && _core.types.isExpressionStatement($ = body[0]) && _core.types.isCallExpression($ = $.expression) && $.arguments.length === 2 && _core.types.isThisExpression($.arguments[0]) && _core.types.isIdentifier($.arguments[1], {
  76. name: params[0].name
  77. }) && _core.types.isIdentifier($ = $.callee)) {
  78. update.setId = _core.types.cloneNode($);
  79. update.setterDeclared = true;
  80. } else {
  81. update.setId = prop.scope.generateUidIdentifier(`set_${name}`);
  82. }
  83. } else if (prop.node.kind === "method") {
  84. update.methodId = prop.scope.generateUidIdentifier(name);
  85. }
  86. }
  87. privateNamesMap.set(name, update);
  88. }
  89. }
  90. return privateNamesMap;
  91. }
  92. function buildPrivateNamesNodes(privateNamesMap, privateFieldsAsProperties, privateFieldsAsSymbols, state) {
  93. const initNodes = [];
  94. const injectedIds = new Set();
  95. for (const [name, value] of privateNamesMap) {
  96. const {
  97. static: isStatic,
  98. method: isMethod,
  99. getId,
  100. setId
  101. } = value;
  102. const isGetterOrSetter = getId || setId;
  103. const id = _core.types.cloneNode(value.id);
  104. let init;
  105. if (privateFieldsAsProperties) {
  106. init = _core.types.callExpression(state.addHelper("classPrivateFieldLooseKey"), [_core.types.stringLiteral(name)]);
  107. } else if (privateFieldsAsSymbols) {
  108. init = _core.types.callExpression(_core.types.identifier("Symbol"), [_core.types.stringLiteral(name)]);
  109. } else if (!isStatic) {
  110. if (injectedIds.has(id.name)) continue;
  111. injectedIds.add(id.name);
  112. init = _core.types.newExpression(_core.types.identifier(isMethod && (!isGetterOrSetter || newHelpers(state)) ? "WeakSet" : "WeakMap"), []);
  113. }
  114. if (init) {
  115. if (!privateFieldsAsSymbols) {
  116. (0, _helperAnnotateAsPure.default)(init);
  117. }
  118. initNodes.push(_core.template.statement.ast`var ${id} = ${init}`);
  119. }
  120. }
  121. return initNodes;
  122. }
  123. function privateNameVisitorFactory(visitor) {
  124. const nestedVisitor = _traverse.visitors.environmentVisitor(Object.assign({}, visitor));
  125. const privateNameVisitor = Object.assign({}, visitor, {
  126. Class(path) {
  127. const {
  128. privateNamesMap
  129. } = this;
  130. const body = path.get("body.body");
  131. const visiblePrivateNames = new Map(privateNamesMap);
  132. const redeclared = [];
  133. for (const prop of body) {
  134. if (!prop.isPrivate()) continue;
  135. const {
  136. name
  137. } = prop.node.key.id;
  138. visiblePrivateNames.delete(name);
  139. redeclared.push(name);
  140. }
  141. if (!redeclared.length) {
  142. return;
  143. }
  144. path.get("body").traverse(nestedVisitor, Object.assign({}, this, {
  145. redeclared
  146. }));
  147. path.traverse(privateNameVisitor, Object.assign({}, this, {
  148. privateNamesMap: visiblePrivateNames
  149. }));
  150. path.skipKey("body");
  151. }
  152. });
  153. return privateNameVisitor;
  154. }
  155. const privateNameVisitor = privateNameVisitorFactory({
  156. PrivateName(path, {
  157. noDocumentAll
  158. }) {
  159. const {
  160. privateNamesMap,
  161. redeclared
  162. } = this;
  163. const {
  164. node,
  165. parentPath
  166. } = path;
  167. if (!parentPath.isMemberExpression({
  168. property: node
  169. }) && !parentPath.isOptionalMemberExpression({
  170. property: node
  171. })) {
  172. return;
  173. }
  174. const {
  175. name
  176. } = node.id;
  177. if (!privateNamesMap.has(name)) return;
  178. if (redeclared != null && redeclared.includes(name)) return;
  179. this.handle(parentPath, noDocumentAll);
  180. }
  181. });
  182. function unshadow(name, scope, innerBinding) {
  183. while ((_scope = scope) != null && _scope.hasBinding(name) && !scope.bindingIdentifierEquals(name, innerBinding)) {
  184. var _scope;
  185. scope.rename(name);
  186. scope = scope.parent;
  187. }
  188. }
  189. function buildCheckInRHS(rhs, file, inRHSIsObject) {
  190. if (inRHSIsObject || !(file.availableHelper != null && file.availableHelper("checkInRHS"))) return rhs;
  191. return _core.types.callExpression(file.addHelper("checkInRHS"), [rhs]);
  192. }
  193. const privateInVisitor = privateNameVisitorFactory({
  194. BinaryExpression(path, {
  195. file
  196. }) {
  197. const {
  198. operator,
  199. left,
  200. right
  201. } = path.node;
  202. if (operator !== "in") return;
  203. if (!_core.types.isPrivateName(left)) return;
  204. const {
  205. privateFieldsAsProperties,
  206. privateNamesMap,
  207. redeclared
  208. } = this;
  209. const {
  210. name
  211. } = left.id;
  212. if (!privateNamesMap.has(name)) return;
  213. if (redeclared != null && redeclared.includes(name)) return;
  214. unshadow(this.classRef.name, path.scope, this.innerBinding);
  215. if (privateFieldsAsProperties) {
  216. const {
  217. id
  218. } = privateNamesMap.get(name);
  219. path.replaceWith(_core.template.expression.ast`
  220. Object.prototype.hasOwnProperty.call(${buildCheckInRHS(right, file)}, ${_core.types.cloneNode(id)})
  221. `);
  222. return;
  223. }
  224. const {
  225. id,
  226. static: isStatic
  227. } = privateNamesMap.get(name);
  228. if (isStatic) {
  229. path.replaceWith(_core.template.expression.ast`${buildCheckInRHS(right, file)} === ${_core.types.cloneNode(this.classRef)}`);
  230. return;
  231. }
  232. path.replaceWith(_core.template.expression.ast`${_core.types.cloneNode(id)}.has(${buildCheckInRHS(right, file)})`);
  233. }
  234. });
  235. function readOnlyError(file, name) {
  236. return _core.types.callExpression(file.addHelper("readOnlyError"), [_core.types.stringLiteral(`#${name}`)]);
  237. }
  238. function writeOnlyError(file, name) {
  239. if (!file.availableHelper("writeOnlyError")) {
  240. console.warn(`@babel/helpers is outdated, update it to silence this warning.`);
  241. return _core.types.buildUndefinedNode();
  242. }
  243. return _core.types.callExpression(file.addHelper("writeOnlyError"), [_core.types.stringLiteral(`#${name}`)]);
  244. }
  245. function buildStaticPrivateFieldAccess(expr, noUninitializedPrivateFieldAccess) {
  246. if (noUninitializedPrivateFieldAccess) return expr;
  247. return _core.types.memberExpression(expr, _core.types.identifier("_"));
  248. }
  249. function autoInherits(fn) {
  250. return function (member) {
  251. return _core.types.inherits(fn.apply(this, arguments), member.node);
  252. };
  253. }
  254. const privateNameHandlerSpec = {
  255. memoise(member, count) {
  256. const {
  257. scope
  258. } = member;
  259. const {
  260. object
  261. } = member.node;
  262. const memo = scope.maybeGenerateMemoised(object);
  263. if (!memo) {
  264. return;
  265. }
  266. this.memoiser.set(object, memo, count);
  267. },
  268. receiver(member) {
  269. const {
  270. object
  271. } = member.node;
  272. if (this.memoiser.has(object)) {
  273. return _core.types.cloneNode(this.memoiser.get(object));
  274. }
  275. return _core.types.cloneNode(object);
  276. },
  277. get: autoInherits(function (member) {
  278. const {
  279. classRef,
  280. privateNamesMap,
  281. file,
  282. innerBinding,
  283. noUninitializedPrivateFieldAccess
  284. } = this;
  285. const privateName = member.node.property;
  286. const {
  287. name
  288. } = privateName.id;
  289. const {
  290. id,
  291. static: isStatic,
  292. method: isMethod,
  293. methodId,
  294. getId,
  295. setId
  296. } = privateNamesMap.get(name);
  297. const isGetterOrSetter = getId || setId;
  298. const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
  299. if (isStatic) {
  300. unshadow(classRef.name, member.scope, innerBinding);
  301. if (!newHelpers(file)) {
  302. const helperName = isMethod && !isGetterOrSetter ? "classStaticPrivateMethodGet" : "classStaticPrivateFieldSpecGet";
  303. return _core.types.callExpression(file.addHelper(helperName), [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id)]);
  304. }
  305. const receiver = this.receiver(member);
  306. const skipCheck = _core.types.isIdentifier(receiver) && receiver.name === classRef.name;
  307. if (!isMethod) {
  308. if (skipCheck) {
  309. return buildStaticPrivateFieldAccess(cloneId(id), noUninitializedPrivateFieldAccess);
  310. }
  311. return buildStaticPrivateFieldAccess(_core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, cloneId(id)]), noUninitializedPrivateFieldAccess);
  312. }
  313. if (getId) {
  314. if (skipCheck) {
  315. return _core.types.callExpression(cloneId(getId), [receiver]);
  316. }
  317. return _core.types.callExpression(file.addHelper("classPrivateGetter"), [_core.types.cloneNode(classRef), receiver, cloneId(getId)]);
  318. }
  319. if (setId) {
  320. const err = _core.types.buildUndefinedNode();
  321. if (skipCheck) return err;
  322. return _core.types.sequenceExpression([_core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver]), err]);
  323. }
  324. if (skipCheck) return cloneId(id);
  325. return _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, cloneId(id)]);
  326. }
  327. if (isMethod) {
  328. if (isGetterOrSetter) {
  329. if (!getId) {
  330. return _core.types.sequenceExpression([this.receiver(member), writeOnlyError(file, name)]);
  331. }
  332. if (!newHelpers(file)) {
  333. return _core.types.callExpression(file.addHelper("classPrivateFieldGet"), [this.receiver(member), cloneId(id)]);
  334. }
  335. return _core.types.callExpression(file.addHelper("classPrivateGetter"), [_core.types.cloneNode(id), this.receiver(member), cloneId(getId)]);
  336. }
  337. if (!newHelpers(file)) {
  338. return _core.types.callExpression(file.addHelper("classPrivateMethodGet"), [this.receiver(member), _core.types.cloneNode(id), cloneId(methodId)]);
  339. }
  340. return _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(id), this.receiver(member), cloneId(methodId)]);
  341. }
  342. if (newHelpers(file)) {
  343. return _core.types.callExpression(file.addHelper("classPrivateFieldGet2"), [cloneId(id), this.receiver(member)]);
  344. }
  345. return _core.types.callExpression(file.addHelper("classPrivateFieldGet"), [this.receiver(member), cloneId(id)]);
  346. }),
  347. boundGet(member) {
  348. this.memoise(member, 1);
  349. return _core.types.callExpression(_core.types.memberExpression(this.get(member), _core.types.identifier("bind")), [this.receiver(member)]);
  350. },
  351. set: autoInherits(function (member, value) {
  352. const {
  353. classRef,
  354. privateNamesMap,
  355. file,
  356. noUninitializedPrivateFieldAccess
  357. } = this;
  358. const privateName = member.node.property;
  359. const {
  360. name
  361. } = privateName.id;
  362. const {
  363. id,
  364. static: isStatic,
  365. method: isMethod,
  366. setId,
  367. getId
  368. } = privateNamesMap.get(name);
  369. const isGetterOrSetter = getId || setId;
  370. const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
  371. if (isStatic) {
  372. if (!newHelpers(file)) {
  373. const helperName = isMethod && !isGetterOrSetter ? "classStaticPrivateMethodSet" : "classStaticPrivateFieldSpecSet";
  374. return _core.types.callExpression(file.addHelper(helperName), [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id), value]);
  375. }
  376. const receiver = this.receiver(member);
  377. const skipCheck = _core.types.isIdentifier(receiver) && receiver.name === classRef.name;
  378. if (isMethod && !setId) {
  379. const err = readOnlyError(file, name);
  380. if (skipCheck) return _core.types.sequenceExpression([value, err]);
  381. return _core.types.sequenceExpression([value, _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver]), readOnlyError(file, name)]);
  382. }
  383. if (setId) {
  384. if (skipCheck) {
  385. return _core.types.callExpression(_core.types.cloneNode(setId), [receiver, value]);
  386. }
  387. return _core.types.callExpression(file.addHelper("classPrivateSetter"), [_core.types.cloneNode(classRef), cloneId(setId), receiver, value]);
  388. }
  389. return _core.types.assignmentExpression("=", buildStaticPrivateFieldAccess(cloneId(id), noUninitializedPrivateFieldAccess), skipCheck ? value : _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, value]));
  390. }
  391. if (isMethod) {
  392. if (setId) {
  393. if (!newHelpers(file)) {
  394. return _core.types.callExpression(file.addHelper("classPrivateFieldSet"), [this.receiver(member), cloneId(id), value]);
  395. }
  396. return _core.types.callExpression(file.addHelper("classPrivateSetter"), [_core.types.cloneNode(id), cloneId(setId), this.receiver(member), value]);
  397. }
  398. return _core.types.sequenceExpression([this.receiver(member), value, readOnlyError(file, name)]);
  399. }
  400. if (newHelpers(file)) {
  401. return _core.types.callExpression(file.addHelper("classPrivateFieldSet2"), [cloneId(id), this.receiver(member), value]);
  402. }
  403. return _core.types.callExpression(file.addHelper("classPrivateFieldSet"), [this.receiver(member), cloneId(id), value]);
  404. }),
  405. destructureSet(member) {
  406. const {
  407. classRef,
  408. privateNamesMap,
  409. file,
  410. noUninitializedPrivateFieldAccess
  411. } = this;
  412. const privateName = member.node.property;
  413. const {
  414. name
  415. } = privateName.id;
  416. const {
  417. id,
  418. static: isStatic,
  419. method: isMethod,
  420. setId
  421. } = privateNamesMap.get(name);
  422. const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
  423. if (!newHelpers(file)) {
  424. if (isStatic) {
  425. try {
  426. var helper = file.addHelper("classStaticPrivateFieldDestructureSet");
  427. } catch (_unused) {
  428. throw new Error("Babel can not transpile `[C.#p] = [0]` with @babel/helpers < 7.13.10, \n" + "please update @babel/helpers to the latest version.");
  429. }
  430. return _core.types.memberExpression(_core.types.callExpression(helper, [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id)]), _core.types.identifier("value"));
  431. }
  432. return _core.types.memberExpression(_core.types.callExpression(file.addHelper("classPrivateFieldDestructureSet"), [this.receiver(member), cloneId(id)]), _core.types.identifier("value"));
  433. }
  434. if (isMethod && !setId) {
  435. return _core.types.memberExpression(_core.types.sequenceExpression([member.node.object, readOnlyError(file, name)]), _core.types.identifier("_"));
  436. }
  437. if (isStatic && !isMethod) {
  438. const getCall = this.get(member);
  439. if (!noUninitializedPrivateFieldAccess || !_core.types.isCallExpression(getCall)) {
  440. return getCall;
  441. }
  442. const ref = getCall.arguments.pop();
  443. getCall.arguments.push(_core.template.expression.ast`(_) => ${ref} = _`);
  444. return _core.types.memberExpression(_core.types.callExpression(file.addHelper("toSetter"), [getCall]), _core.types.identifier("_"));
  445. }
  446. const setCall = this.set(member, _core.types.identifier("_"));
  447. if (!_core.types.isCallExpression(setCall) || !_core.types.isIdentifier(setCall.arguments[setCall.arguments.length - 1], {
  448. name: "_"
  449. })) {
  450. throw member.buildCodeFrameError("Internal Babel error while compiling this code. This is a Babel bug. " + "Please report it at https://github.com/babel/babel/issues.");
  451. }
  452. let args;
  453. if (_core.types.isMemberExpression(setCall.callee, {
  454. computed: false
  455. }) && _core.types.isIdentifier(setCall.callee.property) && setCall.callee.property.name === "call") {
  456. args = [setCall.callee.object, _core.types.arrayExpression(setCall.arguments.slice(1, -1)), setCall.arguments[0]];
  457. } else {
  458. args = [setCall.callee, _core.types.arrayExpression(setCall.arguments.slice(0, -1))];
  459. }
  460. return _core.types.memberExpression(_core.types.callExpression(file.addHelper("toSetter"), args), _core.types.identifier("_"));
  461. },
  462. call(member, args) {
  463. this.memoise(member, 1);
  464. return (0, _helperOptimiseCallExpression.default)(this.get(member), this.receiver(member), args, false);
  465. },
  466. optionalCall(member, args) {
  467. this.memoise(member, 1);
  468. return (0, _helperOptimiseCallExpression.default)(this.get(member), this.receiver(member), args, true);
  469. },
  470. delete() {
  471. throw new Error("Internal Babel error: deleting private elements is a parsing error.");
  472. }
  473. };
  474. const privateNameHandlerLoose = {
  475. get(member) {
  476. const {
  477. privateNamesMap,
  478. file
  479. } = this;
  480. const {
  481. object
  482. } = member.node;
  483. const {
  484. name
  485. } = member.node.property.id;
  486. return _core.template.expression`BASE(REF, PROP)[PROP]`({
  487. BASE: file.addHelper("classPrivateFieldLooseBase"),
  488. REF: _core.types.cloneNode(object),
  489. PROP: _core.types.cloneNode(privateNamesMap.get(name).id)
  490. });
  491. },
  492. set() {
  493. throw new Error("private name handler with loose = true don't need set()");
  494. },
  495. boundGet(member) {
  496. return _core.types.callExpression(_core.types.memberExpression(this.get(member), _core.types.identifier("bind")), [_core.types.cloneNode(member.node.object)]);
  497. },
  498. simpleSet(member) {
  499. return this.get(member);
  500. },
  501. destructureSet(member) {
  502. return this.get(member);
  503. },
  504. call(member, args) {
  505. return _core.types.callExpression(this.get(member), args);
  506. },
  507. optionalCall(member, args) {
  508. return _core.types.optionalCallExpression(this.get(member), args, true);
  509. },
  510. delete() {
  511. throw new Error("Internal Babel error: deleting private elements is a parsing error.");
  512. }
  513. };
  514. function transformPrivateNamesUsage(ref, path, privateNamesMap, {
  515. privateFieldsAsProperties,
  516. noUninitializedPrivateFieldAccess,
  517. noDocumentAll,
  518. innerBinding
  519. }, state) {
  520. if (!privateNamesMap.size) return;
  521. const body = path.get("body");
  522. const handler = privateFieldsAsProperties ? privateNameHandlerLoose : privateNameHandlerSpec;
  523. (0, _helperMemberExpressionToFunctions.default)(body, privateNameVisitor, Object.assign({
  524. privateNamesMap,
  525. classRef: ref,
  526. file: state
  527. }, handler, {
  528. noDocumentAll,
  529. noUninitializedPrivateFieldAccess,
  530. innerBinding
  531. }));
  532. body.traverse(privateInVisitor, {
  533. privateNamesMap,
  534. classRef: ref,
  535. file: state,
  536. privateFieldsAsProperties,
  537. innerBinding
  538. });
  539. }
  540. function buildPrivateFieldInitLoose(ref, prop, privateNamesMap) {
  541. const {
  542. id
  543. } = privateNamesMap.get(prop.node.key.id.name);
  544. const value = prop.node.value || prop.scope.buildUndefinedNode();
  545. return inheritPropComments(_core.template.statement.ast`
  546. Object.defineProperty(${ref}, ${_core.types.cloneNode(id)}, {
  547. // configurable is false by default
  548. // enumerable is false by default
  549. writable: true,
  550. value: ${value}
  551. });
  552. `, prop);
  553. }
  554. function buildPrivateInstanceFieldInitSpec(ref, prop, privateNamesMap, state) {
  555. const {
  556. id
  557. } = privateNamesMap.get(prop.node.key.id.name);
  558. const value = prop.node.value || prop.scope.buildUndefinedNode();
  559. {
  560. if (!state.availableHelper("classPrivateFieldInitSpec")) {
  561. return inheritPropComments(_core.template.statement.ast`${_core.types.cloneNode(id)}.set(${ref}, {
  562. // configurable is always false for private elements
  563. // enumerable is always false for private elements
  564. writable: true,
  565. value: ${value},
  566. })`, prop);
  567. }
  568. }
  569. const helper = state.addHelper("classPrivateFieldInitSpec");
  570. return inheritLoc(inheritPropComments(_core.types.expressionStatement(_core.types.callExpression(helper, [_core.types.thisExpression(), inheritLoc(_core.types.cloneNode(id), prop.node.key), newHelpers(state) ? value : _core.template.expression.ast`{ writable: true, value: ${value} }`])), prop), prop.node);
  571. }
  572. function buildPrivateStaticFieldInitSpec(prop, privateNamesMap, noUninitializedPrivateFieldAccess) {
  573. const privateName = privateNamesMap.get(prop.node.key.id.name);
  574. const value = noUninitializedPrivateFieldAccess ? prop.node.value : _core.template.expression.ast`{
  575. _: ${prop.node.value || _core.types.buildUndefinedNode()}
  576. }`;
  577. return inheritPropComments(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.cloneNode(privateName.id), value)]), prop);
  578. }
  579. {
  580. var buildPrivateStaticFieldInitSpecOld = function (prop, privateNamesMap) {
  581. const privateName = privateNamesMap.get(prop.node.key.id.name);
  582. const {
  583. id,
  584. getId,
  585. setId,
  586. initAdded
  587. } = privateName;
  588. const isGetterOrSetter = getId || setId;
  589. if (!prop.isProperty() && (initAdded || !isGetterOrSetter)) return;
  590. if (isGetterOrSetter) {
  591. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  592. initAdded: true
  593. }));
  594. return inheritPropComments(_core.template.statement.ast`
  595. var ${_core.types.cloneNode(id)} = {
  596. // configurable is false by default
  597. // enumerable is false by default
  598. // writable is false by default
  599. get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
  600. set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
  601. }
  602. `, prop);
  603. }
  604. const value = prop.node.value || prop.scope.buildUndefinedNode();
  605. return inheritPropComments(_core.template.statement.ast`
  606. var ${_core.types.cloneNode(id)} = {
  607. // configurable is false by default
  608. // enumerable is false by default
  609. writable: true,
  610. value: ${value}
  611. };
  612. `, prop);
  613. };
  614. }
  615. function buildPrivateMethodInitLoose(ref, prop, privateNamesMap) {
  616. const privateName = privateNamesMap.get(prop.node.key.id.name);
  617. const {
  618. methodId,
  619. id,
  620. getId,
  621. setId,
  622. initAdded
  623. } = privateName;
  624. if (initAdded) return;
  625. if (methodId) {
  626. return inheritPropComments(_core.template.statement.ast`
  627. Object.defineProperty(${ref}, ${id}, {
  628. // configurable is false by default
  629. // enumerable is false by default
  630. // writable is false by default
  631. value: ${methodId.name}
  632. });
  633. `, prop);
  634. }
  635. const isGetterOrSetter = getId || setId;
  636. if (isGetterOrSetter) {
  637. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  638. initAdded: true
  639. }));
  640. return inheritPropComments(_core.template.statement.ast`
  641. Object.defineProperty(${ref}, ${id}, {
  642. // configurable is false by default
  643. // enumerable is false by default
  644. // writable is false by default
  645. get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
  646. set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
  647. });
  648. `, prop);
  649. }
  650. }
  651. function buildPrivateInstanceMethodInitSpec(ref, prop, privateNamesMap, state) {
  652. const privateName = privateNamesMap.get(prop.node.key.id.name);
  653. if (privateName.initAdded) return;
  654. if (!newHelpers(state)) {
  655. const isGetterOrSetter = privateName.getId || privateName.setId;
  656. if (isGetterOrSetter) {
  657. return buildPrivateAccessorInitialization(ref, prop, privateNamesMap, state);
  658. }
  659. }
  660. return buildPrivateInstanceMethodInitialization(ref, prop, privateNamesMap, state);
  661. }
  662. function buildPrivateAccessorInitialization(ref, prop, privateNamesMap, state) {
  663. const privateName = privateNamesMap.get(prop.node.key.id.name);
  664. const {
  665. id,
  666. getId,
  667. setId
  668. } = privateName;
  669. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  670. initAdded: true
  671. }));
  672. {
  673. if (!state.availableHelper("classPrivateFieldInitSpec")) {
  674. return inheritPropComments(_core.template.statement.ast`
  675. ${id}.set(${ref}, {
  676. get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
  677. set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
  678. });
  679. `, prop);
  680. }
  681. }
  682. const helper = state.addHelper("classPrivateFieldInitSpec");
  683. return inheritLoc(inheritPropComments(_core.template.statement.ast`${helper}(
  684. ${_core.types.thisExpression()},
  685. ${_core.types.cloneNode(id)},
  686. {
  687. get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
  688. set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
  689. },
  690. )`, prop), prop.node);
  691. }
  692. function buildPrivateInstanceMethodInitialization(ref, prop, privateNamesMap, state) {
  693. const privateName = privateNamesMap.get(prop.node.key.id.name);
  694. const {
  695. id
  696. } = privateName;
  697. {
  698. if (!state.availableHelper("classPrivateMethodInitSpec")) {
  699. return inheritPropComments(_core.template.statement.ast`${id}.add(${ref})`, prop);
  700. }
  701. }
  702. const helper = state.addHelper("classPrivateMethodInitSpec");
  703. return inheritPropComments(_core.template.statement.ast`${helper}(
  704. ${_core.types.thisExpression()},
  705. ${_core.types.cloneNode(id)}
  706. )`, prop);
  707. }
  708. function buildPublicFieldInitLoose(ref, prop) {
  709. const {
  710. key,
  711. computed
  712. } = prop.node;
  713. const value = prop.node.value || prop.scope.buildUndefinedNode();
  714. return inheritPropComments(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(ref, key, computed || _core.types.isLiteral(key)), value)), prop);
  715. }
  716. function buildPublicFieldInitSpec(ref, prop, state) {
  717. const {
  718. key,
  719. computed
  720. } = prop.node;
  721. const value = prop.node.value || prop.scope.buildUndefinedNode();
  722. return inheritPropComments(_core.types.expressionStatement(_core.types.callExpression(state.addHelper("defineProperty"), [ref, computed || _core.types.isLiteral(key) ? key : _core.types.stringLiteral(key.name), value])), prop);
  723. }
  724. function buildPrivateStaticMethodInitLoose(ref, prop, state, privateNamesMap) {
  725. const privateName = privateNamesMap.get(prop.node.key.id.name);
  726. const {
  727. id,
  728. methodId,
  729. getId,
  730. setId,
  731. initAdded
  732. } = privateName;
  733. if (initAdded) return;
  734. const isGetterOrSetter = getId || setId;
  735. if (isGetterOrSetter) {
  736. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  737. initAdded: true
  738. }));
  739. return inheritPropComments(_core.template.statement.ast`
  740. Object.defineProperty(${ref}, ${id}, {
  741. // configurable is false by default
  742. // enumerable is false by default
  743. // writable is false by default
  744. get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
  745. set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
  746. })
  747. `, prop);
  748. }
  749. return inheritPropComments(_core.template.statement.ast`
  750. Object.defineProperty(${ref}, ${id}, {
  751. // configurable is false by default
  752. // enumerable is false by default
  753. // writable is false by default
  754. value: ${methodId.name}
  755. });
  756. `, prop);
  757. }
  758. function buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties = false) {
  759. const privateName = privateNamesMap.get(prop.node.key.id.name);
  760. const {
  761. id,
  762. methodId,
  763. getId,
  764. setId,
  765. getterDeclared,
  766. setterDeclared,
  767. static: isStatic
  768. } = privateName;
  769. const {
  770. params,
  771. body,
  772. generator,
  773. async
  774. } = prop.node;
  775. const isGetter = getId && params.length === 0;
  776. const isSetter = setId && params.length > 0;
  777. if (isGetter && getterDeclared || isSetter && setterDeclared) {
  778. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  779. initAdded: true
  780. }));
  781. return null;
  782. }
  783. if (newHelpers(file) && (isGetter || isSetter) && !privateFieldsAsSymbolsOrProperties) {
  784. const scope = prop.get("body").scope;
  785. const thisArg = scope.generateUidIdentifier("this");
  786. const state = {
  787. thisRef: thisArg,
  788. argumentsPath: []
  789. };
  790. prop.traverse(thisContextVisitor, state);
  791. if (state.argumentsPath.length) {
  792. const argumentsId = scope.generateUidIdentifier("arguments");
  793. scope.push({
  794. id: argumentsId,
  795. init: _core.template.expression.ast`[].slice.call(arguments, 1)`
  796. });
  797. for (const path of state.argumentsPath) {
  798. path.replaceWith(_core.types.cloneNode(argumentsId));
  799. }
  800. }
  801. params.unshift(_core.types.cloneNode(thisArg));
  802. }
  803. let declId = methodId;
  804. if (isGetter) {
  805. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  806. getterDeclared: true,
  807. initAdded: true
  808. }));
  809. declId = getId;
  810. } else if (isSetter) {
  811. privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
  812. setterDeclared: true,
  813. initAdded: true
  814. }));
  815. declId = setId;
  816. } else if (isStatic && !privateFieldsAsSymbolsOrProperties) {
  817. declId = id;
  818. }
  819. return inheritPropComments(_core.types.functionDeclaration(_core.types.cloneNode(declId), params, body, generator, async), prop);
  820. }
  821. const thisContextVisitor = _traverse.visitors.environmentVisitor({
  822. Identifier(path, state) {
  823. if (state.argumentsPath && path.node.name === "arguments") {
  824. state.argumentsPath.push(path);
  825. }
  826. },
  827. UnaryExpression(path) {
  828. const {
  829. node
  830. } = path;
  831. if (node.operator === "delete") {
  832. const argument = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes)(node.argument);
  833. if (_core.types.isThisExpression(argument)) {
  834. path.replaceWith(_core.types.booleanLiteral(true));
  835. }
  836. }
  837. },
  838. ThisExpression(path, state) {
  839. state.needsClassRef = true;
  840. path.replaceWith(_core.types.cloneNode(state.thisRef));
  841. },
  842. MetaProperty(path) {
  843. const {
  844. node,
  845. scope
  846. } = path;
  847. if (node.meta.name === "new" && node.property.name === "target") {
  848. path.replaceWith(scope.buildUndefinedNode());
  849. }
  850. }
  851. });
  852. const innerReferencesVisitor = {
  853. ReferencedIdentifier(path, state) {
  854. if (path.scope.bindingIdentifierEquals(path.node.name, state.innerBinding)) {
  855. state.needsClassRef = true;
  856. path.node.name = state.thisRef.name;
  857. }
  858. }
  859. };
  860. function replaceThisContext(path, ref, innerBindingRef) {
  861. var _state$thisRef;
  862. const state = {
  863. thisRef: ref,
  864. needsClassRef: false,
  865. innerBinding: innerBindingRef
  866. };
  867. if (!path.isMethod()) {
  868. path.traverse(thisContextVisitor, state);
  869. }
  870. if (innerBindingRef != null && (_state$thisRef = state.thisRef) != null && _state$thisRef.name && state.thisRef.name !== innerBindingRef.name) {
  871. path.traverse(innerReferencesVisitor, state);
  872. }
  873. return state.needsClassRef;
  874. }
  875. function isNameOrLength({
  876. key,
  877. computed
  878. }) {
  879. if (key.type === "Identifier") {
  880. return !computed && (key.name === "name" || key.name === "length");
  881. }
  882. if (key.type === "StringLiteral") {
  883. return key.value === "name" || key.value === "length";
  884. }
  885. return false;
  886. }
  887. function inheritPropComments(node, prop) {
  888. _core.types.inheritLeadingComments(node, prop.node);
  889. _core.types.inheritInnerComments(node, prop.node);
  890. return node;
  891. }
  892. function inheritLoc(node, original) {
  893. node.start = original.start;
  894. node.end = original.end;
  895. node.loc = original.loc;
  896. return node;
  897. }
  898. function buildFieldsInitNodes(ref, superRef, props, privateNamesMap, file, setPublicClassFields, privateFieldsAsSymbolsOrProperties, noUninitializedPrivateFieldAccess, constantSuper, innerBindingRef) {
  899. var _ref, _ref2;
  900. let classRefFlags = 0;
  901. let injectSuperRef;
  902. const staticNodes = [];
  903. const instanceNodes = [];
  904. let lastInstanceNodeReturnsThis = false;
  905. const pureStaticNodes = [];
  906. let classBindingNode = null;
  907. const getSuperRef = _core.types.isIdentifier(superRef) ? () => superRef : () => {
  908. var _injectSuperRef;
  909. (_injectSuperRef = injectSuperRef) != null ? _injectSuperRef : injectSuperRef = props[0].scope.generateUidIdentifierBasedOnNode(superRef);
  910. return injectSuperRef;
  911. };
  912. const classRefForInnerBinding = (_ref = ref) != null ? _ref : props[0].scope.generateUidIdentifier((innerBindingRef == null ? void 0 : innerBindingRef.name) || "Class");
  913. (_ref2 = ref) != null ? _ref2 : ref = _core.types.cloneNode(innerBindingRef);
  914. for (const prop of props) {
  915. if (prop.isClassProperty()) {
  916. ts.assertFieldTransformed(prop);
  917. }
  918. const isStatic = !(_core.types.isStaticBlock != null && _core.types.isStaticBlock(prop.node)) && prop.node.static;
  919. const isInstance = !isStatic;
  920. const isPrivate = prop.isPrivate();
  921. const isPublic = !isPrivate;
  922. const isField = prop.isProperty();
  923. const isMethod = !isField;
  924. const isStaticBlock = prop.isStaticBlock == null ? void 0 : prop.isStaticBlock();
  925. if (isStatic) classRefFlags |= 1;
  926. if (isStatic || isMethod && isPrivate || isStaticBlock) {
  927. new _helperReplaceSupers.default({
  928. methodPath: prop,
  929. constantSuper,
  930. file: file,
  931. refToPreserve: innerBindingRef,
  932. getSuperRef,
  933. getObjectRef() {
  934. classRefFlags |= 2;
  935. if (isStatic || isStaticBlock) {
  936. return classRefForInnerBinding;
  937. } else {
  938. return _core.types.memberExpression(classRefForInnerBinding, _core.types.identifier("prototype"));
  939. }
  940. }
  941. }).replace();
  942. const replaced = replaceThisContext(prop, classRefForInnerBinding, innerBindingRef);
  943. if (replaced) {
  944. classRefFlags |= 2;
  945. }
  946. }
  947. lastInstanceNodeReturnsThis = false;
  948. switch (true) {
  949. case isStaticBlock:
  950. {
  951. const blockBody = prop.node.body;
  952. if (blockBody.length === 1 && _core.types.isExpressionStatement(blockBody[0])) {
  953. staticNodes.push(inheritPropComments(blockBody[0], prop));
  954. } else {
  955. staticNodes.push(_core.types.inheritsComments(_core.template.statement.ast`(() => { ${blockBody} })()`, prop.node));
  956. }
  957. break;
  958. }
  959. case isStatic && isPrivate && isField && privateFieldsAsSymbolsOrProperties:
  960. staticNodes.push(buildPrivateFieldInitLoose(_core.types.cloneNode(ref), prop, privateNamesMap));
  961. break;
  962. case isStatic && isPrivate && isField && !privateFieldsAsSymbolsOrProperties:
  963. if (!newHelpers(file)) {
  964. staticNodes.push(buildPrivateStaticFieldInitSpecOld(prop, privateNamesMap));
  965. } else {
  966. staticNodes.push(buildPrivateStaticFieldInitSpec(prop, privateNamesMap, noUninitializedPrivateFieldAccess));
  967. }
  968. break;
  969. case isStatic && isPublic && isField && setPublicClassFields:
  970. if (!isNameOrLength(prop.node)) {
  971. staticNodes.push(buildPublicFieldInitLoose(_core.types.cloneNode(ref), prop));
  972. break;
  973. }
  974. case isStatic && isPublic && isField && !setPublicClassFields:
  975. staticNodes.push(buildPublicFieldInitSpec(_core.types.cloneNode(ref), prop, file));
  976. break;
  977. case isInstance && isPrivate && isField && privateFieldsAsSymbolsOrProperties:
  978. instanceNodes.push(buildPrivateFieldInitLoose(_core.types.thisExpression(), prop, privateNamesMap));
  979. break;
  980. case isInstance && isPrivate && isField && !privateFieldsAsSymbolsOrProperties:
  981. instanceNodes.push(buildPrivateInstanceFieldInitSpec(_core.types.thisExpression(), prop, privateNamesMap, file));
  982. break;
  983. case isInstance && isPrivate && isMethod && privateFieldsAsSymbolsOrProperties:
  984. instanceNodes.unshift(buildPrivateMethodInitLoose(_core.types.thisExpression(), prop, privateNamesMap));
  985. pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
  986. break;
  987. case isInstance && isPrivate && isMethod && !privateFieldsAsSymbolsOrProperties:
  988. instanceNodes.unshift(buildPrivateInstanceMethodInitSpec(_core.types.thisExpression(), prop, privateNamesMap, file));
  989. pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
  990. break;
  991. case isStatic && isPrivate && isMethod && !privateFieldsAsSymbolsOrProperties:
  992. if (!newHelpers(file)) {
  993. staticNodes.unshift(buildPrivateStaticFieldInitSpecOld(prop, privateNamesMap));
  994. }
  995. pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
  996. break;
  997. case isStatic && isPrivate && isMethod && privateFieldsAsSymbolsOrProperties:
  998. staticNodes.unshift(buildPrivateStaticMethodInitLoose(_core.types.cloneNode(ref), prop, file, privateNamesMap));
  999. pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
  1000. break;
  1001. case isInstance && isPublic && isField && setPublicClassFields:
  1002. instanceNodes.push(buildPublicFieldInitLoose(_core.types.thisExpression(), prop));
  1003. break;
  1004. case isInstance && isPublic && isField && !setPublicClassFields:
  1005. lastInstanceNodeReturnsThis = true;
  1006. instanceNodes.push(buildPublicFieldInitSpec(_core.types.thisExpression(), prop, file));
  1007. break;
  1008. default:
  1009. throw new Error("Unreachable.");
  1010. }
  1011. }
  1012. if (classRefFlags & 2 && innerBindingRef != null) {
  1013. classBindingNode = _core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(classRefForInnerBinding), _core.types.cloneNode(innerBindingRef)));
  1014. }
  1015. return {
  1016. staticNodes: staticNodes.filter(Boolean),
  1017. instanceNodes: instanceNodes.filter(Boolean),
  1018. lastInstanceNodeReturnsThis,
  1019. pureStaticNodes: pureStaticNodes.filter(Boolean),
  1020. classBindingNode,
  1021. wrapClass(path) {
  1022. for (const prop of props) {
  1023. prop.node.leadingComments = null;
  1024. prop.remove();
  1025. }
  1026. if (injectSuperRef) {
  1027. path.scope.push({
  1028. id: _core.types.cloneNode(injectSuperRef)
  1029. });
  1030. path.set("superClass", _core.types.assignmentExpression("=", injectSuperRef, path.node.superClass));
  1031. }
  1032. if (classRefFlags !== 0) {
  1033. if (path.isClassExpression()) {
  1034. path.scope.push({
  1035. id: ref
  1036. });
  1037. path.replaceWith(_core.types.assignmentExpression("=", _core.types.cloneNode(ref), path.node));
  1038. } else {
  1039. if (innerBindingRef == null) {
  1040. path.node.id = ref;
  1041. }
  1042. if (classBindingNode != null) {
  1043. path.scope.push({
  1044. id: classRefForInnerBinding
  1045. });
  1046. }
  1047. }
  1048. }
  1049. return path;
  1050. }
  1051. };
  1052. }
  1053. //# sourceMappingURL=fields.js.map