opal 1.0.1 → 1.1.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +14 -12
  3. data/.gitattributes +1 -1
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/workflows/build.yml +90 -0
  6. data/.jshintrc +1 -1
  7. data/.overcommit.yml +35 -0
  8. data/.rubocop.yml +44 -7
  9. data/{.rubocop_todo.yml → .rubocop/todo.yml} +4 -5
  10. data/CHANGELOG.md +129 -7
  11. data/Gemfile +2 -3
  12. data/HACKING.md +2 -9
  13. data/README.md +20 -17
  14. data/UNRELEASED.md +106 -7
  15. data/benchmark-ips/bm_array_pop_1.rb +8 -0
  16. data/benchmark-ips/bm_array_shift.rb +7 -0
  17. data/benchmark-ips/class_shovel_vs_singleton_class.rb +16 -0
  18. data/bin/build-browser-source-map-support +5 -0
  19. data/bin/format-filters +54 -0
  20. data/bin/git-submodule-fast-install +49 -0
  21. data/bin/remove-filters +39 -0
  22. data/bin/setup +4 -0
  23. data/bin/yarn +11 -0
  24. data/docs/releasing.md +18 -0
  25. data/docs/roda-sprockets.md +86 -0
  26. data/docs/sinatra.md +5 -12
  27. data/examples/rack/Gemfile +1 -0
  28. data/examples/rack/app/application.rb +3 -0
  29. data/examples/rack/config.ru +5 -4
  30. data/exe/opal-repl +2 -83
  31. data/lib/opal/ast/builder.rb +1 -1
  32. data/lib/opal/builder.rb +2 -10
  33. data/lib/opal/builder_processors.rb +1 -1
  34. data/lib/opal/cli.rb +4 -1
  35. data/lib/opal/cli_options.rb +11 -3
  36. data/lib/opal/cli_runners.rb +27 -37
  37. data/lib/opal/cli_runners/applescript.rb +5 -44
  38. data/lib/opal/cli_runners/chrome.js +7 -35
  39. data/lib/opal/cli_runners/chrome.rb +77 -19
  40. data/lib/opal/cli_runners/compiler.rb +17 -0
  41. data/lib/opal/cli_runners/nashorn.rb +9 -43
  42. data/lib/opal/cli_runners/nodejs.rb +18 -47
  43. data/lib/opal/cli_runners/server.rb +18 -6
  44. data/lib/opal/cli_runners/source-map-support-browser.js +6445 -0
  45. data/lib/opal/cli_runners/source-map-support.js +639 -0
  46. data/lib/opal/cli_runners/system_runner.rb +45 -0
  47. data/lib/opal/compiler.rb +57 -29
  48. data/lib/opal/config.rb +0 -5
  49. data/lib/opal/erb.rb +1 -1
  50. data/lib/opal/magic_comments.rb +34 -0
  51. data/lib/opal/nodes/args/arity_check.rb +2 -1
  52. data/lib/opal/nodes/base.rb +1 -1
  53. data/lib/opal/nodes/call.rb +1 -4
  54. data/lib/opal/nodes/def.rb +2 -0
  55. data/lib/opal/nodes/iter.rb +1 -1
  56. data/lib/opal/nodes/literal.rb +19 -14
  57. data/lib/opal/nodes/logic.rb +5 -80
  58. data/lib/opal/nodes/masgn.rb +2 -0
  59. data/lib/opal/nodes/rescue.rb +1 -1
  60. data/lib/opal/nodes/super.rb +24 -10
  61. data/lib/opal/nodes/top.rb +5 -4
  62. data/lib/opal/parser/patch.rb +15 -0
  63. data/lib/opal/parser/with_c_lexer.rb +2 -1
  64. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  65. data/lib/opal/path_reader.rb +2 -2
  66. data/lib/opal/paths.rb +8 -5
  67. data/lib/opal/repl.rb +103 -0
  68. data/lib/opal/rewriter.rb +4 -0
  69. data/lib/opal/rewriters/for_rewriter.rb +1 -1
  70. data/lib/opal/rewriters/js_reserved_words.rb +7 -7
  71. data/lib/opal/rewriters/numblocks.rb +31 -0
  72. data/lib/opal/rewriters/returnable_logic.rb +33 -0
  73. data/lib/opal/util.rb +11 -48
  74. data/lib/opal/version.rb +1 -1
  75. data/opal.gemspec +25 -25
  76. data/opal/corelib/array.rb +160 -118
  77. data/opal/corelib/array/pack.rb +5 -3
  78. data/opal/corelib/basic_object.rb +4 -4
  79. data/opal/corelib/class.rb +2 -1
  80. data/opal/corelib/comparable.rb +49 -31
  81. data/opal/corelib/constants.rb +5 -5
  82. data/opal/corelib/enumerable.rb +108 -46
  83. data/opal/corelib/enumerator.rb +27 -12
  84. data/opal/corelib/file.rb +3 -1
  85. data/opal/corelib/hash.rb +6 -1
  86. data/opal/corelib/helpers.rb +8 -28
  87. data/opal/corelib/io.rb +12 -7
  88. data/opal/corelib/kernel.rb +45 -14
  89. data/opal/corelib/kernel/format.rb +3 -1
  90. data/opal/corelib/math.rb +8 -6
  91. data/opal/corelib/method.rb +8 -0
  92. data/opal/corelib/module.rb +17 -2
  93. data/opal/corelib/number.rb +3 -12
  94. data/opal/corelib/proc.rb +16 -0
  95. data/opal/corelib/random/mersenne_twister.rb +147 -0
  96. data/opal/corelib/range.rb +3 -13
  97. data/opal/corelib/regexp.rb +10 -6
  98. data/opal/corelib/runtime.js +208 -81
  99. data/opal/corelib/string.rb +55 -49
  100. data/opal/corelib/string/encoding.rb +109 -32
  101. data/opal/corelib/string/unpack.rb +2 -17
  102. data/opal/corelib/struct.rb +14 -1
  103. data/opal/corelib/time.rb +4 -0
  104. data/opal/opal.rb +1 -1
  105. data/opal/opal/mini.rb +1 -1
  106. data/package.json +16 -0
  107. data/spec/README.md +10 -0
  108. data/spec/filters/bugs/array.rb +76 -0
  109. data/spec/filters/bugs/base64.rb +10 -0
  110. data/spec/filters/bugs/basicobject.rb +12 -0
  111. data/spec/filters/bugs/bigdecimal.rb +248 -0
  112. data/spec/filters/bugs/class.rb +12 -0
  113. data/spec/filters/bugs/complex.rb +7 -0
  114. data/spec/filters/bugs/date.rb +104 -0
  115. data/spec/filters/bugs/encoding.rb +259 -0
  116. data/spec/filters/bugs/enumerable.rb +26 -0
  117. data/spec/filters/bugs/enumerator.rb +48 -0
  118. data/spec/filters/bugs/exception.rb +120 -0
  119. data/spec/filters/bugs/file.rb +48 -0
  120. data/spec/filters/bugs/float.rb +74 -0
  121. data/spec/filters/bugs/hash.rb +60 -0
  122. data/spec/filters/bugs/integer.rb +78 -0
  123. data/spec/filters/bugs/io.rb +9 -0
  124. data/spec/filters/bugs/kernel.rb +401 -0
  125. data/spec/filters/bugs/language.rb +451 -0
  126. data/spec/filters/bugs/marshal.rb +50 -0
  127. data/spec/filters/bugs/math.rb +4 -0
  128. data/spec/filters/bugs/method.rb +79 -0
  129. data/spec/filters/bugs/module.rb +281 -0
  130. data/spec/filters/bugs/nilclass.rb +4 -0
  131. data/spec/filters/bugs/numeric.rb +27 -0
  132. data/spec/filters/bugs/openstruct.rb +8 -0
  133. data/spec/filters/bugs/pack_unpack.rb +138 -0
  134. data/spec/filters/bugs/pathname.rb +9 -0
  135. data/spec/filters/bugs/proc.rb +80 -0
  136. data/spec/filters/bugs/random.rb +20 -0
  137. data/spec/filters/bugs/range.rb +139 -0
  138. data/spec/filters/bugs/rational.rb +12 -0
  139. data/spec/filters/bugs/regexp.rb +91 -0
  140. data/spec/filters/bugs/set.rb +51 -0
  141. data/spec/filters/bugs/singleton.rb +7 -0
  142. data/spec/filters/bugs/string.rb +341 -0
  143. data/spec/filters/bugs/stringscanner.rb +78 -0
  144. data/spec/filters/bugs/struct.rb +26 -0
  145. data/spec/filters/bugs/symbol.rb +7 -0
  146. data/spec/filters/bugs/time.rb +109 -0
  147. data/spec/filters/bugs/unboundmethod.rb +33 -0
  148. data/spec/filters/bugs/warnings.rb +30 -0
  149. data/spec/filters/unsupported/array.rb +168 -0
  150. data/spec/filters/unsupported/basicobject.rb +15 -0
  151. data/spec/filters/unsupported/bignum.rb +55 -0
  152. data/spec/filters/unsupported/class.rb +5 -0
  153. data/spec/filters/unsupported/delegator.rb +6 -0
  154. data/spec/filters/unsupported/enumerable.rb +12 -0
  155. data/spec/filters/unsupported/enumerator.rb +14 -0
  156. data/spec/filters/unsupported/file.rb +4 -0
  157. data/spec/filters/unsupported/fixnum.rb +15 -0
  158. data/spec/filters/unsupported/float.rb +47 -0
  159. data/spec/filters/unsupported/freeze.rb +259 -0
  160. data/spec/filters/unsupported/hash.rb +44 -0
  161. data/spec/filters/unsupported/integer.rb +101 -0
  162. data/spec/filters/unsupported/kernel.rb +35 -0
  163. data/spec/filters/unsupported/language.rb +25 -0
  164. data/spec/filters/unsupported/marshal.rb +44 -0
  165. data/spec/filters/unsupported/matchdata.rb +63 -0
  166. data/spec/filters/unsupported/math.rb +4 -0
  167. data/spec/filters/unsupported/pathname.rb +4 -0
  168. data/spec/filters/unsupported/privacy.rb +287 -0
  169. data/spec/filters/unsupported/proc.rb +4 -0
  170. data/spec/filters/unsupported/random.rb +5 -0
  171. data/spec/filters/unsupported/range.rb +8 -0
  172. data/spec/filters/unsupported/regexp.rb +70 -0
  173. data/spec/filters/unsupported/set.rb +5 -0
  174. data/spec/filters/unsupported/singleton.rb +7 -0
  175. data/spec/filters/unsupported/string.rb +687 -0
  176. data/spec/filters/unsupported/struct.rb +7 -0
  177. data/spec/filters/unsupported/symbol.rb +21 -0
  178. data/spec/filters/unsupported/taint.rb +162 -0
  179. data/spec/filters/unsupported/thread.rb +10 -0
  180. data/spec/filters/unsupported/time.rb +204 -0
  181. data/spec/filters/unsupported/usage_of_files.rb +262 -0
  182. data/spec/lib/builder_processors_spec.rb +44 -0
  183. data/spec/lib/builder_spec.rb +133 -0
  184. data/spec/lib/cli_runners/server_spec.rb +25 -0
  185. data/spec/lib/cli_runners_spec.rb +16 -0
  186. data/spec/lib/cli_spec.rb +256 -0
  187. data/spec/lib/compiler_spec.rb +693 -0
  188. data/spec/lib/config_spec.rb +112 -0
  189. data/spec/lib/dependency_resolver_spec.rb +43 -0
  190. data/spec/lib/deprecations_spec.rb +17 -0
  191. data/spec/lib/fixtures/complex_sprockets.js.rb.erb +4 -0
  192. data/spec/lib/fixtures/file_with_directives.js +2 -0
  193. data/spec/lib/fixtures/jst_file.js.jst +1 -0
  194. data/spec/lib/fixtures/no_requires.rb +1 -0
  195. data/spec/lib/fixtures/opal_file.rb +2 -0
  196. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  197. data/spec/lib/fixtures/required_file.js +1 -0
  198. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  199. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  200. data/spec/lib/fixtures/requires.rb +7 -0
  201. data/spec/lib/fixtures/source_location_test.rb +7 -0
  202. data/spec/lib/fixtures/source_map.rb +1 -0
  203. data/spec/lib/fixtures/source_map/subfolder/other_file.rb +1 -0
  204. data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
  205. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  206. data/spec/lib/path_reader_spec.rb +47 -0
  207. data/spec/lib/paths_spec.rb +18 -0
  208. data/spec/lib/repl_spec.rb +28 -0
  209. data/spec/lib/rewriters/base_spec.rb +68 -0
  210. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +153 -0
  211. data/spec/lib/rewriters/block_to_iter_spec.rb +28 -0
  212. data/spec/lib/rewriters/dot_js_syntax_spec.rb +108 -0
  213. data/spec/lib/rewriters/explicit_writer_return_spec.rb +186 -0
  214. data/spec/lib/rewriters/for_rewriter_spec.rb +92 -0
  215. data/spec/lib/rewriters/hashes/key_duplicates_rewriter_spec.rb +47 -0
  216. data/spec/lib/rewriters/js_reserved_words_spec.rb +119 -0
  217. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +202 -0
  218. data/spec/lib/rewriters/opal_engine_check_spec.rb +84 -0
  219. data/spec/lib/rewriters/returnable_logic_spec.rb +52 -0
  220. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +59 -0
  221. data/spec/lib/simple_server_spec.rb +56 -0
  222. data/spec/lib/source_map/file_spec.rb +67 -0
  223. data/spec/lib/source_map/index_spec.rb +80 -0
  224. data/spec/lib/spec_helper.rb +105 -0
  225. data/spec/mspec-opal/formatters.rb +197 -0
  226. data/spec/mspec-opal/runner.rb +172 -0
  227. data/spec/opal/compiler/irb_spec.rb +44 -0
  228. data/spec/opal/compiler/unicode_spec.rb +10 -0
  229. data/spec/opal/core/array/dup_spec.rb +23 -0
  230. data/spec/opal/core/array/intersection_spec.rb +38 -0
  231. data/spec/opal/core/array/minus_spec.rb +38 -0
  232. data/spec/opal/core/array/union_spec.rb +38 -0
  233. data/spec/opal/core/array/uniq_spec.rb +49 -0
  234. data/spec/opal/core/class/inherited_spec.rb +18 -0
  235. data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
  236. data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
  237. data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
  238. data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
  239. data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
  240. data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
  241. data/spec/opal/core/enumerable/each_slice_break_spec.rb +6 -0
  242. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
  243. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
  244. data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
  245. data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
  246. data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
  247. data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
  248. data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
  249. data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
  250. data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
  251. data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
  252. data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
  253. data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
  254. data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
  255. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  256. data/spec/opal/core/exception_spec.rb +8 -0
  257. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  261. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  262. data/spec/opal/core/fixtures/require_tree_files/nested/nested 1.rb +1 -0
  263. data/spec/opal/core/fixtures/require_tree_files/nested/nested 2.rb +1 -0
  264. data/spec/opal/core/fixtures/require_tree_files/other/other 1.rb +1 -0
  265. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  266. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  267. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  268. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  269. data/spec/opal/core/hash/internals_spec.rb +339 -0
  270. data/spec/opal/core/helpers_spec.rb +14 -0
  271. data/spec/opal/core/iterable_props_spec.rb +53 -0
  272. data/spec/opal/core/kernel/at_exit_spec.rb +70 -0
  273. data/spec/opal/core/kernel/freeze_spec.rb +15 -0
  274. data/spec/opal/core/kernel/instance_variables_spec.rb +110 -0
  275. data/spec/opal/core/kernel/methods_spec.rb +25 -0
  276. data/spec/opal/core/kernel/public_methods_spec.rb +25 -0
  277. data/spec/opal/core/kernel/require_tree_spec.rb +18 -0
  278. data/spec/opal/core/kernel/respond_to_spec.rb +15 -0
  279. data/spec/opal/core/language/DATA/characters_support_spec.rb +9 -0
  280. data/spec/opal/core/language/DATA/empty___END___spec.rb +7 -0
  281. data/spec/opal/core/language/DATA/multiple___END___spec.rb +10 -0
  282. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +18 -0
  283. data/spec/opal/core/language/keyword_arguments_spec.rb +9 -0
  284. data/spec/opal/core/language/numblocks_spec.rb +16 -0
  285. data/spec/opal/core/language/safe_navigator_spec.rb +7 -0
  286. data/spec/opal/core/language/while_spec.rb +31 -0
  287. data/spec/opal/core/language_spec.rb +29 -0
  288. data/spec/opal/core/marshal/dump_spec.rb +81 -0
  289. data/spec/opal/core/marshal/load_spec.rb +13 -0
  290. data/spec/opal/core/module_spec.rb +27 -0
  291. data/spec/opal/core/object_id_spec.rb +56 -0
  292. data/spec/opal/core/regexp/interpolation_spec.rb +40 -0
  293. data/spec/opal/core/regexp/match_spec.rb +78 -0
  294. data/spec/opal/core/runtime/bridged_classes_spec.rb +123 -0
  295. data/spec/opal/core/runtime/constants_spec.rb +16 -0
  296. data/spec/opal/core/runtime/eval_spec.rb +5 -0
  297. data/spec/opal/core/runtime/exit_spec.rb +29 -0
  298. data/spec/opal/core/runtime/is_a_spec.rb +48 -0
  299. data/spec/opal/core/runtime/loaded_spec.rb +20 -0
  300. data/spec/opal/core/runtime/main_methods_spec.rb +39 -0
  301. data/spec/opal/core/runtime/method_missing_spec.rb +68 -0
  302. data/spec/opal/core/runtime/rescue_spec.rb +37 -0
  303. data/spec/opal/core/runtime/string_spec.rb +25 -0
  304. data/spec/opal/core/runtime/truthy_spec.rb +61 -0
  305. data/spec/opal/core/runtime_spec.rb +58 -0
  306. data/spec/opal/core/string/each_byte_spec.rb +19 -0
  307. data/spec/opal/core/string/gsub_spec.rb +35 -0
  308. data/spec/opal/core/string/to_sym_spec.rb +9 -0
  309. data/spec/opal/core/string_spec.rb +28 -0
  310. data/spec/opal/core/struct/dup_spec.rb +11 -0
  311. data/spec/opal/core/time_spec.rb +68 -0
  312. data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
  313. data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
  314. data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
  315. data/spec/opal/stdlib/erb/simple.opalerb +1 -0
  316. data/spec/opal/stdlib/js_spec.rb +72 -0
  317. data/spec/opal/stdlib/json/ext_spec.rb +55 -0
  318. data/spec/opal/stdlib/json/parse_spec.rb +37 -0
  319. data/spec/opal/stdlib/logger/logger_spec.rb +308 -0
  320. data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
  321. data/spec/opal/stdlib/native/array_spec.rb +11 -0
  322. data/spec/opal/stdlib/native/date_spec.rb +12 -0
  323. data/spec/opal/stdlib/native/deprecated_include_spec.rb +8 -0
  324. data/spec/opal/stdlib/native/each_spec.rb +13 -0
  325. data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
  326. data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
  327. data/spec/opal/stdlib/native/ext_spec.rb +19 -0
  328. data/spec/opal/stdlib/native/hash_spec.rb +67 -0
  329. data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
  330. data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
  331. data/spec/opal/stdlib/native/native_alias_spec.rb +26 -0
  332. data/spec/opal/stdlib/native/native_class_spec.rb +18 -0
  333. data/spec/opal/stdlib/native/native_module_spec.rb +13 -0
  334. data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
  335. data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
  336. data/spec/opal/stdlib/native/new_spec.rb +92 -0
  337. data/spec/opal/stdlib/native/struct_spec.rb +12 -0
  338. data/spec/opal/stdlib/pp_spec.rb +5 -0
  339. data/spec/opal/stdlib/promise/always_spec.rb +49 -0
  340. data/spec/opal/stdlib/promise/error_spec.rb +15 -0
  341. data/spec/opal/stdlib/promise/rescue_spec.rb +53 -0
  342. data/spec/opal/stdlib/promise/then_spec.rb +79 -0
  343. data/spec/opal/stdlib/promise/trace_spec.rb +51 -0
  344. data/spec/opal/stdlib/promise/value_spec.rb +15 -0
  345. data/spec/opal/stdlib/promise/when_spec.rb +34 -0
  346. data/spec/opal/stdlib/source_map_spec.rb +8 -0
  347. data/spec/opal/stdlib/strscan/scan_spec.rb +11 -0
  348. data/spec/opal/stdlib/template/paths_spec.rb +10 -0
  349. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  350. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  351. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  352. data/spec/ruby_specs +183 -0
  353. data/spec/spec_helper.rb +31 -0
  354. data/spec/support/guard_platform.rb +4 -0
  355. data/spec/support/match_helpers.rb +57 -0
  356. data/spec/support/mspec_rspec_adapter.rb +33 -0
  357. data/spec/support/rewriters_helper.rb +54 -0
  358. data/spec/support/source_map_helper.rb +190 -0
  359. data/stdlib/base64.rb +2 -2
  360. data/stdlib/bigdecimal.rb +15 -3
  361. data/stdlib/bigdecimal/bignumber.js.rb +1 -1
  362. data/stdlib/bigdecimal/util.rb +148 -0
  363. data/stdlib/delegate.rb +8 -0
  364. data/stdlib/nodejs/fileutils.rb +1 -1
  365. data/stdlib/nodejs/kernel.rb +0 -13
  366. data/stdlib/nodejs/stacktrace.rb +4 -179
  367. data/stdlib/ostruct.rb +5 -0
  368. data/stdlib/pp.rb +586 -19
  369. data/stdlib/prettyprint.rb +556 -0
  370. data/stdlib/rbconfig/sizeof.rb +2 -0
  371. data/stdlib/securerandom.rb +32 -0
  372. data/stdlib/set.rb +36 -0
  373. data/stdlib/strscan.rb +15 -0
  374. data/tasks/benchmarking.rake +1 -1
  375. data/tasks/linting.rake +3 -5
  376. data/tasks/releasing.rake +2 -5
  377. data/tasks/testing.rake +16 -11
  378. data/tasks/testing/mspec_special_calls.rb +1 -19
  379. data/test/nodejs/fixtures/cat.png +0 -0
  380. data/test/nodejs/fixtures/hello.rb +1 -0
  381. data/test/nodejs/fixtures/iso88591.txt +1 -0
  382. data/test/nodejs/fixtures/utf8.txt +1 -0
  383. data/test/nodejs/fixtures/win1258.txt +1 -0
  384. data/test/nodejs/test_dir.rb +39 -0
  385. data/test/nodejs/test_env.rb +62 -0
  386. data/test/nodejs/test_error.rb +29 -0
  387. data/test/nodejs/test_file.rb +206 -0
  388. data/test/nodejs/test_file_encoding.rb +20 -0
  389. data/test/nodejs/test_io.rb +18 -0
  390. data/test/nodejs/test_opal_builder.rb +12 -0
  391. data/test/nodejs/test_pathname.rb +16 -0
  392. data/test/opal/cat.png +0 -0
  393. data/test/opal/http_server.rb +52 -0
  394. data/test/opal/test_base64.rb +115 -0
  395. data/test/opal/test_keyword.rb +590 -0
  396. data/test/opal/test_matrix.rb +661 -0
  397. data/test/opal/test_openuri.rb +53 -0
  398. data/test/opal/unsupported_and_bugs.rb +39 -0
  399. data/yarn.lock +1355 -0
  400. metadata +899 -36
  401. data/.travis.yml +0 -109
  402. data/appveyor.yml +0 -35
  403. data/lib/opal/nodes/runtime_helpers.rb +0 -51
  404. data/opal/corelib/random/MersenneTwister.js +0 -137
  405. data/opal/corelib/random/mersenne_twister.js.rb +0 -13
  406. data/stdlib/bigdecimal/kernel.rb +0 -5
