jass 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ };