opal 1.0.5 → 1.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (394) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +14 -12
  3. data/.gitattributes +1 -1
  4. data/.github/workflows/build.yml +15 -10
  5. data/.jshintrc +1 -1
  6. data/.overcommit.yml +35 -0
  7. data/.rubocop.yml +44 -7
  8. data/{.rubocop_todo.yml → .rubocop/todo.yml} +4 -5
  9. data/CHANGELOG.md +87 -2
  10. data/Gemfile +1 -2
  11. data/HACKING.md +2 -9
  12. data/README.md +20 -17
  13. data/UNRELEASED.md +108 -0
  14. data/benchmark-ips/bm_array_pop_1.rb +8 -0
  15. data/benchmark-ips/bm_array_shift.rb +7 -0
  16. data/benchmark-ips/class_shovel_vs_singleton_class.rb +16 -0
  17. data/bin/build-browser-source-map-support +5 -0
  18. data/bin/format-filters +54 -0
  19. data/bin/remove-filters +39 -0
  20. data/docs/roda-sprockets.md +86 -0
  21. data/docs/sinatra.md +5 -12
  22. data/examples/rack/Gemfile +1 -0
  23. data/examples/rack/app/application.rb +3 -0
  24. data/examples/rack/config.ru +5 -4
  25. data/exe/opal-repl +2 -83
  26. data/lib/opal/ast/builder.rb +1 -1
  27. data/lib/opal/builder.rb +2 -10
  28. data/lib/opal/builder_processors.rb +1 -1
  29. data/lib/opal/cli_runners.rb +27 -37
  30. data/lib/opal/cli_runners/applescript.rb +5 -44
  31. data/lib/opal/cli_runners/chrome.js +7 -35
  32. data/lib/opal/cli_runners/chrome.rb +75 -17
  33. data/lib/opal/cli_runners/compiler.rb +17 -0
  34. data/lib/opal/cli_runners/nashorn.rb +9 -43
  35. data/lib/opal/cli_runners/nodejs.rb +18 -47
  36. data/lib/opal/cli_runners/server.rb +18 -6
  37. data/lib/opal/cli_runners/source-map-support-browser.js +6445 -0
  38. data/lib/opal/cli_runners/source-map-support.js +639 -0
  39. data/lib/opal/cli_runners/system_runner.rb +45 -0
  40. data/lib/opal/compiler.rb +57 -29
  41. data/lib/opal/config.rb +0 -5
  42. data/lib/opal/erb.rb +1 -1
  43. data/lib/opal/magic_comments.rb +34 -0
  44. data/lib/opal/nodes/args/arity_check.rb +2 -1
  45. data/lib/opal/nodes/base.rb +1 -1
  46. data/lib/opal/nodes/call.rb +1 -4
  47. data/lib/opal/nodes/def.rb +2 -0
  48. data/lib/opal/nodes/iter.rb +1 -1
  49. data/lib/opal/nodes/literal.rb +19 -14
  50. data/lib/opal/nodes/logic.rb +5 -80
  51. data/lib/opal/nodes/masgn.rb +2 -0
  52. data/lib/opal/nodes/rescue.rb +1 -1
  53. data/lib/opal/nodes/super.rb +24 -10
  54. data/lib/opal/nodes/top.rb +5 -4
  55. data/lib/opal/parser/with_c_lexer.rb +2 -1
  56. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  57. data/lib/opal/path_reader.rb +2 -2
  58. data/lib/opal/paths.rb +8 -5
  59. data/lib/opal/repl.rb +103 -0
  60. data/lib/opal/rewriter.rb +4 -0
  61. data/lib/opal/rewriters/for_rewriter.rb +1 -1
  62. data/lib/opal/rewriters/js_reserved_words.rb +7 -7
  63. data/lib/opal/rewriters/numblocks.rb +31 -0
  64. data/lib/opal/rewriters/returnable_logic.rb +33 -0
  65. data/lib/opal/version.rb +1 -1
  66. data/opal.gemspec +25 -25
  67. data/opal/corelib/array.rb +160 -118
  68. data/opal/corelib/array/pack.rb +5 -3
  69. data/opal/corelib/basic_object.rb +4 -4
  70. data/opal/corelib/class.rb +2 -1
  71. data/opal/corelib/comparable.rb +49 -31
  72. data/opal/corelib/constants.rb +5 -5
  73. data/opal/corelib/enumerable.rb +108 -46
  74. data/opal/corelib/enumerator.rb +27 -12
  75. data/opal/corelib/file.rb +3 -1
  76. data/opal/corelib/hash.rb +6 -1
  77. data/opal/corelib/helpers.rb +8 -28
  78. data/opal/corelib/io.rb +12 -7
  79. data/opal/corelib/kernel.rb +45 -14
  80. data/opal/corelib/kernel/format.rb +3 -1
  81. data/opal/corelib/math.rb +8 -6
  82. data/opal/corelib/method.rb +8 -0
  83. data/opal/corelib/module.rb +17 -2
  84. data/opal/corelib/number.rb +3 -12
  85. data/opal/corelib/proc.rb +16 -0
  86. data/opal/corelib/random/mersenne_twister.rb +147 -0
  87. data/opal/corelib/range.rb +3 -13
  88. data/opal/corelib/regexp.rb +10 -6
  89. data/opal/corelib/runtime.js +208 -81
  90. data/opal/corelib/string.rb +55 -49
  91. data/opal/corelib/string/encoding.rb +109 -32
  92. data/opal/corelib/string/unpack.rb +2 -17
  93. data/opal/corelib/struct.rb +14 -1
  94. data/opal/corelib/time.rb +4 -0
  95. data/opal/opal.rb +1 -1
  96. data/opal/opal/mini.rb +1 -1
  97. data/package.json +1 -0
  98. data/spec/README.md +10 -0
  99. data/spec/filters/bugs/array.rb +76 -0
  100. data/spec/filters/bugs/base64.rb +10 -0
  101. data/spec/filters/bugs/basicobject.rb +12 -0
  102. data/spec/filters/bugs/bigdecimal.rb +248 -0
  103. data/spec/filters/bugs/class.rb +12 -0
  104. data/spec/filters/bugs/complex.rb +7 -0
  105. data/spec/filters/bugs/date.rb +104 -0
  106. data/spec/filters/bugs/encoding.rb +259 -0
  107. data/spec/filters/bugs/enumerable.rb +26 -0
  108. data/spec/filters/bugs/enumerator.rb +48 -0
  109. data/spec/filters/bugs/exception.rb +120 -0
  110. data/spec/filters/bugs/file.rb +48 -0
  111. data/spec/filters/bugs/float.rb +74 -0
  112. data/spec/filters/bugs/hash.rb +60 -0
  113. data/spec/filters/bugs/integer.rb +78 -0
  114. data/spec/filters/bugs/io.rb +9 -0
  115. data/spec/filters/bugs/kernel.rb +401 -0
  116. data/spec/filters/bugs/language.rb +451 -0
  117. data/spec/filters/bugs/marshal.rb +50 -0
  118. data/spec/filters/bugs/math.rb +4 -0
  119. data/spec/filters/bugs/method.rb +79 -0
  120. data/spec/filters/bugs/module.rb +281 -0
  121. data/spec/filters/bugs/nilclass.rb +4 -0
  122. data/spec/filters/bugs/numeric.rb +27 -0
  123. data/spec/filters/bugs/openstruct.rb +8 -0
  124. data/spec/filters/bugs/pack_unpack.rb +138 -0
  125. data/spec/filters/bugs/pathname.rb +9 -0
  126. data/spec/filters/bugs/proc.rb +80 -0
  127. data/spec/filters/bugs/random.rb +20 -0
  128. data/spec/filters/bugs/range.rb +139 -0
  129. data/spec/filters/bugs/rational.rb +12 -0
  130. data/spec/filters/bugs/regexp.rb +91 -0
  131. data/spec/filters/bugs/set.rb +51 -0
  132. data/spec/filters/bugs/singleton.rb +7 -0
  133. data/spec/filters/bugs/string.rb +341 -0
  134. data/spec/filters/bugs/stringscanner.rb +78 -0
  135. data/spec/filters/bugs/struct.rb +26 -0
  136. data/spec/filters/bugs/symbol.rb +7 -0
  137. data/spec/filters/bugs/time.rb +109 -0
  138. data/spec/filters/bugs/unboundmethod.rb +33 -0
  139. data/spec/filters/bugs/warnings.rb +30 -0
  140. data/spec/filters/unsupported/array.rb +168 -0
  141. data/spec/filters/unsupported/basicobject.rb +15 -0
  142. data/spec/filters/unsupported/bignum.rb +55 -0
  143. data/spec/filters/unsupported/class.rb +5 -0
  144. data/spec/filters/unsupported/delegator.rb +6 -0
  145. data/spec/filters/unsupported/enumerable.rb +12 -0
  146. data/spec/filters/unsupported/enumerator.rb +14 -0
  147. data/spec/filters/unsupported/file.rb +4 -0
  148. data/spec/filters/unsupported/fixnum.rb +15 -0
  149. data/spec/filters/unsupported/float.rb +47 -0
  150. data/spec/filters/unsupported/freeze.rb +259 -0
  151. data/spec/filters/unsupported/hash.rb +44 -0
  152. data/spec/filters/unsupported/integer.rb +101 -0
  153. data/spec/filters/unsupported/kernel.rb +35 -0
  154. data/spec/filters/unsupported/language.rb +25 -0
  155. data/spec/filters/unsupported/marshal.rb +44 -0
  156. data/spec/filters/unsupported/matchdata.rb +63 -0
  157. data/spec/filters/unsupported/math.rb +4 -0
  158. data/spec/filters/unsupported/pathname.rb +4 -0
  159. data/spec/filters/unsupported/privacy.rb +287 -0
  160. data/spec/filters/unsupported/proc.rb +4 -0
  161. data/spec/filters/unsupported/random.rb +5 -0
  162. data/spec/filters/unsupported/range.rb +8 -0
  163. data/spec/filters/unsupported/regexp.rb +70 -0
  164. data/spec/filters/unsupported/set.rb +5 -0
  165. data/spec/filters/unsupported/singleton.rb +7 -0
  166. data/spec/filters/unsupported/string.rb +687 -0
  167. data/spec/filters/unsupported/struct.rb +7 -0
  168. data/spec/filters/unsupported/symbol.rb +21 -0
  169. data/spec/filters/unsupported/taint.rb +162 -0
  170. data/spec/filters/unsupported/thread.rb +10 -0
  171. data/spec/filters/unsupported/time.rb +204 -0
  172. data/spec/filters/unsupported/usage_of_files.rb +262 -0
  173. data/spec/lib/builder_processors_spec.rb +44 -0
  174. data/spec/lib/builder_spec.rb +133 -0
  175. data/spec/lib/cli_runners/server_spec.rb +25 -0
  176. data/spec/lib/cli_runners_spec.rb +16 -0
  177. data/spec/lib/cli_spec.rb +256 -0
  178. data/spec/lib/compiler_spec.rb +693 -0
  179. data/spec/lib/config_spec.rb +112 -0
  180. data/spec/lib/dependency_resolver_spec.rb +43 -0
  181. data/spec/lib/deprecations_spec.rb +17 -0
  182. data/spec/lib/fixtures/complex_sprockets.js.rb.erb +4 -0
  183. data/spec/lib/fixtures/file_with_directives.js +2 -0
  184. data/spec/lib/fixtures/jst_file.js.jst +1 -0
  185. data/spec/lib/fixtures/no_requires.rb +1 -0
  186. data/spec/lib/fixtures/opal_file.rb +2 -0
  187. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  188. data/spec/lib/fixtures/required_file.js +1 -0
  189. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  190. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  191. data/spec/lib/fixtures/requires.rb +7 -0
  192. data/spec/lib/fixtures/source_location_test.rb +7 -0
  193. data/spec/lib/fixtures/source_map.rb +1 -0
  194. data/spec/lib/fixtures/source_map/subfolder/other_file.rb +1 -0
  195. data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
  196. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  197. data/spec/lib/path_reader_spec.rb +47 -0
  198. data/spec/lib/paths_spec.rb +18 -0
  199. data/spec/lib/repl_spec.rb +28 -0
  200. data/spec/lib/rewriters/base_spec.rb +68 -0
  201. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +153 -0
  202. data/spec/lib/rewriters/block_to_iter_spec.rb +28 -0
  203. data/spec/lib/rewriters/dot_js_syntax_spec.rb +108 -0
  204. data/spec/lib/rewriters/explicit_writer_return_spec.rb +186 -0
  205. data/spec/lib/rewriters/for_rewriter_spec.rb +92 -0
  206. data/spec/lib/rewriters/hashes/key_duplicates_rewriter_spec.rb +47 -0
  207. data/spec/lib/rewriters/js_reserved_words_spec.rb +119 -0
  208. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +202 -0
  209. data/spec/lib/rewriters/opal_engine_check_spec.rb +84 -0
  210. data/spec/lib/rewriters/returnable_logic_spec.rb +52 -0
  211. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +59 -0
  212. data/spec/lib/simple_server_spec.rb +56 -0
  213. data/spec/lib/source_map/file_spec.rb +67 -0
  214. data/spec/lib/source_map/index_spec.rb +80 -0
  215. data/spec/lib/spec_helper.rb +105 -0
  216. data/spec/mspec-opal/formatters.rb +197 -0
  217. data/spec/mspec-opal/runner.rb +172 -0
  218. data/spec/opal/compiler/irb_spec.rb +44 -0
  219. data/spec/opal/compiler/unicode_spec.rb +10 -0
  220. data/spec/opal/core/array/dup_spec.rb +23 -0
  221. data/spec/opal/core/array/intersection_spec.rb +38 -0
  222. data/spec/opal/core/array/minus_spec.rb +38 -0
  223. data/spec/opal/core/array/union_spec.rb +38 -0
  224. data/spec/opal/core/array/uniq_spec.rb +49 -0
  225. data/spec/opal/core/class/inherited_spec.rb +18 -0
  226. data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
  227. data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
  228. data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
  229. data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
  230. data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
  231. data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
  232. data/spec/opal/core/enumerable/each_slice_break_spec.rb +6 -0
  233. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
  234. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
  235. data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
  236. data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
  237. data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
  238. data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
  239. data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
  240. data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
  241. data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
  242. data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
  243. data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
  244. data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
  245. data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
  246. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  247. data/spec/opal/core/exception_spec.rb +8 -0
  248. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  249. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  250. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  251. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  252. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  253. data/spec/opal/core/fixtures/require_tree_files/nested/nested 1.rb +1 -0
  254. data/spec/opal/core/fixtures/require_tree_files/nested/nested 2.rb +1 -0
  255. data/spec/opal/core/fixtures/require_tree_files/other/other 1.rb +1 -0
  256. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  257. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  260. data/spec/opal/core/hash/internals_spec.rb +339 -0
  261. data/spec/opal/core/helpers_spec.rb +14 -0
  262. data/spec/opal/core/iterable_props_spec.rb +53 -0
  263. data/spec/opal/core/kernel/at_exit_spec.rb +70 -0
  264. data/spec/opal/core/kernel/freeze_spec.rb +15 -0
  265. data/spec/opal/core/kernel/instance_variables_spec.rb +110 -0
  266. data/spec/opal/core/kernel/methods_spec.rb +25 -0
  267. data/spec/opal/core/kernel/public_methods_spec.rb +25 -0
  268. data/spec/opal/core/kernel/require_tree_spec.rb +18 -0
  269. data/spec/opal/core/kernel/respond_to_spec.rb +15 -0
  270. data/spec/opal/core/language/DATA/characters_support_spec.rb +9 -0
  271. data/spec/opal/core/language/DATA/empty___END___spec.rb +7 -0
  272. data/spec/opal/core/language/DATA/multiple___END___spec.rb +10 -0
  273. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +18 -0
  274. data/spec/opal/core/language/keyword_arguments_spec.rb +9 -0
  275. data/spec/opal/core/language/numblocks_spec.rb +16 -0
  276. data/spec/opal/core/language/safe_navigator_spec.rb +7 -0
  277. data/spec/opal/core/language/while_spec.rb +31 -0
  278. data/spec/opal/core/language_spec.rb +29 -0
  279. data/spec/opal/core/marshal/dump_spec.rb +81 -0
  280. data/spec/opal/core/marshal/load_spec.rb +13 -0
  281. data/spec/opal/core/module_spec.rb +27 -0
  282. data/spec/opal/core/object_id_spec.rb +56 -0
  283. data/spec/opal/core/regexp/interpolation_spec.rb +40 -0
  284. data/spec/opal/core/regexp/match_spec.rb +78 -0
  285. data/spec/opal/core/runtime/bridged_classes_spec.rb +123 -0
  286. data/spec/opal/core/runtime/constants_spec.rb +16 -0
  287. data/spec/opal/core/runtime/eval_spec.rb +5 -0
  288. data/spec/opal/core/runtime/exit_spec.rb +29 -0
  289. data/spec/opal/core/runtime/is_a_spec.rb +48 -0
  290. data/spec/opal/core/runtime/loaded_spec.rb +20 -0
  291. data/spec/opal/core/runtime/main_methods_spec.rb +39 -0
  292. data/spec/opal/core/runtime/method_missing_spec.rb +68 -0
  293. data/spec/opal/core/runtime/rescue_spec.rb +37 -0
  294. data/spec/opal/core/runtime/string_spec.rb +25 -0
  295. data/spec/opal/core/runtime/truthy_spec.rb +61 -0
  296. data/spec/opal/core/runtime_spec.rb +58 -0
  297. data/spec/opal/core/string/each_byte_spec.rb +19 -0
  298. data/spec/opal/core/string/gsub_spec.rb +35 -0
  299. data/spec/opal/core/string/to_sym_spec.rb +9 -0
  300. data/spec/opal/core/string_spec.rb +28 -0
  301. data/spec/opal/core/struct/dup_spec.rb +11 -0
  302. data/spec/opal/core/time_spec.rb +68 -0
  303. data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
  304. data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
  305. data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
  306. data/spec/opal/stdlib/erb/simple.opalerb +1 -0
  307. data/spec/opal/stdlib/js_spec.rb +72 -0
  308. data/spec/opal/stdlib/json/ext_spec.rb +55 -0
  309. data/spec/opal/stdlib/json/parse_spec.rb +37 -0
  310. data/spec/opal/stdlib/logger/logger_spec.rb +308 -0
  311. data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
  312. data/spec/opal/stdlib/native/array_spec.rb +11 -0
  313. data/spec/opal/stdlib/native/date_spec.rb +12 -0
  314. data/spec/opal/stdlib/native/deprecated_include_spec.rb +8 -0
  315. data/spec/opal/stdlib/native/each_spec.rb +13 -0
  316. data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
  317. data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
  318. data/spec/opal/stdlib/native/ext_spec.rb +19 -0
  319. data/spec/opal/stdlib/native/hash_spec.rb +67 -0
  320. data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
  321. data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
  322. data/spec/opal/stdlib/native/native_alias_spec.rb +26 -0
  323. data/spec/opal/stdlib/native/native_class_spec.rb +18 -0
  324. data/spec/opal/stdlib/native/native_module_spec.rb +13 -0
  325. data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
  326. data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
  327. data/spec/opal/stdlib/native/new_spec.rb +92 -0
  328. data/spec/opal/stdlib/native/struct_spec.rb +12 -0
  329. data/spec/opal/stdlib/pp_spec.rb +5 -0
  330. data/spec/opal/stdlib/promise/always_spec.rb +49 -0
  331. data/spec/opal/stdlib/promise/error_spec.rb +15 -0
  332. data/spec/opal/stdlib/promise/rescue_spec.rb +53 -0
  333. data/spec/opal/stdlib/promise/then_spec.rb +79 -0
  334. data/spec/opal/stdlib/promise/trace_spec.rb +51 -0
  335. data/spec/opal/stdlib/promise/value_spec.rb +15 -0
  336. data/spec/opal/stdlib/promise/when_spec.rb +34 -0
  337. data/spec/opal/stdlib/source_map_spec.rb +8 -0
  338. data/spec/opal/stdlib/strscan/scan_spec.rb +11 -0
  339. data/spec/opal/stdlib/template/paths_spec.rb +10 -0
  340. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  341. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  342. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  343. data/spec/ruby_specs +183 -0
  344. data/spec/spec_helper.rb +31 -0
  345. data/spec/support/guard_platform.rb +4 -0
  346. data/spec/support/match_helpers.rb +57 -0
  347. data/spec/support/mspec_rspec_adapter.rb +33 -0
  348. data/spec/support/rewriters_helper.rb +54 -0
  349. data/spec/support/source_map_helper.rb +190 -0
  350. data/stdlib/base64.rb +2 -2
  351. data/stdlib/bigdecimal.rb +15 -3
  352. data/stdlib/bigdecimal/bignumber.js.rb +1 -1
  353. data/stdlib/bigdecimal/util.rb +148 -0
  354. data/stdlib/delegate.rb +8 -0
  355. data/stdlib/nodejs/fileutils.rb +1 -1
  356. data/stdlib/nodejs/kernel.rb +0 -13
  357. data/stdlib/nodejs/stacktrace.rb +4 -179
  358. data/stdlib/ostruct.rb +5 -0
  359. data/stdlib/pp.rb +586 -19
  360. data/stdlib/prettyprint.rb +556 -0
  361. data/stdlib/rbconfig/sizeof.rb +2 -0
  362. data/stdlib/securerandom.rb +32 -0
  363. data/stdlib/set.rb +36 -0
  364. data/stdlib/strscan.rb +15 -0
  365. data/tasks/benchmarking.rake +1 -1
  366. data/tasks/releasing.rake +0 -3
  367. data/tasks/testing.rake +16 -11
  368. data/tasks/testing/mspec_special_calls.rb +1 -19
  369. data/test/nodejs/fixtures/cat.png +0 -0
  370. data/test/nodejs/fixtures/hello.rb +1 -0
  371. data/test/nodejs/fixtures/iso88591.txt +1 -0
  372. data/test/nodejs/fixtures/utf8.txt +1 -0
  373. data/test/nodejs/fixtures/win1258.txt +1 -0
  374. data/test/nodejs/test_dir.rb +39 -0
  375. data/test/nodejs/test_env.rb +62 -0
  376. data/test/nodejs/test_error.rb +29 -0
  377. data/test/nodejs/test_file.rb +206 -0
  378. data/test/nodejs/test_file_encoding.rb +20 -0
  379. data/test/nodejs/test_io.rb +18 -0
  380. data/test/nodejs/test_opal_builder.rb +12 -0
  381. data/test/nodejs/test_pathname.rb +16 -0
  382. data/test/opal/cat.png +0 -0
  383. data/test/opal/http_server.rb +52 -0
  384. data/test/opal/test_base64.rb +115 -0
  385. data/test/opal/test_keyword.rb +590 -0
  386. data/test/opal/test_matrix.rb +661 -0
  387. data/test/opal/test_openuri.rb +53 -0
  388. data/test/opal/unsupported_and_bugs.rb +39 -0
  389. data/yarn.lock +1114 -3
  390. metadata +889 -31
  391. data/lib/opal/nodes/runtime_helpers.rb +0 -51
  392. data/opal/corelib/random/MersenneTwister.js +0 -137
  393. data/opal/corelib/random/mersenne_twister.js.rb +0 -13
  394. data/stdlib/bigdecimal/kernel.rb +0 -5