@@ -3,58 +3,19 @@
3
3
  module Opal
4
4
  module CliRunners
5
5
  class Applescript
6
- def initialize(options)
6
+ def self.call(data)
7
7
  unless system('which osalang > /dev/null')
8
8
  raise MissingJavaScriptSupport, 'JavaScript Automation is only supported by OS X Yosemite and above.'
9
9
  end
10
10
 
11
- @output = options.fetch(:output, $stdout)
12
- end
13
- attr_reader :output, :exit_status
14
-
15
- def puts(*args)
16
- output.puts(*args)
17
- end
18
-
19
- def run(code, argv)
20
- require 'tempfile'
21
- tempfile = Tempfile.new('opal-applescript-runner-')
22
- # tempfile = File.new('opal-applescript-runner.js', 'w') # for debugging
23
- tempfile.puts code
24
- tempfile.puts "'';" # OSAScript will output the last thing
25
- tempfile.close
26
- _successful = system_with_output('osascript', '-l', 'JavaScript', tempfile.path, *argv)
11
+ SystemRunner.call(data) do |tempfile|
12
+ tempfile.puts "'';" # OSAScript will output the last thing
13
+ ['osascript', '-l', 'JavaScript', tempfile.path, *data[:argv]]
14
+ end
27
15
  rescue Errno::ENOENT
