fields.js 40 KB

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