Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

3 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. function _helperPluginUtils() {
  7. const data = require("@babel/helper-plugin-utils");
  8. _helperPluginUtils = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _helperFunctionName() {
  14. const data = _interopRequireDefault(require("@babel/helper-function-name"));
  15. _helperFunctionName = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _pluginSyntaxClassProperties() {
  21. const data = _interopRequireDefault(require("@babel/plugin-syntax-class-properties"));
  22. _pluginSyntaxClassProperties = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _core() {
  28. const data = require("@babel/core");
  29. _core = function () {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _helperReplaceSupers() {
  35. const data = require("@babel/helper-replace-supers");
  36. _helperReplaceSupers = function () {
  37. return data;
  38. };
  39. return data;
  40. }
  41. function _helperMemberExpressionToFunctions() {
  42. const data = _interopRequireDefault(require("@babel/helper-member-expression-to-functions"));
  43. _helperMemberExpressionToFunctions = function () {
  44. return data;
  45. };
  46. return data;
  47. }
  48. function _helperOptimiseCallExpression() {
  49. const data = _interopRequireDefault(require("@babel/helper-optimise-call-expression"));
  50. _helperOptimiseCallExpression = function () {
  51. return data;
  52. };
  53. return data;
  54. }
  55. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  56. var _default = (0, _helperPluginUtils().declare)((api, options) => {
  57. api.assertVersion(7);
  58. const {
  59. loose
  60. } = options;
  61. const findBareSupers = _core().traverse.visitors.merge([{
  62. Super(path) {
  63. const {
  64. node,
  65. parentPath
  66. } = path;
  67. if (parentPath.isCallExpression({
  68. callee: node
  69. })) {
  70. this.push(parentPath);
  71. }
  72. }
  73. }, _helperReplaceSupers().environmentVisitor]);
  74. const referenceVisitor = {
  75. "TSTypeAnnotation|TypeAnnotation"(path) {
  76. path.skip();
  77. },
  78. ReferencedIdentifier(path) {
  79. if (this.scope.hasOwnBinding(path.node.name)) {
  80. this.scope.rename(path.node.name);
  81. path.skip();
  82. }
  83. }
  84. };
  85. const classFieldDefinitionEvaluationTDZVisitor = _core().traverse.visitors.merge([{
  86. ReferencedIdentifier(path) {
  87. if (this.classBinding && this.classBinding === path.scope.getBinding(path.node.name)) {
  88. const classNameTDZError = this.file.addHelper("classNameTDZError");
  89. const throwNode = _core().types.callExpression(classNameTDZError, [_core().types.stringLiteral(path.node.name)]);
  90. path.replaceWith(_core().types.sequenceExpression([throwNode, path.node]));
  91. path.skip();
  92. }
  93. }
  94. }, _helperReplaceSupers().environmentVisitor]);
  95. const privateNameVisitor = {
  96. PrivateName(path) {
  97. const {
  98. name
  99. } = this;
  100. const {
  101. node,
  102. parentPath
  103. } = path;
  104. if (!parentPath.isMemberExpression({
  105. property: node
  106. })) return;
  107. if (node.id.name !== name) return;
  108. this.handle(parentPath);
  109. },
  110. Class(path) {
  111. const {
  112. name
  113. } = this;
  114. const body = path.get("body.body");
  115. for (const prop of body) {
  116. if (!prop.isClassPrivateProperty()) continue;
  117. if (prop.node.key.id.name !== name) continue;
  118. path.traverse(privateNameInnerVisitor, this);
  119. path.skip();
  120. break;
  121. }
  122. }
  123. };
  124. const privateNameInnerVisitor = _core().traverse.visitors.merge([{
  125. PrivateName: privateNameVisitor.PrivateName
  126. }, _helperReplaceSupers().environmentVisitor]);
  127. const privateNameHandlerSpec = {
  128. memoise(member, count) {
  129. const {
  130. scope
  131. } = member;
  132. const {
  133. object
  134. } = member.node;
  135. const memo = scope.maybeGenerateMemoised(object);
  136. if (!memo) {
  137. return;
  138. }
  139. this.memoiser.set(object, memo, count);
  140. },
  141. receiver(member) {
  142. const {
  143. object
  144. } = member.node;
  145. if (this.memoiser.has(object)) {
  146. return _core().types.cloneNode(this.memoiser.get(object));
  147. }
  148. return _core().types.cloneNode(object);
  149. },
  150. get(member) {
  151. const {
  152. map,
  153. file
  154. } = this;
  155. return _core().types.callExpression(file.addHelper("classPrivateFieldGet"), [this.receiver(member), _core().types.cloneNode(map)]);
  156. },
  157. set(member, value) {
  158. const {
  159. map,
  160. file
  161. } = this;
  162. return _core().types.callExpression(file.addHelper("classPrivateFieldSet"), [this.receiver(member), _core().types.cloneNode(map), value]);
  163. },
  164. call(member, args) {
  165. this.memoise(member, 1);
  166. return (0, _helperOptimiseCallExpression().default)(this.get(member), this.receiver(member), args);
  167. }
  168. };
  169. const privateNameHandlerLoose = {
  170. handle(member) {
  171. const {
  172. prop,
  173. file
  174. } = this;
  175. const {
  176. object
  177. } = member.node;
  178. member.replaceWith(_core().template.expression`BASE(REF, PROP)[PROP]`({
  179. BASE: file.addHelper("classPrivateFieldLooseBase"),
  180. REF: object,
  181. PROP: prop
  182. }));
  183. }
  184. };
  185. const staticPrivatePropertyHandlerSpec = Object.assign({}, privateNameHandlerSpec, {
  186. get(member) {
  187. const {
  188. file,
  189. privateId,
  190. classRef
  191. } = this;
  192. return _core().types.callExpression(file.addHelper("classStaticPrivateFieldSpecGet"), [this.receiver(member), _core().types.cloneNode(classRef), _core().types.cloneNode(privateId)]);
  193. },
  194. set(member, value) {
  195. const {
  196. file,
  197. privateId,
  198. classRef
  199. } = this;
  200. return _core().types.callExpression(file.addHelper("classStaticPrivateFieldSpecSet"), [this.receiver(member), _core().types.cloneNode(classRef), _core().types.cloneNode(privateId), value]);
  201. }
  202. });
  203. function buildClassPropertySpec(ref, path, state) {
  204. const {
  205. scope
  206. } = path;
  207. const {
  208. key,
  209. value,
  210. computed
  211. } = path.node;
  212. return _core().types.expressionStatement(_core().types.callExpression(state.addHelper("defineProperty"), [ref, computed || _core().types.isLiteral(key) ? key : _core().types.stringLiteral(key.name), value || scope.buildUndefinedNode()]));
  213. }
  214. function buildClassPropertyLoose(ref, path) {
  215. const {
  216. scope
  217. } = path;
  218. const {
  219. key,
  220. value,
  221. computed
  222. } = path.node;
  223. return _core().types.expressionStatement(_core().types.assignmentExpression("=", _core().types.memberExpression(ref, key, computed || _core().types.isLiteral(key)), value || scope.buildUndefinedNode()));
  224. }
  225. function buildClassPrivatePropertySpec(ref, path, initNodes, state) {
  226. const {
  227. parentPath,
  228. scope
  229. } = path;
  230. const {
  231. name
  232. } = path.node.key.id;
  233. const map = scope.generateUidIdentifier(name);
  234. (0, _helperMemberExpressionToFunctions().default)(parentPath, privateNameVisitor, Object.assign({
  235. name,
  236. map,
  237. file: state
  238. }, privateNameHandlerSpec));
  239. initNodes.push(_core().template.statement`var MAP = new WeakMap();`({
  240. MAP: map
  241. }));
  242. return () => _core().template.statement`
  243. MAP.set(REF, {
  244. // configurable is always false for private elements
  245. // enumerable is always false for private elements
  246. writable: true,
  247. value: VALUE
  248. });
  249. `({
  250. MAP: map,
  251. REF: ref,
  252. VALUE: path.node.value || scope.buildUndefinedNode()
  253. });
  254. }
  255. function buildClassPrivatePropertyLooseHelper(ref, path, state) {
  256. const {
  257. parentPath,
  258. scope
  259. } = path;
  260. const {
  261. name
  262. } = path.node.key.id;
  263. const prop = scope.generateUidIdentifier(name);
  264. parentPath.traverse(privateNameVisitor, Object.assign({
  265. name,
  266. prop,
  267. file: state
  268. }, privateNameHandlerLoose));
  269. return {
  270. keyDecl: _core().template.statement`var PROP = HELPER(NAME);`({
  271. PROP: prop,
  272. HELPER: state.addHelper("classPrivateFieldLooseKey"),
  273. NAME: _core().types.stringLiteral(name)
  274. }),
  275. buildInit: () => _core().template.statement.ast`
  276. Object.defineProperty(${ref}, ${prop}, {
  277. // configurable is false by default
  278. // enumerable is false by default
  279. writable: true,
  280. value: ${path.node.value || scope.buildUndefinedNode()}
  281. });
  282. `
  283. };
  284. }
  285. function buildClassInstancePrivatePropertyLoose(ref, path, initNodes, state) {
  286. const {
  287. keyDecl,
  288. buildInit
  289. } = buildClassPrivatePropertyLooseHelper(ref, path, state);
  290. initNodes.push(keyDecl);
  291. return buildInit;
  292. }
  293. function buildClassStaticPrivatePropertyLoose(ref, path, state) {
  294. const {
  295. keyDecl,
  296. buildInit
  297. } = buildClassPrivatePropertyLooseHelper(ref, path, state);
  298. return [keyDecl, buildInit()];
  299. }
  300. function buildClassStaticPrivatePropertySpec(ref, path, state) {
  301. const {
  302. parentPath,
  303. scope
  304. } = path;
  305. const {
  306. name
  307. } = path.node.key.id;
  308. const privateId = scope.generateUidIdentifier(name);
  309. (0, _helperMemberExpressionToFunctions().default)(parentPath, privateNameVisitor, Object.assign({
  310. name,
  311. privateId,
  312. classRef: ref,
  313. file: state
  314. }, staticPrivatePropertyHandlerSpec));
  315. return [_core().template.statement.ast`
  316. var ${privateId} = {
  317. // configurable is always false for private elements
  318. // enumerable is always false for private elements
  319. writable: true,
  320. value: ${path.node.value || scope.buildUndefinedNode()}
  321. }
  322. `];
  323. }
  324. const buildClassProperty = loose ? buildClassPropertyLoose : buildClassPropertySpec;
  325. const buildClassPrivateProperty = loose ? buildClassInstancePrivatePropertyLoose : buildClassPrivatePropertySpec;
  326. const buildClassStaticPrivateProperty = loose ? buildClassStaticPrivatePropertyLoose : buildClassStaticPrivatePropertySpec;
  327. return {
  328. inherits: _pluginSyntaxClassProperties().default,
  329. visitor: {
  330. Class(path, state) {
  331. const isDerived = !!path.node.superClass;
  332. let constructor;
  333. const props = [];
  334. const computedPaths = [];
  335. const privateNames = new Set();
  336. const body = path.get("body");
  337. for (const path of body.get("body")) {
  338. const {
  339. computed,
  340. decorators
  341. } = path.node;
  342. if (computed) {
  343. computedPaths.push(path);
  344. }
  345. if (decorators && decorators.length > 0) {
  346. throw path.buildCodeFrameError("Decorators transform is necessary.");
  347. }
  348. if (path.isClassPrivateProperty()) {
  349. const {
  350. key: {
  351. id: {
  352. name
  353. }
  354. }
  355. } = path.node;
  356. if (privateNames.has(name)) {
  357. throw path.buildCodeFrameError("Duplicate private field");
  358. }
  359. privateNames.add(name);
  360. }
  361. if (path.isProperty()) {
  362. props.push(path);
  363. } else if (path.isClassMethod({
  364. kind: "constructor"
  365. })) {
  366. constructor = path;
  367. }
  368. }
  369. if (!props.length) return;
  370. let ref;
  371. if (path.isClassExpression() || !path.node.id) {
  372. (0, _helperFunctionName().default)(path);
  373. ref = path.scope.generateUidIdentifier("class");
  374. } else {
  375. ref = path.node.id;
  376. }
  377. const computedNodes = [];
  378. const staticNodes = [];
  379. const instanceBody = [];
  380. for (const computedPath of computedPaths) {
  381. computedPath.traverse(classFieldDefinitionEvaluationTDZVisitor, {
  382. classBinding: path.node.id && path.scope.getBinding(path.node.id.name),
  383. file: this.file
  384. });
  385. const computedNode = computedPath.node;
  386. if (!computedPath.get("key").isConstantExpression()) {
  387. const ident = path.scope.generateUidIdentifierBasedOnNode(computedNode.key);
  388. computedNodes.push(_core().types.variableDeclaration("var", [_core().types.variableDeclarator(ident, computedNode.key)]));
  389. computedNode.key = _core().types.cloneNode(ident);
  390. }
  391. }
  392. const privateMaps = [];
  393. const privateMapInits = [];
  394. for (const prop of props) {
  395. if (prop.isPrivate() && !prop.node.static) {
  396. const inits = [];
  397. privateMapInits.push(inits);
  398. privateMaps.push(buildClassPrivateProperty(_core().types.thisExpression(), prop, inits, state));
  399. }
  400. }
  401. let p = 0;
  402. for (const prop of props) {
  403. if (prop.node.static) {
  404. if (prop.isPrivate()) {
  405. staticNodes.push(...buildClassStaticPrivateProperty(_core().types.cloneNode(ref), prop, state));
  406. } else {
  407. staticNodes.push(buildClassProperty(_core().types.cloneNode(ref), prop, state));
  408. }
  409. } else if (prop.isPrivate()) {
  410. instanceBody.push(privateMaps[p]());
  411. staticNodes.push(...privateMapInits[p]);
  412. p++;
  413. } else {
  414. instanceBody.push(buildClassProperty(_core().types.thisExpression(), prop, state));
  415. }
  416. }
  417. if (instanceBody.length) {
  418. if (!constructor) {
  419. const newConstructor = _core().types.classMethod("constructor", _core().types.identifier("constructor"), [], _core().types.blockStatement([]));
  420. if (isDerived) {
  421. newConstructor.params = [_core().types.restElement(_core().types.identifier("args"))];
  422. newConstructor.body.body.push(_core().types.expressionStatement(_core().types.callExpression(_core().types.super(), [_core().types.spreadElement(_core().types.identifier("args"))])));
  423. }
  424. [constructor] = body.unshiftContainer("body", newConstructor);
  425. }
  426. const state = {
  427. scope: constructor.scope
  428. };
  429. for (const prop of props) {
  430. if (prop.node.static) continue;
  431. prop.traverse(referenceVisitor, state);
  432. }
  433. if (isDerived) {
  434. const bareSupers = [];
  435. constructor.traverse(findBareSupers, bareSupers);
  436. for (const bareSuper of bareSupers) {
  437. bareSuper.insertAfter(instanceBody);
  438. }
  439. } else {
  440. constructor.get("body").unshiftContainer("body", instanceBody);
  441. }
  442. }
  443. for (const prop of props) {
  444. prop.remove();
  445. }
  446. if (computedNodes.length === 0 && staticNodes.length === 0) return;
  447. if (path.isClassExpression()) {
  448. path.scope.push({
  449. id: ref
  450. });
  451. path.replaceWith(_core().types.assignmentExpression("=", _core().types.cloneNode(ref), path.node));
  452. } else if (!path.node.id) {
  453. path.node.id = ref;
  454. }
  455. path.insertBefore(computedNodes);
  456. path.insertAfter(staticNodes);
  457. },
  458. PrivateName(path) {
  459. throw path.buildCodeFrameError(`Unknown PrivateName "${path}"`);
  460. }
  461. }
  462. };
  463. });
  464. exports.default = _default;