28
16
  raise MissingAppleScript, 'AppleScript is only available on Mac OS X.'
29
17
  end
30
18
 
31
- # Let's support fake IO objects like StringIO
32
- def system_with_output(env, *cmd)
33
- if (_io_output = IO.try_convert(output))
34
- system(env, *cmd)
35
- @exit_status = $?.exitstatus
36
- return
37
- end
38
-
39
- if RUBY_PLATFORM == 'java'
40
- # JRuby has issues in dealing with subprocesses (at least up to 1.7.15)
41
- # @headius told me it's mostly fixed on master, but while we wait for it
42
- # to ship here's a tempfile workaround.
43
- require 'tempfile'
44
- require 'shellwords'
45
- tempfile = Tempfile.new('opal-applescript-output')
46
- system(env, cmd.shelljoin + " > #{tempfile.path}")
47
- @exit_status = $?.exitstatus
48
- captured_output = File.read tempfile.path
49
- tempfile.close
50
- else
51
- require 'open3'
52
- captured_output, status = Open3.capture2(env, *cmd)
53
- @exit_status = status.exitstatus
54
- end
55
- output.write captured_output
56
- end
57
-
58
19
  class MissingJavaScriptSupport < RunnerError
59
20
  end
60
21
 
@@ -3,22 +3,7 @@ var fs = require("fs");
3
3
 
