UI for Zipcoin Blue

AMDDefineDependencyParserPlugin.js 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const AMDRequireItemDependency = require("./AMDRequireItemDependency");
  7. const AMDRequireContextDependency = require("./AMDRequireContextDependency");
  8. const ConstDependency = require("./ConstDependency");
  9. const AMDDefineDependency = require("./AMDDefineDependency");
  10. const AMDRequireArrayDependency = require("./AMDRequireArrayDependency");
  11. const LocalModuleDependency = require("./LocalModuleDependency");
  12. const ContextDependencyHelpers = require("./ContextDependencyHelpers");
  13. const LocalModulesHelpers = require("./LocalModulesHelpers");
  14. function isBoundFunctionExpression(expr) {
  15. if(expr.type !== "CallExpression") return false;
  16. if(expr.callee.type !== "MemberExpression") return false;
  17. if(expr.callee.computed) return false;
  18. if(expr.callee.object.type !== "FunctionExpression") return false;
  19. if(expr.callee.property.type !== "Identifier") return false;
  20. if(expr.callee.property.name !== "bind") return false;
  21. return true;
  22. }
  23. class AMDDefineDependencyParserPlugin {
  24. constructor(options) {
  25. this.options = options;
  26. }
  27. newDefineDependency(range, arrayRange, functionRange, objectRange, namedModule) {
  28. return new AMDDefineDependency(range, arrayRange, functionRange, objectRange, namedModule);
  29. }
  30. apply(parser) {
  31. const options = this.options;
  32. parser.plugin("call define", (expr) => {
  33. let array, fn, obj, namedModule;
  34. switch(expr.arguments.length) {
  35. case 1:
  36. if(expr.arguments[0].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[0])) {
  37. // define(f() {...})
  38. fn = expr.arguments[0];
  39. } else if(expr.arguments[0].type === "ObjectExpression") {
  40. // define({...})
  41. obj = expr.arguments[0];
  42. } else {
  43. // define(expr)
  44. // unclear if function or object
  45. obj = fn = expr.arguments[0];
  46. }
  47. break;
  48. case 2:
  49. if(expr.arguments[0].type === "Literal") {
  50. namedModule = expr.arguments[0].value;
  51. // define("...", ...)
  52. if(expr.arguments[1].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[1])) {
  53. // define("...", f() {...})
  54. fn = expr.arguments[1];
  55. } else if(expr.arguments[1].type === "ObjectExpression") {
  56. // define("...", {...})
  57. obj = expr.arguments[1];
  58. } else {
  59. // define("...", expr)
  60. // unclear if function or object
  61. obj = fn = expr.arguments[1];
  62. }
  63. } else {
  64. array = expr.arguments[0];
  65. if(expr.arguments[1].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[1])) {
  66. // define([...], f() {})
  67. fn = expr.arguments[1];
  68. } else if(expr.arguments[1].type === "ObjectExpression") {
  69. // define([...], {...})
  70. obj = expr.arguments[1];
  71. } else {
  72. // define([...], expr)
  73. // unclear if function or object
  74. obj = fn = expr.arguments[1];
  75. }
  76. }
  77. break;
  78. case 3:
  79. // define("...", [...], f() {...})
  80. namedModule = expr.arguments[0].value;
  81. array = expr.arguments[1];
  82. if(expr.arguments[2].type === "FunctionExpression" || isBoundFunctionExpression(expr.arguments[2])) {
  83. // define("...", [...], f() {})
  84. fn = expr.arguments[2];
  85. } else if(expr.arguments[2].type === "ObjectExpression") {
  86. // define("...", [...], {...})
  87. obj = expr.arguments[2];
  88. } else {
  89. // define("...", [...], expr)
  90. // unclear if function or object
  91. obj = fn = expr.arguments[2];
  92. }
  93. break;
  94. default:
  95. return;
  96. }
  97. let fnParams = null;
  98. let fnParamsOffset = 0;
  99. if(fn) {
  100. if(fn.type === "FunctionExpression") fnParams = fn.params;
  101. else if(isBoundFunctionExpression(fn)) {
  102. fnParams = fn.callee.object.params;
  103. fnParamsOffset = fn.arguments.length - 1;
  104. if(fnParamsOffset < 0) fnParamsOffset = 0;
  105. }
  106. }
  107. let fnRenames = Object.create(parser.scope.renames);
  108. let identifiers;
  109. if(array) {
  110. identifiers = {};
  111. const param = parser.evaluateExpression(array);
  112. const result = parser.applyPluginsBailResult("call define:amd:array", expr, param, identifiers, namedModule);
  113. if(!result) return;
  114. if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
  115. if(identifiers[idx]) {
  116. fnRenames["$" + param.name] = identifiers[idx];
  117. return false;
  118. }
  119. return true;
  120. });
  121. } else {
  122. identifiers = ["require", "exports", "module"];
  123. if(fnParams) fnParams = fnParams.slice(fnParamsOffset).filter((param, idx) => {
  124. if(identifiers[idx]) {
  125. fnRenames["$" + param.name] = identifiers[idx];
  126. return false;
  127. }
  128. return true;
  129. });
  130. }
  131. let inTry;
  132. if(fn && fn.type === "FunctionExpression") {
  133. inTry = parser.scope.inTry;
  134. parser.inScope(fnParams, () => {
  135. parser.scope.renames = fnRenames;
  136. parser.scope.inTry = inTry;
  137. if(fn.body.type === "BlockStatement")
  138. parser.walkStatement(fn.body);
  139. else
  140. parser.walkExpression(fn.body);
  141. });
  142. } else if(fn && isBoundFunctionExpression(fn)) {
  143. inTry = parser.scope.inTry;
  144. parser.inScope(fn.callee.object.params.filter((i) => ["require", "module", "exports"].indexOf(i.name) < 0), () => {
  145. parser.scope.renames = fnRenames;
  146. parser.scope.inTry = inTry;
  147. if(fn.callee.object.body.type === "BlockStatement")
  148. parser.walkStatement(fn.callee.object.body);
  149. else
  150. parser.walkExpression(fn.callee.object.body);
  151. });
  152. if(fn.arguments)
  153. parser.walkExpressions(fn.arguments);
  154. } else if(fn || obj) {
  155. parser.walkExpression(fn || obj);
  156. }
  157. const dep = this.newDefineDependency(
  158. expr.range,
  159. array ? array.range : null,
  160. fn ? fn.range : null,
  161. obj ? obj.range : null,
  162. namedModule ? namedModule : null
  163. );
  164. dep.loc = expr.loc;
  165. if(namedModule) {
  166. dep.localModule = LocalModulesHelpers.addLocalModule(parser.state, namedModule);
  167. }
  168. parser.state.current.addDependency(dep);
  169. return true;
  170. });
  171. parser.plugin("call define:amd:array", (expr, param, identifiers, namedModule) => {
  172. if(param.isArray()) {
  173. param.items.forEach((param, idx) => {
  174. if(param.isString() && ["require", "module", "exports"].indexOf(param.string) >= 0)
  175. identifiers[idx] = param.string;
  176. const result = parser.applyPluginsBailResult("call define:amd:item", expr, param, namedModule);
  177. if(result === undefined) {
  178. parser.applyPluginsBailResult("call define:amd:context", expr, param);
  179. }
  180. });
  181. return true;
  182. } else if(param.isConstArray()) {
  183. const deps = [];
  184. param.array.forEach((request, idx) => {
  185. let dep;
  186. let localModule;
  187. if(request === "require") {
  188. identifiers[idx] = request;
  189. dep = "__webpack_require__";
  190. } else if(["exports", "module"].indexOf(request) >= 0) {
  191. identifiers[idx] = request;
  192. dep = request;
  193. } else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, request)) { // eslint-disable-line no-cond-assign
  194. dep = new LocalModuleDependency(localModule);
  195. dep.loc = expr.loc;
  196. parser.state.current.addDependency(dep);
  197. } else {
  198. dep = new AMDRequireItemDependency(request);
  199. dep.loc = expr.loc;
  200. dep.optional = !!parser.scope.inTry;
  201. parser.state.current.addDependency(dep);
  202. }
  203. deps.push(dep);
  204. });
  205. const dep = new AMDRequireArrayDependency(deps, param.range);
  206. dep.loc = expr.loc;
  207. dep.optional = !!parser.scope.inTry;
  208. parser.state.current.addDependency(dep);
  209. return true;
  210. }
  211. });
  212. parser.plugin("call define:amd:item", (expr, param, namedModule) => {
  213. if(param.isConditional()) {
  214. param.options.forEach((param) => {
  215. const result = parser.applyPluginsBailResult("call define:amd:item", expr, param);
  216. if(result === undefined) {
  217. parser.applyPluginsBailResult("call define:amd:context", expr, param);
  218. }
  219. });
  220. return true;
  221. } else if(param.isString()) {
  222. let dep, localModule;
  223. if(param.string === "require") {
  224. dep = new ConstDependency("__webpack_require__", param.range);
  225. } else if(["require", "exports", "module"].indexOf(param.string) >= 0) {
  226. dep = new ConstDependency(param.string, param.range);
  227. } else if(localModule = LocalModulesHelpers.getLocalModule(parser.state, param.string, namedModule)) { // eslint-disable-line no-cond-assign
  228. dep = new LocalModuleDependency(localModule, param.range);
  229. } else {
  230. dep = new AMDRequireItemDependency(param.string, param.range);
  231. }
  232. dep.loc = expr.loc;
  233. dep.optional = !!parser.scope.inTry;
  234. parser.state.current.addDependency(dep);
  235. return true;
  236. }
  237. });
  238. parser.plugin("call define:amd:context", (expr, param) => {
  239. const dep = ContextDependencyHelpers.create(AMDRequireContextDependency, param.range, param, expr, options);
  240. if(!dep) return;
  241. dep.loc = expr.loc;
  242. dep.optional = !!parser.scope.inTry;
  243. parser.state.current.addDependency(dep);
  244. return true;
  245. });
  246. }
  247. }
  248. module.exports = AMDDefineDependencyParserPlugin;