applyDecs.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import _typeof from "./typeof.js";
  2. function createMetadataMethodsForProperty(metadataMap, kind, property) {
  3. return {
  4. getMetadata: function getMetadata(key) {
  5. if ("symbol" != _typeof(key)) throw new TypeError("Metadata keys must be symbols, received: " + key);
  6. var metadataForKey = metadataMap[key];
  7. if (void 0 !== metadataForKey) if (1 === kind) {
  8. var pub = metadataForKey["public"];
  9. if (void 0 !== pub) return pub[property];
  10. } else if (2 === kind) {
  11. var priv = metadataForKey["private"];
  12. if (void 0 !== priv) return priv.get(property);
  13. } else if (Object.hasOwnProperty.call(metadataForKey, "constructor")) return metadataForKey.constructor;
  14. },
  15. setMetadata: function setMetadata(key, value) {
  16. if ("symbol" != _typeof(key)) throw new TypeError("Metadata keys must be symbols, received: " + key);
  17. var metadataForKey = metadataMap[key];
  18. if (void 0 === metadataForKey && (metadataForKey = metadataMap[key] = {}), 1 === kind) {
  19. var pub = metadataForKey["public"];
  20. void 0 === pub && (pub = metadataForKey["public"] = {}), pub[property] = value;
  21. } else if (2 === kind) {
  22. var priv = metadataForKey.priv;
  23. void 0 === priv && (priv = metadataForKey["private"] = new Map()), priv.set(property, value);
  24. } else metadataForKey.constructor = value;
  25. }
  26. };
  27. }
  28. function convertMetadataMapToFinal(obj, metadataMap) {
  29. var parentMetadataMap = obj[Symbol.metadata || Symbol["for"]("Symbol.metadata")],
  30. metadataKeys = Object.getOwnPropertySymbols(metadataMap);
  31. if (0 !== metadataKeys.length) {
  32. for (var i = 0; i < metadataKeys.length; i++) {
  33. var key = metadataKeys[i],
  34. metaForKey = metadataMap[key],
  35. parentMetaForKey = parentMetadataMap ? parentMetadataMap[key] : null,
  36. pub = metaForKey["public"],
  37. parentPub = parentMetaForKey ? parentMetaForKey["public"] : null;
  38. pub && parentPub && Object.setPrototypeOf(pub, parentPub);
  39. var priv = metaForKey["private"];
  40. if (priv) {
  41. var privArr = Array.from(priv.values()),
  42. parentPriv = parentMetaForKey ? parentMetaForKey["private"] : null;
  43. parentPriv && (privArr = privArr.concat(parentPriv)), metaForKey["private"] = privArr;
  44. }
  45. parentMetaForKey && Object.setPrototypeOf(metaForKey, parentMetaForKey);
  46. }
  47. parentMetadataMap && Object.setPrototypeOf(metadataMap, parentMetadataMap), obj[Symbol.metadata || Symbol["for"]("Symbol.metadata")] = metadataMap;
  48. }
  49. }
  50. function createAddInitializerMethod(initializers) {
  51. return function (initializer) {
  52. assertValidInitializer(initializer), initializers.push(initializer);
  53. };
  54. }
  55. function memberDecCtx(base, name, desc, metadataMap, initializers, kind, isStatic, isPrivate) {
  56. var kindStr;
  57. switch (kind) {
  58. case 1:
  59. kindStr = "accessor";
  60. break;
  61. case 2:
  62. kindStr = "method";
  63. break;
  64. case 3:
  65. kindStr = "getter";
  66. break;
  67. case 4:
  68. kindStr = "setter";
  69. break;
  70. default:
  71. kindStr = "field";
  72. }
  73. var metadataKind,
  74. metadataName,
  75. ctx = {
  76. kind: kindStr,
  77. name: isPrivate ? "#" + name : name,
  78. isStatic: isStatic,
  79. isPrivate: isPrivate
  80. };
  81. if (0 !== kind && (ctx.addInitializer = createAddInitializerMethod(initializers)), isPrivate) {
  82. metadataKind = 2, metadataName = Symbol(name);
  83. var access = {};
  84. 0 === kind ? (access.get = desc.get, access.set = desc.set) : 2 === kind ? access.get = function () {
  85. return desc.value;
  86. } : (1 !== kind && 3 !== kind || (access.get = function () {
  87. return desc.get.call(this);
  88. }), 1 !== kind && 4 !== kind || (access.set = function (v) {
  89. desc.set.call(this, v);
  90. })), ctx.access = access;
  91. } else metadataKind = 1, metadataName = name;
  92. return Object.assign(ctx, createMetadataMethodsForProperty(metadataMap, metadataKind, metadataName));
  93. }
  94. function assertValidInitializer(initializer) {
  95. if ("function" != typeof initializer) throw new Error("initializers must be functions");
  96. }
  97. function assertValidReturnValue(kind, value) {
  98. var type = _typeof(value);
  99. if (1 === kind) {
  100. if ("object" !== type || null === value) throw new Error("accessor decorators must return an object with get, set, or initializer properties or void 0");
  101. } else if ("function" !== type) throw 0 === kind ? new Error("field decorators must return a initializer function or void 0") : new Error("method decorators must return a function or void 0");
  102. }
  103. function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, metadataMap, initializers) {
  104. var desc,
  105. initializer,
  106. value,
  107. decs = decInfo[0];
  108. isPrivate ? desc = 0 === kind || 1 === kind ? {
  109. get: decInfo[3],
  110. set: decInfo[4]
  111. } : 3 === kind ? {
  112. get: decInfo[3]
  113. } : 4 === kind ? {
  114. set: decInfo[3]
  115. } : {
  116. value: decInfo[3]
  117. } : 0 !== kind && (desc = Object.getOwnPropertyDescriptor(base, name)), 1 === kind ? value = {
  118. get: desc.get,
  119. set: desc.set
  120. } : 2 === kind ? value = desc.value : 3 === kind ? value = desc.get : 4 === kind && (value = desc.set);
  121. var newValue,
  122. get,
  123. set,
  124. ctx = memberDecCtx(base, name, desc, metadataMap, initializers, kind, isStatic, isPrivate);
  125. if ("function" == typeof decs) void 0 !== (newValue = decs(value, ctx)) && (assertValidReturnValue(kind, newValue), 0 === kind ? initializer = newValue : 1 === kind ? (initializer = newValue.initializer, get = newValue.get || value.get, set = newValue.set || value.set, value = {
  126. get: get,
  127. set: set
  128. }) : value = newValue);else for (var i = decs.length - 1; i >= 0; i--) {
  129. var newInit;
  130. if (void 0 !== (newValue = (0, decs[i])(value, ctx))) assertValidReturnValue(kind, newValue), 0 === kind ? newInit = newValue : 1 === kind ? (newInit = newValue.initializer, get = newValue.get || value.get, set = newValue.set || value.set, value = {
  131. get: get,
  132. set: set
  133. }) : value = newValue, void 0 !== newInit && (void 0 === initializer ? initializer = newInit : "function" == typeof initializer ? initializer = [initializer, newInit] : initializer.push(newInit));
  134. }
  135. if (0 === kind || 1 === kind) {
  136. if (void 0 === initializer) initializer = function initializer(instance, init) {
  137. return init;
  138. };else if ("function" != typeof initializer) {
  139. var ownInitializers = initializer;
  140. initializer = function initializer(instance, init) {
  141. for (var value = init, i = 0; i < ownInitializers.length; i++) {
  142. value = ownInitializers[i].call(instance, value);
  143. }
  144. return value;
  145. };
  146. } else {
  147. var originalInitializer = initializer;
  148. initializer = function initializer(instance, init) {
  149. return originalInitializer.call(instance, init);
  150. };
  151. }
  152. ret.push(initializer);
  153. }
  154. 0 !== kind && (1 === kind ? (desc.get = value.get, desc.set = value.set) : 2 === kind ? desc.value = value : 3 === kind ? desc.get = value : 4 === kind && (desc.set = value), isPrivate ? 1 === kind ? (ret.push(function (instance, args) {
  155. return value.get.call(instance, args);
  156. }), ret.push(function (instance, args) {
  157. return value.set.call(instance, args);
  158. })) : 2 === kind ? ret.push(value) : ret.push(function (instance, args) {
  159. return value.call(instance, args);
  160. }) : Object.defineProperty(base, name, desc));
  161. }
  162. function applyMemberDecs(ret, Class, protoMetadataMap, staticMetadataMap, decInfos) {
  163. for (var protoInitializers = [], staticInitializers = [], existingProtoNonFields = new Map(), existingStaticNonFields = new Map(), i = 0; i < decInfos.length; i++) {
  164. var decInfo = decInfos[i];
  165. if (Array.isArray(decInfo)) {
  166. var base,
  167. metadataMap,
  168. initializers,
  169. kind = decInfo[1],
  170. name = decInfo[2],
  171. isPrivate = decInfo.length > 3,
  172. isStatic = kind >= 5;
  173. if (isStatic ? (base = Class, metadataMap = staticMetadataMap, kind -= 5, initializers = staticInitializers) : (base = Class.prototype, metadataMap = protoMetadataMap, initializers = protoInitializers), 0 !== kind && !isPrivate) {
  174. var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields,
  175. existingKind = existingNonFields.get(name) || 0;
  176. if (!0 === existingKind || 3 === existingKind && 4 !== kind || 4 === existingKind && 3 !== kind) throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
  177. !existingKind && kind > 2 ? existingNonFields.set(name, kind) : existingNonFields.set(name, !0);
  178. }
  179. applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, metadataMap, initializers);
  180. }
  181. }
  182. protoInitializers.length > 0 && pushInitializers(ret, protoInitializers), staticInitializers.length > 0 && pushInitializers(ret, staticInitializers);
  183. }
  184. function pushInitializers(ret, initializers) {
  185. initializers.length > 0 ? (initializers = initializers.slice(), ret.push(function (instance) {
  186. for (var i = 0; i < initializers.length; i++) {
  187. initializers[i].call(instance, instance);
  188. }
  189. return instance;
  190. })) : ret.push(function (instance) {
  191. return instance;
  192. });
  193. }
  194. function applyClassDecs(ret, targetClass, metadataMap, classDecs) {
  195. for (var initializers = [], newClass = targetClass, name = targetClass.name, ctx = Object.assign({
  196. kind: "class",
  197. name: name,
  198. addInitializer: createAddInitializerMethod(initializers)
  199. }, createMetadataMethodsForProperty(metadataMap, 0, name)), i = classDecs.length - 1; i >= 0; i--) {
  200. newClass = classDecs[i](newClass, ctx) || newClass;
  201. }
  202. ret.push(newClass), initializers.length > 0 ? ret.push(function () {
  203. for (var i = 0; i < initializers.length; i++) {
  204. initializers[i].call(newClass, newClass);
  205. }
  206. }) : ret.push(function () {});
  207. }
  208. export default function applyDecs(targetClass, memberDecs, classDecs) {
  209. var ret = [],
  210. staticMetadataMap = {};
  211. if (memberDecs) {
  212. var protoMetadataMap = {};
  213. applyMemberDecs(ret, targetClass, protoMetadataMap, staticMetadataMap, memberDecs), convertMetadataMapToFinal(targetClass.prototype, protoMetadataMap);
  214. }
  215. return classDecs && applyClassDecs(ret, targetClass, staticMetadataMap, classDecs), convertMetadataMapToFinal(targetClass, staticMetadataMap), ret;
  216. }