4
4
  // NOTE: the code above doesn't work on Windows
5
5
  // and it doesn't support interactive stdin input (which is ok for our scenario)
6
- var opal_code = fs.readFileSync("/dev/stdin").toString();
7
-
8
- // Chrome can't handle huge data passed to `addScriptToEvaluateOnLoad`
9
- // https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/U5qyeX_ydBo
10
- // The only way is to create temporary files and pass them to chrome.
11
- fs.writeFileSync("/tmp/chrome-opal.js", opal_code);
12
- fs.writeFileSync("/tmp/chrome-opal.html", "" +
13
- "<html>" +
14
- "<head>" +
15
- "<meta charset='utf-8'>" +
16
- "<script src='chrome-opal.js'></script>" +
17
- "</head>" +
18
- "<body>" +
19
- "</body>" +
20
- "</html>"
21
- );
6
+ var dir = fs.readFileSync("/dev/stdin").toString();
22
7
 
23
8
  var options = {
24
9
  host: process.env.CHROME_HOST || 'localhost',
@@ -89,31 +74,18 @@ CDP(options, function(client) {
89
74
  });
90
75
 
91
76
  Runtime.exceptionThrown(function(exception) {
92
- var exceptionDetails = exception.exceptionDetails,
93
- properties = exceptionDetails.exception.preview.properties,
94
- stackTrace = exceptionDetails.stackTrace ? exceptionDetails.stackTrace.callFrames : [],
95
- name, message, trace = [], i;
96
-
77
+ var properties = exception.exceptionDetails.exception.preview.properties,
78
+ stack, i;
97
79
 
98
80
  for (i = 0; i < properties.length; i++) {
99
81
  var property = properties[i];
100
82
 
101
- if (property.name == "name") {
102
- name = property.value;
103
- }
104
-
105
- if (property.name == "message") {
106
- message = property.value;
83
+ if (property.name == "stack") {
84
+ stack = property.value;
107
85
  }
108
86
  }
109
87
 
110
- console.log(name + " : " + message);
111
-
112
- for (i = 0; i < stackTrace.length; i++) {
113
- var raw = stackTrace[i];
114
-
115
- console.log(" at " + raw.functionName + " (" + raw.url + ":" + raw.lineNumber + ":" + raw.columnNumber + ")")
116
- }
88
+ console.log(stack);
117
89
 
118
90
  process.exit(1);
119
91
  })
@@ -130,6 +102,6 @@ CDP(options, function(client) {
130
102
  })
131
103
  });
