jass 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (503) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +47 -0
  3. data/README.md +45 -0
  4. data/lib/jass.rb +55 -0
  5. data/lib/jass/base.rb +141 -0
  6. data/lib/jass/bundle_processor.rb +28 -0
  7. data/lib/jass/compiler.rb +112 -0
  8. data/lib/jass/dependency.rb +14 -0
  9. data/lib/jass/errors.rb +29 -0
  10. data/lib/jass/es6_processor.rb +17 -0
  11. data/lib/jass/function.rb +13 -0
  12. data/lib/jass/global_directive_processor.rb +12 -0
  13. data/lib/jass/plugin.rb +13 -0
  14. data/lib/jass/railtie.rb +12 -0
  15. data/lib/jass/version.rb +3 -0
  16. data/vendor/node_modules/@types/acorn/index.d.ts +256 -0
  17. data/vendor/node_modules/@types/acorn/package.json +29 -0
  18. data/vendor/node_modules/@types/estree/index.d.ts +546 -0
  19. data/vendor/node_modules/@types/estree/package.json +22 -0
  20. data/vendor/node_modules/acorn-dynamic-import/lib/index.js +17 -0
  21. data/vendor/node_modules/acorn-dynamic-import/lib/inject.js +72 -0
  22. data/vendor/node_modules/acorn-dynamic-import/lib/walk.js +22 -0
  23. data/vendor/node_modules/acorn-dynamic-import/package.json +45 -0
  24. data/vendor/node_modules/acorn-dynamic-import/src/index.js +4 -0
  25. data/vendor/node_modules/acorn-dynamic-import/src/inject.js +52 -0
  26. data/vendor/node_modules/acorn-dynamic-import/src/walk.js +12 -0
  27. data/vendor/node_modules/acorn-es7-plugin/acorn-es7-plugin.js +17 -0
  28. data/vendor/node_modules/acorn-es7-plugin/acorn-v3.js +333 -0
  29. data/vendor/node_modules/acorn-es7-plugin/acorn-v4.js +194 -0
  30. data/vendor/node_modules/acorn-es7-plugin/package.json +29 -0
  31. data/vendor/node_modules/acorn-jsx/index.js +3 -0
  32. data/vendor/node_modules/acorn-jsx/inject.js +449 -0
  33. data/vendor/node_modules/acorn-jsx/package.json +28 -0
  34. data/vendor/node_modules/acorn-jsx/xhtml.js +255 -0
  35. data/vendor/node_modules/acorn/bin/_acorn.js +69 -0
  36. data/vendor/node_modules/acorn/bin/acorn +4 -0
  37. data/vendor/node_modules/acorn/bin/run_test262.js +22 -0
  38. data/vendor/node_modules/acorn/bin/test262.whitelist +409 -0
  39. data/vendor/node_modules/acorn/dist/acorn.es.js +5305 -0
  40. data/vendor/node_modules/acorn/dist/acorn.js +5336 -0
  41. data/vendor/node_modules/acorn/dist/acorn_loose.es.js +1412 -0
  42. data/vendor/node_modules/acorn/dist/acorn_loose.js +1422 -0
  43. data/vendor/node_modules/acorn/dist/walk.es.js +419 -0
  44. data/vendor/node_modules/acorn/dist/walk.js +439 -0
  45. data/vendor/node_modules/acorn/package.json +56 -0
  46. data/vendor/node_modules/ansi-styles/index.js +165 -0
  47. data/vendor/node_modules/ansi-styles/package.json +56 -0
  48. data/vendor/node_modules/arr-diff/index.js +58 -0
  49. data/vendor/node_modules/arr-diff/package.json +49 -0
  50. data/vendor/node_modules/arr-flatten/index.js +22 -0
  51. data/vendor/node_modules/arr-flatten/package.json +76 -0
  52. data/vendor/node_modules/array-unique/index.js +28 -0
  53. data/vendor/node_modules/array-unique/package.json +37 -0
  54. data/vendor/node_modules/braces/index.js +399 -0
  55. data/vendor/node_modules/braces/package.json +83 -0
  56. data/vendor/node_modules/buble/bin/buble +24 -0
  57. data/vendor/node_modules/buble/bin/handleError.js +58 -0
  58. data/vendor/node_modules/buble/bin/runBuble.js +150 -0
  59. data/vendor/node_modules/buble/bin/showHelp.js +16 -0
  60. data/vendor/node_modules/buble/dist/buble-browser-deps.umd.js +14857 -0
  61. data/vendor/node_modules/buble/dist/buble-browser.cjs.js +9941 -0
  62. data/vendor/node_modules/buble/dist/buble-browser.es.js +9933 -0
  63. data/vendor/node_modules/buble/dist/buble.cjs.js +9433 -0
  64. data/vendor/node_modules/buble/dist/buble.es.js +9425 -0
  65. data/vendor/node_modules/buble/package.json +74 -0
  66. data/vendor/node_modules/buble/register.js +90 -0
  67. data/vendor/node_modules/buble/src/index.js +98 -0
  68. data/vendor/node_modules/buble/src/program/BlockStatement.js +373 -0
  69. data/vendor/node_modules/buble/src/program/Node.js +112 -0
  70. data/vendor/node_modules/buble/src/program/Program.js +74 -0
  71. data/vendor/node_modules/buble/src/program/Scope.js +116 -0
  72. data/vendor/node_modules/buble/src/program/extractNames.js +35 -0
  73. data/vendor/node_modules/buble/src/program/keys.js +4 -0
  74. data/vendor/node_modules/buble/src/program/types/ArrayExpression.js +70 -0
  75. data/vendor/node_modules/buble/src/program/types/ArrowFunctionExpression.js +52 -0
  76. data/vendor/node_modules/buble/src/program/types/AssignmentExpression.js +185 -0
  77. data/vendor/node_modules/buble/src/program/types/BinaryExpression.js +12 -0
  78. data/vendor/node_modules/buble/src/program/types/BreakStatement.js +26 -0
  79. data/vendor/node_modules/buble/src/program/types/CallExpression.js +104 -0
  80. data/vendor/node_modules/buble/src/program/types/ClassBody.js +237 -0
  81. data/vendor/node_modules/buble/src/program/types/ClassDeclaration.js +79 -0
  82. data/vendor/node_modules/buble/src/program/types/ClassExpression.js +51 -0
  83. data/vendor/node_modules/buble/src/program/types/ContinueStatement.js +17 -0
  84. data/vendor/node_modules/buble/src/program/types/ExportDefaultDeclaration.js +10 -0
  85. data/vendor/node_modules/buble/src/program/types/ExportNamedDeclaration.js +10 -0
  86. data/vendor/node_modules/buble/src/program/types/ForInStatement.js +76 -0
  87. data/vendor/node_modules/buble/src/program/types/ForOfStatement.js +89 -0
  88. data/vendor/node_modules/buble/src/program/types/ForStatement.js +54 -0
  89. data/vendor/node_modules/buble/src/program/types/FunctionDeclaration.js +25 -0
  90. data/vendor/node_modules/buble/src/program/types/FunctionExpression.js +74 -0
  91. data/vendor/node_modules/buble/src/program/types/Identifier.js +54 -0
  92. data/vendor/node_modules/buble/src/program/types/IfStatement.js +29 -0
  93. data/vendor/node_modules/buble/src/program/types/ImportDeclaration.js +10 -0
  94. data/vendor/node_modules/buble/src/program/types/ImportDefaultSpecifier.js +8 -0
  95. data/vendor/node_modules/buble/src/program/types/ImportSpecifier.js +8 -0
  96. data/vendor/node_modules/buble/src/program/types/JSXAttribute.js +20 -0
  97. data/vendor/node_modules/buble/src/program/types/JSXClosingElement.js +27 -0
  98. data/vendor/node_modules/buble/src/program/types/JSXClosingFragment.js +22 -0
  99. data/vendor/node_modules/buble/src/program/types/JSXElement.js +57 -0
  100. data/vendor/node_modules/buble/src/program/types/JSXExpressionContainer.js +10 -0
  101. data/vendor/node_modules/buble/src/program/types/JSXFragment.js +4 -0
  102. data/vendor/node_modules/buble/src/program/types/JSXOpeningElement.js +93 -0
  103. data/vendor/node_modules/buble/src/program/types/JSXOpeningFragment.js +7 -0
  104. data/vendor/node_modules/buble/src/program/types/JSXSpreadAttribute.js +10 -0
  105. data/vendor/node_modules/buble/src/program/types/Literal.js +43 -0
  106. data/vendor/node_modules/buble/src/program/types/MemberExpression.js +13 -0
  107. data/vendor/node_modules/buble/src/program/types/NewExpression.js +55 -0
  108. data/vendor/node_modules/buble/src/program/types/ObjectExpression.js +250 -0
  109. data/vendor/node_modules/buble/src/program/types/Property.js +52 -0
  110. data/vendor/node_modules/buble/src/program/types/ReturnStatement.js +32 -0
  111. data/vendor/node_modules/buble/src/program/types/SpreadElement.js +12 -0
  112. data/vendor/node_modules/buble/src/program/types/Super.js +88 -0
  113. data/vendor/node_modules/buble/src/program/types/TaggedTemplateExpression.js +63 -0
  114. data/vendor/node_modules/buble/src/program/types/TemplateElement.js +7 -0
  115. data/vendor/node_modules/buble/src/program/types/TemplateLiteral.js +80 -0
  116. data/vendor/node_modules/buble/src/program/types/ThisExpression.js +31 -0
  117. data/vendor/node_modules/buble/src/program/types/UpdateExpression.js +32 -0
  118. data/vendor/node_modules/buble/src/program/types/VariableDeclaration.js +101 -0
  119. data/vendor/node_modules/buble/src/program/types/VariableDeclarator.js +43 -0
  120. data/vendor/node_modules/buble/src/program/types/index.js +98 -0
  121. data/vendor/node_modules/buble/src/program/types/shared/LoopStatement.js +105 -0
  122. data/vendor/node_modules/buble/src/program/types/shared/ModuleDeclaration.js +10 -0
  123. data/vendor/node_modules/buble/src/program/wrap.js +68 -0
  124. data/vendor/node_modules/buble/src/support.js +97 -0
  125. data/vendor/node_modules/buble/src/utils/CompileError.js +30 -0
  126. data/vendor/node_modules/buble/src/utils/array.js +11 -0
  127. data/vendor/node_modules/buble/src/utils/checkConst.js +8 -0
  128. data/vendor/node_modules/buble/src/utils/deindent.js +30 -0
  129. data/vendor/node_modules/buble/src/utils/destructure.js +377 -0
  130. data/vendor/node_modules/buble/src/utils/getSnippet.js +30 -0
  131. data/vendor/node_modules/buble/src/utils/isReference.js +41 -0
  132. data/vendor/node_modules/buble/src/utils/locate.js +20 -0
  133. data/vendor/node_modules/buble/src/utils/patterns.js +1 -0
  134. data/vendor/node_modules/buble/src/utils/removeTrailingComma.js +13 -0
  135. data/vendor/node_modules/buble/src/utils/reserved.js +6 -0
  136. data/vendor/node_modules/buble/src/utils/spread.js +70 -0
  137. data/vendor/node_modules/builtin-modules/builtin-modules.json +39 -0
  138. data/vendor/node_modules/builtin-modules/index.js +10 -0
  139. data/vendor/node_modules/builtin-modules/package.json +40 -0
  140. data/vendor/node_modules/builtin-modules/static.js +2 -0
  141. data/vendor/node_modules/chalk/index.js +228 -0
  142. data/vendor/node_modules/chalk/package.json +66 -0
  143. data/vendor/node_modules/chalk/templates.js +128 -0
  144. data/vendor/node_modules/chalk/types/index.d.ts +97 -0
  145. data/vendor/node_modules/color-convert/conversions.js +861 -0
  146. data/vendor/node_modules/color-convert/index.js +78 -0
  147. data/vendor/node_modules/color-convert/package.json +46 -0
  148. data/vendor/node_modules/color-convert/route.js +97 -0
  149. data/vendor/node_modules/color-name/index.js +152 -0
  150. data/vendor/node_modules/color-name/package.json +25 -0
  151. data/vendor/node_modules/color-name/test.js +7 -0
  152. data/vendor/node_modules/date-time/index.js +33 -0
  153. data/vendor/node_modules/date-time/package.json +39 -0
  154. data/vendor/node_modules/escape-string-regexp/index.js +11 -0
  155. data/vendor/node_modules/escape-string-regexp/package.json +41 -0
  156. data/vendor/node_modules/estree-walker/dist/estree-walker.es.js +57 -0
  157. data/vendor/node_modules/estree-walker/dist/estree-walker.umd.js +68 -0
  158. data/vendor/node_modules/estree-walker/package.json +34 -0
  159. data/vendor/node_modules/estree-walker/src/estree-walker.js +51 -0
  160. data/vendor/node_modules/expand-brackets/index.js +163 -0
  161. data/vendor/node_modules/expand-brackets/package.json +62 -0
  162. data/vendor/node_modules/expand-range/index.js +43 -0
  163. data/vendor/node_modules/expand-range/package.json +73 -0
  164. data/vendor/node_modules/extglob/index.js +178 -0
  165. data/vendor/node_modules/extglob/package.json +60 -0
  166. data/vendor/node_modules/filename-regex/index.js +10 -0
  167. data/vendor/node_modules/filename-regex/package.json +50 -0
  168. data/vendor/node_modules/fill-range/index.js +408 -0
  169. data/vendor/node_modules/fill-range/package.json +61 -0
  170. data/vendor/node_modules/for-in/index.js +16 -0
  171. data/vendor/node_modules/for-in/package.json +68 -0
  172. data/vendor/node_modules/for-own/index.js +19 -0
  173. data/vendor/node_modules/for-own/package.json +70 -0
  174. data/vendor/node_modules/glob-base/index.js +51 -0
  175. data/vendor/node_modules/glob-base/package.json +52 -0
  176. data/vendor/node_modules/glob-parent/index.js +10 -0
  177. data/vendor/node_modules/glob-parent/package.json +35 -0
  178. data/vendor/node_modules/glob-parent/test.js +28 -0
  179. data/vendor/node_modules/has-flag/index.js +8 -0
  180. data/vendor/node_modules/has-flag/package.json +44 -0
  181. data/vendor/node_modules/irregular-plurals/irregular-plurals.json +146 -0
  182. data/vendor/node_modules/irregular-plurals/package.json +39 -0
  183. data/vendor/node_modules/is-buffer/index.js +21 -0
  184. data/vendor/node_modules/is-buffer/package.json +51 -0
  185. data/vendor/node_modules/is-dotfile/index.js +14 -0
  186. data/vendor/node_modules/is-dotfile/package.json +69 -0
  187. data/vendor/node_modules/is-equal-shallow/index.js +27 -0
  188. data/vendor/node_modules/is-equal-shallow/package.json +54 -0
  189. data/vendor/node_modules/is-extendable/index.js +13 -0
  190. data/vendor/node_modules/is-extendable/package.json +51 -0
  191. data/vendor/node_modules/is-extglob/index.js +11 -0
  192. data/vendor/node_modules/is-extglob/package.json +48 -0
  193. data/vendor/node_modules/is-glob/index.js +14 -0
  194. data/vendor/node_modules/is-glob/package.json +60 -0
  195. data/vendor/node_modules/is-module/index.js +11 -0
  196. data/vendor/node_modules/is-module/package.json +20 -0
  197. data/vendor/node_modules/is-number/index.js +19 -0
  198. data/vendor/node_modules/is-number/package.json +59 -0
  199. data/vendor/node_modules/is-posix-bracket/index.js +10 -0
  200. data/vendor/node_modules/is-posix-bracket/package.json +64 -0
  201. data/vendor/node_modules/is-primitive/index.js +13 -0
  202. data/vendor/node_modules/is-primitive/package.json +46 -0
  203. data/vendor/node_modules/is-reference/dist/is-reference.es.js +26 -0
  204. data/vendor/node_modules/is-reference/dist/is-reference.js +34 -0
  205. data/vendor/node_modules/is-reference/dist/types/index.d.ts +2 -0
  206. data/vendor/node_modules/is-reference/package.json +47 -0
  207. data/vendor/node_modules/isarray/index.js +5 -0
  208. data/vendor/node_modules/isarray/package.json +45 -0
  209. data/vendor/node_modules/isarray/test.js +20 -0
  210. data/vendor/node_modules/isobject/index.js +14 -0
  211. data/vendor/node_modules/isobject/package.json +67 -0
  212. data/vendor/node_modules/kind-of/index.js +116 -0
  213. data/vendor/node_modules/kind-of/package.json +90 -0
  214. data/vendor/node_modules/locate-character/dist/locate-character.es.js +43 -0
  215. data/vendor/node_modules/locate-character/dist/locate-character.umd.js +54 -0
  216. data/vendor/node_modules/locate-character/dist/types/index.d.ts +17 -0
  217. data/vendor/node_modules/locate-character/package.json +41 -0
  218. data/vendor/node_modules/magic-string/dist/magic-string.cjs.js +1300 -0
  219. data/vendor/node_modules/magic-string/dist/magic-string.es.js +1296 -0
  220. data/vendor/node_modules/magic-string/dist/magic-string.umd.js +1352 -0
  221. data/vendor/node_modules/magic-string/index.d.ts +83 -0
  222. data/vendor/node_modules/magic-string/node_modules/vlq/dist/vlq.js +91 -0
  223. data/vendor/node_modules/magic-string/node_modules/vlq/package.json +27 -0
  224. data/vendor/node_modules/magic-string/node_modules/vlq/src/vlq.js +78 -0
  225. data/vendor/node_modules/magic-string/package.json +55 -0
  226. data/vendor/node_modules/micromatch/index.js +431 -0
  227. data/vendor/node_modules/micromatch/lib/chars.js +67 -0
  228. data/vendor/node_modules/micromatch/lib/expand.js +304 -0
  229. data/vendor/node_modules/micromatch/lib/glob.js +193 -0
  230. data/vendor/node_modules/micromatch/lib/utils.js +149 -0
  231. data/vendor/node_modules/micromatch/package.json +114 -0
  232. data/vendor/node_modules/minimist/index.js +236 -0
  233. data/vendor/node_modules/minimist/package.json +45 -0
  234. data/vendor/node_modules/nodent-compiler/compiler.js +171 -0
  235. data/vendor/node_modules/nodent-compiler/lib/arboriculture.js +2694 -0
  236. data/vendor/node_modules/nodent-compiler/lib/output.js +934 -0
  237. data/vendor/node_modules/nodent-compiler/lib/parser.js +291 -0
  238. data/vendor/node_modules/nodent-compiler/package.json +37 -0
  239. data/vendor/node_modules/normalize-path/index.js +19 -0
  240. data/vendor/node_modules/normalize-path/package.json +78 -0
  241. data/vendor/node_modules/object.omit/index.js +40 -0
  242. data/vendor/node_modules/object.omit/package.json +67 -0
  243. data/vendor/node_modules/os-homedir/index.js +24 -0
  244. data/vendor/node_modules/os-homedir/package.json +41 -0
  245. data/vendor/node_modules/parse-glob/index.js +156 -0
  246. data/vendor/node_modules/parse-glob/package.json +62 -0
  247. data/vendor/node_modules/parse-ms/index.js +16 -0
  248. data/vendor/node_modules/parse-ms/package.json +34 -0
  249. data/vendor/node_modules/path-parse/index.js +93 -0
  250. data/vendor/node_modules/path-parse/index.min.js +1 -0
  251. data/vendor/node_modules/path-parse/package.json +33 -0
  252. data/vendor/node_modules/path-parse/test.js +77 -0
  253. data/vendor/node_modules/path-parse/test.min.js +1 -0
  254. data/vendor/node_modules/plur/index.js +20 -0
  255. data/vendor/node_modules/plur/package.json +42 -0
  256. data/vendor/node_modules/preserve/index.js +54 -0
  257. data/vendor/node_modules/preserve/package.json +48 -0
  258. data/vendor/node_modules/preserve/test.js +48 -0
  259. data/vendor/node_modules/pretty-ms/index.js +48 -0
  260. data/vendor/node_modules/pretty-ms/package.json +48 -0
  261. data/vendor/node_modules/randomatic/index.js +82 -0
  262. data/vendor/node_modules/randomatic/node_modules/is-number/index.js +22 -0
  263. data/vendor/node_modules/randomatic/node_modules/is-number/node_modules/kind-of/index.js +116 -0
  264. data/vendor/node_modules/randomatic/node_modules/is-number/node_modules/kind-of/package.json +90 -0
  265. data/vendor/node_modules/randomatic/node_modules/is-number/package.json +83 -0
  266. data/vendor/node_modules/randomatic/node_modules/kind-of/index.js +119 -0
  267. data/vendor/node_modules/randomatic/node_modules/kind-of/package.json +90 -0
  268. data/vendor/node_modules/randomatic/package.json +78 -0
  269. data/vendor/node_modules/regex-cache/index.js +68 -0
  270. data/vendor/node_modules/regex-cache/package.json +64 -0
  271. data/vendor/node_modules/remove-trailing-separator/index.js +17 -0
  272. data/vendor/node_modules/remove-trailing-separator/package.json +37 -0
  273. data/vendor/node_modules/repeat-element/index.js +18 -0
  274. data/vendor/node_modules/repeat-element/package.json +44 -0
  275. data/vendor/node_modules/repeat-string/index.js +70 -0
  276. data/vendor/node_modules/repeat-string/package.json +77 -0
  277. data/vendor/node_modules/require-relative/index.js +33 -0
  278. data/vendor/node_modules/require-relative/package.json +22 -0
  279. data/vendor/node_modules/resolve/index.js +8 -0
  280. data/vendor/node_modules/resolve/lib/async.js +203 -0
  281. data/vendor/node_modules/resolve/lib/caller.js +8 -0
  282. data/vendor/node_modules/resolve/lib/core.js +53 -0
  283. data/vendor/node_modules/resolve/lib/core.json +69 -0
  284. data/vendor/node_modules/resolve/lib/node-modules-paths.js +45 -0
  285. data/vendor/node_modules/resolve/lib/sync.js +93 -0
  286. data/vendor/node_modules/resolve/package.json +40 -0
  287. data/vendor/node_modules/rollup-plugin-commonjs/dist/rollup-plugin-commonjs.cjs.js +804 -0
  288. data/vendor/node_modules/rollup-plugin-commonjs/dist/rollup-plugin-commonjs.es.js +800 -0
  289. data/vendor/node_modules/rollup-plugin-commonjs/package.json +52 -0
  290. data/vendor/node_modules/rollup-plugin-commonjs/src/ast-utils.js +104 -0
  291. data/vendor/node_modules/rollup-plugin-commonjs/src/defaultResolver.js +39 -0
  292. data/vendor/node_modules/rollup-plugin-commonjs/src/helpers.js +19 -0
  293. data/vendor/node_modules/rollup-plugin-commonjs/src/index.js +198 -0
  294. data/vendor/node_modules/rollup-plugin-commonjs/src/transform.js +431 -0
  295. data/vendor/node_modules/rollup-plugin-commonjs/src/utils.js +13 -0
  296. data/vendor/node_modules/rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.cjs.js +218 -0
  297. data/vendor/node_modules/rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.es.js +214 -0
  298. data/vendor/node_modules/rollup-plugin-node-resolve/package.json +51 -0
  299. data/vendor/node_modules/rollup-plugin-node-resolve/src/empty.js +1 -0
  300. data/vendor/node_modules/rollup-plugin-node-resolve/src/index.js +205 -0
  301. data/vendor/node_modules/rollup-pluginutils/dist/pluginutils.cjs.js +223 -0
  302. data/vendor/node_modules/rollup-pluginutils/dist/pluginutils.es.js +214 -0
  303. data/vendor/node_modules/rollup-pluginutils/dist/pluginutils.es6.js +217 -0
  304. data/vendor/node_modules/rollup-pluginutils/node_modules/estree-walker/dist/estree-walker.es.js +55 -0
  305. data/vendor/node_modules/rollup-pluginutils/node_modules/estree-walker/dist/estree-walker.es6.js +59 -0
  306. data/vendor/node_modules/rollup-pluginutils/node_modules/estree-walker/dist/estree-walker.umd.js +65 -0
  307. data/vendor/node_modules/rollup-pluginutils/node_modules/estree-walker/package.json +33 -0
  308. data/vendor/node_modules/rollup-pluginutils/node_modules/estree-walker/src/estree-walker.js +49 -0
  309. data/vendor/node_modules/rollup-pluginutils/package.json +40 -0
  310. data/vendor/node_modules/rollup-pluginutils/src/addExtension.js +6 -0
  311. data/vendor/node_modules/rollup-pluginutils/src/attachScopes.js +147 -0
  312. data/vendor/node_modules/rollup-pluginutils/src/createFilter.js +33 -0
  313. data/vendor/node_modules/rollup-pluginutils/src/index.js +4 -0
  314. data/vendor/node_modules/rollup-pluginutils/src/makeLegalIdentifier.js +15 -0
  315. data/vendor/node_modules/rollup-pluginutils/src/utils/ensureArray.js +5 -0
  316. data/vendor/node_modules/rollup/bin/rollup +4085 -0
  317. data/vendor/node_modules/rollup/dist/rollup.browser.js +19829 -0
  318. data/vendor/node_modules/rollup/dist/rollup.es.js +23586 -0
  319. data/vendor/node_modules/rollup/dist/rollup.js +23597 -0
  320. data/vendor/node_modules/rollup/dist/typings/Chunk.d.ts +85 -0
  321. data/vendor/node_modules/rollup/dist/typings/ExternalModule.d.ts +30 -0
  322. data/vendor/node_modules/rollup/dist/typings/Graph.d.ts +47 -0
  323. data/vendor/node_modules/rollup/dist/typings/Module.d.ts +130 -0
  324. data/vendor/node_modules/rollup/dist/typings/ast/CallOptions.d.ts +20 -0
  325. data/vendor/node_modules/rollup/dist/typings/ast/Entity.d.ts +16 -0
  326. data/vendor/node_modules/rollup/dist/typings/ast/ExecutionPathOptions.d.ts +57 -0
  327. data/vendor/node_modules/rollup/dist/typings/ast/clone.d.ts +1 -0
  328. data/vendor/node_modules/rollup/dist/typings/ast/enhance.d.ts +3 -0
  329. data/vendor/node_modules/rollup/dist/typings/ast/keys.d.ts +4 -0
  330. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ArrayExpression.d.ts +14 -0
  331. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ArrayPattern.d.ts +14 -0
  332. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ArrowFunctionExpression.d.ts +25 -0
  333. data/vendor/node_modules/rollup/dist/typings/ast/nodes/AssignmentExpression.d.ts +13 -0
  334. data/vendor/node_modules/rollup/dist/typings/ast/nodes/AssignmentPattern.d.ts +16 -0
  335. data/vendor/node_modules/rollup/dist/typings/ast/nodes/AssignmentProperty.d.ts +10 -0
  336. data/vendor/node_modules/rollup/dist/typings/ast/nodes/AwaitExpression.d.ts +8 -0
  337. data/vendor/node_modules/rollup/dist/typings/ast/nodes/BinaryExpression.d.ts +13 -0
  338. data/vendor/node_modules/rollup/dist/typings/ast/nodes/BlockStatement.d.ts +19 -0
  339. data/vendor/node_modules/rollup/dist/typings/ast/nodes/BreakStatement.d.ts +9 -0
  340. data/vendor/node_modules/rollup/dist/typings/ast/nodes/CallExpression.d.ts +22 -0
  341. data/vendor/node_modules/rollup/dist/typings/ast/nodes/CatchClause.d.ts +14 -0
  342. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ClassBody.d.ts +13 -0
  343. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ClassDeclaration.d.ts +14 -0
  344. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ClassExpression.d.ts +10 -0
  345. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ConditionalExpression.d.ts +28 -0
  346. data/vendor/node_modules/rollup/dist/typings/ast/nodes/DoWhileStatement.d.ts +9 -0
  347. data/vendor/node_modules/rollup/dist/typings/ast/nodes/EmptyStatement.d.ts +8 -0
  348. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ExportAllDeclaration.d.ts +12 -0
  349. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ExportDefaultDeclaration.d.ts +21 -0
  350. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ExportNamedDeclaration.d.ts +21 -0
  351. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ExportSpecifier.d.ts +8 -0
  352. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ExpressionStatement.d.ts +10 -0
  353. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ForInStatement.d.ts +20 -0
  354. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ForOfStatement.d.ts +21 -0
  355. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ForStatement.d.ts +19 -0
  356. data/vendor/node_modules/rollup/dist/typings/ast/nodes/FunctionDeclaration.d.ts +9 -0
  357. data/vendor/node_modules/rollup/dist/typings/ast/nodes/FunctionExpression.d.ts +6 -0
  358. data/vendor/node_modules/rollup/dist/typings/ast/nodes/Identifier.d.ts +29 -0
  359. data/vendor/node_modules/rollup/dist/typings/ast/nodes/IfStatement.d.ts +17 -0
  360. data/vendor/node_modules/rollup/dist/typings/ast/nodes/Import.d.ts +14 -0
  361. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ImportDeclaration.d.ts +17 -0
  362. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ImportDefaultSpecifier.d.ts +7 -0
  363. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ImportNamespaceSpecifier.d.ts +7 -0
  364. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ImportSpecifier.d.ts +8 -0
  365. data/vendor/node_modules/rollup/dist/typings/ast/nodes/LabeledStatement.d.ts +10 -0
  366. data/vendor/node_modules/rollup/dist/typings/ast/nodes/Literal.d.ts +22 -0
  367. data/vendor/node_modules/rollup/dist/typings/ast/nodes/LogicalExpression.d.ts +23 -0
  368. data/vendor/node_modules/rollup/dist/typings/ast/nodes/MemberExpression.d.ts +34 -0
  369. data/vendor/node_modules/rollup/dist/typings/ast/nodes/MethodDefinition.d.ts +16 -0
  370. data/vendor/node_modules/rollup/dist/typings/ast/nodes/NewExpression.d.ts +14 -0
  371. data/vendor/node_modules/rollup/dist/typings/ast/nodes/NodeType.d.ts +64 -0
  372. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ObjectExpression.d.ts +22 -0
  373. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ObjectPattern.d.ts +15 -0
  374. data/vendor/node_modules/rollup/dist/typings/ast/nodes/Program.d.ts +9 -0
  375. data/vendor/node_modules/rollup/dist/typings/ast/nodes/Property.d.ts +30 -0
  376. data/vendor/node_modules/rollup/dist/typings/ast/nodes/RestElement.d.ts +14 -0
  377. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ReturnStatement.d.ts +9 -0
  378. data/vendor/node_modules/rollup/dist/typings/ast/nodes/SequenceExpression.d.ts +13 -0
  379. data/vendor/node_modules/rollup/dist/typings/ast/nodes/SpreadElement.d.ts +6 -0
  380. data/vendor/node_modules/rollup/dist/typings/ast/nodes/SwitchCase.d.ts +11 -0
  381. data/vendor/node_modules/rollup/dist/typings/ast/nodes/SwitchStatement.d.ts +12 -0
  382. data/vendor/node_modules/rollup/dist/typings/ast/nodes/TaggedTemplateExpression.d.ts +13 -0
  383. data/vendor/node_modules/rollup/dist/typings/ast/nodes/TemplateElement.d.ts +12 -0
  384. data/vendor/node_modules/rollup/dist/typings/ast/nodes/TemplateLiteral.d.ts +12 -0
  385. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ThisExpression.d.ts +17 -0
  386. data/vendor/node_modules/rollup/dist/typings/ast/nodes/ThrowStatement.d.ts +8 -0
  387. data/vendor/node_modules/rollup/dist/typings/ast/nodes/UnaryExpression.d.ts +16 -0
  388. data/vendor/node_modules/rollup/dist/typings/ast/nodes/UnknownNode.d.ts +5 -0
  389. data/vendor/node_modules/rollup/dist/typings/ast/nodes/UpdateExpression.d.ts +13 -0
  390. data/vendor/node_modules/rollup/dist/typings/ast/nodes/VariableDeclaration.d.ts +21 -0
  391. data/vendor/node_modules/rollup/dist/typings/ast/nodes/VariableDeclarator.d.ts +13 -0
  392. data/vendor/node_modules/rollup/dist/typings/ast/nodes/WhileStatement.d.ts +9 -0
  393. data/vendor/node_modules/rollup/dist/typings/ast/nodes/YieldExpression.d.ts +9 -0
  394. data/vendor/node_modules/rollup/dist/typings/ast/nodes/index.d.ts +6 -0
  395. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/ClassNode.d.ts +17 -0
  396. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/Expression.d.ts +21 -0
  397. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/FunctionNode.d.ts +25 -0
  398. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/Node.d.ts +133 -0
  399. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/Pattern.d.ts +4 -0
  400. data/vendor/node_modules/rollup/dist/typings/ast/nodes/shared/pureFunctions.d.ts +4 -0
  401. data/vendor/node_modules/rollup/dist/typings/ast/scopes/BlockScope.d.ts +9 -0
  402. data/vendor/node_modules/rollup/dist/typings/ast/scopes/CatchScope.d.ts +10 -0
  403. data/vendor/node_modules/rollup/dist/typings/ast/scopes/FunctionScope.d.ts +20 -0
  404. data/vendor/node_modules/rollup/dist/typings/ast/scopes/GlobalScope.d.ts +7 -0
  405. data/vendor/node_modules/rollup/dist/typings/ast/scopes/ModuleScope.d.ts +11 -0
  406. data/vendor/node_modules/rollup/dist/typings/ast/scopes/ParameterScope.d.ts +16 -0
  407. data/vendor/node_modules/rollup/dist/typings/ast/scopes/ReturnValueScope.d.ts +11 -0
  408. data/vendor/node_modules/rollup/dist/typings/ast/scopes/Scope.d.ts +42 -0
  409. data/vendor/node_modules/rollup/dist/typings/ast/utils/extractNames.d.ts +2 -0
  410. data/vendor/node_modules/rollup/dist/typings/ast/values.d.ts +31 -0
  411. data/vendor/node_modules/rollup/dist/typings/ast/variables/ArgumentsVariable.d.ts +15 -0
  412. data/vendor/node_modules/rollup/dist/typings/ast/variables/ExportDefaultVariable.d.ts +16 -0
  413. data/vendor/node_modules/rollup/dist/typings/ast/variables/ExternalVariable.d.ts +12 -0
  414. data/vendor/node_modules/rollup/dist/typings/ast/variables/GlobalVariable.d.ts +11 -0
  415. data/vendor/node_modules/rollup/dist/typings/ast/variables/LocalVariable.d.ts +21 -0
  416. data/vendor/node_modules/rollup/dist/typings/ast/variables/NamespaceVariable.d.ts +20 -0
  417. data/vendor/node_modules/rollup/dist/typings/ast/variables/ParameterVariable.d.ts +5 -0
  418. data/vendor/node_modules/rollup/dist/typings/ast/variables/ReplaceableInitializationVariable.d.ts +14 -0
  419. data/vendor/node_modules/rollup/dist/typings/ast/variables/ThisVariable.d.ts +4 -0
  420. data/vendor/node_modules/rollup/dist/typings/ast/variables/Variable.d.ts +43 -0
  421. data/vendor/node_modules/rollup/dist/typings/ast/variables/VariableReassignmentTracker.d.ts +11 -0
  422. data/vendor/node_modules/rollup/dist/typings/finalisers/amd.d.ts +11 -0
  423. data/vendor/node_modules/rollup/dist/typings/finalisers/cjs.d.ts +10 -0
  424. data/vendor/node_modules/rollup/dist/typings/finalisers/es.d.ts +9 -0
  425. data/vendor/node_modules/rollup/dist/typings/finalisers/iife.d.ts +10 -0
  426. data/vendor/node_modules/rollup/dist/typings/finalisers/index.d.ts +15 -0
  427. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/esModuleExport.d.ts +2 -0
  428. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/getExportBlock.d.ts +2 -0
  429. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/getGlobalNameMaker.d.ts +4 -0
  430. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/getInteropBlock.d.ts +3 -0
  431. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/sanitize.d.ts +2 -0
  432. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/setupNamespace.d.ts +2 -0
  433. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/trimEmptyImports.d.ts +2 -0
  434. data/vendor/node_modules/rollup/dist/typings/finalisers/shared/warnOnBuiltins.d.ts +2 -0
  435. data/vendor/node_modules/rollup/dist/typings/finalisers/system.d.ts +8 -0
  436. data/vendor/node_modules/rollup/dist/typings/finalisers/umd.d.ts +10 -0
  437. data/vendor/node_modules/rollup/dist/typings/node-entry.d.ts +6 -0
  438. data/vendor/node_modules/rollup/dist/typings/rollup/index.d.ts +167 -0
  439. data/vendor/node_modules/rollup/dist/typings/utils/callIfFunction.d.ts +1 -0
  440. data/vendor/node_modules/rollup/dist/typings/utils/collapseSourcemaps.d.ts +5 -0
  441. data/vendor/node_modules/rollup/dist/typings/utils/commondir.d.ts +1 -0
  442. data/vendor/node_modules/rollup/dist/typings/utils/defaults.d.ts +6 -0
  443. data/vendor/node_modules/rollup/dist/typings/utils/deprecateOptions.d.ts +6 -0
  444. data/vendor/node_modules/rollup/dist/typings/utils/ensureArray.d.ts +2 -0
  445. data/vendor/node_modules/rollup/dist/typings/utils/entryHashing.d.ts +3 -0
  446. data/vendor/node_modules/rollup/dist/typings/utils/error.d.ts +18 -0
  447. data/vendor/node_modules/rollup/dist/typings/utils/first-sync.d.ts +1 -0
  448. data/vendor/node_modules/rollup/dist/typings/utils/first.d.ts +1 -0
  449. data/vendor/node_modules/rollup/dist/typings/utils/flushTime.d.ts +5 -0
  450. data/vendor/node_modules/rollup/dist/typings/utils/fs.d.ts +3 -0
  451. data/vendor/node_modules/rollup/dist/typings/utils/getCodeFrame.d.ts +1 -0
  452. data/vendor/node_modules/rollup/dist/typings/utils/getExportMode.d.ts +3 -0
  453. data/vendor/node_modules/rollup/dist/typings/utils/getIndentString.d.ts +4 -0
  454. data/vendor/node_modules/rollup/dist/typings/utils/identifierHelpers.d.ts +3 -0
  455. data/vendor/node_modules/rollup/dist/typings/utils/mergeOptions.d.ts +19 -0
  456. data/vendor/node_modules/rollup/dist/typings/utils/object.d.ts +7 -0
  457. data/vendor/node_modules/rollup/dist/typings/utils/path.d.ts +6 -0
  458. data/vendor/node_modules/rollup/dist/typings/utils/promise.d.ts +2 -0
  459. data/vendor/node_modules/rollup/dist/typings/utils/relativeId.d.ts +1 -0
  460. data/vendor/node_modules/rollup/dist/typings/utils/renderHelpers.d.ts +26 -0
  461. data/vendor/node_modules/rollup/dist/typings/utils/sourceMappingURL.d.ts +3 -0
  462. data/vendor/node_modules/rollup/dist/typings/utils/timers.d.ts +7 -0
  463. data/vendor/node_modules/rollup/dist/typings/utils/transform.d.ts +25 -0
  464. data/vendor/node_modules/rollup/dist/typings/utils/transformBundle.d.ts +3 -0
  465. data/vendor/node_modules/rollup/dist/typings/watch/chokidar.d.ts +3 -0
  466. data/vendor/node_modules/rollup/dist/typings/watch/fileWatchers.d.ts +14 -0
  467. data/vendor/node_modules/rollup/dist/typings/watch/index.d.ts +47 -0
  468. data/vendor/node_modules/rollup/package.json +122 -0
  469. data/vendor/node_modules/rollup/typings/package.json.d.ts +3 -0
  470. data/vendor/node_modules/signal-exit/index.js +157 -0
  471. data/vendor/node_modules/signal-exit/package.json +38 -0
  472. data/vendor/node_modules/signal-exit/signals.js +53 -0
  473. data/vendor/node_modules/source-map/dist/source-map.debug.js +3091 -0
  474. data/vendor/node_modules/source-map/dist/source-map.js +3090 -0
  475. data/vendor/node_modules/source-map/dist/source-map.min.js +2 -0
  476. data/vendor/node_modules/source-map/lib/array-set.js +121 -0
  477. data/vendor/node_modules/source-map/lib/base64-vlq.js +140 -0
  478. data/vendor/node_modules/source-map/lib/base64.js +67 -0
  479. data/vendor/node_modules/source-map/lib/binary-search.js +111 -0
  480. data/vendor/node_modules/source-map/lib/mapping-list.js +79 -0
  481. data/vendor/node_modules/source-map/lib/quick-sort.js +114 -0
  482. data/vendor/node_modules/source-map/lib/source-map-consumer.js +1082 -0
  483. data/vendor/node_modules/source-map/lib/source-map-generator.js +416 -0
  484. data/vendor/node_modules/source-map/lib/source-node.js +413 -0
  485. data/vendor/node_modules/source-map/lib/util.js +417 -0
  486. data/vendor/node_modules/source-map/package.json +72 -0
  487. data/vendor/node_modules/source-map/source-map.js +8 -0
  488. data/vendor/node_modules/sourcemap-codec/dist/sourcemap-codec.es.js +129 -0
  489. data/vendor/node_modules/sourcemap-codec/dist/sourcemap-codec.umd.js +140 -0
  490. data/vendor/node_modules/sourcemap-codec/dist/types/sourcemap-codec.d.ts +5 -0
  491. data/vendor/node_modules/sourcemap-codec/package.json +52 -0
  492. data/vendor/node_modules/supports-color/browser.js +5 -0
  493. data/vendor/node_modules/supports-color/index.js +135 -0
  494. data/vendor/node_modules/supports-color/package.json +53 -0
  495. data/vendor/node_modules/time-zone/index.js +10 -0
  496. data/vendor/node_modules/time-zone/package.json +35 -0
  497. data/vendor/node_modules/vlq/dist/types/vlq.d.ts +2 -0
  498. data/vendor/node_modules/vlq/dist/vlq.es.js +64 -0
  499. data/vendor/node_modules/vlq/dist/vlq.js +75 -0
  500. data/vendor/node_modules/vlq/package.json +30 -0
  501. data/vendor/package.json +15 -0
  502. data/vendor/yarn.lock +453 -0
  503. metadata +641 -0
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "minimist",
3
+ "version": "1.2.0",
4
+ "description": "parse argument options",
5
+ "main": "index.js",
6
+ "devDependencies": {
7
+ "covert": "^1.0.0",
8
+ "tap": "~0.4.0",
9
+ "tape": "^3.5.0"
10
+ },
11
+ "scripts": {
12
+ "test": "tap test/*.js",
13
+ "coverage": "covert test/*.js"
14
+ },
15
+ "testling": {
16
+ "files": "test/*.js",
17
+ "browsers": [
18
+ "ie/6..latest",
19
+ "ff/5",
20
+ "firefox/latest",
21
+ "chrome/10",
22
+ "chrome/latest",
23
+ "safari/5.1",
24
+ "safari/latest",
25
+ "opera/12"
26
+ ]
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git://github.com/substack/minimist.git"
31
+ },
32
+ "homepage": "https://github.com/substack/minimist",
33
+ "keywords": [
34
+ "argv",
35
+ "getopt",
36
+ "parser",
37
+ "optimist"
38
+ ],
39
+ "author": {
40
+ "name": "James Halliday",
41
+ "email": "mail@substack.net",
42
+ "url": "http://substack.net"
43
+ },
44
+ "license": "MIT"
45
+ }
@@ -0,0 +1,171 @@
1
+ var parser = require('./lib/parser') ;
2
+ var treeSurgeon = require('./lib/arboriculture') ;
3
+ var outputCode = require('./lib/output') ;
4
+
5
+ /* Utils */
6
+ function copyObj(a){
7
+ var o = {} ;
8
+ a.forEach(function(b){
9
+ if (b && typeof b==='object')
10
+ for (var k in b)
11
+ o[k] = b[k] ;
12
+ }) ;
13
+ return o ;
14
+ }
15
+
16
+ function btoa(str) {
17
+ var buffer ;
18
+ if (str instanceof Buffer) {
19
+ buffer = str;
20
+ } else {
21
+ buffer = new Buffer(str.toString(), 'binary');
22
+ }
23
+
24
+ return buffer.toString('base64');
25
+ }
26
+
27
+ function noLogger(){}
28
+
29
+ /* NodentCompiler prototypes, that refer to 'this' */
30
+ function compile(code,origFilename,__sourceMapping,opts) {
31
+ if (typeof __sourceMapping==="object" && opts===undefined)
32
+ opts = __sourceMapping ;
33
+
34
+ opts = opts || {} ;
35
+
36
+ // Fill in any default codeGen options
37
+ for (var k in NodentCompiler.initialCodeGenOpts) {
38
+ if (!(k in opts))
39
+ opts[k] = NodentCompiler.initialCodeGenOpts[k] ;
40
+ }
41
+
42
+ var pr = this.parse(code,origFilename,null,opts);
43
+ this.asynchronize(pr,null,opts,this.log || noLogger) ;
44
+ this.prettyPrint(pr,opts) ;
45
+ return pr ;
46
+ }
47
+
48
+ function prettyPrint(pr,opts) {
49
+ var map ;
50
+ var filepath = pr.filename ? pr.filename.split("/") :["anonymous"] ;
51
+ var filename = filepath.pop() ;
52
+
53
+ var out = outputCode(pr.ast,(opts && opts.sourcemap)?{map:{
54
+ startLine: opts.mapStartLine || 0,
55
+ file: filename+"(original)",
56
+ sourceMapRoot: filepath.join("/"),
57
+ sourceContent: pr.origCode
58
+ }}:null, pr.origCode) ;
59
+
60
+ if (opts && opts.sourcemap){
61
+ try {
62
+ var mapUrl = "" ;
63
+ var jsmap = out.map.toJSON();
64
+ if (jsmap) {
65
+ // require an expression to defeat browserify
66
+ var SourceMapConsumer = require('source-map').SourceMapConsumer;
67
+ pr.sourcemap = jsmap ;
68
+ this.smCache[pr.filename] = {map:jsmap,smc:new SourceMapConsumer(jsmap)} ;
69
+ mapUrl = "\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,"
70
+ +btoa(JSON.stringify(jsmap))+"\n" ;
71
+ }
72
+ pr.code = out.code+mapUrl ;
73
+ } catch (ex) {
74
+ pr.code = out ;
75
+ }
76
+ } else {
77
+ pr.code = out ;
78
+ }
79
+ return pr ;
80
+ }
81
+
82
+ function NodentCompiler(members) {
83
+ this.covers = {} ;
84
+ this._ident = NodentCompiler.prototype.version+"_"+Math.random() ;
85
+ this.setOptions(members || {}) ;
86
+ }
87
+
88
+ NodentCompiler.prototype.smCache = {} ;
89
+
90
+ NodentCompiler.prototype.setOptions = function(members){
91
+ this.log = members.log===false?noLogger:members.log||this.log;
92
+ this.options = copyObj([this.options,members]) ;
93
+ delete this.options.log ;
94
+ return this ;
95
+ };
96
+
97
+ function parseCode(code,origFilename,__sourceMapping,opts) {
98
+ if (typeof __sourceMapping==="object" && opts===undefined)
99
+ opts = __sourceMapping ;
100
+
101
+ var r = { origCode:code.toString(), filename:origFilename } ;
102
+ try {
103
+ r.ast = parser.parse(r.origCode, opts && opts.parser) ;
104
+ if (opts.babelTree) {
105
+ parser.treeWalker(r.ast,function(node,descend,path){
106
+ if (node.type==='Literal')
107
+ path[0].replace(treeSurgeon.babelLiteralNode(node.value)) ;
108
+ else if (node.type==='Property') {
109
+ // Class/ObjectProperty in babel6
110
+ if (path[0].parent.type==='ClassBody'){
111
+ // There's no easy mapping here as it appears to be borderline in the specification?
112
+ // It's definitely a kind of ClassProperty tho....
113
+ node.type = 'ClassProperty' ;
114
+ } else {
115
+ node.type = 'ObjectProperty' ;
116
+ }
117
+ }
118
+ descend() ;
119
+ }) ;
120
+ }
121
+ return r ;
122
+ } catch (ex) {
123
+ if (ex instanceof SyntaxError) {
124
+ var l = r.origCode.substr(ex.pos-ex.loc.column) ;
125
+ l = l.split("\n")[0] ;
126
+ ex.message += " "+origFilename+" (nodent)\n"+l+"\n"+l.replace(/[\S ]/g,"-").substring(0,ex.loc.column)+"^" ;
127
+ ex.stack = "" ;
128
+ }
129
+ throw ex ;
130
+ }
131
+ }
132
+
133
+ NodentCompiler.prototype.version = require("./package.json").version ;
134
+ NodentCompiler.prototype.isThenable = function(x) { return x && x instanceof Object && typeof x.then==="function"} ;
135
+ NodentCompiler.prototype.compile = compile ;
136
+ // Exported ; but not to be used lightly!
137
+ NodentCompiler.prototype.parse = parseCode ;
138
+ NodentCompiler.prototype.asynchronize = treeSurgeon.asynchronize ;
139
+ NodentCompiler.prototype.printNode = treeSurgeon.printNode ;
140
+ NodentCompiler.prototype.prettyPrint = prettyPrint ;
141
+ NodentCompiler.prototype.getDefaultCompileOptions = undefined ;
142
+
143
+ Object.defineProperty(NodentCompiler.prototype,"Promise",{
144
+ get:function (){
145
+ initOpts.log("Warning: nodent.Promise is deprecated. Use nodent.Thenable instead");
146
+ return Thenable;
147
+ },
148
+ enumerable:false,
149
+ configurable:false
150
+ }) ;
151
+
152
+ NodentCompiler.initialCodeGenOpts = {
153
+ noRuntime:false,
154
+ lazyThenables:false,
155
+ es6target:false,
156
+ noUseDirective:false,
157
+ wrapAwait:null,
158
+ mapStartLine:0,
159
+ sourcemap:true,
160
+ engine:false,
161
+ parser:{sourceType:'script'},
162
+ $return:"$return",
163
+ $error:"$error",
164
+ $arguments:"$args",
165
+ $asyncspawn:"$asyncspawn",
166
+ $asyncbind:"$asyncbind",
167
+ generatedSymbolPrefix:"$",
168
+ $makeThenable:'$makeThenable'
169
+ };
170
+
171
+ module.exports = NodentCompiler ;
@@ -0,0 +1,2694 @@
1
+ 'use strict';
2
+
3
+ /* We manipulate (abstract syntax) trees */
4
+ var parser = require('./parser');
5
+ var outputCode = require('./output');
6
+ /** Helpers **/
7
+ /*global.printNode = */function printNode(n) {
8
+ if (!n) return '' ;
9
+ if (Array.isArray(n))
10
+ return n.map(printNode).join("|\n");
11
+ try {
12
+ return outputCode(n) ; //+"\t//@"+Object.keys(n).filter(function(k){ return k[0]==='$'}).map(function(k){ return k+":"+n[k] });
13
+ } catch (ex) {
14
+ return ex.message + ": " + (n && n.type);
15
+ }
16
+ }
17
+
18
+ function cloneNode(n) {
19
+ if (Array.isArray(n))
20
+ return n.map(function (n) {
21
+ return cloneNode(n);
22
+ });
23
+ var o = {};
24
+ Object.keys(n).forEach(function (k) {
25
+ o[k] = n[k];
26
+ });
27
+ return o;
28
+ }
29
+
30
+ /* Bit of a hack: without having to search for references to this
31
+ * node, force it to be some replacement node */
32
+ var locationInfo = { start:true, end: true, loc: true, range: true } ;
33
+ function coerce(node, replace) {
34
+ if (node===replace) return ;
35
+ node.__proto__ = Object.getPrototypeOf(replace);
36
+ Object.keys(node).forEach(function (k) {
37
+ if (!(k in locationInfo))
38
+ delete node[k];
39
+ });
40
+ Object.keys(replace).forEach(function (k) {
41
+ if (!(k in node))
42
+ node[k] = replace[k];
43
+ });
44
+ }
45
+
46
+ function Nothing(){}
47
+
48
+ var examinations = {
49
+ getScope: function(){ return this.node.type === 'FunctionDeclaration' || this.node.type === 'FunctionExpression' || this.node.type === 'Function' || this.node.type === 'ObjectMethod' || this.node.type === 'ClassMethod' || (this.node.type === 'ArrowFunctionExpression' && this.node.body.type === 'BlockStatement') ? this.node.body.body : this.node.type === 'Program' ? this.node.body : null},
50
+ isScope: function(){ return this.node.type === 'FunctionDeclaration' || this.node.type === 'FunctionExpression' || this.node.type === 'Function' || this.node.type === 'Program' || this.node.type === 'ObjectMethod' || this.node.type === 'ClassMethod' || (this.node.type === 'ArrowFunctionExpression' && this.node.body.type === 'BlockStatement')},
51
+ isFunction: function(){ return this.node.type === 'FunctionDeclaration' || this.node.type === 'FunctionExpression' || this.node.type === 'Function' || this.node.type === 'ObjectMethod' || this.node.type === 'ClassMethod' || this.node.type === 'ArrowFunctionExpression'},
52
+ isClass: function(){ return this.node.type === 'ClassDeclaration' || this.node.type === 'ClassExpression'},
53
+ isBlockStatement: function(){ return this.node.type==='ClassBody' || this.node.type === 'Program' || this.node.type === 'BlockStatement' ? this.node.body : this.node.type === 'SwitchCase' ? this.node.consequent : false},
54
+ isExpressionStatement: function(){ return this.node.type === 'ExpressionStatement'},
55
+ isLiteral: function(){ return this.node.type === 'Literal' || this.node.type === 'BooleanLiteral' || this.node.type === 'RegExpLiteral' || this.node.type === 'NumericLiteral' || this.node.type === 'StringLiteral' || this.node.type === 'NullLiteral'},
56
+ isDirective: function(){ return this.node.type === 'ExpressionStatement' && (this.node.expression.type === 'StringLiteral' || this.node.expression.type === 'Literal' && typeof this.node.expression.value === 'string')},
57
+ isUnaryExpression: function(){ return this.node.type === 'UnaryExpression'},
58
+ isAwait: function(){ return this.node.type === 'AwaitExpression' && !this.node.$hidden},
59
+ isAsync: function(){ return this.node.async },
60
+ isStatement: function(){ return this.node.type.match(/[a-zA-Z]+Declaration/) !== null || this.node.type.match(/[a-zA-Z]+Statement/) !== null},
61
+ isExpression: function(){ return this.node.type.match(/[a-zA-Z]+Expression/) !== null},
62
+ isLoop: function(){ return this.node.type === 'ForStatement' || this.node.type === 'WhileStatement' || this.node.type === 'DoWhileStatement'}, // Other loops?
63
+ isJump: function(){ return this.node.type === 'ReturnStatement' || this.node.type === 'ThrowStatement' || this.node.type === 'BreakStatement' || this.node.type === 'ContinueStatement'},
64
+ isES6: function(){
65
+ switch (this.node.type) {
66
+ case 'ExportNamedDeclaration':
67
+ case 'ExportSpecifier':
68
+ case 'ExportDefaultDeclaration':
69
+ case 'ExportAllDeclaration':
70
+ case 'ImportDeclaration':
71
+ case 'ImportSpecifier':
72
+ case 'ImportDefaultSpecifier':
73
+ case 'ImportNamespaceSpecifier':
74
+ case 'ArrowFunctionExpression':
75
+ case 'ForOfStatement':
76
+ case 'YieldExpression':
77
+ case 'Super':
78
+ case 'RestElement':
79
+ case 'RestProperty':
80
+ case 'SpreadElement':
81
+ case 'TemplateLiteral':
82
+ case 'ClassDeclaration':
83
+ case 'ClassExpression':
84
+ return true ;
85
+
86
+ case 'VariableDeclaration':
87
+ return this.node.kind && this.node.kind !== 'var' ;
88
+
89
+ case 'FunctionDeclaration':
90
+ case 'FunctionExpression':
91
+ return !!this.node.generator;
92
+ }
93
+ }
94
+ };
95
+
96
+ var NodeExaminer = {} ;
97
+ Object.keys(examinations).forEach(function(k){
98
+ Object.defineProperty(NodeExaminer,k,{
99
+ get:examinations[k]
100
+ }) ;
101
+ }) ;
102
+
103
+ function examine(node) {
104
+ if (!node)
105
+ return {};
106
+ NodeExaminer.node = node ;
107
+ return NodeExaminer ;
108
+ }
109
+
110
+ /*
111
+ * descendOn = true Enter scopes within scopes
112
+ * descendOn = false/undefined/null Do not enter scopes within scopes
113
+ * descendOn = function Descend when function(node) is true
114
+ */
115
+ function contains(ast, fn, descendOn) {
116
+ if (!ast)
117
+ return null;
118
+ if (fn && typeof fn === 'object') {
119
+ var keys = Object.keys(fn);
120
+ return contains(ast, function (node) {
121
+ return keys.every(function (k) {
122
+ return node[k] == fn[k];
123
+ });
124
+ });
125
+ }
126
+ var n, found = {};
127
+ if (Array.isArray(ast)) {
128
+ for (var i = 0;i < ast.length; i++)
129
+ if (n = contains(ast[i], fn))
130
+ return n;
131
+ return null;
132
+ }
133
+
134
+ var subScopes = descendOn ;
135
+ if (typeof descendOn !== "function") {
136
+ if (descendOn) {
137
+ subScopes = function(n) { return true } ;
138
+ } else {
139
+ subScopes = function(n) { return !examine(n).isScope } ;
140
+ }
141
+ }
142
+
143
+ try {
144
+ parser.treeWalker(ast, function (node, descend, path) {
145
+ if (fn(node)) {
146
+ found.path = path;
147
+ throw found;
148
+ }
149
+ if (node === ast || subScopes(node))
150
+ descend();
151
+ });
152
+ } catch (ex) {
153
+ if (ex === found)
154
+ return found.path;
155
+ throw ex;
156
+ }
157
+ return null;
158
+ }
159
+
160
+ function containsAwait(ast) {
161
+ return contains(ast, function(n){
162
+ return n.type==='AwaitExpression' && !n.$hidden
163
+ });
164
+ }
165
+
166
+ function containsAwaitInBlock(ast) {
167
+ return contains(ast, function(n){
168
+ return n.type==='AwaitExpression' && !n.$hidden
169
+ }, function (n) {
170
+ var x = examine(n) ;
171
+ return !x.isBlockStatement && !x.isScope
172
+ });
173
+ }
174
+
175
+ function containsThis(ast) {
176
+ return contains(ast, {
177
+ type: 'ThisExpression'
178
+ });
179
+ }
180
+
181
+ function babelLiteralNode(value) {
182
+ if (value === null)
183
+ return {
184
+ type: 'NullLiteral',
185
+ value: null,
186
+ raw: 'null'
187
+ };
188
+ if (value === true || value === false)
189
+ return {
190
+ type: 'BooleanLiteral',
191
+ value: value,
192
+ raw: JSON.stringify(value)
193
+ };
194
+ if (value instanceof RegExp) {
195
+ var str = value.toString();
196
+ var parts = str.split('/');
197
+ return {
198
+ type: 'RegExpLiteral',
199
+ value: value,
200
+ raw: str,
201
+ pattern: parts[1],
202
+ flags: parts[2]
203
+ };
204
+ }
205
+ if (typeof value === 'number')
206
+ return {
207
+ type: 'NumericLiteral',
208
+ value: value,
209
+ raw: JSON.stringify(value)
210
+ };
211
+ return {
212
+ type: 'StringLiteral',
213
+ value: value,
214
+ raw: JSON.stringify(value)
215
+ };
216
+ }
217
+
218
+ function ident(name, loc) {
219
+ return {
220
+ type: 'Identifier',
221
+ name: name,
222
+ loc: loc
223
+ };
224
+ }
225
+
226
+ function idents(s) {
227
+ var r = {};
228
+ for (var k in s)
229
+ r[k] = typeof s[k] === "string" ? ident(s[k]) : s[k];
230
+ return r;
231
+ }
232
+
233
+ function asynchronize(pr, __sourceMapping, opts, logger) {
234
+ var continuations = {};
235
+ var generatedSymbol = 1;
236
+ var genIdent = {};
237
+ Object.keys(opts).filter(function (k) {
238
+ return k[0] === '$';
239
+ }).forEach(function (k) {
240
+ genIdent[k.slice(1)] = ident(opts[k]);
241
+ });
242
+
243
+ /* Generate a prototypical call of the form:
244
+ * (left).$asyncbind(this,...args)
245
+ */
246
+ function bindAsync(left,arg) {
247
+ if (opts.es6target && !left.id && !arg && left.type.indexOf("Function")===0) {
248
+ left.type = 'ArrowFunctionExpression' ;
249
+ return left ;
250
+ }
251
+
252
+ if (opts.noRuntime) {
253
+ if (arg) {
254
+ if (examine(arg).isLiteral) {
255
+ throw new Error("Nodent: 'noRuntime' option only compatible with -promise and -engine modes") ;
256
+ }
257
+ // Add a global synchronous exception handler to (left)
258
+ left.body.body = parser.part("try {$:0} catch($2) {return $1($2)}",[cloneNode(left.body),arg,ident('$boundEx')]).body ;
259
+ } else if (opts.es6target && !left.id && left.type.indexOf("Function")===0) {
260
+ left.type = 'ArrowFunctionExpression' ;
261
+ return left ;
262
+ }
263
+ if (opts.es6target && !left.id) {
264
+ left.type = 'ArrowFunctionExpression' ;
265
+ return left;
266
+ }
267
+ return parser.part("$0.bind(this)",[left]).expr;
268
+ }
269
+
270
+ var params = [{ "type": "ThisExpression" }] ;
271
+ if (arg) {
272
+ return parser.part("$0.$1(this,$2)",[left,genIdent.asyncbind,arg]).expr;
273
+ }
274
+ return parser.part("$0.$1(this)",[left,genIdent.asyncbind]).expr;
275
+ }
276
+
277
+ function makeBoundFn(name, body, argnames, binding) {
278
+ return parser.part("var $0 = $1",[ident(name),bindAsync({
279
+ "type": "FunctionExpression",
280
+ "id": null,
281
+ "generator": false,
282
+ "expression": false,
283
+ "params": argnames || [],
284
+ "body": Array.isArray(body)?{type:'BlockStatement',body:body}:body
285
+ }, binding)]).body[0] ;
286
+ }
287
+
288
+ function where(node) {
289
+ return pr.filename + (node && node.loc && node.loc.start ? "(" + node.loc.start.line + ":" + node.loc.start.column + ")\t" : "\t");
290
+ }
291
+
292
+ function literal(value) {
293
+ if (opts.babelTree) {
294
+ return babelLiteralNode(value);
295
+ } else {
296
+ return {
297
+ type: 'Literal',
298
+ value: value,
299
+ raw: JSON.stringify(value)
300
+ };
301
+ }
302
+ }
303
+
304
+ function getMemberFunction(node) {
305
+ if (!node)
306
+ return null ;
307
+ if (opts.babelTree && (node.type === 'ClassMethod' || node.type === 'ObjectMethod')) {
308
+ return node;
309
+ } else if ((!opts.babelTree && node.type === 'MethodDefinition' || node.type === 'Property' && (node.method || node.kind == 'get' || node.kind == 'set')) && examine(node.value).isFunction) {
310
+ return node.value;
311
+ }
312
+ return null;
313
+ }
314
+
315
+ var assign$Args = parser.part("var $0 = arguments",[genIdent.arguments]).body[0] ;
316
+
317
+ /* Replace 'arguments' identifiers in a function. Return true if a
318
+ * replacement has been made and so the symbol opts.$arguments needs
319
+ * initializing.
320
+ */
321
+ function replaceArguments(ast,nested) {
322
+ if (!examine(ast).isFunction)
323
+ throw new Error("Can only replace 'arguments' in functions") ;
324
+
325
+ if (!('$usesArguments' in ast)) {
326
+ parser.treeWalker(ast, function (node, descend, path) {
327
+ if (node.type === 'Identifier' && node.name === 'arguments') {
328
+ // Fix up shorthand properties
329
+ if (path[0].parent.shorthand) {
330
+ path[0].parent.shorthand = false ;
331
+ path[0].parent.key = ident('arguments') ;
332
+ ast.$usesArguments = true ;
333
+ }
334
+
335
+ // Replace identifiers that are not keys
336
+ if (path[0].field !== 'key') {
337
+ node.name = opts.$arguments;
338
+ ast.$usesArguments = true ;
339
+ }
340
+ } else if (node === ast || !examine(node).isFunction) {
341
+ descend();
342
+ } else if (node.type==='ArrowFunctionExpression') {
343
+ replaceArguments(node) ;
344
+ ast.$usesArguments = ast.$usesArguments || node.$usesArguments ;
345
+ }
346
+ });
347
+ ast.$usesArguments = ast.$usesArguments || false ;
348
+ }
349
+ return ast.$usesArguments && ast.type !== 'ArrowFunctionExpression';
350
+ }
351
+
352
+ function generateSymbol(node) {
353
+ if (typeof node != 'string')
354
+ node = node.type.replace(/Statement|Expression/g,"");
355
+ return opts.generatedSymbolPrefix + node + "_" + generatedSymbol++;
356
+ }
357
+
358
+ function setExit(n, sym) {
359
+ if (n) {
360
+ n.$exit = idents({
361
+ $error: sym.$error,
362
+ $return: sym.$return
363
+ });
364
+ }
365
+ return n;
366
+ }
367
+
368
+ function getExitNode(path) {
369
+ for (var n = 0;n < path.length; n++) {
370
+ if (path[n].self.$exit) {
371
+ return path[n].self;
372
+ }
373
+ if (path[n].parent && path[n].parent.$exit) {
374
+ return path[n].parent;
375
+ }
376
+ }
377
+ return null;
378
+ }
379
+
380
+ function getExit(path, parents) {
381
+ var n = getExitNode(path);
382
+ if (n)
383
+ return n.$exit;
384
+ if (parents) {
385
+ for (var i = 0;i < parents.length; i++)
386
+ if (parents[i])
387
+ return idents(parents[i]);
388
+ }
389
+ return null;
390
+ }
391
+
392
+ // actually do the transforms
393
+ if (opts.engine) {
394
+ // Only Transform extensions:
395
+ // - await outside of async
396
+ // - async return <optional-expression>
397
+ // - async throw <expression>
398
+ // - get async id(){} / async get id(){}
399
+ // - super references (in case they are used by async exits - in general they aren't)
400
+ // Everything else is passed through unmolested to be run by a JS engine such as V8 v5.4
401
+ pr.ast = fixSuperReferences(pr.ast,true);
402
+ pr.ast = asyncSpawn(pr.ast, opts.engine);
403
+ pr.ast = exposeCompilerOpts(pr.ast);
404
+ cleanCode(pr.ast)
405
+ } else if (opts.generators) {
406
+ // Transform to generators
407
+ pr.ast = fixSuperReferences(pr.ast);
408
+ pr.ast = asyncSpawn(pr.ast);
409
+ pr.ast = exposeCompilerOpts(pr.ast);
410
+ cleanCode(pr.ast)
411
+ } else {
412
+ // Transform to callbacks, optionally with Promises
413
+ pr.ast = fixSuperReferences(pr.ast);
414
+ asyncTransforms(pr.ast);
415
+ }
416
+ if (opts.babelTree) {
417
+ parser.treeWalker(pr.ast, function (node, descend, path) {
418
+ descend();
419
+ if (node.type === 'Literal') {
420
+ coerce(node, literal(node.value));
421
+ }
422
+ });
423
+ }
424
+ return pr;
425
+
426
+ function asyncTransforms(ast, awaitFlag) {
427
+ var useLazyLoops = !(opts.promises || opts.generators || opts.engine) && opts.lazyThenables ;
428
+ // Because we create functions (and scopes), we need all declarations before use
429
+ blockifyArrows(ast);
430
+ hoistDeclarations(ast);
431
+ // All TryCatch blocks need a name so we can (if necessary) find out what the enclosing catch routine is called
432
+ labelTryCatch(ast);
433
+ // Convert async functions and their contained returns & throws
434
+ asyncDefine(ast);
435
+ asyncDefineMethod(ast);
436
+ // Loops are asynchronized in an odd way - the loop is turned into a function that is
437
+ // invoked through tail recursion OR callback. They are like the inner functions of
438
+ // async functions to allow for completion and throwing
439
+ (useLazyLoops?asyncLoops_1:Nothing)(ast);
440
+ // Handle the various JS control flow keywords by splitting into continuations that could
441
+ // be invoked asynchronously
442
+ mapLogicalOp(ast);
443
+ mapCondOp(ast);
444
+ walkDown(ast, [mapTryCatch,(useLazyLoops?Nothing:mapLoops),mapIfStmt,mapSwitch,mapBlock]);
445
+ // Map awaits by creating continuations and passing them into the async resolver
446
+ asyncAwait(ast, awaitFlag);
447
+ exposeCompilerOpts(ast);
448
+ // Remove guff generated by transpiling
449
+ cleanCode(ast);
450
+ }
451
+
452
+ /* Create a 'continuation' - a block of statements that have been hoisted
453
+ * into a named function so they can be invoked conditionally or asynchronously */
454
+ function makeContinuation(name, body) {
455
+ var ctn = {
456
+ $continuation: true,
457
+ type: name?'FunctionDeclaration':'FunctionExpression',
458
+ id: name?typeof name==="string"?ident(name):name:undefined,
459
+ params: [],
460
+ body: {
461
+ type: 'BlockStatement',
462
+ body: cloneNode(body)
463
+ }
464
+ };
465
+ if (name) {
466
+ continuations[name] = {
467
+ def: ctn
468
+ };
469
+ }
470
+ return ctn;
471
+ }
472
+
473
+ /* Generate an expression AST the immediate invokes the specified async function, e.g.
474
+ * (await ((async function(){ ...body... })()))
475
+ */
476
+ function internalIIAFE(body) {
477
+ return {
478
+ type: 'AwaitExpression',
479
+ argument: asyncDefine({
480
+ "type": "FunctionExpression",
481
+ "generator": false,
482
+ "expression": false,
483
+ "async": true,
484
+ "params": [],
485
+ "body": {
486
+ "type": "BlockStatement",
487
+ "body": body
488
+ }
489
+ }).body.body[0].argument
490
+ }
491
+ }
492
+
493
+ /* Used to invoke a 'continuation' - a function that represents
494
+ * a block of statements lifted out so they can be labelled (as
495
+ * a function definition) to be invoked via multiple execution
496
+ * paths - either conditional or asynchronous. Since 'this' existed
497
+ * in the original scope of the statements, the continuation function
498
+ * must also have the correct 'this'.*/
499
+ function thisCall(name, args) {
500
+ if (typeof name === 'string')
501
+ name = ident(name);
502
+ var n = parser.part("$0.call($1)",[name,[{"type": "ThisExpression"}].concat(args || [])]).expr ;
503
+ name.$thisCall = n;
504
+ n.$thisCallName = name.name;
505
+ return n;
506
+ }
507
+ function returnThisCall(name,args) {
508
+ return {
509
+ type:'ReturnStatement',
510
+ argument: thisCall(name,args)
511
+ }
512
+ }
513
+
514
+ function deferredFinally(node, expr) {
515
+ return {
516
+ "type": "CallExpression",
517
+ "callee": ident(node.$seh + "Finally"),
518
+ "arguments": expr ? [expr] : []
519
+ };
520
+ }
521
+
522
+ /**
523
+ * returnMapper is an Uglify2 transformer that is used to change statements such as:
524
+ * return some-expression ;
525
+ * into
526
+ * return $return(some-expression) ;
527
+ * for the current scope only -i.e. returns nested in inner functions are NOT modified.
528
+ *
529
+ * This allows us to capture a normal "return" statement and actually implement it
530
+ * by calling the locally-scoped function $return()
531
+ */
532
+ function mapReturns(n, path) {
533
+ if (Array.isArray(n)) {
534
+ return n.map(function (m) {
535
+ return mapReturns(m, path);
536
+ });
537
+ }
538
+ var lambdaNesting = 0;
539
+ var tryNesting = 0 ;
540
+ return parser.treeWalker(n, function (node, descend, path) {
541
+ if (node.type === 'ReturnStatement' && !node.$mapped) {
542
+ if (lambdaNesting > 0) {
543
+ if (!examine(node).isAsync) {
544
+ return descend(node);
545
+ }
546
+ delete node.async;
547
+ }
548
+ /* NB: There is a special case where we do a REAL return to allow for chained async-calls and synchronous returns
549
+ *
550
+ * The selected syntax for this is:
551
+ * return void (expr) ;
552
+ * which is mapped to:
553
+ * return (expr) ;
554
+ *
555
+ * Note that the parenthesis are necessary in the case of anything except a single symbol as "void" binds to
556
+ * values before operator. In the case where we REALLY want to return undefined to the callback, a simple
557
+ * "return" or "return undefined" works.
558
+ *
559
+ * There is an argument for only allowing this exception in es7 mode, as Promises and generators might (one day)
560
+ * get their own cancellation method.
561
+ * */
562
+ node.$mapped = true;
563
+ if (examine(node.argument).isUnaryExpression && node.argument.operator === "void") {
564
+ node.argument = node.argument.argument;
565
+ } else {
566
+ node.argument = {
567
+ "type": "CallExpression",
568
+ callee: getExit(path, [opts]).$return,
569
+ "arguments": node.argument ? [node.argument] : []
570
+ };
571
+ }
572
+ return;
573
+ } else if (node.type === 'ThrowStatement') {
574
+ var isAsync = examine(node).isAsync ;
575
+ if (lambdaNesting > 0) {
576
+ if (!isAsync) {
577
+ return descend(node);
578
+ }
579
+ delete node.async;
580
+ }
581
+ if (!isAsync && tryNesting) {
582
+ descend() ;
583
+ } else {
584
+ node.type = 'ReturnStatement';
585
+ node.$mapped = true;
586
+ node.argument = {
587
+ type: 'CallExpression',
588
+ callee: getExit(path, [opts]).$error,
589
+ arguments: [node.argument]
590
+ };
591
+ }
592
+ return;
593
+ } else if (node.type === 'TryStatement') {
594
+ tryNesting++;
595
+ descend(node);
596
+ tryNesting--;
597
+ return;
598
+ } else if (examine(node).isFunction) {
599
+ lambdaNesting++;
600
+ descend(node);
601
+ lambdaNesting--;
602
+ return;
603
+ } else {
604
+ descend(node);
605
+ return;
606
+ }
607
+ }, path);
608
+ }
609
+
610
+ /*
611
+ To implement conditional execution, a?b:c is mapped to
612
+
613
+ await (async function(){ if (a) return b ; return c })
614
+
615
+ Note that 'await (async function(){})()' can be optimized to a Thenable since no args are passed
616
+ */
617
+ function mapCondOp(ast, state) {
618
+ if (Array.isArray(ast))
619
+ return ast.map(function (n) {
620
+ return mapCondOp(n, state);
621
+ });
622
+ parser.treeWalker(ast, function (node, descend, path) {
623
+ descend();
624
+ if (node.type === 'ConditionalExpression' && (containsAwait(node.alternate) || containsAwait(node.consequent))) {
625
+ var z = ident(generateSymbol("condOp"));
626
+ var xform = internalIIAFE(parser.part("if ($0) return $1 ; return $2",[node.test,node.consequent,node.alternate]).body);
627
+ coerce(node, xform);
628
+ }
629
+ }, state);
630
+ return ast;
631
+ }
632
+
633
+ /*
634
+ To implement conditional execution, logical operators with an awaited RHS are mapped thus:
635
+
636
+ Translate a || b into await (async function Or(){ var z ; if (!(z=a)) z=b ; return z })
637
+ Translate a && b into await (async function And(){ var z ; if (z=a) z=b ; return z })
638
+
639
+ Note that 'await (async function(){})()' can be optimized to a Thenable since no args are passed
640
+ */
641
+ function mapLogicalOp(ast, state) {
642
+ if (Array.isArray(ast))
643
+ return ast.map(function (n) {
644
+ return mapLogicalOp(n, state);
645
+ });
646
+ parser.treeWalker(ast, function (node, descend, path) {
647
+ descend();
648
+ if (node.type === 'LogicalExpression' && containsAwait(node.right)) {
649
+ var codeFrag;
650
+ var z = ident(generateSymbol("logical" + (node.operator === '&&' ? "And" : "Or")));
651
+
652
+ if (node.operator === '||') {
653
+ codeFrag = "var $0; if (!($0 = $1)) {$0 = $2} return $0" ;
654
+ } else if (node.operator === '&&') {
655
+ codeFrag = "var $0; if ($0 = $1) {$0 = $2} return $0" ;
656
+ } else
657
+ throw new Error(where(node) + "Illegal logical operator: "+node.operator);
658
+
659
+ coerce(node, internalIIAFE(parser.part(codeFrag,[z,node.left, node.right]).body));
660
+ }
661
+ }, state);
662
+ return ast;
663
+ }
664
+
665
+ function mapBlock(block, path, down) {
666
+ if (block.type !== "SwitchCase" && examine(block).isBlockStatement) {
667
+ var idx = 0 ;
668
+ while (idx < block.body.length) {
669
+ var node = block.body[idx] ;
670
+ if (node.type !== "SwitchCase" && examine(node).isBlockStatement) {
671
+ var blockScoped = containsBlockScopedDeclarations(node.body) ;
672
+ if (!blockScoped) {
673
+ block.body.splice.apply(block.body,[idx,1].concat(node.body));
674
+ } else {
675
+ if (containsAwaitInBlock(node)) {
676
+ var symName = generateSymbol(node);
677
+ var deferredCode = block.body.splice(idx + 1, block.body.length - (idx + 1));
678
+ if (deferredCode.length) {
679
+ var ctn = makeContinuation(symName, deferredCode);
680
+ delete continuations[symName] ;
681
+ node.body.push(returnThisCall(symName));
682
+ block.body.push(ctn) ;
683
+ idx++ ;
684
+ } else idx++ ;
685
+ } else idx++ ;
686
+ }
687
+ } else idx++ ;
688
+ }
689
+ }
690
+ }
691
+
692
+ /*
693
+ * Translate:
694
+ if (x) { y; } more... ;
695
+ * into
696
+ if (x) { y; return $more(); } function $more() { more... } $more() ;
697
+ *
698
+ * ...in case 'y' uses await, in which case we need to invoke $more() at the end of the
699
+ * callback to continue execution after the case.
700
+ */
701
+ function mapIfStmt(ifStmt, path, down) {
702
+ if (ifStmt.type === 'IfStatement' && containsAwait([ifStmt.consequent,ifStmt.alternate])) {
703
+ var symName = generateSymbol(ifStmt);
704
+ var ref = path[0];
705
+ var synthBlock = {
706
+ type: 'BlockStatement',
707
+ body: [ifStmt]
708
+ };
709
+ if ('index' in ref) {
710
+ var idx = ref.index;
711
+ var deferredCode = ref.parent[ref.field].splice(idx + 1, ref.parent[ref.field].length - (idx + 1));
712
+ ref.replace(synthBlock);
713
+ if (deferredCode.length) {
714
+ var call = returnThisCall(symName);
715
+ synthBlock.body.push(down(makeContinuation(symName, deferredCode)));
716
+ [ifStmt.consequent,ifStmt.alternate].forEach(function (cond) {
717
+ if (!cond)
718
+ return;
719
+ var blockEnd;
720
+ if (!examine(cond).isBlockStatement)
721
+ blockEnd = cond;
722
+ else
723
+ blockEnd = cond.body[cond.body.length - 1];
724
+ if (!(blockEnd && blockEnd.type === 'ReturnStatement')) {
725
+ if (!(cond.type === 'BlockStatement')) {
726
+ coerce(cond, {
727
+ type: 'BlockStatement',
728
+ body: [cloneNode(cond)]
729
+ });
730
+ }
731
+ cond.$deferred = true;
732
+ cond.body.push(cloneNode(call));
733
+ }
734
+ down(cond);
735
+ });
736
+ // If both blocks are transformed, the trailing call to $post_if()
737
+ // can be omitted as it'll be unreachable via a synchronous path
738
+ if (!(ifStmt.consequent && ifStmt.alternate && ifStmt.consequent.$deferred && ifStmt.alternate.$deferred))
739
+ synthBlock.body.push(cloneNode(call));
740
+ }
741
+ } else {
742
+ ref.parent[ref.field] = synthBlock;
743
+ }
744
+ }
745
+ }
746
+
747
+ function mapSwitch(switchStmt, path, down) {
748
+ if (!switchStmt.$switched && switchStmt.type === 'SwitchStatement' && containsAwait(switchStmt.cases)) {
749
+ switchStmt.$switched = true;
750
+ var symName, deferred, deferredCode, ref = path[0];
751
+ if ('index' in ref) {
752
+ var j = ref.index + 1;
753
+ deferredCode = ref.parent[ref.field].splice(j, ref.parent[ref.field].length - j);
754
+ if (deferredCode.length && deferredCode[deferredCode.length - 1].type === 'BreakStatement')
755
+ ref.parent[ref.field].push(deferredCode.pop());
756
+ symName = generateSymbol(switchStmt);
757
+ deferred = returnThisCall(symName);
758
+ ref.parent[ref.field].unshift(makeContinuation(symName, deferredCode));
759
+ ref.parent[ref.field].push(cloneNode(deferred));
760
+ }
761
+ // Now transform each case so that 'break' looks like return <deferred>
762
+ switchStmt.cases.forEach(function (caseStmt, idx) {
763
+ if (!(caseStmt.type === 'SwitchCase')) {
764
+ throw new Error("switch contains non-case/default statement: " + caseStmt.type);
765
+ }
766
+ if (containsAwait(caseStmt.consequent)) {
767
+ var end = caseStmt.consequent[caseStmt.consequent.length - 1];
768
+ if (end.type === 'BreakStatement') {
769
+ caseStmt.consequent[caseStmt.consequent.length - 1] = cloneNode(deferred) ;
770
+ } else if (end.type === 'ReturnStatement' || end.type === 'ThrowStatement') {} else {
771
+ // Do nothing - block ends in return or throw
772
+ logger(where(caseStmt) + "switch-case fall-through not supported - added break. See https://github.com/MatAtBread/nodent#differences-from-the-es7-specification");
773
+ caseStmt.consequent.push(cloneNode(deferred));
774
+ }
775
+ }
776
+ });
777
+ return true;
778
+ }
779
+ }
780
+
781
+ function isExitStatement(n) {
782
+ return n.type==='ReturnStatement' || n.type==='ThrowStatement'
783
+ }
784
+ /* Give unique names to TryCatch blocks */
785
+ function labelTryCatch(ast,engineMode) {
786
+ parser.treeWalker(ast, function (node, descend, path) {
787
+ if (node.type === 'TryStatement' && !node.$seh) {
788
+ if (!examine(path[0].parent).isBlockStatement) {
789
+ path[0].parent[path[0].field] = {
790
+ type:'BlockStatement',
791
+ body:[node]
792
+ } ;
793
+ }
794
+ // Every try-catch needs a name, so asyncDefine/asyncAwait knows who's handling errors
795
+ node.$seh = generateSymbol("Try") + "_";
796
+ node.$containedAwait = !!containsAwait(node);
797
+ node.$finallyExit = node.finalizer && inAsync(path) && !!contains(node.finalizer.body,isExitStatement) ;
798
+
799
+ if (node.$containedAwait || node.$finallyExit) {
800
+ node.$needsMapping = engineMode? !node.$finallyExit : true ;
801
+ var parent = getExit(path, [opts]);
802
+ if (node.finalizer && !node.handler) {
803
+ // We have a finally, but no 'catch'. Create the default catch clause 'catch(_ex) { throw _ex }'
804
+ var exSym = ident(generateSymbol("exception"));
805
+ node.handler = {
806
+ "type": "CatchClause",
807
+ "param": exSym,
808
+ "body": {
809
+ "type": "BlockStatement",
810
+ "body": [{
811
+ "type": "ThrowStatement",
812
+ "argument": exSym
813
+ }]
814
+ }
815
+ };
816
+ }
817
+ if (!node.handler && !node.finalizer) {
818
+ var ex = new SyntaxError(where(node.value) + "try requires catch and/or finally clause", pr.filename, node.start);
819
+ ex.pos = node.start;
820
+ ex.loc = node.loc.start;
821
+ throw ex;
822
+ }
823
+ if (node.finalizer) {
824
+ setExit(node.block, {
825
+ $error: node.$seh + "Catch",
826
+ $return: deferredFinally(node, parent.$return)
827
+ });
828
+ setExit(node.handler, {
829
+ $error: deferredFinally(node, parent.$error),
830
+ $return: deferredFinally(node, parent.$return)
831
+ });
832
+ } else {
833
+ setExit(node.block, {
834
+ $error: node.$seh + "Catch",
835
+ $return: parent.$return
836
+ });
837
+ }
838
+ }
839
+ }
840
+ descend();
841
+ });
842
+ return ast;
843
+ }
844
+
845
+ function afterDirectives(body,nodes) {
846
+ for (var i=0; i<body.length; i++) {
847
+ if (examine(body[i]).isDirective)
848
+ continue ;
849
+ body.splice.apply(body,[i,0].concat(nodes)) ;
850
+ return ;
851
+ }
852
+ body.splice.apply(body,[body.length,0].concat(nodes)) ;
853
+ }
854
+
855
+ function inAsync(path) {
856
+ for (var i=0; i<path.length; i++)
857
+ if (examine(path[i].self).isFunction)
858
+ return path[i].self.async || path[i].self.$wasAsync ;
859
+ return false ;
860
+ }
861
+
862
+ function mapTryCatch(node, path, down) {
863
+ if (node.$needsMapping) {
864
+ var continuation, ctnName, catchBody;
865
+ var ref = path[0];
866
+ if ('index' in ref) {
867
+ var i = ref.index + 1;
868
+ var afterTry = ref.parent[ref.field].splice(i, ref.parent[ref.field].length - i);
869
+ if (afterTry.length) {
870
+ ctnName = node.$seh + "Post";
871
+ var afterContinuation = down(makeBoundFn(ctnName, afterTry, [], getExit(path, [opts]).$error));
872
+ ref.parent[ref.field].splice(ref.index,0,afterContinuation);
873
+ continuation = parser.part("return $0()",
874
+ [node.finalizer ? deferredFinally(node, ident(ctnName)) : ident(ctnName)]).body[0] ;
875
+ } else if (node.finalizer) {
876
+ continuation = returnThisCall(deferredFinally(node));
877
+ }
878
+ } else {
879
+ throw new Error(pr.filename + " - malformed try/catch blocks");
880
+ }
881
+ node.$mapped = true;
882
+ if (continuation) {
883
+ node.block.body.push(cloneNode(continuation));
884
+ node.handler.body.body.push(cloneNode(continuation));
885
+ }
886
+ var binding = getExit(path, [opts]);
887
+ if (node.handler) {
888
+ var symCatch = ident(node.$seh + "Catch");
889
+ catchBody = cloneNode(node.handler.body);
890
+ var catcher = makeBoundFn(symCatch.name, catchBody, [cloneNode(node.handler.param)], node.finalizer ? deferredFinally(node, binding.$error) : binding.$error);
891
+ node.handler.body.body = [{
892
+ type: 'CallExpression',
893
+ callee: symCatch,
894
+ arguments: [cloneNode(node.handler.param)]
895
+ }];
896
+ ref.parent[ref.field].splice(ref.index,0,catcher) ;
897
+ }
898
+ if (node.finalizer) {
899
+ down(node.finalizer) ;
900
+ var finalParams = {
901
+ exit:ident(node.$seh + "Exit"),
902
+ value:ident(node.$seh + "Value"),
903
+ body:cloneNode(node.finalizer.body),
904
+ } ;
905
+
906
+ var chainFinalize = parser.part(
907
+ "(function ($value) { "+
908
+ " $:body; "+
909
+ " return $exit && ($exit.call(this, $value)); "+
910
+ " })",finalParams).expr ;
911
+
912
+ var finalizer = {
913
+ type: 'VariableDeclaration',
914
+ kind: 'var',
915
+ declarations: [{
916
+ type: "VariableDeclarator",
917
+ id: ident(node.$seh + "Finally"),
918
+ init: bindAsync({
919
+ type:'FunctionExpression',
920
+ params:[finalParams.exit],
921
+ id:null,
922
+ body:{
923
+ type:'BlockStatement',
924
+ body:[{
925
+ type: 'ReturnStatement',
926
+ argument: bindAsync(chainFinalize,binding.$error)
927
+ }]
928
+ }
929
+ })
930
+ }]
931
+ } ;
932
+
933
+ afterDirectives(ref.parent[ref.field],[finalizer]);
934
+ var callFinally = parser.part("return $0()",
935
+ [node.finalizer ? deferredFinally(node, ident(ctnName)) : ident(ctnName)]).body[0] ;
936
+ catchBody.body[catchBody.length - 1] = callFinally;
937
+ node.block.body[node.block.body.length - 1] = callFinally;
938
+ delete node.finalizer;
939
+ }
940
+ }
941
+ }
942
+
943
+ function walkDown(ast, mappers, state) {
944
+ var walked = [];
945
+
946
+ function closedWalk(ast,state) {
947
+ return parser.treeWalker(ast, function (node, descend, path) {
948
+ function walkDownSubtree(node) {
949
+ return closedWalk(node, path);
950
+ }
951
+
952
+ if (walked.indexOf(node) < 0) {
953
+ walked.push(node) ;
954
+ mappers.forEach(function (m) {
955
+ m(node, path, walkDownSubtree);
956
+ });
957
+ }
958
+ descend();
959
+ return;
960
+ }, state);
961
+ }
962
+
963
+ closedWalk(ast,state)
964
+ return ast ;
965
+ }
966
+
967
+ function asyncAwait(ast, inAsync, parentCatcher) {
968
+ parser.treeWalker(ast, function (node, descend, path) {
969
+ if (node.type == 'IfStatement') {
970
+ if (node.consequent.type != 'BlockStatement' && containsAwait(node.consequent))
971
+ node.consequent = {
972
+ type: 'BlockStatement',
973
+ body: [node.consequent]
974
+ };
975
+ if (node.alternate && node.alternate.type != 'BlockStatement' && containsAwait(node.alternate))
976
+ node.alternate = {
977
+ type: 'BlockStatement',
978
+ body: [node.alternate]
979
+ };
980
+ }
981
+ descend();
982
+ if (examine(node).isAwait) {
983
+ var loc = node.loc;
984
+ /* Warn if this await expression is not inside an async function, as the return
985
+ * will depend on the Thenable implementation, and references to $return might
986
+ * not resolve to anything */
987
+ inAsync = inAsync || path.some(function (ancestor) {
988
+ return ancestor.self && ancestor.self.$wasAsync;
989
+ });
990
+ if (!inAsync || inAsync === "warn") {
991
+ var errMsg = where(node) + "'await' used inside non-async function. ";
992
+ if (opts.promises)
993
+ errMsg += "'return' value Promise runtime-specific";
994
+ else
995
+ errMsg += "'return' value from await is synchronous";
996
+ logger(errMsg + ". See https://github.com/MatAtBread/nodent#differences-from-the-es7-specification");
997
+ }
998
+ var parent = path[0].parent;
999
+ if (parent.type === 'LogicalExpression' && parent.right === node) {
1000
+ logger(where(node.argument) + "'" + printNode(parent) + "' on right of " + parent.operator + " will always evaluate '" + printNode(node.argument) + "'");
1001
+ }
1002
+ if (parent.type === 'ConditionalExpression' && parent.test !== node) {
1003
+ logger(where(node.argument) + "'" + printNode(parent) + "' will always evaluate '" + printNode(node.argument) + "'");
1004
+ }
1005
+ var result = ident(generateSymbol("await"));
1006
+ var expr = cloneNode(node.argument);
1007
+ coerce(node, result);
1008
+ // Find the statement containing this await expression (and it's parent)
1009
+ var stmt, body;
1010
+ for (var n = 1;n < path.length; n++) {
1011
+ if (body = examine(path[n].self).isBlockStatement) {
1012
+ stmt = path[n - 1];
1013
+ break;
1014
+ }
1015
+ }
1016
+ if (!stmt)
1017
+ throw new Error(where(node) + "Illegal await not contained in a statement");
1018
+ var containingExits = getExit(path, [parentCatcher,opts]);
1019
+ var i = stmt.index;
1020
+ var callback, callBack = body.splice(i, body.length - i).slice(1);
1021
+ var returner;
1022
+ // If stmt is of the form 'return fn(result.name)', just replace it a
1023
+ // reference to 'fn'.
1024
+ if (stmt.self.type === 'ReturnStatement' && stmt.self.argument.type === 'CallExpression' && stmt.self.argument.arguments.length === 1 && stmt.self.argument.arguments[0].name === result.name) {
1025
+ returner = (callback = stmt.self.argument.callee);
1026
+ // If stmt is only a reference to the result, suppress the result
1027
+ // reference as it does nothing
1028
+ } else if (!(stmt.self.type === 'Identifier' || stmt.self.name === result.name || stmt.self.type === 'ExpressionStatement' && stmt.self.expression.type === 'Identifier' && stmt.self.expression.name === result.name)) {
1029
+ callBack.unshift(stmt.self);
1030
+ callback = {
1031
+ type: 'FunctionExpression',
1032
+ params: [cloneNode(result)],
1033
+ body: asyncAwait({
1034
+ type: 'BlockStatement',
1035
+ body: cloneNode(callBack)
1036
+ }, inAsync, containingExits)
1037
+ };
1038
+ } else {
1039
+ if (callBack.length)
1040
+ callback = {
1041
+ type: 'FunctionExpression',
1042
+ params: [cloneNode(result)],
1043
+ body: asyncAwait({
1044
+ type: 'BlockStatement',
1045
+ body: cloneNode(callBack)
1046
+ }, inAsync, containingExits)
1047
+ };
1048
+ else {
1049
+ callback = {
1050
+ type: 'FunctionExpression',
1051
+ params: [],
1052
+ body: {
1053
+ type: 'BlockStatement',
1054
+ body: []
1055
+ }
1056
+ };
1057
+ }
1058
+ }
1059
+ // Wrap the callback statement(s) in a Block and transform them
1060
+ if (!returner) {
1061
+ if (callback) {
1062
+ returner = bindAsync(callback,containingExits.$error) ;
1063
+ } else {
1064
+ returner = {
1065
+ type: 'FunctionExpression',
1066
+ params: [],
1067
+ body: {
1068
+ type: 'BlockStatement',
1069
+ body: []
1070
+ }
1071
+ };
1072
+ }
1073
+ }
1074
+ if (opts.wrapAwait) {
1075
+ expr = {
1076
+ type: 'CallExpression',
1077
+ arguments: [expr],
1078
+ callee: (opts.promises || opts.generators)?{
1079
+ type: 'MemberExpression',
1080
+ object: ident('Promise'),
1081
+ property: ident('resolve')
1082
+ }:{
1083
+ // ES7 makeThenable
1084
+ type: 'MemberExpression',
1085
+ object: ident('Object'),
1086
+ property: ident('$makeThenable')
1087
+ }
1088
+ };
1089
+ }
1090
+ var exitCall = {
1091
+ type: 'CallExpression',
1092
+ callee: {
1093
+ type: 'MemberExpression',
1094
+ object: expr,
1095
+ property: ident('then', loc),
1096
+ computed: false
1097
+ },
1098
+ arguments: [returner,containingExits.$error]
1099
+ };
1100
+ body.push({
1101
+ loc: loc,
1102
+ type: 'ReturnStatement',
1103
+ argument: exitCall
1104
+ });
1105
+ }
1106
+ return true;
1107
+ });
1108
+ return ast;
1109
+ }
1110
+
1111
+ // Transform a for..in into it's iterative equivalent
1112
+ function transformForIn(node, path) {
1113
+ var label = node.$label ;
1114
+ delete node.$label ;
1115
+
1116
+ var idx = ident(generateSymbol("idx"))
1117
+ var inArray = ident(generateSymbol("in"));
1118
+ var declVars = parser.part("var $0,$1 = [];for ($0 in $2) $1.push($0)",[idx,inArray,node.right]).body ;
1119
+ var loop = parser.part("for ($0; $1.length;){ $2 = $1.shift(); $:3 ; }",[
1120
+ node.left,
1121
+ inArray,
1122
+ node.left.type === 'VariableDeclaration' ? node.left.declarations[0].id : node.left,
1123
+ node.body]).body[0] ;
1124
+ loop.$label = label ;
1125
+ for (var b=0; b<path.length; b++) {
1126
+ if (examine(path[b].parent).isBlockStatement) {
1127
+ path[b].parent[path[b].field].splice(path[b].index,0,declVars[0],declVars[1]) ;
1128
+ break ;
1129
+ }
1130
+ }
1131
+ coerce(node,loop) ;
1132
+ }
1133
+
1134
+ // Transform a for..of into it's iterative equivalent
1135
+ function iterizeForOf(node, path) {
1136
+ if (node.body.type !== 'BlockStatement') {
1137
+ node.body = {
1138
+ type: 'BlockStatement',
1139
+ body: [node.body]
1140
+ };
1141
+ }
1142
+ var index, iterator, initIterator = parser.part("[$0[Symbol.iterator]()]",[node.right]).expr;
1143
+
1144
+ if (node.left.type === 'VariableDeclaration') {
1145
+ if (node.left.kind==='const')
1146
+ node.left.kind = 'let' ;
1147
+
1148
+ index = node.left.declarations[0].id ;
1149
+ var decls = getDeclNames(node.left.declarations[0].id) ;
1150
+ iterator = ident(generateSymbol("iterator_" + decls.join('_')));
1151
+
1152
+ node.left.declarations = decls.map(function(name){
1153
+ return {
1154
+ type: "VariableDeclarator",
1155
+ id: ident(name)
1156
+ } ;
1157
+ }) ;
1158
+ node.left.declarations.push({
1159
+ type: "VariableDeclarator",
1160
+ id: iterator,
1161
+ init: initIterator
1162
+ });
1163
+ node.init = node.left;
1164
+ } else {
1165
+ index = node.left;
1166
+ iterator = ident(generateSymbol("iterator_" + index.name));
1167
+ var declaration = {
1168
+ type: 'VariableDeclaration',
1169
+ kind: 'var',
1170
+ declarations: [{
1171
+ type: "VariableDeclarator",
1172
+ id: iterator,
1173
+ init: initIterator
1174
+ }]
1175
+ };
1176
+ node.init = declaration;
1177
+ }
1178
+ node.type = 'ForStatement';
1179
+ node.test = parser.part("!($0[1] = $0[0].next()).done && (($1 = $0[1].value) || true)",[iterator,index]).expr ;
1180
+ delete node.left;
1181
+ delete node.right;
1182
+ }
1183
+
1184
+ /* Map loops */
1185
+ /* As of v3.0.0 loops are asynchronized via a trampoline to prevent stack overflow in big loops with no actionable awaits. */
1186
+ function mapLoops(node, path, down) {
1187
+ var depth = node.$depth ;
1188
+ if (node.type === 'ForInStatement' && containsAwait(node)) {
1189
+ transformForIn(node, path) ;
1190
+ } else if (node.type === 'ForOfStatement' && containsAwait(node)) {
1191
+ iterizeForOf(node, path);
1192
+ }
1193
+
1194
+ // Are we inside a loop that has already been asynchronized and is labelled?
1195
+ var inAsyncLoop = path.some(function(p){
1196
+ return ('$label' in p.self && p.self.type==='ForStatement' && p.self.$mapped) ;
1197
+ }) ;
1198
+
1199
+ // Check if the loop contains an await, or a labelled exit if we're inside an async loop
1200
+ function mappableLoop(n){
1201
+ return (n.type==='AwaitExpression' && !n.$hidden)
1202
+ || (inAsyncLoop && (n.type==='BreakStatement'|| n.type==='ContinueStatement') && n.label)
1203
+ };
1204
+
1205
+ if (!node.$mapped && examine(node).isLoop && contains(node,mappableLoop)) {
1206
+ path[0].self.$mapped = true ;
1207
+ var p ;
1208
+ var mapped = [] ;
1209
+ var init = node.init;
1210
+ var test = node.test || literal(true);
1211
+ var step = node.update;
1212
+ var body = node.body;
1213
+
1214
+ if (step) {
1215
+ step = {
1216
+ type:'ExpressionStatement',
1217
+ expression: step
1218
+ } ;
1219
+ }
1220
+
1221
+ if (init) {
1222
+ if (!examine(init).isStatement) {
1223
+ init = {
1224
+ type: 'ExpressionStatement',
1225
+ expression: init
1226
+ };
1227
+ }
1228
+ mapped.push(init) ;
1229
+ }
1230
+
1231
+ var ref, label ;
1232
+ if (node.$label) {
1233
+ label = node.$label.name ;
1234
+ ref = path[1] ;
1235
+ } else {
1236
+ label = generatedSymbol++ ;
1237
+ ref = path[0] ;
1238
+ }
1239
+
1240
+ label = opts.generatedSymbolPrefix + "Loop_" + label;
1241
+ var idTrampoline = ident(label + "_trampoline") ;
1242
+ var idIter = ident(label) ;
1243
+ var idStep = step ? ident(label + "_step") : idIter ;
1244
+ var idContinuation = ident(label + "_exit") ;
1245
+ var idBounce = ident("q") ;
1246
+ var idCatchParam = ident("$exception") ;
1247
+ var continuation, deferredCode ;
1248
+
1249
+ if ('index' in ref) {
1250
+ var idx = ref.index;
1251
+ deferredCode = ref.parent[ref.field].splice(idx + 1, ref.parent[ref.field].length - (idx + 1));
1252
+ } else {
1253
+ deferredCode = [] ;
1254
+ }
1255
+
1256
+ continuation = makeContinuation(idContinuation, deferredCode) ;
1257
+ var returnIter = {
1258
+ "type": "ReturnStatement",
1259
+ "argument": idIter
1260
+ } ;
1261
+
1262
+ var returnStep = {
1263
+ "type": "ReturnStatement",
1264
+ "argument": idStep
1265
+ } ;
1266
+
1267
+ var returnBreak = {
1268
+ type: 'ReturnStatement',
1269
+ argument: {
1270
+ "type": "ArrayExpression",
1271
+ "elements":[literal(1)]
1272
+ }
1273
+ };
1274
+
1275
+ parser.treeWalker(body, function mapExits(n, descend, subpath) {
1276
+ if (examine(n).isFunction || examine(n).isLoop) {
1277
+ return true;
1278
+ } else if (n.type === 'BreakStatement' || n.type === 'ContinueStatement') {
1279
+ if (n.label) {
1280
+ var labelStack = subpath.filter(function(p){
1281
+ return '$label' in p.self
1282
+ }).map(function(p,idx){
1283
+ return p.self.$label && p.self.$label.name
1284
+ }) ;
1285
+
1286
+ // Work out how many loops to exit by examining subpath.
1287
+ var loops = [] ;
1288
+ for (var l=0; l<labelStack.length; l++) {
1289
+ if (labelStack[l] === n.label.name) {
1290
+ if (n.type === 'BreakStatement')
1291
+ loops.push(literal(1)) ;
1292
+ subpath[0].replace({
1293
+ type: 'ReturnStatement',
1294
+ argument: {
1295
+ "type": "ArrayExpression",
1296
+ "elements":loops.reverse()
1297
+ }
1298
+ }) ;
1299
+ break ;
1300
+ }
1301
+ loops.push(literal(0)) ;
1302
+ }
1303
+ } else {
1304
+ if (n.type === 'BreakStatement')
1305
+ subpath[0].replace(returnBreak) ;
1306
+ else // continue;
1307
+ subpath[0].replace(returnStep) ;
1308
+ }
1309
+ } else {
1310
+ descend();
1311
+ }
1312
+ },path) ;
1313
+
1314
+ if (body.type === 'BlockStatement')
1315
+ body = body.body.slice(0) ;
1316
+ else
1317
+ body = [body] ;
1318
+
1319
+ if (node.type==='DoWhileStatement') {
1320
+ body = body.concat({
1321
+ "type": "IfStatement",
1322
+ "test": {
1323
+ type:'UnaryExpression',
1324
+ argument:test,
1325
+ prefix:true,
1326
+ operator:'!'
1327
+ },
1328
+ "consequent": returnBreak,
1329
+ alternate:returnStep
1330
+ }) ;
1331
+ } else {
1332
+ body = [{
1333
+ "type": "IfStatement",
1334
+ "test": test,
1335
+ "consequent": {
1336
+ "type": "BlockStatement",
1337
+ "body": body.concat(returnStep)
1338
+ },
1339
+ alternate:returnBreak
1340
+ }] ;
1341
+ }
1342
+
1343
+ if (opts.noRuntime) {
1344
+ mapped.push({
1345
+ "type": "VariableDeclaration",
1346
+ "declarations": [{
1347
+ "type": "VariableDeclarator",
1348
+ "id": idTrampoline
1349
+ }],
1350
+ "kind": "var"
1351
+ }) ;
1352
+ }
1353
+ var invokeIterate ;
1354
+ var exit = getExit(path, [opts]).$error ;
1355
+ if (opts.noRuntime) {
1356
+ invokeIterate = parser.part(
1357
+ opts.es6target?
1358
+ "($idTrampoline = ((q) => { "+
1359
+ " $$setMapped: while (q) { "+
1360
+ " if (q.then) "+
1361
+ (depth===1?
1362
+ " return void q.then($idTrampoline, $exit); ":
1363
+ " return q.then($idTrampoline, $exit); ")+
1364
+ " try { "+
1365
+ " if (q.pop) "+
1366
+ " if (q.length) "+
1367
+ " return q.pop() ? $idContinuation.call(this) : q; "+
1368
+ " else "+
1369
+ " q = $idStep; "+
1370
+ " else "+
1371
+ " q = q.call(this) "+
1372
+ " } catch (_exception) { "+
1373
+ " return $exit(_exception); "+
1374
+ " } "+
1375
+ " } "+
1376
+ "}))($idIter)":
1377
+ "($idTrampoline = (function (q) { "+
1378
+ " $$setMapped: while (q) { "+
1379
+ " if (q.then) "+
1380
+ (depth===1?
1381
+ " return void q.then($idTrampoline, $exit); ":
1382
+ " return q.then($idTrampoline, $exit); ")+
1383
+ " try { "+
1384
+ " if (q.pop) "+
1385
+ " if (q.length) "+
1386
+ " return q.pop() ? $idContinuation.call(this) : q; "+
1387
+ " else "+
1388
+ " q = $idStep; "+
1389
+ " else "+
1390
+ " q = q.call(this) "+
1391
+ " } catch (_exception) { "+
1392
+ " return $exit(_exception); "+
1393
+ " } "+
1394
+ " } "+
1395
+ "}).bind(this))($idIter)",
1396
+ {
1397
+ setMapped:function(n){ n.$mapped = true ; return n },
1398
+ idTrampoline:idTrampoline,
1399
+ exit:exit,
1400
+ idIter:idIter,
1401
+ idContinuation:idContinuation,
1402
+ idStep:idStep
1403
+ }).expr ;
1404
+ } else {
1405
+ invokeIterate = parser.part("(Function.$0.trampoline(this,$1,$2,$3,$5)($4))",[
1406
+ genIdent.asyncbind,
1407
+ idContinuation,idStep,exit,
1408
+ idIter,
1409
+ literal(depth===1)
1410
+ ]).expr;
1411
+ }
1412
+
1413
+ mapped.push({type:'ReturnStatement',argument:invokeIterate}) ;
1414
+ mapped.push({
1415
+ $label:node.$label,
1416
+ "type": "FunctionDeclaration",
1417
+ "id": idIter,
1418
+ "params": [],
1419
+ "body": {
1420
+ "type": "BlockStatement",
1421
+ "body": body
1422
+ }
1423
+ }) ;
1424
+
1425
+ if (step) {
1426
+ mapped.push({
1427
+ "type": "FunctionDeclaration",
1428
+ id: idStep,
1429
+ "params": [],
1430
+ "body": {
1431
+ "type": "BlockStatement",
1432
+ "body": [ step,returnIter ]
1433
+ }
1434
+ }) ;
1435
+ }
1436
+
1437
+ if (init && init.type==='VariableDeclaration' && (init.kind==='let' || init.kind==='const')) {
1438
+ if (init.kind==='const')
1439
+ init.kind = 'let' ;
1440
+
1441
+ path[0].replace([{
1442
+ type:'BlockStatement',
1443
+ body:mapped.map(down)
1444
+ },down(continuation)]) ;
1445
+ } else {
1446
+ mapped.push(continuation) ;
1447
+ path[0].replace(mapped.map(down)) ;
1448
+ }
1449
+ }
1450
+ }
1451
+
1452
+ /* Previous, recursive implementation for backwards compatibility */
1453
+ function asyncLoops_1(ast,state) {
1454
+ parser.treeWalker(ast, function (node, descend, path) {
1455
+ function mapContinue(label) {
1456
+ return {
1457
+ type: 'ReturnStatement',
1458
+ argument: {
1459
+ type: 'UnaryExpression',
1460
+ operator: 'void',
1461
+ prefix: true,
1462
+ argument: thisCall(label || symContinue)
1463
+ }
1464
+ };
1465
+ };
1466
+ function mapExits(n, descend) {
1467
+ if (n.type === 'BreakStatement') {
1468
+ coerce(n, cloneNode(mapBreak(n.label && opts.generatedSymbolPrefix + "Loop_" + n.label.name + "_exit")));
1469
+ } else if (n.type === 'ContinueStatement') {
1470
+ coerce(n, cloneNode(mapContinue(n.label && opts.generatedSymbolPrefix + "Loop_" + n.label.name + "_next")));
1471
+ } else if (examine(n).isFunction) {
1472
+ return true;
1473
+ }
1474
+ descend();
1475
+ }
1476
+
1477
+ if (node.type === 'ForInStatement' && containsAwait(node)) {
1478
+ transformForIn(node, path) ;
1479
+ } else if (node.type === 'ForOfStatement' && containsAwait(node)) {
1480
+ iterizeForOf(node, path);
1481
+ }
1482
+ descend();
1483
+ var p;
1484
+ if (examine(node).isLoop && containsAwait(node)) {
1485
+ var init = node.init;
1486
+ var condition = node.test || literal(true);
1487
+ var step = node.update;
1488
+ var body = node.body;
1489
+ var loopUsesThis = containsThis(body) ;
1490
+ if (init) {
1491
+ if (!examine(init).isStatement) {
1492
+ init = {
1493
+ type: 'ExpressionStatement',
1494
+ expression: init
1495
+ };
1496
+ }
1497
+ }
1498
+ step = step && {
1499
+ type: 'ExpressionStatement',
1500
+ expression: step
1501
+ } ;
1502
+ body = examine(body).isBlockStatement ? cloneNode(body).body : [cloneNode(body)];
1503
+ var label = node.$label && node.$label.name ;
1504
+ label = "Loop_" + (label || generatedSymbol++);
1505
+ var symExit = opts.generatedSymbolPrefix + (label + "_exit");
1506
+ var symContinue = opts.generatedSymbolPrefix + (label + "_next");
1507
+ var loop = ident(opts.generatedSymbolPrefix + (label));
1508
+ // How to exit the loop
1509
+ var mapBreak = function (label) {
1510
+ return {
1511
+ type: 'ReturnStatement',
1512
+ argument: {
1513
+ type: 'UnaryExpression',
1514
+ operator: 'void',
1515
+ prefix: true,
1516
+ argument: {
1517
+ type: 'CallExpression',
1518
+ callee: ident(label || symExit),
1519
+ arguments: []
1520
+ }
1521
+ }
1522
+ };
1523
+ };
1524
+
1525
+ // How to continue the loop
1526
+ var defContinue = makeContinuation(symContinue, [{
1527
+ type: 'ReturnStatement',
1528
+ argument: {
1529
+ type: 'CallExpression',
1530
+ callee: loopUsesThis? bindAsync(loop):loop,
1531
+ arguments: [ident(symExit),genIdent.error]
1532
+ }
1533
+ }]);
1534
+ if (step)
1535
+ defContinue.body.body.unshift(step);
1536
+ for (var i = 0;i < body.length; i++) {
1537
+ parser.treeWalker(body[i], mapExits);
1538
+ }
1539
+ body.push(cloneNode(mapContinue()));
1540
+ var subCall = {
1541
+ type: 'FunctionExpression',
1542
+ id: loop,
1543
+ params: [ident(symExit),genIdent.error],
1544
+ body: {
1545
+ type: 'BlockStatement',
1546
+ body: [defContinue]
1547
+ }
1548
+ };
1549
+ if (node.type === 'DoWhileStatement') {
1550
+ defContinue.body.body = [{
1551
+ type: 'IfStatement',
1552
+ test: cloneNode(condition),
1553
+ consequent: {
1554
+ type: 'BlockStatement',
1555
+ body: cloneNode(defContinue.body.body)
1556
+ },
1557
+ alternate: {
1558
+ type: 'ReturnStatement',
1559
+ argument: {
1560
+ type: 'CallExpression',
1561
+ callee: ident(symExit),
1562
+ arguments: []
1563
+ }
1564
+ }
1565
+ }];
1566
+ subCall.body.body = [defContinue].concat(body);
1567
+ } else {
1568
+ var nextTest = {
1569
+ type: 'IfStatement',
1570
+ test: cloneNode(condition),
1571
+ consequent: {
1572
+ type: 'BlockStatement',
1573
+ body: body
1574
+ },
1575
+ alternate: cloneNode(mapBreak())
1576
+ };
1577
+ subCall.body.body.push(nextTest);
1578
+ }
1579
+ var replace = {
1580
+ type: 'ExpressionStatement',
1581
+ expression: {
1582
+ type: 'AwaitExpression',
1583
+ argument: bindAsync(subCall, literal(0))
1584
+ }
1585
+ };
1586
+
1587
+ if (init && init.type==='VariableDeclaration' && (init.kind==='let' || init.kind==='const')) {
1588
+ if (init.kind==='const')
1589
+ init.kind = 'let' ;
1590
+ replace = {
1591
+ type:'BlockStatement',
1592
+ body:[cloneNode(init),replace]
1593
+ };
1594
+ init = null ;
1595
+ }
1596
+
1597
+ for (p = 0; p < path.length; p++) {
1598
+ var ref = path[p];
1599
+ if ('index' in ref) {
1600
+ if (init) {
1601
+ ref.parent[ref.field].splice(ref.index, 1, cloneNode(init), replace);
1602
+ } else {
1603
+ ref.parent[ref.field][ref.index] = replace;
1604
+ }
1605
+ return true;
1606
+ }
1607
+ }
1608
+ }
1609
+ return true;
1610
+ },state);
1611
+ return ast;
1612
+ }
1613
+
1614
+ function containsAsyncExit(fn) {
1615
+ if (!examine(fn).isFunction) {
1616
+ throw new Error("Cannot examine non-Function node types for async exits") ;
1617
+ }
1618
+
1619
+ return contains(fn.body,function(node){
1620
+ return ((node.type === 'Identifier' && (node.name === opts.$return || node.name === opts.$error))
1621
+ || (isExitStatement(node) && examine(node).isAsync)) ;
1622
+ },function(node){
1623
+ return !(examine(node).isFunction && (node.$wasAsync || examine(node).isAsync)) ;
1624
+ }) ;
1625
+ }
1626
+
1627
+ // TODO: Hoist directives (as in asyncDefine)
1628
+ function asyncDefineMethod(ast) {
1629
+ return parser.treeWalker(ast, function (node, descend, path) {
1630
+ var transform = getMemberFunction(node);
1631
+ descend();
1632
+ if (!transform || !examine(transform).isAsync)
1633
+ return;
1634
+ if (node.kind == 'set') {
1635
+ var ex = new SyntaxError(where(transform) + "method 'async set' cannot be invoked", pr.filename, node.start);
1636
+ ex.pos = node.start;
1637
+ ex.loc = node.loc.start;
1638
+ throw ex;
1639
+ }
1640
+
1641
+ transform.async = false;
1642
+ var usesArgs = replaceArguments(transform);
1643
+ if (!containsAsyncExit(transform) && (transform.body.body.length === 0 || transform.body.body[transform.body.body.length - 1].type !== 'ReturnStatement')) {
1644
+ transform.body.body.push({
1645
+ type: 'ReturnStatement'
1646
+ });
1647
+ }
1648
+ var funcback = bindAsync(setExit({
1649
+ type: 'FunctionExpression',
1650
+ params: [genIdent.return,genIdent.error],
1651
+ body: asyncDefineMethod(mapReturns(transform.body, path)),
1652
+ $wasAsync: true
1653
+ }, opts),(opts.promises || opts.generators || opts.engine) ? null : literal(opts.lazyThenables?0:true) ) ;
1654
+
1655
+ if (opts.promises) {
1656
+ transform.body = {
1657
+ type: 'BlockStatement',
1658
+ body: [{
1659
+ type: 'ReturnStatement',
1660
+ argument: {
1661
+ type: 'NewExpression',
1662
+ callee: ident('Promise'),
1663
+ arguments: [funcback]
1664
+ }
1665
+ }]
1666
+ };
1667
+ } else {
1668
+ transform.body = {
1669
+ type: 'BlockStatement',
1670
+ body: [{
1671
+ type: 'ReturnStatement',
1672
+ argument: funcback
1673
+ }]
1674
+ };
1675
+ }
1676
+ if (usesArgs) {
1677
+ afterDirectives(transform.body.body,[assign$Args]);
1678
+ }
1679
+ });
1680
+ }
1681
+
1682
+ function asyncDefine(ast) {
1683
+ parser.treeWalker(ast, function (node, descend, path) {
1684
+ descend();
1685
+ if (examine(node).isAsync && examine(node).isFunction) {
1686
+ var member ;
1687
+ if ((member = getMemberFunction(path[0].parent))
1688
+ && examine(member).isAsync && path[0].parent.kind === 'get') {
1689
+ warnAsyncGetter(path[0].parent.key) ;
1690
+ }
1691
+ delete node.async;
1692
+
1693
+ var usesArgs = replaceArguments(node);
1694
+ var fnBody = setExit({
1695
+ type: 'FunctionExpression',
1696
+ params: [genIdent.return,genIdent.error],
1697
+ $wasAsync: true
1698
+ }, opts) ;
1699
+ var thisPath = [{self:fnBody}].concat(path) ;
1700
+
1701
+ if (examine(node.body).isBlockStatement) {
1702
+ if (!containsAsyncExit(node) && (node.body.body.length === 0 || node.body.body[node.body.body.length - 1].type !== 'ReturnStatement')) {
1703
+ node.body.body.push({
1704
+ type: 'ReturnStatement'
1705
+ });
1706
+ }
1707
+ fnBody.body = {
1708
+ type: 'BlockStatement',
1709
+ body: node.body.body.map(function (sub) {
1710
+ return mapReturns(sub, thisPath);
1711
+ })
1712
+ };
1713
+ } else {
1714
+ fnBody.body = {
1715
+ type: 'BlockStatement',
1716
+ body: [mapReturns({
1717
+ type: 'ReturnStatement',
1718
+ argument: node.body
1719
+ }, thisPath)]
1720
+ };
1721
+ node.expression = false;
1722
+ }
1723
+
1724
+ fnBody = bindAsync(fnBody,(opts.promises || opts.generators || opts.engine) ? null : literal(opts.lazyThenables?0:true)) ;
1725
+
1726
+ if (opts.promises) {
1727
+ fnBody = {
1728
+ type: 'NewExpression',
1729
+ callee: ident('Promise'),
1730
+ arguments: [fnBody]
1731
+ };
1732
+ }
1733
+ fnBody = {
1734
+ type: 'BlockStatement',
1735
+ body: [{
1736
+ type: 'ReturnStatement',
1737
+ loc: node.loc,
1738
+ argument: fnBody
1739
+ }]
1740
+ };
1741
+ if (usesArgs)
1742
+ afterDirectives(fnBody.body,[assign$Args]);
1743
+ node.body = fnBody;
1744
+ return;
1745
+ }
1746
+ });
1747
+ return ast;
1748
+ }
1749
+
1750
+ /*
1751
+ * Rewrite
1752
+ async function <name>?<argumentlist><body>
1753
+ to
1754
+ function <name>?<argumentlist>{ return function*() {<body>}.$asyncspawn(); }
1755
+ */
1756
+ // Like mapReturns, but ONLY for return/throw async
1757
+ function mapAsyncReturns(ast) {
1758
+ if (Array.isArray(ast)) {
1759
+ return ast.map(mapAsyncReturns);
1760
+ }
1761
+ var lambdaNesting = 0;
1762
+ return parser.treeWalker(ast, function (node, descend, path) {
1763
+ if ((node.type === 'ThrowStatement' || node.type === 'ReturnStatement') && !node.$mapped) {
1764
+ if (lambdaNesting > 0) {
1765
+ if (examine(node).isAsync) {
1766
+ delete node.async;
1767
+ node.argument = {
1768
+ "type": "CallExpression",
1769
+ "callee": node.type === 'ThrowStatement' ? genIdent.error : genIdent.return,
1770
+ "arguments": node.argument ? [node.argument] : []
1771
+ };
1772
+ node.type = 'ReturnStatement';
1773
+ return;
1774
+ }
1775
+ }
1776
+ } else if (examine(node).isFunction) {
1777
+ lambdaNesting++;
1778
+ descend(node);
1779
+ lambdaNesting--;
1780
+ return;
1781
+ }
1782
+ descend(node);
1783
+ });
1784
+ }
1785
+
1786
+ function spawnBody(body, deferExit) {
1787
+ if (opts.noRuntime)
1788
+ throw new Error("Nodent: 'noRuntime' option only compatible with -promise and -engine modes") ;
1789
+
1790
+ return parser.part("{ return (function*($return,$error){ $:body }).$asyncspawn(Promise,this) }",{
1791
+ 'return':genIdent.return,
1792
+ error:genIdent.error,
1793
+ asyncspawn:genIdent.asyncspawn,
1794
+ body: mapAsyncReturns(body).concat(deferExit ? [{
1795
+ type: 'ReturnStatement',
1796
+ argument: genIdent.return
1797
+ }] : [])
1798
+ }).body[0] ;
1799
+ }
1800
+
1801
+ function warnAsyncGetter(id) {
1802
+ if (!id.$asyncgetwarninig) {
1803
+ id.$asyncgetwarninig = true;
1804
+ logger(where(id) + "'async get "+printNode(id)+"(){...}' is non-standard. See https://github.com/MatAtBread/nodent#differences-from-the-es7-specification");
1805
+ }
1806
+ }
1807
+
1808
+ function asyncSpawn(ast,engine) {
1809
+ function mapAwaits(ast,hide) {
1810
+ parser.treeWalker(ast, function (node, descend, path) {
1811
+ if (node !== ast && examine(node).isFunction)
1812
+ return;
1813
+ if (examine(node).isAwait) {
1814
+ if (hide) {
1815
+ node.$hidden = true;
1816
+ descend();
1817
+ } else {
1818
+ delete node.operator;
1819
+ node.delegate = false;
1820
+ node.type = 'YieldExpression';
1821
+ descend();
1822
+ }
1823
+ } else
1824
+ descend();
1825
+ });
1826
+ }
1827
+
1828
+ function promiseTransform(ast) {
1829
+ var promises = opts.promises;
1830
+ opts.promises = true;
1831
+ asyncTransforms(ast, true);
1832
+ opts.promises = promises;
1833
+ }
1834
+
1835
+ function expandArrows(fn) {
1836
+ if (fn.body.type !== 'BlockStatement') {
1837
+ fn.body = {
1838
+ type: 'BlockStatement',
1839
+ body: [{
1840
+ type: 'ReturnStatement',
1841
+ argument: fn.body
1842
+ }]
1843
+ };
1844
+ }
1845
+ return fn;
1846
+ }
1847
+
1848
+ function warnAsyncExit(exit, fn) {
1849
+ if (!fn.$asyncexitwarninig) {
1850
+ fn.$asyncexitwarninig = true;
1851
+ logger(where(exit) + "'async " + ({
1852
+ ReturnStatement: 'return',
1853
+ ThrowStatement: 'throw'
1854
+ })[exit.type] + "' not possible in "+(engine?'engine':'generator')+" mode. Using Promises for function at " + where(fn));
1855
+ }
1856
+ }
1857
+
1858
+ parser.treeWalker(ast, function (node, descend, path) {
1859
+ descend();
1860
+ var fn, exit, usesArgs;
1861
+ if (examine(node).isAsync && examine(node).isFunction) {
1862
+ var member ;
1863
+ if ((member = getMemberFunction(path[0].parent))
1864
+ && examine(member).isAsync && path[0].parent.kind === 'get') {
1865
+ warnAsyncGetter(path[0].parent.key) ;
1866
+ }
1867
+ if (exit = containsAsyncExit(node)) {
1868
+ // Do the Promise transform
1869
+ warnAsyncExit(exit, node.body);
1870
+ promiseTransform(node);
1871
+ } else if (!engine) {
1872
+ fn = node;
1873
+ delete fn.async;
1874
+ usesArgs = replaceArguments(fn);
1875
+ mapAwaits(fn,false);
1876
+ fn = expandArrows(fn);
1877
+ fn.body = spawnBody(fn.body.body, exit);
1878
+ if (usesArgs)
1879
+ afterDirectives(fn.body.body,[assign$Args]);
1880
+ if (fn.id && path[0].parent.type === 'ExpressionStatement') {
1881
+ fn.type = 'FunctionDeclaration';
1882
+ path[1].replace(fn);
1883
+ } else {
1884
+ path[0].replace(fn);
1885
+ }
1886
+ } else if (path[0].parent.kind !== 'get')
1887
+ mapAwaits(node,true) ;
1888
+ } else if ((fn = getMemberFunction(node)) && examine(fn).isAsync) {
1889
+ if (exit = containsAsyncExit(fn)) {
1890
+ // Do the Promise transform
1891
+ warnAsyncExit(exit, fn);
1892
+ promiseTransform(node);
1893
+ } else if (!engine || node.kind==='get') {
1894
+ if (engine) {
1895
+ promiseTransform(node) ;
1896
+ } else {
1897
+ node.async = false;
1898
+ usesArgs = replaceArguments(fn);
1899
+ mapAwaits(fn,false);
1900
+ coerce(fn, expandArrows(fn));
1901
+ fn.body = spawnBody(fn.body.body, exit);
1902
+ }
1903
+ if (usesArgs)
1904
+ afterDirectives(fn.body.body,[assign$Args]);
1905
+ }
1906
+ }
1907
+ });
1908
+
1909
+ // Map (and warn) about any out-of-scope awaits that are being
1910
+ // mapped using Promises.
1911
+ var st = cloneNode(opts);
1912
+ opts.engine = false;
1913
+ opts.generators = false;
1914
+ blockifyArrows(ast);
1915
+ hoistDeclarations(ast);
1916
+ labelTryCatch(ast,st.engine);
1917
+ mapLogicalOp(ast);
1918
+ mapCondOp(ast);
1919
+ walkDown(ast, [mapTryCatch,mapLoops,mapIfStmt,mapSwitch,mapBlock]);
1920
+ asyncAwait(ast, "warn");
1921
+ opts.engine = st.engine;
1922
+ opts.generators = st.generators;
1923
+ return ast;
1924
+ }
1925
+
1926
+ /* Find all nodes within this scope matching the specified function */
1927
+ function scopedNodes(ast, matching, flat) {
1928
+ var matches = [];
1929
+ parser.treeWalker(ast, function (node, descend, path) {
1930
+ if (node === ast)
1931
+ return descend();
1932
+ if (matching(node, path)) {
1933
+ matches.push([].concat(path));
1934
+ return;
1935
+ }
1936
+ if (flat || examine(node).isScope) {
1937
+ return;
1938
+ }
1939
+ descend();
1940
+ });
1941
+ return matches;
1942
+ }
1943
+
1944
+ function extractVars(vars,kind) {
1945
+ var varDecls = [];
1946
+ var duplicates = {} ;
1947
+ vars = vars.filter(function(v){ return v[0].parent.type !== 'ExportNamedDeclaration'}) ;
1948
+ if (vars.length) {
1949
+ var definitions = {};
1950
+ vars.forEach(function (path) {
1951
+ function addName(name) {
1952
+ if (name in definitions) {
1953
+ duplicates[name] = self.declarations[i] ;
1954
+ } else {
1955
+ definitions[name] = self.declarations[i] ;
1956
+ }
1957
+ }
1958
+
1959
+ var ref = path[0];
1960
+ var self = ref.self;
1961
+ var kind = self.kind ;
1962
+ var values = [];
1963
+ for (var i = 0;i < self.declarations.length; i++) {
1964
+ var decl = self.declarations[i] ;
1965
+ getDeclNames(decl.id).forEach(addName) ;
1966
+ if (decl.init) {
1967
+ var value = {
1968
+ type: 'AssignmentExpression',
1969
+ left: cloneNode(decl.id),
1970
+ operator: '=',
1971
+ right: cloneNode(decl.init)
1972
+ };
1973
+ values.push(value);
1974
+ }
1975
+ }
1976
+ if (values.length == 0)
1977
+ ref.remove();
1978
+ else {
1979
+ var repl = (values.length > 1)?{type:'SequenceExpression',expressions:values} : values[0] ;
1980
+ if (ref.parent.type.slice(0,3)!=='For')
1981
+ repl = {type:'ExpressionStatement',expression:repl} ;
1982
+ ref.replace(repl);
1983
+ }
1984
+ });
1985
+
1986
+ var defs = Object.keys(definitions) ;
1987
+ if (defs.length) {
1988
+ defs = defs.map(function (name) {
1989
+ return {
1990
+ type: 'VariableDeclarator',
1991
+ id: ident(name),
1992
+ loc: definitions[name].loc,
1993
+ start: definitions[name].start,
1994
+ end: definitions[name].end
1995
+ };
1996
+ });
1997
+ if (!varDecls[0] || varDecls[0].type !== 'VariableDeclaration') {
1998
+ varDecls.unshift({
1999
+ type: 'VariableDeclaration',
2000
+ kind: kind,
2001
+ declarations: defs
2002
+ });
2003
+ } else {
2004
+ varDecls[0].declarations = varDecls[0].declarations.concat(defs);
2005
+ }
2006
+ }
2007
+ }
2008
+ return { decls: varDecls, duplicates: duplicates } ;
2009
+ }
2010
+
2011
+ function getDeclNames(id) {
2012
+ if (!id) return [] ;
2013
+ if (Array.isArray(id)) {
2014
+ return id.reduce(function(z,j){ return z.concat(getDeclNames(j.id))},[]) ;
2015
+ }
2016
+ switch (id.type) {
2017
+ case 'Identifier':
2018
+ return [id.name] ;
2019
+ case 'AssignmentPattern':
2020
+ return getDeclNames(id.left);
2021
+ case 'ArrayPattern':
2022
+ return id.elements.reduce(function(z,e){ return z.concat(getDeclNames(e)) },[]) ;
2023
+ case 'ObjectPattern':
2024
+ return id.properties.reduce(function(z,e){ return z.concat(getDeclNames(e)) },[]) ;
2025
+ case 'ObjectProperty':
2026
+ case 'Property':
2027
+ return getDeclNames(id.value) ;
2028
+ case 'RestElement':
2029
+ case 'RestProperty':
2030
+ return getDeclNames(id.argument) ;
2031
+ }
2032
+ }
2033
+
2034
+ function checkConstsNotAssigned(ast) {
2035
+ /* Ensure no consts are on the LHS of an AssignmentExpression */
2036
+ var names = {} ;
2037
+
2038
+ function fail(node){
2039
+ logger(where(node) + "Possible assignment to 'const " + printNode(node)+"'");
2040
+ }
2041
+
2042
+ function checkAssignable(target) {
2043
+ switch (target.type) {
2044
+ case 'Identifier':
2045
+ // Find the declaration of any names on the left
2046
+ if (names[target.name] === 'const') fail(target) ;
2047
+ break ;
2048
+ case 'ArrayPattern':
2049
+ target.elements.forEach(function(e){
2050
+ if (names[e.name] === 'const') fail(e) ;
2051
+ }) ;
2052
+ break ;
2053
+ case 'ObjectPattern':
2054
+ target.properties.forEach(function(p){
2055
+ if (names[p.key.name] === 'const') fail(p) ;
2056
+ }) ;
2057
+ break ;
2058
+ }
2059
+ }
2060
+
2061
+ parser.treeWalker(ast, function (node, descend, path) {
2062
+ var body = examine(node).isBlockStatement ;
2063
+ if (body) {
2064
+ names = Object.create(names) ;
2065
+
2066
+ for (var h=0; h<body.length; h++) {
2067
+ if (body[h].type === 'VariableDeclaration') {
2068
+ for (var i=0; i<body[h].declarations.length; i++) {
2069
+ getDeclNames(body[h].declarations[i].id).forEach(function(name){
2070
+ names[name] = body[h].kind ;
2071
+ }) ;
2072
+ }
2073
+ }
2074
+ }
2075
+ }
2076
+ descend() ;
2077
+
2078
+ if (node.type === 'AssignmentExpression')
2079
+ checkAssignable(node.left) ;
2080
+ else if (node.type === 'UpdateExpression')
2081
+ checkAssignable(node.argument) ;
2082
+ if (body)
2083
+ names = Object.getPrototypeOf(names) ;
2084
+ });
2085
+ }
2086
+
2087
+ /* Move directives, vars and named functions to the top of their scope iff. the scope contains an 'await' */
2088
+ function hoistDeclarations(ast) {
2089
+ var sequences = {
2090
+ TemplateLiteral:function(x) { return x.expressions },
2091
+ NewExpression:function(x) { return x.arguments },
2092
+ CallExpression:function(x) { return x.arguments },
2093
+ SequenceExpression:function(x) { return x.expressions },
2094
+ ArrayExpression:function(x) { return x.elements },
2095
+ ObjectExpression:function(oe){ return oe.properties.map(function(p){ return p.value })}
2096
+ };
2097
+ /* Identify SequenceExpressions, Parameter lists and VariableDeclarators that contain assigments and split them up
2098
+ to ensure the correct evaluation order */
2099
+
2100
+ function containsAssign(ast){
2101
+ return contains(ast, function(n){
2102
+ return n.type==='AssignmentExpression'
2103
+ });
2104
+ }
2105
+
2106
+ parser.treeWalker(ast, function (node, descend, path) {
2107
+ var i ;
2108
+ descend() ;
2109
+ // Ensure assigments are evaluated before any await expressions, eg:
2110
+ // f(a=1, b = await a) --> a=1; f(a,b=await a)
2111
+
2112
+ function moveAssignments(dest){
2113
+ if (assignments.length) {
2114
+ dest.argument = {
2115
+ type:'SequenceExpression',
2116
+ expressions:assignments.map(function(a){
2117
+ var b = cloneNode(a)
2118
+ coerce(a,a.left);
2119
+ return b ;
2120
+ }).concat(dest.argument)
2121
+ } ;
2122
+ assignments = [] ;
2123
+ }
2124
+ }
2125
+
2126
+
2127
+ if (node.type in sequences && !node.$hoisted) {
2128
+ var expr = sequences[node.type](node) ;
2129
+ var assignments = [] ;
2130
+ var path ;
2131
+ for (i=0; i<expr.length;i++) {
2132
+ if (examine(expr[i]).isScope)
2133
+ continue ;
2134
+
2135
+ if (path = containsAwait(expr[i]))
2136
+ moveAssignments(path[0].self) ;
2137
+
2138
+ if (!containsAwait(expr.slice(i+1)))
2139
+ break ;
2140
+
2141
+ if (path = containsAssign(expr[i]))
2142
+ assignments.push(path[0].self) ;
2143
+ }
2144
+ } else if (node.type === 'VariableDeclaration') {
2145
+ // If any of the VariableDeclarators contain an initial value and are followed by a VariableDeclarator
2146
+ // containing an await, split them up into multiple statements
2147
+ for (i=node.declarations.length-1; i>0; i--) {
2148
+ if (node.declarations[i] && node.declarations[i].init && containsAwait(node.declarations[i].init)) {
2149
+ var insert = {
2150
+ type:'VariableDeclaration',
2151
+ kind: node.kind,
2152
+ declarations: node.declarations.splice(i)
2153
+ } ;
2154
+ var ref = path[0] ;
2155
+ if ('index' in ref) {
2156
+ ref.parent[ref.field].splice(ref.index+1,0,insert) ;
2157
+ } else throw new Error("VariableDeclaration not in a block") ;
2158
+ }
2159
+ }
2160
+ }
2161
+ }) ;
2162
+
2163
+ /* Hoist declarations */
2164
+ function isFreeVariable(kinds) {
2165
+ return function(n, path) {
2166
+ if (n.type === 'VariableDeclaration' && (n.kind = n.kind || 'var') && kinds.indexOf(n.kind)>=0) {
2167
+ var p = path[0] ;
2168
+ // Don't hoist the LHS of for (var/let/const _ of/in ... ; ;){}
2169
+ if (p.field == "left" && (p.parent.type === 'ForInStatement' || p.parent.type === 'ForOfStatement'))
2170
+ return false;
2171
+
2172
+ // Don't hoist the LHS of for (let/const _ = ... ; ;){}
2173
+ if (p.field == "init" && p.parent.type === 'ForStatement' && (n.kind==="const" || n.kind==="let"))
2174
+ return false;
2175
+
2176
+ return true;
2177
+ }
2178
+ }
2179
+ }
2180
+
2181
+ function isHoistableFunction(n, path) {
2182
+ // YES: We're a named function, but not a continuation
2183
+ if (n.type==='FunctionDeclaration' && n.id) {
2184
+ return examine(n).isAsync || !n.$continuation;
2185
+ }
2186
+ // No, we're not a hoistable function
2187
+ return false;
2188
+ }
2189
+
2190
+ checkConstsNotAssigned(ast) ;
2191
+
2192
+ var inStrictBody = false ;
2193
+ parser.treeWalker(ast, function (node, descend, path) {
2194
+ var prevScope = inStrictBody ;
2195
+ inStrictBody = inStrictBody || isStrict(node) ;
2196
+
2197
+ if (examine(node).isBlockStatement) {
2198
+ if (containsAwait(node)) {
2199
+ // For this scope/block, find all the hoistable functions, vars and directives
2200
+ var isScope = !path[0].parent || examine(path[0].parent).isScope ;
2201
+
2202
+ /* 'const' is highly problematic. In early version of Chrome (Node 0.10, 4.x, 5.x) non-standard behaviour:
2203
+ *
2204
+ * Node scope multiple-decls
2205
+ * v0.1x function SyntaxError
2206
+ * v0.1x strict SyntaxError SyntaxError
2207
+ * 4/5.x function SyntaxError
2208
+ * 4/5.x strict block ok (SyntaxError on duplicate in block)
2209
+ * 6.x (as 4/5.x strict)
2210
+ *
2211
+ * To make these non-standard behaviours work, we treat a single declaration of a const identifier as requiring function scope (which works everywhere),
2212
+ * declare as a 'var' and initialize inline.
2213
+ * We treat multiple declarations as block-scoped, and let the engine work it out. To make consts blocked-scope, we use 'const' where possible (i.e. before
2214
+ * any await expressions), or declare as 'let' after an await. This breaks in non-strict mode in Node 4/5, as 'let' requires strict mode.
2215
+ *
2216
+ * In summary, what this means is:
2217
+ * - const's with a single declaration in the current scope (NOT block) should be hoisted to function level, and defined as 'var'
2218
+ * - const's with duplicate declarations in the current scope (NOT block) should be hoisted to block level, and defined as 'let'
2219
+ */
2220
+
2221
+ var directives, consts, vars, lets, functions ;
2222
+ if (isScope) {
2223
+ consts = scopedNodes(node, isFreeVariable(['const']),false);
2224
+ var names = {}, duplicates = {} ;
2225
+
2226
+ // Work out which const identifiers are duplicates
2227
+ // Ones that are only declared once can simply be treated as vars, whereas
2228
+ // identifiers that are declared multiple times have block-scope and are
2229
+ // only valid in node 6 or in strict mode on node 4/5
2230
+ consts.forEach(function(d){
2231
+ d[0].self.declarations.forEach(function(e){
2232
+ getDeclNames(e.id).forEach(function(n){
2233
+ if (names[n] || duplicates[n]) {
2234
+ delete names[n] ;
2235
+ duplicates[n] = e ;
2236
+ } else {
2237
+ names[n] = e ;
2238
+ }
2239
+ }) ;
2240
+ }) ;
2241
+ }) ;
2242
+
2243
+ // Change all the declarations into assignments, since consts are always initialized
2244
+ consts.forEach(function(d){
2245
+ for (var depth=0; depth<d.length; depth++)
2246
+ if (examine(d[depth].parent).isBlockStatement)
2247
+ break ;
2248
+
2249
+ var ref = d[depth] ;
2250
+ ref.append({
2251
+ type: 'ExpressionStatement',
2252
+ expression: {
2253
+ type: 'SequenceExpression',
2254
+ expressions: d[0].self.declarations.map(function (d) {
2255
+ var a = {
2256
+ type: 'AssignmentExpression',
2257
+ operator: '=',
2258
+ left: d.id,
2259
+ right: d.init
2260
+ };
2261
+ d.init = null ;
2262
+ return a ;
2263
+ })
2264
+ }
2265
+ });
2266
+ var ids = getDeclNames(d[0].self.declarations) ;
2267
+ var decls = ids.filter(function(name){ return name in duplicates }) ;
2268
+ if (decls.length) {
2269
+ d[0].append({
2270
+ type:'VariableDeclaration',
2271
+ kind:'let',
2272
+ declarations: decls.map(function(name){
2273
+ return {
2274
+ type:'VariableDeclarator',
2275
+ id:ident(name)
2276
+ }
2277
+ })
2278
+ }) ;
2279
+ }
2280
+
2281
+ d[0].self.kind = 'var' ;
2282
+ decls = ids.filter(function(name){ return name in names }) ;
2283
+ if (decls.length) {
2284
+ d[0].self.declarations = decls.map(function(name){
2285
+ return {
2286
+ type:'VariableDeclarator',
2287
+ id:ident(name)
2288
+ }
2289
+ });
2290
+ } else {
2291
+ ref.remove() ;
2292
+ }
2293
+ }) ;
2294
+ vars = scopedNodes(node, isFreeVariable(['var']),false);
2295
+ lets = [] ;
2296
+ } else {
2297
+ lets = scopedNodes(node, isFreeVariable(['const']),true);
2298
+ }
2299
+ lets = lets.concat(scopedNodes(node, isFreeVariable(['let']),true));
2300
+ directives = scopedNodes(node, function (n) { return examine(n).isDirective },true);
2301
+ functions = scopedNodes(node, isHoistableFunction, inStrictBody);
2302
+
2303
+ vars = vars?extractVars(vars,'var'):{duplicates:{},decls:[]} ;
2304
+ lets = lets?extractVars(lets,'let'):{duplicates:{},decls:[]} ;
2305
+
2306
+ Object.keys(vars.duplicates).forEach(function(id){
2307
+ logger(where(vars.duplicates[id]) + "Duplicate declaration '" + printNode(vars.duplicates[id]) + "'");
2308
+ }) ;
2309
+ Object.keys(lets.duplicates).forEach(function(id){
2310
+ logger(where(lets.duplicates[id]) + "Duplicate declaration '" + printNode(lets.duplicates[id]) + "'");
2311
+ }) ;
2312
+
2313
+ functions = functions.map(function (path) {
2314
+ var ref = path[0], symName;
2315
+ // What is the name of this function (could be async, so check the expression if necessary),
2316
+ // and should we remove and hoist, or reference and hoist?
2317
+ if (examine(ref.self).isAsync) {
2318
+ symName = ref.self.id.name;
2319
+ // If we're actually a top-level async FunctionExpression, redeclare as a FunctionDeclaration
2320
+ if (examine(ref.parent).isBlockStatement) {
2321
+ ref.self.type = 'FunctionDeclaration';
2322
+ ref.remove();
2323
+ return ref.self;
2324
+ }
2325
+ // We're an async FunctionExpression
2326
+ return ref.replace(ident(symName));
2327
+ }
2328
+ // We're just a vanilla FunctionDeclaration or FunctionExpression
2329
+ symName = ref.self.id.name;
2330
+ var movedFn = ref.self.type === 'FunctionDeclaration' ? ref.remove() : ref.replace(ident(symName));
2331
+ return movedFn;
2332
+ });
2333
+
2334
+ directives = directives.map(function (path) {
2335
+ var ref = path[0];
2336
+ return ref.remove();
2337
+ });
2338
+ if (directives.length || vars.decls.length || lets.decls.length || functions.length) {
2339
+ node.body = directives.concat(vars.decls).concat(lets.decls).concat(functions).concat(node.body);
2340
+ }
2341
+ }
2342
+ inStrictBody = prevScope ;
2343
+ }
2344
+
2345
+ // Labeled blocks need to be treated as loops that exit on the first iteration if they contain awaits and labelled breaks
2346
+ if (node.type==='LabeledStatement' && node.body.type==='BlockStatement' && containsAwait(node.body) && contains(node.body,function(m){
2347
+ return m.type === 'BreakStatement' && m.label
2348
+ })) {
2349
+ node.body.body.push({ type: 'BreakStatement' }) ;
2350
+ node.body = {
2351
+ type: 'DoWhileStatement',
2352
+ test: literal(0),
2353
+ body: node.body
2354
+ };
2355
+ }
2356
+
2357
+ descend();
2358
+
2359
+ // It makes life easier if labeled loops have the label to hand, so we simply reference them here with a hidden $label
2360
+ // and keep a record of how nested the for loop is (since it's transformed top to bottom and counting during
2361
+ // transformation is therefore not possible
2362
+ if (node.type==='ForOfStatement' || node.type==='ForInStatement' || examine(node).isLoop) {
2363
+ var depth = 0 ;
2364
+ for (var n=0; n<path.length;n++)
2365
+ if (path[n].self.type==='ForOfStatement' || path[n].self.type==='ForInStatement' || examine(path[n].self).isLoop)
2366
+ depth += 1 ;
2367
+ else if (examine(path[n].self).isFunction)
2368
+ break ;
2369
+
2370
+ node.$depth = depth ;
2371
+ if (path[0].parent.type==='LabeledStatement') {
2372
+ node.$label = path[0].parent.label ;
2373
+ } else {
2374
+ node.$label = null ;
2375
+ }
2376
+ }
2377
+ return true;
2378
+ });
2379
+ return ast;
2380
+ }
2381
+
2382
+ function mapSupers(classNode, engine) {
2383
+ function superID() {
2384
+ return classNode.$superID = classNode.$superID || ident("$super$" + generatedSymbol++);
2385
+ }
2386
+
2387
+ return function (method) {
2388
+ method = getMemberFunction(method);
2389
+ if (method && examine(method).isAsync && (!engine || method.kind === 'get' || contains(method,function(n){
2390
+ return (examine(n).isFunction && contains(n,function(n){
2391
+ return n.type==='Super'
2392
+ }) && contains(n,function(n){
2393
+ return n.async && (n.type==='ReturnStatement' || n.type==='ThrowStatement') ;
2394
+ }))
2395
+ },true))) {
2396
+ parser.treeWalker(method.body, function (node, descend, path) {
2397
+ var r;
2398
+ if (!examine(node).isClass) {
2399
+ descend();
2400
+ if (node.type === 'Super') {
2401
+ if (path[0].parent.type === 'MemberExpression') {
2402
+ if (path[1].parent.type === 'CallExpression' && path[1].field === 'callee') {
2403
+ // super[m](...) maps to: this.$superid(m).call(this,...)
2404
+ r = parser.part("this.$super($field).call(this,$args)",{
2405
+ 'super':superID(),
2406
+ field:path[0].parent.computed ? path[0].parent.property:literal(path[0].parent.property.name),
2407
+ args:path[1].parent.arguments
2408
+ }).expr ;
2409
+ path[2].replace(r);
2410
+ } else {
2411
+ // super[f], maps to: this.$superid(f)
2412
+ r = parser.part("this.$super($field)",{
2413
+ 'super':superID(),
2414
+ field:path[0].parent.computed ?path[0].parent.property : literal(path[0].parent.property.name)
2415
+ }).expr ;
2416
+ path[1].replace(r);
2417
+ }
2418
+ } else {
2419
+ logger(where(node) + "'super' in async methods must be deferenced. 'async constructor()'/'await super()' not valid.");
2420
+ }
2421
+ }
2422
+ }
2423
+ });
2424
+ }
2425
+ };
2426
+ }
2427
+
2428
+ function fixSuperReferences(ast,engine) {
2429
+ return parser.treeWalker(ast, function (node, descend, path) {
2430
+ descend();
2431
+ if (node.type === 'ClassDeclaration' || node.type === 'ClassExpression') {
2432
+ node.body.body.forEach(mapSupers(node,engine));
2433
+ if (node.$superID) {
2434
+ var method = parser.part("(function($field) { return super[$field] })",{ field:ident("$field") }).expr ;
2435
+ if (opts.babelTree) {
2436
+ method.type = 'ClassMethod';
2437
+ method.key = node.$superID;
2438
+ method.kind = 'method';
2439
+ node.body.body.push(method);
2440
+ } else {
2441
+ node.body.body.push({
2442
+ type: 'MethodDefinition',
2443
+ key: node.$superID,
2444
+ kind: 'method',
2445
+ value: method
2446
+ });
2447
+ }
2448
+ }
2449
+ }
2450
+ });
2451
+ }
2452
+
2453
+ function blockifyArrows(ast) {
2454
+ parser.treeWalker(ast, function (node, descend, path) {
2455
+ var awaiting = containsAwait(node);
2456
+ if (awaiting) {
2457
+ if (node.type === 'ArrowFunctionExpression' && node.body.type !== 'BlockStatement') {
2458
+ node.body = {
2459
+ type: "BlockStatement",
2460
+ body: [{
2461
+ type: "ReturnStatement",
2462
+ argument: node.body
2463
+ }]
2464
+ };
2465
+ }
2466
+ }
2467
+ descend();
2468
+ return true;
2469
+ });
2470
+ return ast;
2471
+ }
2472
+
2473
+ function exposeCompilerOpts(ast) {
2474
+ // Expose compiler
2475
+ parser.treeWalker(ast, function (node, descend, path) {
2476
+ descend();
2477
+ if (node.type === 'Identifier' && node.name === '__nodent') {
2478
+ coerce(node, literal(opts));
2479
+ }
2480
+ });
2481
+ return ast;
2482
+ }
2483
+
2484
+ /* Called with a Program or FunctionDeclaration.body */
2485
+ function isStrict(node) {
2486
+ if (node.type === 'Program' && node.sourceType === 'module')
2487
+ return true ;
2488
+
2489
+ var nodes ;
2490
+ if (node.type === 'Program')
2491
+ nodes = node.body ;
2492
+ else if (examine(node).isFunction)
2493
+ nodes = node.body.body ;
2494
+ else return false ;
2495
+
2496
+ if (nodes) for (var i=0; i<nodes.length; i++)
2497
+ if (examine(nodes[i]).isDirective && nodes[i].expression.value.match(/^\s*use\s+strict\s*$/))
2498
+ return true ;
2499
+ return false ;
2500
+ }
2501
+
2502
+ function containsBlockScopedDeclarations(nodes) {
2503
+ for (var i = 0;i < nodes.length; i++) {
2504
+ var node = nodes[i];
2505
+ if (node.type === 'ClassDeclaration' ||
2506
+ (node.type === 'VariableDeclaration' && (node.kind === 'let' || node.kind === 'const')) ||
2507
+ (node.type === 'FunctionDeclaration' && node.id && node.id.name && !node.$continuation)) {
2508
+ return true;
2509
+ }
2510
+ }
2511
+ return false;
2512
+ }
2513
+
2514
+ /* Remove un-necessary nested blocks and crunch down empty function implementations */
2515
+ function cleanCode(ast) {
2516
+ // Coalese BlockStatements
2517
+ parser.treeWalker(ast, function (node, descend, path) {
2518
+ descend();
2519
+ if (node.type==='ArrowFunctionExpression'
2520
+ && node.body.type === 'BlockStatement'
2521
+ && node.body.body.length===1
2522
+ && node.body.body[0].type==='ReturnStatement') {
2523
+ node.body = node.body.body[0].argument
2524
+ } else {
2525
+ var block, child;
2526
+ // If this node is a block with vanilla BlockStatements (no controlling entity), merge them
2527
+ if (block = examine(node).isBlockStatement) {
2528
+ // Remove any empty statements from within the block
2529
+ // For ES6, this needs more care, as blocks containing 'let/const/class' have a scope of their own
2530
+ for (var i = 0;i < block.length; i++) {
2531
+ if ((child = examine(block[i]).isBlockStatement) && !containsBlockScopedDeclarations(child)) {
2532
+ if (!containsBlockScopedDeclarations(block[i]))
2533
+ [].splice.apply(block, [i,1].concat(child));
2534
+ }
2535
+ }
2536
+ }
2537
+ }
2538
+ });
2539
+ // Truncate BlockStatements with a Jump (break;continue;return;throw) inside
2540
+ parser.treeWalker(ast, function (node, descend, path) {
2541
+ descend();
2542
+ if (examine(node).isJump) {
2543
+ var ref = path[0];
2544
+ if ('index' in ref) {
2545
+ var i = ref.index + 1;
2546
+ var ctn = ref.parent[ref.field];
2547
+ while (i < ctn.length) {
2548
+ // Remove any statements EXCEPT for function/var definitions
2549
+ if (ctn[i].type === 'VariableDeclaration' || examine(ctn[i]).isFunction && ctn[i].id)
2550
+ i += 1;
2551
+ else
2552
+ ctn.splice(i, 1);
2553
+ }
2554
+ }
2555
+ }
2556
+ });
2557
+ /* Inline continuations that are only referenced once */
2558
+ // Find any continuations that have a single reference
2559
+ parser.treeWalker(ast, function (node, descend, path) {
2560
+ descend();
2561
+ if (node.$thisCall && continuations[node.name]) {
2562
+ if (continuations[node.name].ref) {
2563
+ delete continuations[node.name]; // Multiple ref
2564
+ } else {
2565
+ continuations[node.name].ref = node.$thisCall;
2566
+ }
2567
+ }
2568
+ });
2569
+ var calls = Object.keys(continuations).map(function (c) {
2570
+ return continuations[c].ref;
2571
+ });
2572
+ if (calls.length) {
2573
+ // Replace all the calls to the continuation with the body from the continuation followed by 'return;'
2574
+ parser.treeWalker(ast, function (node, descend, path) {
2575
+ descend();
2576
+ if (calls.indexOf(node) >= 0) {
2577
+ if (path[1].self.type === 'ReturnStatement') {
2578
+ var sym = node.$thisCallName;
2579
+ var repl = cloneNode(continuations[sym].def.body.body);
2580
+ continuations[sym].$inlined = true;
2581
+ if (!examine(path[1].self).isJump)
2582
+ repl.push({
2583
+ type: 'ReturnStatement'
2584
+ });
2585
+ path[1].replace(repl);
2586
+ }
2587
+ }
2588
+ });
2589
+ var defs = Object.keys(continuations).map(function (c) {
2590
+ return continuations[c].$inlined && continuations[c].def;
2591
+ });
2592
+ // Remove all the (now inline) declarations of the continuations
2593
+ parser.treeWalker(ast, function (node, descend, path) {
2594
+ descend();
2595
+ if (defs.indexOf(node) >= 0) {
2596
+ path[0].remove();
2597
+ }
2598
+ });
2599
+ }
2600
+
2601
+ // Hoist generated FunctionDeclarations within ES5 Strict functions (actually put them at the
2602
+ // end of the scope-block, don't hoist them, it's just an expensive operation)
2603
+ var looksLikeES6 = (ast.type==='Program' && ast.sourceType==='module') || contains(ast,function(n){
2604
+ return examine(n).isES6 ;
2605
+ },true) ;
2606
+
2607
+ if (!looksLikeES6) {
2608
+ var useStrict = isStrict(ast) ;
2609
+ (function(ast){
2610
+ parser.treeWalker(ast, function (node, descend, path) {
2611
+ if (node.type==='Program' || node.type==='FunctionDeclaration' || node.type==='FunctionExpression') {
2612
+ var wasStrict = useStrict ;
2613
+ useStrict = useStrict || isStrict(node) ;
2614
+ if (useStrict) {
2615
+ descend();
2616
+
2617
+ var functionScope = node.type === 'Program' ? node : node.body ;
2618
+ var functions = scopedNodes(functionScope,function(n,path){
2619
+ if (n.type==='FunctionDeclaration') {
2620
+ return path[0].parent !== functionScope ;
2621
+ }
2622
+ }) ;
2623
+
2624
+ functions = functions.map(function (path) {
2625
+ return path[0].remove() ;
2626
+ });
2627
+ [].push.apply(functionScope.body,functions) ;
2628
+ } else {
2629
+ descend();
2630
+ }
2631
+ useStrict = wasStrict ;
2632
+ } else {
2633
+ descend();
2634
+ }
2635
+ }) ;
2636
+ })(ast);
2637
+ }
2638
+
2639
+ /*
2640
+ function replaceSymbols(ast,from,to) {
2641
+ parser.treeWalker(ast,function(node,descend,path){
2642
+ descend() ;
2643
+ if (node.type=='Identifier' && node.name==from) {
2644
+ node.name = to ;
2645
+ }
2646
+ }) ;
2647
+ return ast ;
2648
+ }
2649
+
2650
+ // Find declarations of functions of the form:
2651
+ // function [sym]() { return _call_.call(this) }
2652
+ // or
2653
+ // function [sym]() { return _call_() }
2654
+ // and replace with:
2655
+ // _call_
2656
+ // If the [sym] exists and is referenced elsewhere, replace those too. This
2657
+ // needs to be done recursively from the bottom of the tree upwards.
2658
+ // NB: If _call_ is in the parameter list for the function, this is NOT a correct optimization
2659
+
2660
+
2661
+ // The symbol folding above might generate lines like:
2662
+ // $return.$asyncbind(this,$error)
2663
+ // these can be simplified to:
2664
+ // $return
2665
+ */
2666
+
2667
+ // Remove all the 'hiiden' node info generated during transformation
2668
+ parser.treeWalker(ast,function(node,descend,path){
2669
+ descend() ;
2670
+ Object.keys(node).filter(function(k){ return k[0]==='$'}).forEach(function(k){
2671
+ delete node[k] ;
2672
+ }) ;
2673
+ }) ;
2674
+ return ast;
2675
+ }
2676
+ }
2677
+
2678
+ module.exports = {
2679
+ printNode:printNode,
2680
+ babelLiteralNode: babelLiteralNode,
2681
+ asynchronize: function (pr, __sourceMapping, opts, logger) {
2682
+ try {
2683
+ return asynchronize(pr, __sourceMapping, opts, logger);
2684
+ } catch (ex) {
2685
+ if (ex instanceof SyntaxError) {
2686
+ var l = pr.origCode.substr(ex.pos - ex.loc.column);
2687
+ l = l.split("\n")[0];
2688
+ ex.message += " (nodent)\n" + l + "\n" + l.replace(/[\S ]/g, "-").substring(0, ex.loc.column) + "^";
2689
+ ex.stack = "";
2690
+ }
2691
+ throw ex;
2692
+ }
2693
+ }
2694
+ };