@@ -6,7 +6,7 @@ module Base64
6
6
 
7
7
  // encoder
8
8
  // [https://gist.github.com/999166] by [https://github.com/nignag]
9
- encode = Opal.global.btoa || function (input) {
9
+ encode = function (input) {
10
10
  var str = String(input);
11
11
  /* jshint ignore:start */
12
12
  for (
@@ -31,7 +31,7 @@ module Base64
31
31
 
32
32
  // decoder
33
33
  // [https://gist.github.com/1020396] by [https://github.com/atk]
34
- decode = Opal.global.atob || function (input) {
34
+ decode = function (input) {
35
35
  var str = String(input).replace(/=+$/, '');
36
36
  if (str.length % 4 == 1) {
37
37
  #{raise ArgumentError, 'invalid base64 (failed: The string to be decoded is not correctly encoded.)'};
@@ -1,10 +1,22 @@
1
1
  class BigDecimal < Numeric; end
2
2
 
3
3
  require 'js'
4
- require 'bigdecimal/kernel'
5
- require 'bigdecimal/bignumber.js'
4
+ require 'bigdecimal/bignumber'
6
5
 
7
- class BigDecimal
6
+ module Kernel
7
+ def BigDecimal(initial, digits = 0)
8
+ bigdecimal = BigDecimal.allocate
9
+ bigdecimal.initialize(initial, digits)
10
+ bigdecimal
11
+ end
12
+ end
13
+
14
+ def BigDecimal.new(*args, **kwargs)
15
+ warn 'BigDecimal.new is deprecated; use BigDecimal() method instead.', uplevel: 1
16
+ BigDecimal(*args, **kwargs)
17
+ end
18
+
19
+ class BigDecimal < Numeric
8
20
  ROUND_MODE = 256
9
21
 
10
22
  # NOTE: the numeric values of the ROUND_* constants
@@ -1,4 +1,4 @@
1
- class BigDecimal
1
+ class BigDecimal < Numeric
2
2
  %x{
3
3
  var define = function (f) { Opal.const_set(self, 'BigNumber', f()); };
4
4
  define.amd = true;
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: false
2
+ #
3
+ #--
4
+ # bigdecimal/util extends various native classes to provide the #to_d method,
5
+ # and provides BigDecimal#to_d and BigDecimal#to_digits.
6
+ #++
7
+
8
+ require 'bigdecimal'
9
+
10
+ class Integer < Numeric
11
+ # call-seq:
12
+ # int.to_d -> bigdecimal
13
+ #
14
+ # Returns the value of +int+ as a BigDecimal.
15
+ #
16
+ # require 'bigdecimal'
17
+ # require 'bigdecimal/util'
18
+ #
19
+ # 42.to_d # => 0.42e2
20
+ #
21
+ # See also BigDecimal::new.
22
+ #
23
+ def to_d
24
+ BigDecimal(self)
25
+ end
26
+ end
27
+
28
+
29
+ class Float < Numeric
30
+ # call-seq:
31
+ # float.to_d -> bigdecimal
32
+ # float.to_d(precision) -> bigdecimal
33
+ #
34
+ # Returns the value of +float+ as a BigDecimal.
35
+ # The +precision+ parameter is used to determine the number of
36
+ # significant digits for the result (the default is Float::DIG).
37
+ #
38
+ # require 'bigdecimal'
39
+ # require 'bigdecimal/util'
40
+ #
41
+ # 0.5.to_d # => 0.5e0
42
+ # 1.234.to_d(2) # => 0.12e1
43
+ #
44
+ # See also BigDecimal::new.
45
+ #
46
+ def to_d(precision = Float::DIG)
47
+ BigDecimal(self, precision)
48
+ end
49
+ end
50
+
51
+
52
+ class String
53
+ # call-seq:
54
+ # str.to_d -> bigdecimal
55
+ #
56
+ # Returns the result of interpreting leading characters in +str+
57
+ # as a BigDecimal.
58
+ #
59
+ # require 'bigdecimal'
60
+ # require 'bigdecimal/util'
61
+ #
62
+ # "0.5".to_d # => 0.5e0
63
+ # "123.45e1".to_d # => 0.12345e4
64
+ # "45.67 degrees".to_d # => 0.4567e2
65
+ #
66
+ # See also BigDecimal::new.
67
+ #
68
+ def to_d
69
+ BigDecimal(`#{self}.replace("_", '').replace(/ .*$/,'')`)
70
+ end
71
+ end
72
+
73
+
74
+ class BigDecimal < Numeric
75
+ # call-seq:
76
+ # a.to_digits -> string
77
+ #
78
+ # Converts a BigDecimal to a String of the form "nnnnnn.mmm".
79
+ # This method is deprecated; use BigDecimal#to_s("F") instead.
80
+ #
81
+ # require 'bigdecimal/util'
82
+ #
83
+ # d = BigDecimal("3.14")
84
+ # d.to_digits # => "3.14"
85
+ #
86
+ def to_digits
87
+ if nan? || infinite? || zero?
88
+ to_s
89
+ else
90
+ i = to_i.to_s
91
+ _, f, _, z = frac.split
92
+ i + '.' + ('0' * -z) + f
93
+ end
94
+ end
95
+
96
+ # call-seq:
97
+ # a.to_d -> bigdecimal
98
+ #
99
+ # Returns self.
100
+ #
101
+ # require 'bigdecimal/util'
102
+ #
103
+ # d = BigDecimal("3.14")
104
+ # d.to_d # => 0.314e1
105
+ #
106
+ def to_d
107
+ self
108
+ end
109
+ end
110
+
111
+
112
+ class Rational < Numeric
113
+ # call-seq:
114
+ # rat.to_d(precision) -> bigdecimal
115
+ #
116
+ # Returns the value as a BigDecimal.
117
+ #
118
+ # The required +precision+ parameter is used to determine the number of
119
+ # significant digits for the result.
120
+ #
121
+ # require 'bigdecimal'
122
+ # require 'bigdecimal/util'
123
+ #
124
+ # Rational(22, 7).to_d(3) # => 0.314e1
125
+ #
126
+ # See also BigDecimal::new.
127
+ #
128
+ def to_d(precision)
129
+ BigDecimal(self, precision)
130
+ end
131
+ end
132
+
133
+
134
+ class NilClass
135
+ # call-seq:
136
+ # nil.to_d -> bigdecimal
137
+ #
138
+ # Returns nil represented as a BigDecimal.
139
+ #
140
+ # require 'bigdecimal'
141
+ # require 'bigdecimal/util'
142
+ #
143
+ # nil.to_d # => 0.0
144
+ #
145
+ def to_d
146
+ BigDecimal(0)
147
+ end
148
+ end
@@ -12,6 +12,14 @@ class Delegator < BasicObject
12
12
  super(m, *args, &block)
13
13
  end
14
14
  end
15
+
16
+ #
17
+ # Checks for a method provided by this the delegate object by forwarding the
18
+ # call through \_\_getobj\_\_.
19
+ #
20
+ def respond_to_missing?(m, include_private)
21
+ __getobj__.respond_to?(m, include_private)
22
+ end
15
23
  end
16
24
 
17
25
  class SimpleDelegator < Delegator
@@ -11,7 +11,7 @@ module FileUtils
11
11
 
12
12
  def cp(source, target)
13
13
  target = File.join(target, File.basename(source)) if File.directory? target
14
- `__fs__.writeFileSync(target, __fs__.readFileSync(source));`
14
+ `__fs__.writeFileSync(target, __fs__.readFileSync(source))`
15
15
  end
16
16
 
17
17
  def rm(path)
@@ -3,19 +3,6 @@
3
3
  module Kernel
4
4
  NODE_REQUIRE = `require`
5
5
 
6
- def caller(*args)
7
- %x{
8
- var stack;
9
- try {
10
- var err = Error("my error");
11
- throw err;
12
- } catch(e) {
13
- stack = e.stack;
14
- }
15
- return stack.$split("\n").slice(3);
16
- }
17
- end
18
-
19
6
  # @deprecated Please use `require('module')` instead
20
7
  def node_require(path)
21
8
  warn '[DEPRECATION] node_require is deprecated. Please use `require(\'module\')` instead.'
@@ -1,179 +1,4 @@
1
- # SOURCE: https://raw.githubusercontent.com/RReverser/stack-displayname/13732cedc506200ee8465edcbfce00a9e914853c/displayName.js
2
-
3
- # Copyright 2014 Ingvar Stepanyan
4
- #
5
- # Copyright 2006-2011, the V8 project authors. All rights reserved.
6
- # Redistribution and use in source and binary forms, with or without
7
- # modification, are permitted provided that the following conditions are
8
- # met:
9
- #
10
- # * Redistributions of source code must retain the above copyright
11
- # notice, this list of conditions and the following disclaimer.
12
- # * Redistributions in binary form must reproduce the above
13
- # copyright notice, this list of conditions and the following
14
- # disclaimer in the documentation and/or other materials provided
15
- # with the distribution.
16
- # * Neither the name of Google Inc. nor the names of its
17
- # contributors may be used to endorse or promote products derived
18
- # from this software without specific prior written permission.
19
- #
20
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
- # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23
- # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
- # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
- # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26
- # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27
- # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28
- # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
- # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
-
32
- %x{
33
- (function () {
34
-
35
- if (!Error.captureStackTrace) {
36
- return;
37
- }
38
-
39
- var ObjectToString = Object.prototype.toString;
40
-
41
- var NODE = ObjectToString.call(process) === "[object process]";
42
-
43
- // https://github.com/v8/v8/blob/cab94bbe3d532d85705950ed049a294050fcb4c9/src/messages.js#L1112-L1124 [converted to JS]
44
- function GetTypeName(receiver, requireConstructor) {
45
- if (receiver == null) return null;
46
- var constructor = receiver.constructor;
47
- if (!constructor) {
48
- return requireConstructor ? null : ObjectToString.call(receiver);
49
- }
50
- var constructorName = constructor.name;
51
- if (!constructorName) {
52
- return requireConstructor ? null : ObjectToString.call(receiver);
53
- }
54
- return constructorName;
55
- }
56
-
57
- // https://github.com/v8/v8/blob/cab94bbe3d532d85705950ed049a294050fcb4c9/src/messages.js#L917-L981 [converted & modified]
58
- function CallSiteToString() {
59
- var fileName;
60
- var fileLocation = "";
61
- if (this.isNative()) {
62
- fileLocation = "native";
63
- } else {
64
- fileName = this.getScriptNameOrSourceURL();
65
- if (!fileName && this.isEval()) {
66
- fileLocation = this.getEvalOrigin();
67
- fileLocation += ", "; // Expecting source position to follow.
68
- }
69
-
70
- if (fileName) {
71
- fileLocation += fileName;
72
- } else {
73
- // Source code does not originate from a file and is not native, but we
74
- // can still get the source position inside the source string, e.g. in
75
- // an eval string.
76
- fileLocation += "<anonymous>";
77
- }
78
- var lineNumber = this.getLineNumber();
79
- if (lineNumber !== null) {
80
- fileLocation += ":" + lineNumber;
81
- var columnNumber = this.getColumnNumber();
82
- if (columnNumber) {
83
- fileLocation += ":" + columnNumber;
84
- }
85
- }
86
- }
87
-
88
- var line = "";
89
- var func = this.getFunction();
90
- if (func) var customName = func.displayName;
91
- if (NODE && customName) {
92
- if (customName && func.$$owner) {
93
- var customNameOwner;
94
- customNameOwner = (func.$$owner.displayName || func.$$owner.$$name);
95
- customName = (func.$$owner.singleton_of ? '.' : '#') + customName;
96
- }
97
- customName = customNameOwner + customName;
98
- }
99
- var functionName = customName || this.getFunctionName();
100
- var addSuffix = true;
101
- var isConstructor = this.isConstructor();
102
- var isMethodCall = !(this.isToplevel() || isConstructor);
103
- if (isMethodCall) {
104
- var typeName = GetTypeName(this.receiver, true);
105
- var methodName = this.getMethodName();
106
- if (functionName) {
107
- if (!customName && typeName && functionName.indexOf(typeName) !== 0) {
108
- line += typeName + ".";
109
- }
110
- line += functionName;
111
- if (methodName && methodName !== functionName) {//} && functionName.indexOf("." + methodName) !== functionName.length - methodName.length - 1) {
112
- line += " [as " + methodName + "]";
113
- }
114
- } else {
115
- line += typeName + "." + (methodName || "<anonymous>");
116
- }
117
- } else if (isConstructor) {
118
- line += "new " + (functionName || "<anonymous>");
119
- } else if (functionName) {
120
- if (func.$$s) {
121
- if (func.$$s.displayName || func.$$s.$$name) {
122
- line += 'block in ' + (func.$$s.displayName || func.$$s.$$name) + ' [as ' + functionName + ']';
123
- } else if (func.$$s.$$class && func.$$s.$$class.$$name) {
124
- line += 'block in #<' + func.$$s.$$class.$$name + ' $$id: ' + Opal.id(func.$$s) + '> [as ' + functionName + ']';
125
- } else {
126
- line += functionName;
127
- }
128
- } else {
129
- line += functionName;
130
- }
131
- } else {
132
- line += fileLocation;
133
- addSuffix = false;
134
- }
135
- if (addSuffix) {
136
- line += " (" + fileLocation + ")";
137
- }
138
- return line;
139
- }
140
-
141
- var ErrorToString = Error.prototype.toString;
142
-
143
- // https://github.com/v8/v8/blob/cab94bbe3d532d85705950ed049a294050fcb4c9/src/messages.js#L1042-L1052 [converted]
144
- function FormatErrorString(error) {
145
- try {
146
- return ErrorToString.call(error);
147
- } catch (e) {
148
- try {
149
- return "<error: " + e + ">";
150
- } catch (ee) {
151
- return "<error>";
152
- }
153
- }
154
- }
155
-
156
- // https://github.com/v8/v8/blob/cab94bbe3d532d85705950ed049a294050fcb4c9/src/messages.js#L1091-L1108 [logic duplicated]
157
- Error.prepareStackTrace = function (error, frames) {
158
- var lines = [];
159
- lines.push(FormatErrorString(error));
160
- for (var i = 0; i < frames.length; i++) {
161
- var frame = frames[i];
162
- var line;
163
- try {
164
- line = CallSiteToString.call(frame);
165
- } catch (e) {
166
- try {
167
- line = "<error: " + e + ">";
168
- } catch (ee) {
169
- // Any code that reaches this point is seriously nasty!
170
- line = "<error>";
171
- }
172
- }
173
- lines.push(" at " + line);
174
- }
175
- return lines.join("\n");
176
- };
177
-
178
- })();
179
- }
1
+ warn <<-WARN, uplevel: 1
2
+ Requiring nodejs/stacktrace has been deprecated, if you use the default
3
+ Node.js runner stack-traces will have source-map support out of the box.
4
+ WARN
@@ -31,6 +31,11 @@ class OpenStruct
31
31
  end
32
32
  end
33
33
 
34
+ def respond_to_missing?(mid, include_private = false) # :nodoc:
35
+ mname = mid.to_s.chomp('=').to_sym
36
+ @table&.key?(mname) || super
37
+ end
38
+
34
39
  def each_pair
35
40
  return enum_for :each_pair unless block_given?
36
41
 
@@ -1,33 +1,600 @@
1
- module Kernel
2
- def pretty_inspect
3
- inspect
1
+ # frozen_string_literal: true
2
+
3
+ # Opal: load stdlib/thread.rb
4
+ require 'thread'
5
+ require 'stringio'
6
+ require 'prettyprint'
7
+
8
+ ##
9
+ # A pretty-printer for Ruby objects.
10
+ #
11
+ ##
12
+ # == What PP Does
13
+ #
14
+ # Standard output by #p returns this:
15
+ # #<PP:0x81fedf0 @genspace=#<Proc:0x81feda0>, @group_queue=#<PrettyPrint::GroupQueue:0x81fed3c @queue=[[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], []]>, @buffer=[], @newline="\n", @group_stack=[#<PrettyPrint::Group:0x81fed78 @breakables=[], @depth=0, @break=false>], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#<IO:0x8114ee4>>
16
+ #
17
+ # Pretty-printed output returns this:
18
+ # #<PP:0x81fedf0
19
+ # @buffer=[],
20
+ # @buffer_width=0,
21
+ # @genspace=#<Proc:0x81feda0>,
22
+ # @group_queue=
23
+ # #<PrettyPrint::GroupQueue:0x81fed3c
24
+ # @queue=
25
+ # [[#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
26
+ # []]>,
27
+ # @group_stack=
28
+ # [#<PrettyPrint::Group:0x81fed78 @break=false, @breakables=[], @depth=0>],
29
+ # @indent=0,
30
+ # @maxwidth=79,
31
+ # @newline="\n",
32
+ # @output=#<IO:0x8114ee4>,
33
+ # @output_width=2>
34
+ #
35
+ ##
36
+ # == Usage
37
+ #
38
+ # pp(obj) #=> obj
39
+ # pp obj #=> obj
40
+ # pp(obj1, obj2, ...) #=> [obj1, obj2, ...]
41
+ # pp() #=> nil
42
+ #
43
+ # Output <tt>obj(s)</tt> to <tt>$></tt> in pretty printed format.
44
+ #
45
+ # It returns <tt>obj(s)</tt>.
46
+ #
47
+ ##
48
+ # == Output Customization
49
+ #
50
+ # To define a customized pretty printing function for your classes,
51
+ # redefine method <code>#pretty_print(pp)</code> in the class.
52
+ #
53
+ # <code>#pretty_print</code> takes the +pp+ argument, which is an instance of the PP class.
54
+ # The method uses #text, #breakable, #nest, #group and #pp to print the
55
+ # object.
56
+ #
57
+ ##
58
+ # == Pretty-Print JSON
59
+ #
60
+ # To pretty-print JSON refer to JSON#pretty_generate.
61
+ #
62
+ ##
63
+ # == Author
64
+ # Tanaka Akira <akr@fsij.org>
65
+
66
+ class PP < PrettyPrint
67
+ # Outputs +obj+ to +out+ in pretty printed format of
68
+ # +width+ columns in width.
69
+ #
70
+ # If +out+ is omitted, <code>$></code> is assumed.
71
+ # If +width+ is omitted, 79 is assumed.
72
+ #
73
+ # PP.pp returns +out+.
74
+ def PP.pp(obj, out=$stdout, width=79) # Opal: replace $> with $stdout
75
+ q = PP.new(out, width)
76
+ q.guard_inspect_key {q.pp obj}
77
+ q.flush
78
+ #$pp = q
79
+ out << "\n"
4
80
  end
5
81
 
6
- def pp(*objs)
7
- objs.each do |obj|
8
- PP.pp(obj)
82
+ # Outputs +obj+ to +out+ like PP.pp but with no indent and
83
+ # newline.
84
+ #
85
+ # PP.singleline_pp returns +out+.
86
+ def PP.singleline_pp(obj, out=$stdout) # Opal: replace $> with $stdout
87
+ q = SingleLine.new(out)
88
+ q.guard_inspect_key {q.pp obj}
89
+ q.flush
90
+ out
91
+ end
92
+
93
+ # :stopdoc:
94
+ def PP.mcall(obj, mod, meth, *args, &block)
95
+ mod.instance_method(meth).bind_call(obj, *args, &block)
96
+ end
97
+ # :startdoc:
98
+
99
+ @sharing_detection = false
100
+ class << self
101
+ # Returns the sharing detection flag as a boolean value.
102
+ # It is false by default.
103
+ attr_accessor :sharing_detection
104
+ end
105
+
106
+ module PPMethods
107
+
108
+ # Yields to a block
109
+ # and preserves the previous set of objects being printed.
110
+ def guard_inspect_key
111
+ if Thread.current[:__recursive_key__] == nil
112
+ Thread.current[:__recursive_key__] = {}.compare_by_identity
113
+ end
114
+
115
+ if Thread.current[:__recursive_key__][:inspect] == nil
116
+ Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
117
+ end
118
+
119
+ save = Thread.current[:__recursive_key__][:inspect]
120
+
121
+ begin
122
+ Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity
123
+ yield
124
+ ensure
125
+ Thread.current[:__recursive_key__][:inspect] = save
126
+ end
127
+ end
128
+
129
+ # Check whether the object_id +id+ is in the current buffer of objects
130
+ # to be pretty printed. Used to break cycles in chains of objects to be
131
+ # pretty printed.
132
+ def check_inspect_key(id)
133
+ Thread.current[:__recursive_key__] &&
134
+ Thread.current[:__recursive_key__][:inspect] &&
135
+ Thread.current[:__recursive_key__][:inspect].include?(id)
136
+ end
137
+
138
+ # Adds the object_id +id+ to the set of objects being pretty printed, so
139
+ # as to not repeat objects.
140
+ def push_inspect_key(id)
141
+ Thread.current[:__recursive_key__][:inspect][id] = true
142
+ end
143
+
144
+ # Removes an object from the set of objects being pretty printed.
145
+ def pop_inspect_key(id)
146
+ Thread.current[:__recursive_key__][:inspect].delete id
147
+ end
148
+
149
+ # Adds +obj+ to the pretty printing buffer
150
+ # using Object#pretty_print or Object#pretty_print_cycle.
151
+ #
152
+ # Object#pretty_print_cycle is used when +obj+ is already
153
+ # printed, a.k.a the object reference chain has a cycle.
154
+ def pp(obj)
155
+ # If obj is a Delegator then use the object being delegated to for cycle
156
+ # detection
157
+ obj = obj.__getobj__ if defined?(::Delegator) and obj.is_a?(::Delegator)
158
+
159
+ if check_inspect_key(obj)
160
+ group {obj.pretty_print_cycle self}
161
+ return
162
+ end
163
+
164
+ begin
165
+ push_inspect_key(obj)
166
+ group {obj.pretty_print self}
167
+ ensure
168
+ pop_inspect_key(obj) unless PP.sharing_detection
169
+ end
170
+ end
171
+
172
+ # A convenience method which is same as follows:
173
+ #
174
+ # group(1, '#<' + obj.class.name, '>') { ... }
175
+ def object_group(obj, &block) # :yield:
176
+ group(1, '#<' + obj.class.name, '>', &block)
177
+ end
178
+
179
+ # A convenience method, like object_group, but also reformats the Object's
180
+ # object_id.
181
+ def object_address_group(obj, &block)
182
+ str = Kernel.instance_method(:to_s).bind_call(obj)
183
+ str.chomp!('>')
184
+ group(1, str, '>', &block)
185
+ end
186
+
187
+ # A convenience method which is same as follows:
188
+ #
189
+ # text ','
190
+ # breakable
191
+ def comma_breakable
192
+ text ','
193
+ breakable
194
+ end
195
+
196
+ # Adds a separated list.
197
+ # The list is separated by comma with breakable space, by default.
198
+ #
199
+ # #seplist iterates the +list+ using +iter_method+.
200
+ # It yields each object to the block given for #seplist.
201
+ # The procedure +separator_proc+ is called between each yields.
202
+ #
203
+ # If the iteration is zero times, +separator_proc+ is not called at all.
204
+ #
205
+ # If +separator_proc+ is nil or not given,
206
+ # +lambda { comma_breakable }+ is used.
207
+ # If +iter_method+ is not given, :each is used.
208
+ #
209
+ # For example, following 3 code fragments has similar effect.
210
+ #
211
+ # q.seplist([1,2,3]) {|v| xxx v }
212
+ #
213
+ # q.seplist([1,2,3], lambda { q.comma_breakable }, :each) {|v| xxx v }
214
+ #
215
+ # xxx 1
216
+ # q.comma_breakable
217
+ # xxx 2
218
+ # q.comma_breakable
219
+ # xxx 3
220
+ def seplist(list, sep=nil, iter_method=:each) # :yield: element
221
+ sep ||= lambda { comma_breakable }
222
+ first = true
223
+ list.__send__(iter_method) {|*v|
224
+ if first
225
+ first = false
226
+ else
227
+ sep.call
228
+ end
229
+ yield(*v)
230
+ }
231
+ end
232
+
233
+ # A present standard failsafe for pretty printing any given Object
234
+ def pp_object(obj)
235
+ object_address_group(obj) {
236
+ seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v|
237
+ breakable
238
+ v = v.to_s if Symbol === v
239
+ text v
240
+ text '='
241
+ group(1) {
242
+ breakable ''
243
+ pp(obj.instance_eval(v))
244
+ }
245
+ }
246
+ }
247
+ end
248
+
249
+ # A pretty print for a Hash
250
+ def pp_hash(obj)
251
+ group(1, '{', '}') {
252
+ seplist(obj, nil, :each_pair) {|k, v|
253
+ group {
254
+ pp k
255
+ text '=>'
256
+ group(1) {
257
+ breakable ''
258
+ pp v
259
+ }
260
+ }
261
+ }
262
+ }
263
+ end
264
+ end
265
+
266
+ include PPMethods
267
+
268
+ class SingleLine < PrettyPrint::SingleLine # :nodoc:
269
+ include PPMethods
270
+ end
271
+
272
+ module ObjectMixin # :nodoc:
273
+ # 1. specific pretty_print
274
+ # 2. specific inspect
275
+ # 3. generic pretty_print
276
+
277
+ # A default pretty printing method for general objects.
278
+ # It calls #pretty_print_instance_variables to list instance variables.
279
+ #
280
+ # If +self+ has a customized (redefined) #inspect method,
281
+ # the result of self.inspect is used but it obviously has no
282
+ # line break hints.
283
+ #
284
+ # This module provides predefined #pretty_print methods for some of
285
+ # the most commonly used built-in classes for convenience.
286
+ def pretty_print(q)
287
+ umethod_method = Object.instance_method(:method)
288
+ begin
289
+ inspect_method = umethod_method.bind_call(self, :inspect)
290
+ rescue NameError
291
+ end
292
+ if inspect_method && inspect_method.owner != Kernel
293
+ q.text self.inspect
294
+ elsif !inspect_method && self.respond_to?(:inspect)
295
+ q.text self.inspect
296
+ else
297
+ q.pp_object(self)
298
+ end
299
+ end
300
+
301
+ # A default pretty printing method for general objects that are
302
+ # detected as part of a cycle.
303
+ def pretty_print_cycle(q)
304
+ q.object_address_group(self) {
305
+ q.breakable
306
+ q.text '...'
307
+ }
308
+ end
309
+
310
+ # Returns a sorted array of instance variable names.
311
+ #
312
+ # This method should return an array of names of instance variables as symbols or strings as:
313
+ # +[:@a, :@b]+.
314
+ def pretty_print_instance_variables
315
+ instance_variables.sort
316
+ end
317
+
318
+ # Is #inspect implementation using #pretty_print.
319
+ # If you implement #pretty_print, it can be used as follows.
320
+ #
321
+ # alias inspect pretty_print_inspect
322
+ #
323
+ # However, doing this requires that every class that #inspect is called on
324
+ # implement #pretty_print, or a RuntimeError will be raised.
325
+ def pretty_print_inspect
326
+ if Object.instance_method(:method).bind_call(self, :pretty_print).owner == PP::ObjectMixin
327
+ raise "pretty_print is not overridden for #{self.class}"
328
+ end
329
+ PP.singleline_pp(self, ''.dup)
9
330
  end
10
- objs.size <= 1 ? objs.first : objs
11
331
  end
12
- module_function :pp
13
332
  end
14
333
 
15
- class PP
16
- class << self
17
- if `(typeof(console) === "undefined" || typeof(console.log) === "undefined")`
18
- def pp(obj, out = $stdout, width = 79)
19
- p(*args)
334
+ class Array # :nodoc:
335
+ def pretty_print(q) # :nodoc:
336
+ q.group(1, '[', ']') {
337
+ q.seplist(self) {|v|
338
+ q.pp v
339
+ }
340
+ }
341
+ end
342
+
343
+ def pretty_print_cycle(q) # :nodoc:
344
+ q.text(empty? ? '[]' : '[...]')
345
+ end
346
+ end
347
+
348
+ class Hash # :nodoc:
349
+ def pretty_print(q) # :nodoc:
350
+ q.pp_hash self
351
+ end
352
+
353
+ def pretty_print_cycle(q) # :nodoc:
354
+ q.text(empty? ? '{}' : '{...}')
355
+ end
356
+ end
357
+
358
+ class << ENV # :nodoc:
359
+ def pretty_print(q) # :nodoc:
360
+ h = {}
361
+ ENV.keys.sort.each {|k|
362
+ h[k] = ENV[k]
363
+ }
364
+ q.pp_hash h
365
+ end
366
+ end
367
+
368
+ class Struct # :nodoc:
369
+ def pretty_print(q) # :nodoc:
370
+ q.group(1, sprintf("#<struct %s", PP.mcall(self, Kernel, :class).name), '>') {
371
+ q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member|
372
+ q.breakable
373
+ q.text member.to_s
374
+ q.text '='
375
+ q.group(1) {
376
+ q.breakable ''
377
+ q.pp self[member]
378
+ }
379
+ }
380
+ }
381
+ end
382
+
383
+ def pretty_print_cycle(q) # :nodoc:
384
+ q.text sprintf("#<struct %s:...>", PP.mcall(self, Kernel, :class).name)
385
+ end
386
+ end
387
+
388
+ class Range # :nodoc:
389
+ def pretty_print(q) # :nodoc:
390
+ q.pp self.begin
391
+ q.breakable ''
392
+ q.text(self.exclude_end? ? '...' : '..')
393
+ q.breakable ''
394
+ q.pp self.end if self.end
395
+ end
396
+ end
397
+
398
+ class String # :nodoc:
399
+ def pretty_print(q) # :nodoc:
400
+ lines = self.lines
401
+ if lines.size > 1
402
+ q.group(0, '', '') do
403
+ q.seplist(lines, lambda { q.text ' +'; q.breakable }) do |v|
404
+ q.pp v
405
+ end
20
406
  end
21
407
  else
22
- def pp(obj, out = $stdout, width = 79)
23
- if String === out
24
- out + obj.inspect + "\n"
408
+ q.text inspect
409
+ end
410
+ end
411
+ end
412
+
413
+ # Opal: does not have File::Stat
414
+ #class File < IO # :nodoc:
415
+ # class Stat # :nodoc:
416
+ # def pretty_print(q) # :nodoc:
417
+ # require 'etc.so'
418
+ # q.object_group(self) {
419
+ # q.breakable
420
+ # q.text sprintf("dev=0x%x", self.dev); q.comma_breakable
421
+ # q.text "ino="; q.pp self.ino; q.comma_breakable
422
+ # q.group {
423
+ # m = self.mode
424
+ # q.text sprintf("mode=0%o", m)
425
+ # q.breakable
426
+ # q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)",
427
+ # self.ftype,
428
+ # (m & 0400 == 0 ? ?- : ?r),
429
+ # (m & 0200 == 0 ? ?- : ?w),
430
+ # (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) :
431
+ # (m & 04000 == 0 ? ?x : ?s)),
432
+ # (m & 0040 == 0 ? ?- : ?r),
433
+ # (m & 0020 == 0 ? ?- : ?w),
434
+ # (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) :
435
+ # (m & 02000 == 0 ? ?x : ?s)),
436
+ # (m & 0004 == 0 ? ?- : ?r),
437
+ # (m & 0002 == 0 ? ?- : ?w),
438
+ # (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) :
439
+ # (m & 01000 == 0 ? ?x : ?t)))
440
+ # }
441
+ # q.comma_breakable
442
+ # q.text "nlink="; q.pp self.nlink; q.comma_breakable
443
+ # q.group {
444
+ # q.text "uid="; q.pp self.uid
445
+ # begin
446
+ # pw = Etc.getpwuid(self.uid)
447
+ # rescue ArgumentError
448
+ # end
449
+ # if pw
450
+ # q.breakable; q.text "(#{pw.name})"
451
+ # end
452
+ # }
453
+ # q.comma_breakable
454
+ # q.group {
455
+ # q.text "gid="; q.pp self.gid
456
+ # begin
457
+ # gr = Etc.getgrgid(self.gid)
458
+ # rescue ArgumentError
459
+ # end
460
+ # if gr
461
+ # q.breakable; q.text "(#{gr.name})"
462
+ # end
463
+ # }
464
+ # q.comma_breakable
465
+ # q.group {
466
+ # q.text sprintf("rdev=0x%x", self.rdev)
467
+ # if self.rdev_major && self.rdev_minor
468
+ # q.breakable
469
+ # q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor)
470
+ # end
471
+ # }
472
+ # q.comma_breakable
473
+ # q.text "size="; q.pp self.size; q.comma_breakable
474
+ # q.text "blksize="; q.pp self.blksize; q.comma_breakable
475
+ # q.text "blocks="; q.pp self.blocks; q.comma_breakable
476
+ # q.group {
477
+ # t = self.atime
478
+ # q.text "atime="; q.pp t
479
+ # q.breakable; q.text "(#{t.tv_sec})"
480
+ # }
481
+ # q.comma_breakable
482
+ # q.group {
483
+ # t = self.mtime
484
+ # q.text "mtime="; q.pp t
485
+ # q.breakable; q.text "(#{t.tv_sec})"
486
+ # }
487
+ # q.comma_breakable
488
+ # q.group {
489
+ # t = self.ctime
490
+ # q.text "ctime="; q.pp t
491
+ # q.breakable; q.text "(#{t.tv_sec})"
492
+ # }
493
+ # }
494
+ # end
495
+ # end
496
+ #end
497
+
498
+ class MatchData # :nodoc:
499
+ def pretty_print(q) # :nodoc:
500
+ nc = []
501
+ self.regexp.named_captures.each {|name, indexes|
502
+ indexes.each {|i| nc[i] = name }
503
+ }
504
+ q.object_group(self) {
505
+ q.breakable
506
+ q.seplist(0...self.size, lambda { q.breakable }) {|i|
507
+ if i == 0
508
+ q.pp self[i]
25
509
  else
26
- out << obj.inspect + "\n"
510
+ if nc[i]
511
+ q.text nc[i]
512
+ else
513
+ q.pp i
514
+ end
515
+ q.text ':'
516
+ q.pp self[i]
27
517
  end
28
- end
518
+ }
519
+ }
520
+ end
521
+ end
522
+
523
+ # Opal: does not have RubyVM
524
+ #class RubyVM::AbstractSyntaxTree::Node
525
+ # def pretty_print_children(q, names = [])
526
+ # children.zip(names) do |c, n|
527
+ # if n
528
+ # q.breakable
529
+ # q.text "#{n}:"
530
+ # end
531
+ # q.group(2) do
532
+ # q.breakable
533
+ # q.pp c
534
+ # end
535
+ # end
536
+ # end
537
+ #
538
+ # def pretty_print(q)
539
+ # q.group(1, "(#{type}@#{first_lineno}:#{first_column}-#{last_lineno}:#{last_column}", ")") {
540
+ # case type
541
+ # when :SCOPE
542
+ # pretty_print_children(q, %w"tbl args body")
543
+ # when :ARGS
544
+ # pretty_print_children(q, %w[pre_num pre_init opt first_post post_num post_init rest kw kwrest block])
545
+ # when :DEFN
546
+ # pretty_print_children(q, %w[mid body])
547
+ # when :ARYPTN
548
+ # pretty_print_children(q, %w[const pre rest post])
549
+ # when :HSHPTN
550
+ # pretty_print_children(q, %w[const kw kwrest])
551
+ # else
552
+ # pretty_print_children(q)
553
+ # end
554
+ # }
555
+ # end
556
+ #end
557
+
558
+ class Object < BasicObject # :nodoc:
559
+ include PP::ObjectMixin
560
+ end
561
+
562
+ [Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c|
563
+ c.class_eval {
564
+ def pretty_print_cycle(q)
565
+ q.text inspect
29
566
  end
567
+ }
568
+ }
30
569
 
31
- alias singleline_pp pp
570
+ [Numeric, FalseClass, TrueClass, Module].each {|c|
571
+ c.class_eval {
572
+ def pretty_print(q)
573
+ q.text inspect
574
+ end
575
+ }
576
+ }
577
+
578
+ module Kernel
579
+ # Returns a pretty printed object as a string.
580
+ #
581
+ # In order to use this method you must first require the PP module:
582
+ #
583
+ # require 'pp'
584
+ #
585
+ # See the PP module for more information.
586
+ def pretty_inspect
587
+ PP.pp(self, StringIO.new).string
32
588
  end
589
+
590
+ # prints arguments in pretty form.
591
+ #
592
+ # pp returns argument(s).
593
+ def pp(*objs)
594
+ objs.each {|obj|
595
+ PP.pp(obj)
596
+ }
597
+ objs.size <= 1 ? objs.first : objs
598
+ end
599
+ module_function :pp
33
600
  end