132
104
 
133
- Page.navigate({ url: 'file:///tmp/chrome-opal.html' })
105
+ Page.navigate({ url: "file://"+dir+"/index.html" })
134
106
  });
135
107
  });
@@ -3,6 +3,7 @@
3
3
  require 'shellwords'
4
4
  require 'socket'
5
5
  require 'timeout'
6
+ require 'tmpdir'
6
7
 
7
8
  module Opal
8
9
  module CliRunners
@@ -12,23 +13,44 @@ module Opal
12
13
  DEFAULT_CHROME_HOST = 'localhost'
13
14
  DEFAULT_CHROME_PORT = 9222
14
15
 
15
- def initialize(options)
16
+ def self.call(data)
17
+ runner = new(data)
18
+ runner.run
19
+ runner.exit_status
20
+ end
21
+
22
+ def initialize(data)
23
+ builder = data[:builder]
24
+ options = data[:options]
25
+ argv = data[:argv]
26
+
27
+ if argv && argv.any?
28
+ warn "warning: ARGV is not supported by the Chrome runner #{argv.inspect}"
29
+ end
30
+
16
31
  @output = options.fetch(:output, $stdout)
32
+ @builder = builder
17
33
  end
18
- attr_reader :output, :exit_status
19
-
20
- def run(code, _argv)
21
- with_chrome_server do
22
- cmd = [
23
- 'env',
24
- "CHROME_HOST=#{chrome_host}",
25
- "CHROME_PORT=#{chrome_port}",
26
- 'node',
27
- SCRIPT_PATH
28
- ]
29
-
30
- IO.popen(cmd, 'w', out: output) do |io|
31
- io.write(code)
34
+
35
+ attr_reader :output, :exit_status, :builder
36
+
37
+ def run
38
+ mktmpdir do |dir|
39
+ with_chrome_server do
40
+ cmd = [
41
+ 'env',
42
+ "CHROME_HOST=#{chrome_host}",
43
+ "CHROME_PORT=#{chrome_port}",
44
+ 'node',
45
+ '--require', "#{__dir__}/source-map-support",
46
+ SCRIPT_PATH
47
+ ]
48
+
49
+ prepare_files_in(dir)
50
+
51
+ IO.popen(cmd, 'w', out: output) do |io|
52
+ io.write dir
53
+ end
32
54
  end
33
55
 
34
56
  @exit_status = $?.exitstatus
@@ -37,6 +59,35 @@ module Opal
37
59
 
38
60
  private
39
61
 
62
+ def prepare_files_in(dir)
63
+ js = builder.to_s
64
+ map = builder.source_map.to_json
65
+ stack = File.read("#{__dir__}/source-map-support-browser.js")
66
+
67
+ # Chrome can't handle huge data passed to `addScriptToEvaluateOnLoad`
68
+ # https://groups.google.com/a/chromium.org/forum/#!topic/chromium-discuss/U5qyeX_ydBo
69
+ # The only way is to create temporary files and pass them to chrome.
70
+ File.write("#{dir}/index.js", js)
71
+ File.write("#{dir}/source-map-support.js", stack)
72
+ File.write("#{dir}/index.html", <<~HTML)
73
+ <html><head>
74
+ <meta charset='utf-8'>
75
+ <script src='./source-map-support.js'></script>
76
+ <script>
77
+ sourceMapSupport.install({
78
+ retrieveSourceMap: function(path) {
79
+ return path.endsWith('/index.js') ? {
80
+ url: './index.map', map: #{map.to_json}
81
+ } : null;
82
+ }
83
+ });
84
+ </script>
85
+ </head><body>
86
+ <script src='./index.js'></script>
87
+ </body></html>
88
+ HTML
89
+ end
90
+
40
91
  def chrome_host
41
92
  ENV['CHROME_HOST'] || DEFAULT_CHROME_HOST
42
93
  end
@@ -57,15 +108,18 @@ module Opal
57
108
  raise 'Chrome server can be started only on localhost' if chrome_host != DEFAULT_CHROME_HOST
58
109
 
59
110
  # Disable web security with "--disable-web-security" flag to be able to do XMLHttpRequest (see test_openuri.rb)
60
- chrome_server_cmd = "#{chrome_executable} --headless --disable-web-security --disable-gpu --remote-debugging-port=#{chrome_port} #{ENV['CHROME_OPTS']}"
61
- puts chrome_server_cmd
111
+ chrome_server_cmd = "#{chrome_executable} \
112
+ --headless \
113
+ --disable-web-security \
114
+ --remote-debugging-port=#{chrome_port} \
115
+ #{ENV['CHROME_OPTS']}"
62
116
 
63
117
  chrome_pid = Process.spawn(chrome_server_cmd)
64
118
 
65
- Timeout.timeout(1) do
119
+ Timeout.timeout(10) do
66
120
  loop do
67
121
  break if chrome_server_running?
68
- sleep 0.1
122
+ sleep 0.5
69
123
  end
70
124
  end
71
125
 
@@ -107,6 +161,10 @@ module Opal
107
161
  raise 'Headless chrome is supported only by Mac OS and Linux'
108
162
  end
109
163
  end
164
+
165
+ def mktmpdir(&block)
166
+ Dir.mktmpdir('chrome-opal-', &block)
167
+ end
110
168
  end
111
169
  end
112
170
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'opal/paths'
4
+
5
+ # The compiler runner will just output the compiled JavaScript
6
+ Opal::CliRunners::Compiler = ->(data) {
7
+ options = data[:options] || {}
8
+ builder = data.fetch(:builder)
9
+ map_file = options[:map_file]
10
+ output = data.fetch(:output)
11
+
12
+ compiled_source = builder.to_s + "\n" + builder.source_map.to_data_uri_comment
13
+ output.puts compiled_source
14
+ File.write(map_file, builder.source_map.to_json) if map_file
15
+
16
+ 0
17
+ }
@@ -1,55 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'opal/paths'
4
+ require 'opal/cli_runners/system_runner'
4
5
 
5
6
  module Opal
6
7
  module CliRunners
7
8
  class Nashorn
8
- def initialize(options)
9
- @output = options.fetch(:output, $stdout)
10
- end
11
- attr_reader :output, :exit_status
12
-
13
- def puts(*args)
14
- output.puts(*args)
15
- end
16
-
17
- def run(code, argv)
18
- require 'tempfile'
19
- tempfile = Tempfile.new('opal-nashorn-runner-')
20
- tempfile.write code
21
- tempfile.close
22
- system_with_output({}, 'jjs', tempfile.path, *argv)
23
- rescue Errno::ENOENT
24
- raise MissingNashorn, 'Please install JDK to be able to run Opal scripts.'
25
- end
26
-
27
- # Let's support fake IO objects like StringIO
28
- def system_with_output(env, *cmd)
29
- if IO.try_convert(output)
30
- system(env, *cmd)
31
- @exit_status = $?.exitstatus
32
- return
33
- end
9
+ def self.call(data)
10
+ # Allow to change path if using GraalVM, see:
11
+ # https://github.com/graalvm/graaljs/blob/master/docs/user/NashornMigrationGuide.md#launcher-name-js
12
+ exe = ENV['NASHORN_PATH'] || 'jjs'
34
13
 
35
- if RUBY_PLATFORM == 'java'
36
- # JRuby has issues in dealing with subprocesses (at least up to 1.7.15)
37
- # @headius told me it's mostly fixed on master, but while we wait for it
38
- # to ship here's a tempfile workaround.
39
- require 'tempfile'
40
- require 'shellwords'
41
- tempfile = Tempfile.new('opal-nashorn-output')
42
- system(env, cmd.shelljoin + " > #{tempfile.path}")
43
- @exit_status = $?.exitstatus
44
- captured_output = File.read tempfile.path
45
- tempfile.close
46
- else
47
- require 'open3'
48
- captured_output, status = Open3.capture2(env, *cmd)
49
- @exit_status = status.exitstatus
14
+ SystemRunner.call(data) do |tempfile|
15
+ [exe, tempfile.path, *data[:argv]]
50
16
  end
51
-
52
- output.write captured_output
17
+ rescue Errno::ENOENT
18
+ raise MissingNashorn, 'Please install JDK or GraalVM to be able to run Opal scripts.'
53
19
  end
54
20
 
55
21
  class MissingNashorn < RunnerError
@@ -1,65 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'opal/paths'
4
- require 'shellwords'
4
+ require 'opal/cli_runners/system_runner'
5
5
 
6
6
  module Opal
7
7
  module CliRunners
8
8
  class Nodejs
9
9
  NODE_PATH = File.expand_path('../stdlib/nodejs/node_modules', ::Opal.gem_dir)
10
10
 
11
- def initialize(options)
12
- @output = options.fetch(:output, $stdout)
13
- end
14
- attr_reader :output, :exit_status
11
+ def self.call(data)
12
+ (data[:options] ||= {})[:env] = { 'NODE_PATH' => node_modules }
15
13
 
16
- def puts(*args)
17
- output.puts(*args)
18
- end
14
+ argv = data[:argv].dup.to_a
15
+ argv.unshift('--') if argv.any?
19
16
 
20
- def node_modules
21
- paths = ENV['NODE_PATH'].to_s.split(':')
22
- paths << NODE_PATH unless paths.include? NODE_PATH
23
- paths.join(':')
24
- end
25
-
26
- def run(code, argv)
27
- require 'tempfile'
28
- tempfile = Tempfile.new('opal-nodejs-runner-')
29
- # tempfile = File.new('opal-nodejs-runner.js', 'w') # for debugging
30
- tempfile.write code
31
- tempfile.close
32
- system_with_output({ 'NODE_PATH' => node_modules }, 'node', tempfile.path, *argv)
17
+ SystemRunner.call(data) do |tempfile|
18
+ [
19
+ 'node',
20
+ '--require', "#{__dir__}/source-map-support",
21
+ tempfile.path,
22
+ *argv
23
+ ]
24
+ end
33
25
  rescue Errno::ENOENT
34
26
  raise MissingNodeJS, 'Please install Node.js to be able to run Opal scripts.'
35
27
  end
36
28
 
37
- # Let's support fake IO objects like StringIO
38
- def system_with_output(env, *cmd)
39
- if IO.try_convert(output)
40
- system(env, *cmd)
41
- @exit_status = $?.exitstatus
42
- return
43
- end
44
-
45
- if RUBY_PLATFORM == 'java'
46
- # JRuby has issues in dealing with subprocesses (at least up to 1.7.15)
47
- # @headius told me it's mostly fixed on master, but while we wait for it
48
- # to ship here's a tempfile workaround.
49
- require 'tempfile'
50
- require 'shellwords'
51
- tempfile = Tempfile.new('opal-node-output')
52
- system(env, cmd.shelljoin + " > #{tempfile.path}")
53
- @exit_status = $?.exitstatus
54
- captured_output = File.read tempfile.path
55
- tempfile.close
56
- else
57
- require 'open3'
58
- captured_output, status = Open3.capture2(env, *cmd)
59
- @exit_status = status.exitstatus
60
- end
61
-
62
- output.write captured_output
29
+ # Ensure stdlib node_modules is among NODE_PATHs
30
+ def self.node_modules
31
+ ENV['NODE_PATH'].to_s.split(':').tap do |paths|
32
+ paths << NODE_PATH unless paths.include? NODE_PATH
33
+ end.join(':')
63
34
  end
64
35
 
65
36
  class MissingNodeJS < RunnerError
@@ -3,8 +3,20 @@
3
3
  module Opal
4
4
  module CliRunners
5
5
  class Server
6
- def initialize(options)
7
- @output = options.fetch(:output, $stdout)
6
+ def self.call(data)
7
+ runner = new(data)
8
+ runner.run
9
+ runner.exit_status
10
+ end
11
+
12
+ def initialize(data)
13
+ options = data[:options] || {}
14
+ builder = data[:builder]
15
+
16
+ @code = builder.to_s + "\n" + builder.source_map.to_data_uri_comment
17
+ @argv = data[:argv] || []
18
+
19
+ @output = data[:output] || $stdout
8
20
 
9
21
  @port = options.fetch(:port, ENV['OPAL_CLI_RUNNERS_SERVER_PORT'] || 3000).to_i
10
22
 
@@ -12,18 +24,18 @@ module Opal
12
24
  @static_folder = @static_folder == true ? 'public' : @static_folder
13
25
  @static_folder = File.expand_path(@static_folder) if @static_folder
14
26
  end
15
- attr_reader :output, :port, :server, :static_folder
16
27
 
17
- def run(source, argv)
28
+ attr_reader :output, :port, :server, :static_folder, :code, :argv
29
+
30
+ def run
18
31
  unless argv.empty?
19
32
  raise ArgumentError, 'Program arguments are not supported on the Server runner'
20
33
  end
21
34
 
22
35
  require 'rack'
23
- require 'webrick'
24
36
  require 'logger'
25
37
 
26
- app = build_app(source)
38
+ app = build_app(code)
27
39
 
28
40
  @server = Rack::Server.start(
29
41
  app: app,