opal 0.10.6 → 0.11.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (450) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +19 -0
  3. data/.gitmodules +1 -1
  4. data/.jshintrc +1 -2
  5. data/.travis.yml +26 -18
  6. data/CHANGELOG.md +89 -23
  7. data/{CODE_OF_CONDUCT.md → CONDUCT.md} +0 -0
  8. data/Gemfile +19 -21
  9. data/HACKING.md +2 -0
  10. data/README.md +7 -6
  11. data/Rakefile +1 -1
  12. data/appveyor.yml +21 -4
  13. data/benchmark-ips/bm_case.rb +33 -0
  14. data/benchmark-ips/bm_constants_lookup.rb +13 -0
  15. data/benchmark-ips/bm_is_number.rb +29 -0
  16. data/benchmark-ips/bm_symbol_to_proc.rb +19 -0
  17. data/benchmark/bm_constant_lookup_big.rb +799 -0
  18. data/benchmark/bm_constant_lookup_small.rb +59 -0
  19. data/benchmark/bm_module_definition_big.rb +400 -0
  20. data/benchmark/bm_module_definition_small.rb +30 -0
  21. data/bin/opal-repl +23 -1
  22. data/docs/compiled_ruby.md +16 -14
  23. data/docs/faq.md +3 -3
  24. data/docs/rspec.md +2 -1
  25. data/docs/unsupported_features.md +6 -4
  26. data/examples/rack/Gemfile +1 -0
  27. data/examples/rack/app/application.rb +14 -3
  28. data/examples/rack/app/user.rb +2 -0
  29. data/examples/rack/config.ru +1 -1
  30. data/examples/rack/index.html.erb +1 -0
  31. data/lib/opal.rb +6 -1
  32. data/lib/opal/ast/builder.rb +17 -0
  33. data/lib/opal/ast/node.rb +30 -0
  34. data/lib/opal/builder.rb +14 -3
  35. data/lib/opal/builder_processors.rb +1 -0
  36. data/lib/opal/cli.rb +45 -59
  37. data/lib/opal/cli_options.rb +11 -7
  38. data/lib/opal/cli_runners.rb +1 -0
  39. data/lib/opal/cli_runners/applescript.rb +3 -3
  40. data/lib/opal/cli_runners/nashorn.rb +1 -0
  41. data/lib/opal/cli_runners/nodejs.rb +4 -1
  42. data/lib/opal/cli_runners/phantom.js +1 -2
  43. data/lib/opal/cli_runners/phantomjs.rb +3 -2
  44. data/lib/opal/cli_runners/server.rb +1 -0
  45. data/lib/opal/compiler.rb +145 -94
  46. data/lib/opal/config.rb +1 -0
  47. data/lib/opal/deprecations.rb +18 -0
  48. data/lib/opal/erb.rb +1 -0
  49. data/lib/opal/errors.rb +1 -0
  50. data/lib/opal/fragment.rb +1 -0
  51. data/lib/opal/hike_path_finder.rb +1 -0
  52. data/lib/opal/nodes.rb +3 -0
  53. data/lib/opal/nodes/arglist.rb +2 -1
  54. data/lib/opal/nodes/args/initialize_kwargs.rb +1 -0
  55. data/lib/opal/nodes/args/kwarg.rb +7 -7
  56. data/lib/opal/nodes/args/kwoptarg.rb +6 -7
  57. data/lib/opal/nodes/args/kwrestarg.rb +5 -5
  58. data/lib/opal/nodes/args/mlhsarg.rb +3 -2
  59. data/lib/opal/nodes/args/normarg.rb +6 -7
  60. data/lib/opal/nodes/args/optarg.rb +5 -7
  61. data/lib/opal/nodes/args/post_args.rb +6 -5
  62. data/lib/opal/nodes/args/post_kwargs.rb +1 -0
  63. data/lib/opal/nodes/args/restarg.rb +7 -7
  64. data/lib/opal/nodes/array.rb +1 -0
  65. data/lib/opal/nodes/base.rb +24 -3
  66. data/lib/opal/nodes/call.rb +167 -155
  67. data/lib/opal/nodes/call_special.rb +31 -217
  68. data/lib/opal/nodes/case.rb +36 -22
  69. data/lib/opal/nodes/class.rb +4 -3
  70. data/lib/opal/nodes/constants.rb +28 -48
  71. data/lib/opal/nodes/csend.rb +25 -0
  72. data/lib/opal/nodes/def.rb +49 -16
  73. data/lib/opal/nodes/defined.rb +170 -60
  74. data/lib/opal/nodes/definitions.rb +40 -133
  75. data/lib/opal/nodes/defs.rb +29 -0
  76. data/lib/opal/nodes/for.rb +52 -25
  77. data/lib/opal/nodes/hash.rb +12 -35
  78. data/lib/opal/nodes/helpers.rb +27 -54
  79. data/lib/opal/nodes/if.rb +21 -32
  80. data/lib/opal/nodes/inline_args.rb +12 -13
  81. data/lib/opal/nodes/iter.rb +61 -36
  82. data/lib/opal/nodes/literal.rb +189 -116
  83. data/lib/opal/nodes/logic.rb +20 -25
  84. data/lib/opal/nodes/masgn.rb +20 -18
  85. data/lib/opal/nodes/module.rb +10 -11
  86. data/lib/opal/nodes/node_with_args.rb +14 -17
  87. data/lib/opal/nodes/rescue.rb +37 -70
  88. data/lib/opal/nodes/runtime_helpers.rb +8 -3
  89. data/lib/opal/nodes/scope.rb +9 -5
  90. data/lib/opal/nodes/singleton_class.rb +4 -3
  91. data/lib/opal/nodes/super.rb +115 -87
  92. data/lib/opal/nodes/top.rb +7 -2
  93. data/lib/opal/nodes/variables.rb +46 -35
  94. data/lib/opal/nodes/while.rb +11 -1
  95. data/lib/opal/nodes/yield.rb +1 -17
  96. data/lib/opal/parser.rb +28 -770
  97. data/lib/opal/path_reader.rb +5 -1
  98. data/lib/opal/paths.rb +10 -4
  99. data/lib/opal/regexp_anchors.rb +1 -0
  100. data/lib/opal/rewriter.rb +60 -0
  101. data/lib/opal/rewriters/base.rb +60 -0
  102. data/lib/opal/rewriters/binary_operator_assignment.rb +144 -0
  103. data/lib/opal/rewriters/block_to_iter.rb +17 -0
  104. data/lib/opal/rewriters/break_finder.rb +34 -0
  105. data/lib/opal/rewriters/dot_js_syntax.rb +60 -0
  106. data/lib/opal/rewriters/explicit_writer_return.rb +58 -0
  107. data/lib/opal/rewriters/js_reserved_words.rb +111 -0
  108. data/lib/opal/rewriters/logical_operator_assignment.rb +155 -0
  109. data/lib/opal/rewriters/opal_engine_check.rb +42 -0
  110. data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +67 -0
  111. data/lib/opal/server.rb +4 -0
  112. data/lib/opal/simple_server.rb +100 -0
  113. data/lib/opal/source_map.rb +1 -1
  114. data/lib/opal/util.rb +5 -5
  115. data/lib/opal/version.rb +2 -1
  116. data/lib/tilt/opal.rb +1 -0
  117. data/opal.gemspec +8 -7
  118. data/opal/README.md +1 -1
  119. data/opal/corelib/array.rb +137 -83
  120. data/opal/corelib/basic_object.rb +6 -6
  121. data/opal/corelib/class.rb +14 -11
  122. data/opal/corelib/complex.rb +5 -1
  123. data/opal/corelib/constants.rb +3 -3
  124. data/opal/corelib/enumerable.rb +129 -11
  125. data/opal/corelib/error.rb +35 -17
  126. data/opal/corelib/file.rb +65 -170
  127. data/opal/corelib/hash.rb +128 -13
  128. data/opal/corelib/helpers.rb +12 -15
  129. data/opal/corelib/io.rb +1 -0
  130. data/opal/corelib/kernel.rb +40 -21
  131. data/opal/corelib/marshal/read_buffer.rb +1 -1
  132. data/opal/corelib/method.rb +33 -13
  133. data/opal/corelib/module.rb +133 -81
  134. data/opal/corelib/number.rb +141 -25
  135. data/opal/corelib/numeric.rb +0 -8
  136. data/opal/corelib/process.rb +44 -4
  137. data/opal/corelib/random.rb +117 -0
  138. data/opal/corelib/random/seedrandom.js.rb +15 -0
  139. data/opal/corelib/range.rb +133 -10
  140. data/opal/corelib/regexp.rb +37 -9
  141. data/opal/corelib/runtime.js +601 -390
  142. data/opal/corelib/string.rb +39 -8
  143. data/opal/corelib/string/encoding.rb +51 -7
  144. data/opal/corelib/struct.rb +20 -0
  145. data/opal/corelib/time.rb +3 -3
  146. data/opal/corelib/variables.rb +1 -1
  147. data/opal/opal.rb +1 -0
  148. data/spec/filters/bugs/array.rb +5 -1
  149. data/spec/filters/bugs/basicobject.rb +2 -5
  150. data/spec/filters/bugs/bigdecimal.rb +8 -22
  151. data/spec/filters/bugs/class.rb +2 -1
  152. data/spec/filters/bugs/comparable.rb +5 -0
  153. data/spec/filters/bugs/date.rb +3 -3
  154. data/spec/filters/bugs/enumerable.rb +4 -11
  155. data/spec/filters/bugs/enumerator.rb +2 -4
  156. data/spec/filters/bugs/exception.rb +16 -2
  157. data/spec/filters/bugs/file.rb +8 -0
  158. data/spec/filters/bugs/float.rb +7 -1
  159. data/spec/filters/bugs/hash.rb +6 -2
  160. data/spec/filters/bugs/integer.rb +2 -0
  161. data/spec/filters/bugs/io.rb +8 -0
  162. data/spec/filters/bugs/kernel.rb +9 -138
  163. data/spec/filters/bugs/language.rb +89 -174
  164. data/spec/filters/bugs/marshal.rb +33 -35
  165. data/spec/filters/bugs/method.rb +0 -24
  166. data/spec/filters/bugs/module.rb +19 -55
  167. data/spec/filters/bugs/numeric.rb +0 -119
  168. data/spec/filters/bugs/pathname.rb +2 -0
  169. data/spec/filters/bugs/proc.rb +5 -4
  170. data/spec/filters/bugs/random.rb +7 -0
  171. data/spec/filters/bugs/range.rb +12 -120
  172. data/spec/filters/bugs/rational.rb +1 -1
  173. data/spec/filters/bugs/regexp.rb +2 -40
  174. data/spec/filters/bugs/set.rb +0 -1
  175. data/spec/filters/bugs/string.rb +5 -8
  176. data/spec/filters/bugs/stringscanner.rb +11 -19
  177. data/spec/filters/bugs/time.rb +7 -1
  178. data/spec/filters/bugs/unboundmethod.rb +1 -11
  179. data/spec/filters/unsupported/array.rb +5 -1
  180. data/spec/filters/unsupported/basicobject.rb +1 -1
  181. data/spec/filters/unsupported/bignum.rb +4 -1
  182. data/spec/filters/unsupported/class.rb +1 -1
  183. data/spec/filters/unsupported/delegator.rb +1 -1
  184. data/spec/filters/unsupported/enumerable.rb +1 -1
  185. data/spec/filters/unsupported/enumerator.rb +1 -1
  186. data/spec/filters/unsupported/file.rb +4 -0
  187. data/spec/filters/unsupported/fixnum.rb +1 -1
  188. data/spec/filters/unsupported/float.rb +4 -1
  189. data/spec/filters/unsupported/freeze.rb +27 -5
  190. data/spec/filters/unsupported/hash.rb +7 -15
  191. data/spec/filters/unsupported/integer.rb +1 -1
  192. data/spec/filters/unsupported/kernel.rb +2 -1
  193. data/spec/filters/unsupported/language.rb +6 -1
  194. data/spec/filters/unsupported/marshal.rb +1 -1
  195. data/spec/filters/unsupported/matchdata.rb +4 -1
  196. data/spec/filters/unsupported/math.rb +1 -1
  197. data/spec/filters/unsupported/pathname.rb +1 -1
  198. data/spec/filters/unsupported/privacy.rb +141 -9
  199. data/spec/filters/unsupported/proc.rb +1 -1
  200. data/spec/filters/unsupported/random.rb +4 -0
  201. data/spec/filters/unsupported/range.rb +7 -0
  202. data/spec/filters/unsupported/regexp.rb +25 -15
  203. data/spec/filters/unsupported/set.rb +1 -1
  204. data/spec/filters/unsupported/singleton.rb +1 -1
  205. data/spec/filters/unsupported/string.rb +110 -101
  206. data/spec/filters/unsupported/struct.rb +1 -1
  207. data/spec/filters/unsupported/symbol.rb +2 -1
  208. data/spec/filters/unsupported/taint.rb +22 -7
  209. data/spec/filters/unsupported/thread.rb +1 -1
  210. data/spec/filters/unsupported/time.rb +1 -1
  211. data/spec/lib/builder_spec.rb +17 -0
  212. data/spec/lib/cli_spec.rb +37 -8
  213. data/spec/lib/compiler/call_spec.rb +98 -66
  214. data/spec/lib/compiler_spec.rb +39 -30
  215. data/spec/lib/dependency_resolver_spec.rb +2 -2
  216. data/spec/lib/deprecations_spec.rb +16 -0
  217. data/spec/lib/fixtures/source_location_test.rb +7 -0
  218. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +151 -0
  219. data/spec/lib/rewriters/block_to_iter_spec.rb +28 -0
  220. data/spec/lib/rewriters/dot_js_syntax_spec.rb +108 -0
  221. data/spec/lib/rewriters/explicit_writer_return_spec.rb +186 -0
  222. data/spec/lib/rewriters/js_reserved_words_spec.rb +116 -0
  223. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +202 -0
  224. data/spec/lib/rewriters/opal_engine_check_spec.rb +82 -0
  225. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +53 -0
  226. data/spec/lib/simple_server_spec.rb +54 -0
  227. data/spec/mspec-opal/formatters.rb +65 -17
  228. data/spec/mspec-opal/runner.rb +47 -67
  229. data/spec/opal/core/date_spec.rb +14 -0
  230. data/spec/opal/core/exception_spec.rb +10 -0
  231. data/spec/opal/core/hash/internals_spec.rb +10 -10
  232. data/spec/opal/core/kernel/rand_spec.rb +0 -4
  233. data/spec/opal/core/kernel/respond_to_spec.rb +5 -2
  234. data/spec/opal/core/language/constant_lookup_spec.rb +38 -0
  235. data/spec/opal/core/language/predefined_spec.rb +1 -1
  236. data/spec/opal/core/language/safe_navigator_spec.rb +7 -0
  237. data/spec/opal/core/language/send_spec.rb +1 -9
  238. data/spec/opal/core/language/string_spec.rb +8 -8
  239. data/spec/opal/core/language/versions/def_2_0_spec.rb +0 -4
  240. data/spec/opal/core/language_spec.rb +32 -0
  241. data/spec/opal/core/module/const_get_spec.rb +1 -1
  242. data/spec/opal/core/runtime/is_a_spec.rb +36 -0
  243. data/spec/opal/core/runtime/rescue_spec.rb +35 -0
  244. data/spec/opal/core/runtime_spec.rb +4 -4
  245. data/spec/opal/core/string_spec.rb +8 -8
  246. data/spec/opal/core/time_spec.rb +26 -17
  247. data/spec/opal/stdlib/erb/quoted.opalerb +1 -1
  248. data/spec/opal/stdlib/json/parse_spec.rb +4 -0
  249. data/spec/opal/stdlib/native/hash_spec.rb +16 -0
  250. data/spec/ruby_specs +2 -1
  251. data/spec/spec_helper.rb +1 -0
  252. data/spec/support/rewriters_helper.rb +24 -0
  253. data/stdlib/base64.rb +4 -2
  254. data/stdlib/bigdecimal/bignumber.js.rb +1 -1
  255. data/stdlib/date.rb +18 -19
  256. data/stdlib/json.rb +16 -4
  257. data/stdlib/nashorn/file.rb +15 -0
  258. data/stdlib/native.rb +21 -12
  259. data/stdlib/nodejs/dir.rb +1 -1
  260. data/stdlib/nodejs/file.rb +49 -20
  261. data/stdlib/nodejs/io.rb +22 -1
  262. data/stdlib/nodejs/{node_modules/js-yaml/dist/js-yaml.js → js-yaml-3-6-1.js} +815 -626
  263. data/stdlib/nodejs/kernel.rb +3 -1
  264. data/stdlib/nodejs/package.json +0 -1
  265. data/stdlib/nodejs/stacktrace.rb +163 -0
  266. data/stdlib/nodejs/yaml.rb +2 -1
  267. data/stdlib/opal-platform.rb +15 -0
  268. data/stdlib/opal/platform.rb +5 -13
  269. data/stdlib/pathname.rb +1 -1
  270. data/stdlib/strscan.rb +15 -1
  271. data/stdlib/yaml.rb +1 -1
  272. data/tasks/benchmarking.rake +9 -0
  273. data/tasks/building.rake +24 -20
  274. data/tasks/linting.rake +24 -13
  275. data/tasks/testing.rake +322 -205
  276. data/tasks/testing/mspec_special_calls.rb +44 -15
  277. data/tasks/testing/opal_rspec_smoketest.Gemfile +13 -0
  278. data/test/nodejs/fixtures/hello.rb +1 -0
  279. data/test/nodejs/test_file.rb +57 -0
  280. data/test/nodejs/test_io.rb +18 -0
  281. data/test/nodejs/test_opal_builder.rb +12 -0
  282. data/test/opal/unsupported_and_bugs.rb +9 -0
  283. metadata +127 -240
  284. data/lib/opal/parser/grammar.rb +0 -6157
  285. data/lib/opal/parser/grammar.y +0 -2011
  286. data/lib/opal/parser/keywords.rb +0 -66
  287. data/lib/opal/parser/lexer.rb +0 -1352
  288. data/lib/opal/parser/parser_scope.rb +0 -28
  289. data/lib/opal/parser/sexp.rb +0 -90
  290. data/lib/opal/sprockets.rb +0 -77
  291. data/lib/opal/sprockets/environment.rb +0 -23
  292. data/lib/opal/sprockets/erb.rb +0 -28
  293. data/lib/opal/sprockets/path_reader.rb +0 -36
  294. data/lib/opal/sprockets/processor.rb +0 -173
  295. data/lib/opal/sprockets/server.rb +0 -133
  296. data/lib/opal/sprockets/source_map_header_patch.rb +0 -41
  297. data/lib/opal/sprockets/source_map_server.rb +0 -117
  298. data/spec/filters/bugs/compiler_opal.rb +0 -5
  299. data/spec/filters/bugs/language_opal.rb +0 -88
  300. data/spec/filters/unsupported/module.rb +0 -8
  301. data/spec/lib/compiler/pre_processed_conditionals_spec.rb +0 -87
  302. data/spec/lib/lexer_spec.rb +0 -110
  303. data/spec/lib/parser/alias_spec.rb +0 -26
  304. data/spec/lib/parser/and_spec.rb +0 -13
  305. data/spec/lib/parser/aref_spec.rb +0 -10
  306. data/spec/lib/parser/attrasgn_spec.rb +0 -28
  307. data/spec/lib/parser/begin_spec.rb +0 -42
  308. data/spec/lib/parser/block_spec.rb +0 -12
  309. data/spec/lib/parser/break_spec.rb +0 -17
  310. data/spec/lib/parser/call_spec.rb +0 -201
  311. data/spec/lib/parser/class_spec.rb +0 -35
  312. data/spec/lib/parser/comments_spec.rb +0 -11
  313. data/spec/lib/parser/def_spec.rb +0 -109
  314. data/spec/lib/parser/if_spec.rb +0 -26
  315. data/spec/lib/parser/iter_spec.rb +0 -59
  316. data/spec/lib/parser/lambda_spec.rb +0 -219
  317. data/spec/lib/parser/literal_spec.rb +0 -118
  318. data/spec/lib/parser/masgn_spec.rb +0 -37
  319. data/spec/lib/parser/module_spec.rb +0 -27
  320. data/spec/lib/parser/not_spec.rb +0 -21
  321. data/spec/lib/parser/op_asgn1_spec.rb +0 -23
  322. data/spec/lib/parser/op_asgn2_spec.rb +0 -23
  323. data/spec/lib/parser/op_asgn_spec.rb +0 -17
  324. data/spec/lib/parser/or_spec.rb +0 -13
  325. data/spec/lib/parser/return_spec.rb +0 -22
  326. data/spec/lib/parser/sclass_spec.rb +0 -21
  327. data/spec/lib/parser/string_spec.rb +0 -286
  328. data/spec/lib/parser/super_spec.rb +0 -20
  329. data/spec/lib/parser/unary_spec.rb +0 -52
  330. data/spec/lib/parser/undef_spec.rb +0 -19
  331. data/spec/lib/parser/unless_spec.rb +0 -13
  332. data/spec/lib/parser/variables_spec.rb +0 -112
  333. data/spec/lib/parser/while_spec.rb +0 -15
  334. data/spec/lib/parser/yield_spec.rb +0 -20
  335. data/spec/lib/sprockets/erb_spec.rb +0 -38
  336. data/spec/lib/sprockets/path_reader_spec.rb +0 -41
  337. data/spec/lib/sprockets/processor_spec.rb +0 -79
  338. data/spec/lib/sprockets/server_spec.rb +0 -102
  339. data/spec/lib/sprockets_spec.rb +0 -39
  340. data/spec/lib/tilt/opal_spec.rb +0 -37
  341. data/spec/opal/core/language/block_spec.rb +0 -538
  342. data/spec/opal/core/language/proc_spec.rb +0 -263
  343. data/spec/opal/core/language/variables_spec.rb +0 -1366
  344. data/spec/opal/core/runtime/block_send_spec.rb +0 -28
  345. data/spec/opal/core/runtime/send_spec.rb +0 -34
  346. data/spec/support/parser_helpers.rb +0 -37
  347. data/stdlib/nodejs/node_modules/js-yaml/HISTORY.md +0 -277
  348. data/stdlib/nodejs/node_modules/js-yaml/LICENSE +0 -21
  349. data/stdlib/nodejs/node_modules/js-yaml/README.md +0 -288
  350. data/stdlib/nodejs/node_modules/js-yaml/bin/js-yaml.js +0 -140
  351. data/stdlib/nodejs/node_modules/js-yaml/bower.json +0 -23
  352. data/stdlib/nodejs/node_modules/js-yaml/dist/js-yaml.min.js +0 -3
  353. data/stdlib/nodejs/node_modules/js-yaml/examples/custom_types.js +0 -102
  354. data/stdlib/nodejs/node_modules/js-yaml/examples/custom_types.yml +0 -18
  355. data/stdlib/nodejs/node_modules/js-yaml/examples/dumper.js +0 -31
  356. data/stdlib/nodejs/node_modules/js-yaml/examples/dumper.json +0 -22
  357. data/stdlib/nodejs/node_modules/js-yaml/examples/sample_document.js +0 -18
  358. data/stdlib/nodejs/node_modules/js-yaml/examples/sample_document.yml +0 -197
  359. data/stdlib/nodejs/node_modules/js-yaml/index.js +0 -7
  360. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml.js +0 -39
  361. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/common.js +0 -62
  362. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/dumper.js +0 -554
  363. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/exception.js +0 -25
  364. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/loader.js +0 -1581
  365. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/mark.js +0 -78
  366. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema.js +0 -103
  367. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema/core.js +0 -18
  368. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +0 -25
  369. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +0 -28
  370. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +0 -17
  371. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/schema/json.js +0 -25
  372. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type.js +0 -61
  373. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/binary.js +0 -133
  374. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/bool.js +0 -37
  375. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/float.js +0 -110
  376. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/int.js +0 -183
  377. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/js/function.js +0 -85
  378. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +0 -84
  379. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +0 -27
  380. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/map.js +0 -8
  381. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/merge.js +0 -12
  382. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/null.js +0 -36
  383. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/omap.js +0 -56
  384. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/pairs.js +0 -61
  385. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/seq.js +0 -8
  386. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/set.js +0 -33
  387. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/str.js +0 -8
  388. data/stdlib/nodejs/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +0 -98
  389. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/HISTORY.md +0 -115
  390. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/LICENSE +0 -21
  391. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +0 -239
  392. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/arguments.js +0 -36
  393. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/choice.js +0 -22
  394. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/constants.js +0 -59
  395. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/help.js +0 -13
  396. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/nargs.js +0 -33
  397. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/parents.js +0 -28
  398. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/prefix_chars.js +0 -23
  399. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/sub_commands.js +0 -49
  400. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/sum.js +0 -35
  401. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/examples/testformatters.js +0 -270
  402. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/index.js +0 -1
  403. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action.js +0 -146
  404. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/append.js +0 -55
  405. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/append/constant.js +0 -47
  406. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/count.js +0 -40
  407. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/help.js +0 -48
  408. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/store.js +0 -50
  409. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/store/constant.js +0 -43
  410. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/store/false.js +0 -27
  411. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/store/true.js +0 -26
  412. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/subparsers.js +0 -148
  413. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action/version.js +0 -50
  414. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/action_container.js +0 -481
  415. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/argparse.js +0 -14
  416. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/argument/error.js +0 -50
  417. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/argument/exclusive.js +0 -54
  418. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/argument/group.js +0 -75
  419. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/argument_parser.js +0 -1168
  420. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/const.js +0 -18
  421. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/help/added_formatters.js +0 -88
  422. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/help/formatter.js +0 -798
  423. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/lib/namespace.js +0 -77
  424. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.npmignore +0 -2
  425. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/.travis.yml +0 -8
  426. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/README.markdown +0 -825
  427. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/bower.json +0 -33
  428. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/component.json +0 -11
  429. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/foo.js +0 -10
  430. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/gulpfile.js +0 -26
  431. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/lib/underscore.string.js +0 -673
  432. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/libpeerconnection.log +0 -0
  433. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore.string/package.json +0 -107
  434. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/LICENSE +0 -23
  435. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/README.md +0 -22
  436. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/package.json +0 -69
  437. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore-min.js +0 -6
  438. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/node_modules/underscore/underscore.js +0 -1415
  439. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/package.json +0 -62
  440. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/README.md +0 -73
  441. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/bin/esparse.js +0 -117
  442. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/bin/esvalidate.js +0 -177
  443. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/esprima.js +0 -3908
  444. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/package.json +0 -69
  445. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/test/compat.js +0 -239
  446. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/test/reflect.js +0 -422
  447. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/test/run.js +0 -66
  448. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/test/runner.js +0 -387
  449. data/stdlib/nodejs/node_modules/js-yaml/node_modules/esprima/test/test.js +0 -20238
  450. data/stdlib/nodejs/node_modules/js-yaml/package.json +0 -83
@@ -13,6 +13,24 @@
13
13
  // The way the code is digested before going through Yardoc is a secret kept
14
14
  // in the docs repo (https://github.com/opal/docs/tree/master).
15
15
 
16
+ var global_object = this, console;
17
+
18
+ // Detect the global object
19
+ if (typeof(global) !== 'undefined') { global_object = global; }
20
+ if (typeof(window) !== 'undefined') { global_object = window; }
21
+
22
+ // Setup a dummy console object if missing
23
+ if (typeof(global_object.console) === 'object') {
24
+ console = global_object.console;
25
+ } else if (global_object.console == null) {
26
+ console = global_object.console = {};
27
+ } else {
28
+ console = {};
29
+ }
30
+
31
+ if (!('log' in console)) { console.log = function () {}; }
32
+ if (!('warn' in console)) { console.warn = console.log; }
33
+
16
34
  if (typeof(this.Opal) !== 'undefined') {
17
35
  console.warn('Opal already loaded. Loading twice can cause troubles, please fix your setup.');
18
36
  return this.Opal;
@@ -52,31 +70,21 @@
52
70
  var Opal = this.Opal = {};
53
71
 
54
72
  // All bridged classes - keep track to donate methods from Object
55
- var bridges = {};
56
-
57
- // TopScope is used for inheriting constants from the top scope
58
- var TopScope = function(){};
59
-
60
- // Opal just acts as the top scope
61
- TopScope.prototype = Opal;
62
-
63
- // To inherit scopes
64
- Opal.constructor = TopScope;
65
-
66
- // List top scope constants
67
- Opal.constants = [];
73
+ var BridgedClasses = {};
68
74
 
69
75
  // This is a useful reference to global object inside ruby files
70
- Opal.global = this;
76
+ Opal.global = global_object;
77
+ global_object.Opal = Opal;
71
78
 
72
79
  // Configure runtime behavior with regards to require and unsupported fearures
73
80
  Opal.config = {
74
- missing_require_severity: 'error', // error, warning, ignore
75
- unsupported_features_severity: 'warning' // error, warning, ignore
81
+ missing_require_severity: 'error', // error, warning, ignore
82
+ unsupported_features_severity: 'warning', // error, warning, ignore
83
+ enable_stack_trace: true // true, false
76
84
  }
77
85
 
78
86
  // Minify common function calls
79
- var $hasOwn = Opal.hasOwnProperty;
87
+ var $hasOwn = Object.hasOwnProperty;
80
88
  var $slice = Opal.slice = Array.prototype.slice;
81
89
 
82
90
  // Nil object id is always 4
@@ -92,8 +100,11 @@
92
100
  return unique_id;
93
101
  };
94
102
 
95
- // Table holds all class variables
96
- Opal.cvars = {};
103
+ // Retrieve or assign the id of an object
104
+ Opal.id = function(obj) {
105
+ if (obj.$$is_number) return (obj * 2)+1;
106
+ return obj.$$id || (obj.$$id = Opal.uid());
107
+ };
97
108
 
98
109
  // Globals table
99
110
  Opal.gvars = {};
@@ -111,135 +122,221 @@
111
122
  Opal.gvars["!"] = Opal.exceptions.pop() || nil;
112
123
  }
113
124
 
125
+ // Inspect any kind of object, including non Ruby ones
126
+ Opal.inspect = function(obj) {
127
+ if (obj === undefined) {
128
+ return "undefined";
129
+ }
130
+ else if (obj === null) {
131
+ return "null";
132
+ }
133
+ else if (!obj.$$class) {
134
+ return obj.toString();
135
+ }
136
+ else {
137
+ return obj.$inspect();
138
+ }
139
+ }
140
+
114
141
 
115
142
  // Constants
116
143
  // ---------
117
-
118
- // Get a constant on the given scope. Every class and module in Opal has a
119
- // scope used to store, and inherit, constants. For example, the top level
120
- // `Object` in ruby has a scope accessible as `Opal.Object.$$scope`.
121
- //
122
- // To get the `Array` class using this scope, you could use:
123
- //
124
- // Opal.Object.$$scope.get("Array")
125
144
  //
126
- // If a constant with the given name cannot be found, then a dispatch to the
127
- // class/module's `#const_method` is called, which by default will raise an
128
- // error.
145
+ // For future reference:
146
+ // - The Rails autoloading guide (http://guides.rubyonrails.org/v5.0/autoloading_and_reloading_constants.html)
147
+ // - @ConradIrwin's 2012 post on “Everything you ever wanted to know about constant lookup in Ruby” (http://cirw.in/blog/constant-lookup.html)
129
148
  //
130
- // @param name [String] the name of the constant to lookup
131
- // @return [Object]
132
- //
133
- Opal.get = function(name) {
134
- var constant = this[name];
149
+ // Legend of MRI concepts/names:
150
+ // - constant reference (cref): the module/class that acts as a namespace
151
+ // - nesting: the namespaces wrapping the current scope, e.g. nesting inside
152
+ // `module A; module B::C; end; end` is `[B::C, A]`
153
+
154
+ // Get the cosntant in the scope of the current cref
155
+ function const_get_name(cref, name) {
156
+ if (cref) return cref.$$const[name];
157
+ }
158
+
159
+ // Walk up the nesting array looking for the constant
160
+ function const_lookup_nesting(nesting, name) {
161
+ var i, ii, result, constant;
135
162
 
136
- if (constant == null) {
137
- return this.base.$const_get(name);
163
+ if (nesting.length === 0) return;
164
+
165
+ // If the nesting is not empty the constant is looked up in its elements
166
+ // and in order. The ancestors of those elements are ignored.
167
+ for (i = 0, ii = nesting.length; i < ii; i++) {
168
+ constant = nesting[i].$$const[name];
169
+ if (constant != null) return constant;
138
170
  }
171
+ }
139
172
 
140
- return constant;
141
- };
173
+ // Walk up the ancestors chain looking for the constant
174
+ function const_lookup_ancestors(cref, name) {
175
+ var i, ii, result, ancestors;
142
176
 
143
- // Create a new constants scope for the given class with the given
144
- // base. Constants are looked up through their parents, so the base
145
- // scope will be the outer scope of the new klass.
146
- //
147
- // @param base_scope [$$scope] the scope in which the new scope should be created
148
- // @param klass [Class]
149
- // @param id [String, null] the name of the newly created scope
150
- //
151
- Opal.create_scope = function(base_scope, klass, id) {
152
- var const_alloc = function() {};
153
- var const_scope = const_alloc.prototype = new base_scope.constructor();
177
+ if (cref == null) return;
154
178
 
155
- klass.$$scope = const_scope;
156
- klass.$$base_module = base_scope.base;
179
+ ancestors = Opal.ancestors(cref);
157
180
 
158
- const_scope.base = klass;
159
- const_scope.constructor = const_alloc;
160
- const_scope.constants = [];
181
+ for (i = 0, ii = ancestors.length; i < ii; i++) {
182
+ if (ancestors[i].$$const && $hasOwn.call(ancestors[i].$$const, name)) {
183
+ return ancestors[i].$$const[name];
184
+ }
185
+ }
186
+ }
161
187
 
162
- if (id) {
163
- Opal.cdecl(base_scope, id, klass);
164
- const_alloc.displayName = id+"_scope_alloc";
188
+ // Walk up Object's ancestors chain looking for the constant,
189
+ // but only if cref is missing or a module.
190
+ function const_lookup_Object(cref, name) {
191
+ if (cref == null || cref.$$is_module) {
192
+ return const_lookup_ancestors(_Object, name);
165
193
  }
194
+ }
195
+
196
+ // Call const_missing if nothing else worked
197
+ function const_missing(cref, name, skip_missing) {
198
+ if (!skip_missing) {
199
+ return (cref || _Object).$const_missing(name);
200
+ }
201
+ }
202
+
203
+ // Look for the constant just in the current cref or call `#const_missing`
204
+ Opal.const_get_local = function(cref, name, skip_missing) {
205
+ var result;
206
+
207
+ if (cref == null) return;
208
+
209
+ if (cref === '::') cref = _Object;
210
+
211
+ if (!cref.$$is_a_module) {
212
+ throw new Opal.TypeError(cref.toString() + " is not a class/module");
213
+ }
214
+
215
+ result = const_get_name(cref, name); if (result != null) return result;
216
+ result = const_missing(cref, name, skip_missing); if (result != null) return result;
217
+ }
218
+
219
+ // Look for the constant relative to a cref or call `#const_missing` (when the
220
+ // constant is prefixed by `::`).
221
+ Opal.const_get_qualified = function(cref, name, skip_missing) {
222
+ var result, cache, cached, current_version = Opal.const_cache_version;
223
+
224
+ if (cref == null) return;
225
+
226
+ if (cref === '::') cref = _Object;
227
+
228
+ if (!cref.$$is_a_module) {
229
+ throw new Opal.TypeError(cref.toString() + " is not a class/module");
230
+ }
231
+
232
+ if (cref.$$const_cache == null) {
233
+ cache = cref.$$const_cache = Object.create(null);
234
+ } else {
235
+ cache = cref.$$const_cache;
236
+ }
237
+ cached = cache[name];
238
+
239
+ if (cached == null || cached[0] !== current_version) {
240
+ ((result = const_get_name(cref, name)) != null) ||
241
+ ((result = const_lookup_ancestors(cref, name)) != null);
242
+ cache[name] = [current_version, result];
243
+ } else {
244
+ result = cached[1];
245
+ }
246
+
247
+ return result != null ? result : const_missing(cref, name, skip_missing);
166
248
  };
167
249
 
168
- // Constant assignment, see also `Opal.cdecl`
169
- //
170
- // @param base_module [Module, Class] the constant namespace
171
- // @param name [String] the name of the constant
172
- // @param value [Object] the value of the constant
173
- //
174
- // @example Assigning a namespaced constant
175
- // self::FOO = 'bar'
176
- //
177
- // @example Assigning with Module#const_set
178
- // Foo.const_set :BAR, 123
179
- //
180
- Opal.casgn = function(base_module, name, value) {
181
- function update(klass, name) {
182
- klass.$$name = name;
250
+ // Initialize the top level constant cache generation counter
251
+ Opal.const_cache_version = 1;
183
252
 
184
- for (name in klass.$$scope) {
185
- var value = klass.$$scope[name];
253
+ // Look for the constant in the open using the current nesting and the nearest
254
+ // cref ancestors or call `#const_missing` (when the constant has no :: prefix).
255
+ Opal.const_get_relative = function(nesting, name, skip_missing) {
256
+ var cref = nesting[0], result, current_version = Opal.const_cache_version, cache, cached;
186
257
 
187
- if (value.$$name === nil && (value.$$is_class || value.$$is_module)) {
188
- update(value, name)
189
- }
190
- }
258
+ if (nesting.$$const_cache == null) {
259
+ cache = nesting.$$const_cache = Object.create(null);
260
+ } else {
261
+ cache = nesting.$$const_cache;
191
262
  }
263
+ cached = cache[name];
192
264
 
193
- var scope = base_module.$$scope;
265
+ if (cached == null || cached[0] !== current_version) {
266
+ ((result = const_get_name(cref, name)) != null) ||
267
+ ((result = const_lookup_nesting(nesting, name)) != null) ||
268
+ ((result = const_lookup_ancestors(cref, name)) != null) ||
269
+ ((result = const_lookup_Object(cref, name)) != null);
194
270
 
195
- if (value.$$is_class || value.$$is_module) {
196
- // Only checking _Object prevents setting a const on an anonymous class
197
- // that has a superclass that's not Object
198
- if (value.$$is_class || value.$$base_module === _Object) {
199
- value.$$base_module = base_module;
200
- }
271
+ cache[name] = [current_version, result];
272
+ } else {
273
+ result = cached[1];
274
+ }
201
275
 
202
- if (value.$$name === nil && value.$$base_module.$$name !== nil) {
203
- update(value, name);
204
- }
276
+ return result != null ? result : const_missing(cref, name, skip_missing);
277
+ };
278
+
279
+ // Register the constant on a cref and opportunistically set the name of
280
+ // unnamed classes/modules.
281
+ Opal.const_set = function(cref, name, value) {
282
+ if (cref == null || cref === '::') cref = _Object;
283
+
284
+ if (value.$$is_a_module) {
285
+ if (value.$$name == null || value.$$name === nil) value.$$name = name;
286
+ if (value.$$base_module == null) value.$$base_module = cref;
205
287
  }
206
288
 
207
- scope.constants.push(name);
208
- scope[name] = value;
289
+ cref.$$const = (cref.$$const || Object.create(null));
290
+ cref.$$const[name] = value;
291
+
292
+ Opal.const_cache_version++;
293
+
294
+ // Expose top level constants onto the Opal object
295
+ if (cref === _Object) Opal[name] = value;
296
+
297
+ return value;
298
+ };
299
+
300
+ // Get all the constants reachable from a given cref, by default will include
301
+ // inherited constants.
302
+ Opal.constants = function(cref, inherit) {
303
+ if (inherit == null) inherit = true;
304
+
305
+ var module, modules = [cref], module_constants, i, ii, constants = {}, constant;
209
306
 
210
- // If we dynamically declare a constant in a module,
211
- // we should populate all the classes that include this module
212
- // with the same constant
213
- if (base_module.$$is_module && base_module.$$dep) {
214
- for (var i = 0; i < base_module.$$dep.length; i++) {
215
- var dep = base_module.$$dep[i];
216
- Opal.casgn(dep, name, value);
307
+ if (inherit) modules = modules.concat(Opal.ancestors(cref));
308
+ if (inherit && cref.$$is_module) modules = modules.concat([Opal.Object]).concat(Opal.ancestors(Opal.Object));
309
+
310
+ for (i = 0, ii = modules.length; i < ii; i++) {
311
+ module = modules[i];
312
+
313
+ // Don not show Objects constants unless we're querying Object itself
314
+ if (cref !== _Object && module == _Object) break;
315
+
316
+ for (constant in module.$$const) {
317
+ constants[constant] = true;
217
318
  }
218
319
  }
219
320
 
220
- return value;
321
+ return Object.keys(constants);
221
322
  };
222
323
 
223
- // Constant declaration
224
- //
225
- // @example
226
- // FOO = :bar
227
- //
228
- // @param base_scope [$$scope] the current scope
229
- // @param name [String] the name of the constant
230
- // @param value [Object] the value of the constant
231
- Opal.cdecl = function(base_scope, name, value) {
232
- if ((value.$$is_class || value.$$is_module) && value.$$orig_scope == null) {
233
- value.$$name = name;
234
- value.$$orig_scope = base_scope;
235
- // Here we should explicitly set a base module
236
- // (a module where the constant was initially defined)
237
- value.$$base_module = base_scope.base;
238
- base_scope.constructor[name] = value;
324
+ // Remove a constant from a cref.
325
+ Opal.const_remove = function(cref, name) {
326
+ Opal.const_cache_version++;
327
+
328
+ if (cref.$$const[name] != null) {
329
+ var old = cref.$$const[name];
330
+ delete cref.$$const[name];
331
+ return old;
332
+ }
333
+
334
+ if (cref.$$autoload != null && cref.$$autoload[name] != null) {
335
+ delete cref.$$autoload[name];
336
+ return nil;
239
337
  }
240
338
 
241
- base_scope.constants.push(name);
242
- return base_scope[name] = value;
339
+ throw Opal.NameError.$new("constant "+cref+"::"+cref.$name()+" not defined");
243
340
  };
244
341
 
245
342
 
@@ -274,6 +371,10 @@
274
371
  Opal.klass = function(base, superclass, name, constructor) {
275
372
  var klass, bridged, alloc;
276
373
 
374
+ if (base == null) {
375
+ base = _Object;
376
+ }
377
+
277
378
  // If base is an object, use its class
278
379
  if (!base.$$is_class && !base.$$is_module) {
279
380
  base = base.$$class;
@@ -286,10 +387,10 @@
286
387
  }
287
388
 
288
389
  // Try to find the class in the current scope
289
- klass = base.$$scope[name];
390
+ klass = const_get_name(base, name);
290
391
 
291
392
  // If the class exists in the scope, then we must use that
292
- if (klass && klass.$$orig_scope === base.$$scope) {
393
+ if (klass) {
293
394
  // Make sure the existing constant is a class, or raise error
294
395
  if (!klass.$$is_class) {
295
396
  throw Opal.TypeError.$new(name + " is not a class");
@@ -324,8 +425,7 @@
324
425
  // the last included klass
325
426
  klass.$$parent = superclass;
326
427
 
327
- // Every class gets its own constant scope, inherited from current scope
328
- Opal.create_scope(base.$$scope, klass, name);
428
+ Opal.const_set(base, name, klass);
329
429
 
330
430
  // Name new class directly onto current scope (Opal.Foo.Baz = klass)
331
431
  base[name] = klass;
@@ -334,11 +434,6 @@
334
434
  Opal.bridge(klass, alloc);
335
435
  }
336
436
  else {
337
- // Copy all parent constants to child, unless parent is Object
338
- if (superclass !== _Object && superclass !== BasicObject) {
339
- Opal.donate_constants(superclass, klass);
340
- }
341
-
342
437
  // Call .inherited() hook with new class on the superclass
343
438
  if (superclass.$inherited) {
344
439
  superclass.$inherited(klass);
@@ -357,7 +452,7 @@
357
452
  Opal.boot_class_alloc = function(name, constructor, superclass) {
358
453
  if (superclass) {
359
454
  var alloc_proxy = function() {};
360
- alloc_proxy.prototype = superclass.$$proto || superclass.prototype;
455
+ alloc_proxy.prototype = superclass.$$proto || superclass.prototype;
361
456
  constructor.prototype = new alloc_proxy();
362
457
  }
363
458
 
@@ -370,6 +465,30 @@
370
465
  return constructor;
371
466
  };
372
467
 
468
+ Opal.setup_module_or_class = function(module) {
469
+ // @property $$id Each class/module is assigned a unique `id` that helps
470
+ // comparation and implementation of `#object_id`
471
+ module.$$id = Opal.uid();
472
+
473
+ // @property $$is_a_module Will be true for Module and its subclasses
474
+ // instances (namely: Class).
475
+ module.$$is_a_module = true;
476
+
477
+ // @property $$inc included modules
478
+ module.$$inc = [];
479
+
480
+ // initialize the name with nil
481
+ module.$$name = nil;
482
+
483
+ // Initialize the constants table
484
+ module.$$const = Object.create(null);
485
+
486
+ // @property $$cvars class variables defined in the current module
487
+ module.$$cvars = Object.create(null);
488
+ }
489
+
490
+
491
+
373
492
  // Adds common/required properties to class object (as in `Class.new`)
374
493
  //
375
494
  // @param name [String,null] The name of the class
@@ -398,16 +517,14 @@
398
517
  // The built class is the only instance of its singleton_class
399
518
  var klass = new singleton_class_alloc();
400
519
 
520
+ Opal.setup_module_or_class(klass);
521
+
401
522
  // @property $$alloc This is the constructor of instances of the current
402
523
  // class. Its prototype will be used for method lookup
403
524
  klass.$$alloc = alloc;
404
525
 
405
526
  klass.$$name = name || nil;
406
527
 
407
- // @property $$id Each class is assigned a unique `id` that helps
408
- // comparation and implementation of `#object_id`
409
- klass.$$id = Opal.uid();
410
-
411
528
  // Set a displayName for the singleton_class
412
529
  singleton_class_alloc.displayName = "#<Class:"+(name || ("#<Class:"+klass.$$id+">"))+">";
413
530
 
@@ -432,9 +549,6 @@
432
549
  // @property $$class Classes are instances of the class Class
433
550
  klass.$$class = Class;
434
551
 
435
- // @property $$inc included modules
436
- klass.$$inc = [];
437
-
438
552
  return klass;
439
553
  };
440
554
 
@@ -460,20 +574,25 @@
460
574
  Opal.module = function(base, name) {
461
575
  var module;
462
576
 
577
+ if (base == null) {
578
+ base = _Object;
579
+ }
580
+
463
581
  if (!base.$$is_class && !base.$$is_module) {
464
582
  base = base.$$class;
465
583
  }
466
584
 
467
- if ($hasOwn.call(base.$$scope, name)) {
468
- module = base.$$scope[name];
585
+ module = const_get_name(base, name);
586
+ if (module == null && base === _Object) module = const_lookup_ancestors(_Object, name);
469
587
 
588
+ if (module) {
470
589
  if (!module.$$is_module && module !== _Object) {
471
590
  throw Opal.TypeError.$new(name + " is not a module");
472
591
  }
473
592
  }
474
593
  else {
475
594
  module = Opal.module_allocate(Module);
476
- Opal.create_scope(base.$$scope, module, name);
595
+ Opal.const_set(base, name, module);
477
596
  }
478
597
 
479
598
  return module;
@@ -500,15 +619,16 @@
500
619
  var mtor = function() {};
501
620
  mtor.prototype = superclass.$$alloc.prototype;
502
621
 
503
- function module_constructor() {}
622
+ var module_constructor = function() {};
504
623
  module_constructor.prototype = new mtor();
505
624
 
506
625
  var module = new module_constructor();
507
626
  var module_prototype = {};
508
627
 
509
- // @property $$id Each class is assigned a unique `id` that helps
510
- // comparation and implementation of `#object_id`
511
- module.$$id = Opal.uid();
628
+ Opal.setup_module_or_class(module);
629
+
630
+ // initialize dependency tracking
631
+ module.$$included_in = [];
512
632
 
513
633
  // Set the display name of the singleton prototype holder
514
634
  module_constructor.displayName = "#<Class:#<Module:"+module.$$id+">>"
@@ -539,18 +659,6 @@
539
659
  // the last included module
540
660
  module.$$parent = superclass;
541
661
 
542
- // @property $$inc included modules
543
- module.$$inc = [];
544
-
545
- // mark the object as a module
546
- module.$$is_module = true;
547
-
548
- // initialize dependency tracking
549
- module.$$dep = [];
550
-
551
- // initialize the name with nil
552
- module.$$name = nil;
553
-
554
662
  return module;
555
663
  };
556
664
 
@@ -603,12 +711,9 @@
603
711
  superclass = object === BasicObject ? Class : Opal.build_class_singleton_class(object.$$super);
604
712
 
605
713
  klass = Opal.setup_class_object(null, alloc, superclass.$$name, superclass.constructor);
606
- klass.$$super = superclass;
714
+ klass.$$super = superclass;
607
715
  klass.$$parent = superclass;
608
716
 
609
- // The singleton_class retains the same scope as the original class
610
- Opal.create_scope(object.$$scope, klass);
611
-
612
717
  klass.$$is_singleton = true;
613
718
  klass.$$singleton_of = object;
614
719
 
@@ -629,7 +734,6 @@
629
734
  klass.$$super = superclass;
630
735
  klass.$$parent = superclass;
631
736
  klass.$$class = superclass.$$class;
632
- klass.$$scope = superclass.$$scope;
633
737
  klass.$$proto = object;
634
738
 
635
739
  klass.$$is_singleton = true;
@@ -638,11 +742,62 @@
638
742
  return object.$$meta = klass;
639
743
  };
640
744
 
745
+ // Returns an object containing all pairs of names/values
746
+ // for all class variables defined in provided +module+
747
+ // and its ancestors.
748
+ //
749
+ // @param module [Module]
750
+ // @return [Object]
751
+ Opal.class_variables = function(module) {
752
+ var ancestors = Opal.ancestors(module),
753
+ i, length = ancestors.length,
754
+ result = {};
755
+
756
+ for (i = length - 1; i >= 0; i--) {
757
+ var ancestor = ancestors[i];
758
+
759
+ for (var cvar in ancestor.$$cvars) {
760
+ result[cvar] = ancestor.$$cvars[cvar];
761
+ }
762
+ }
763
+
764
+ return result;
765
+ }
766
+
767
+ // Sets class variable with specified +name+ to +value+
768
+ // in provided +module+
769
+ //
770
+ // @param module [Module]
771
+ // @param name [String]
772
+ // @param value [Object]
773
+ Opal.class_variable_set = function(module, name, value) {
774
+ var ancestors = Opal.ancestors(module),
775
+ i, length = ancestors.length;
776
+
777
+ for (i = length - 2; i >= 0; i--) {
778
+ var ancestor = ancestors[i];
779
+
780
+ if ($hasOwn.call(ancestor.$$cvars, name)) {
781
+ ancestor.$$cvars[name] = value;
782
+ return value;
783
+ }
784
+ }
785
+
786
+ module.$$cvars[name] = value;
787
+
788
+ return value;
789
+ }
790
+
641
791
  // Bridges a single method.
642
- Opal.bridge_method = function(target, from, name, body) {
792
+ //
793
+ // @param target [JS::Function] the constructor of the bridged class
794
+ // @param from [Module] the module/class we are importing the method from
795
+ // @param name [String] the method name in JS land (i.e. starting with $)
796
+ // @param body [JS::Function] the body of the method
797
+ Opal.bridge_method = function(target_constructor, from, name, body) {
643
798
  var ancestors, i, ancestor, length;
644
799
 
645
- ancestors = target.$$bridge.$ancestors();
800
+ ancestors = target_constructor.$$bridge.$ancestors();
646
801
 
647
802
  // order important here, we have to check for method presence in
648
803
  // ancestors from the bridged class to the last ancestor
@@ -658,45 +813,83 @@
658
813
  }
659
814
 
660
815
  if (ancestor === from) {
661
- target.prototype[name] = body
816
+ target_constructor.prototype[name] = body
662
817
  break;
663
818
  }
664
819
  }
665
-
666
820
  };
667
821
 
668
822
  // Bridges from *donator* to a *target*.
669
- Opal._bridge = function(target, donator) {
670
- var id, methods, method, i, bridged;
671
-
672
- if (typeof(target) === "function") {
673
- id = donator.$__id__();
674
- methods = donator.$instance_methods();
823
+ //
824
+ // @param target [Module] the potentially associated with bridged classes module
825
+ // @param donator [Module] the module/class source of the methods that should be bridged
826
+ Opal.bridge_methods = function(target, donator) {
827
+ var i,
828
+ bridged = BridgedClasses[target.$__id__()],
829
+ donator_id = donator.$__id__();
675
830
 
676
- for (i = methods.length - 1; i >= 0; i--) {
677
- method = '$' + methods[i];
831
+ if (bridged) {
832
+ BridgedClasses[donator_id] = bridged.slice();
678
833
 
679
- Opal.bridge_method(target, donator, method, donator.$$proto[method]);
834
+ for (i = bridged.length - 1; i >= 0; i--) {
835
+ Opal_bridge_methods_to_constructor(bridged[i], donator)
680
836
  }
837
+ }
838
+ };
681
839
 
682
- if (!bridges[id]) {
683
- bridges[id] = [];
684
- }
840
+ // Actually bridge methods to the bridged (shared) prototype.
841
+ function Opal_bridge_methods_to_constructor(target_constructor, donator) {
842
+ var i,
843
+ method,
844
+ methods = donator.$instance_methods();
685
845
 
686
- bridges[id].push(target);
846
+ for (i = methods.length - 1; i >= 0; i--) {
847
+ method = '$' + methods[i];
848
+ Opal.bridge_method(target_constructor, donator, method, donator.$$proto[method]);
687
849
  }
688
- else {
689
- bridged = bridges[target.$__id__()];
850
+ }
690
851
 
691
- if (bridged) {
692
- for (i = bridged.length - 1; i >= 0; i--) {
693
- Opal._bridge(bridged[i], donator);
694
- }
852
+ // Associate the target as a bridged class for the current "donator"
853
+ function Opal_add_bridged_constructor(target_constructor, donator) {
854
+ var donator_id = donator.$__id__();
695
855
 
696
- bridges[donator.$__id__()] = bridged.slice();
856
+ if (!BridgedClasses[donator_id]) {
857
+ BridgedClasses[donator_id] = [];
858
+ }
859
+ BridgedClasses[donator_id].push(target_constructor);
860
+ }
861
+
862
+ // Walks the dependency tree detecting the presence of the base among its
863
+ // own dependencies.
864
+ //
865
+ // @param [Integer] base_id The id of the base module (eg. the "includer")
866
+ // @param [Array<Module>] deps The array of dependencies (eg. the included module, included.$$deps)
867
+ // @param [String] prop The property that holds dependencies (eg. "$$deps")
868
+ // @param [JS::Object] seen A JS object holding the cache of already visited objects
869
+ // @return [Boolean] true if a cyclic dependency is present
870
+ Opal.has_cyclic_dep = function has_cyclic_dep(base_id, deps, prop, seen) {
871
+ var i, dep_id, dep;
872
+
873
+ for (i = deps.length - 1; i >= 0; i--) {
874
+ dep = deps[i];
875
+ dep_id = dep.$$id;
876
+
877
+ if (seen[dep_id]) {
878
+ continue;
879
+ }
880
+ seen[dep_id] = true;
881
+
882
+ if (dep_id === base_id) {
883
+ return true;
884
+ }
885
+
886
+ if (has_cyclic_dep(base_id, dep[prop], prop, seen)) {
887
+ return true;
697
888
  }
698
889
  }
699
- };
890
+
891
+ return false;
892
+ }
700
893
 
701
894
  // The actual inclusion of a module into a class.
702
895
  //
@@ -714,54 +907,45 @@
714
907
  // the required method.
715
908
  //
716
909
  // @param module [Module] the module to include
717
- // @param klass [Class] the target class to include module into
910
+ // @param includer [Module] the target class to include module into
718
911
  // @return [null]
719
- Opal.append_features = function(module, klass) {
912
+ Opal.append_features = function(module, includer) {
720
913
  var iclass, donator, prototype, methods, id, i;
721
914
 
722
915
  // check if this module is already included in the class
723
- for (i = klass.$$inc.length - 1; i >= 0; i--) {
724
- if (klass.$$inc[i] === module) {
916
+ for (i = includer.$$inc.length - 1; i >= 0; i--) {
917
+ if (includer.$$inc[i] === module) {
725
918
  return;
726
919
  }
727
920
  }
728
921
 
729
- klass.$$inc.push(module);
730
- module.$$dep.push(klass);
731
- Opal._bridge(klass, module);
922
+ // Check that the base module is not also a dependency, classes can't be
923
+ // dependencies so we have a special case for them.
924
+ if (!includer.$$is_class && Opal.has_cyclic_dep(includer.$$id, [module], '$$inc', {})) {
925
+ throw Opal.ArgumentError.$new('cyclic include detected')
926
+ }
927
+
928
+ Opal.const_cache_version++;
929
+ includer.$$inc.push(module);
930
+ module.$$included_in.push(includer);
931
+ Opal.bridge_methods(includer, module);
732
932
 
733
933
  // iclass
734
934
  iclass = {
735
935
  $$name: module.$$name,
736
936
  $$proto: module.$$proto,
737
- $$parent: klass.$$parent,
937
+ $$parent: includer.$$parent,
738
938
  $$module: module,
739
939
  $$iclass: true
740
940
  };
741
941
 
742
- klass.$$parent = iclass;
942
+ includer.$$parent = iclass;
743
943
 
744
- donator = module.$$proto;
745
- prototype = klass.$$proto;
746
- methods = module.$instance_methods();
944
+ methods = module.$instance_methods();
747
945
 
748
946
  for (i = methods.length - 1; i >= 0; i--) {
749
- id = '$' + methods[i];
750
-
751
- // if the target class already has a method of the same name defined
752
- // and that method was NOT donated, then it must be a method defined
753
- // by the class so we do not want to override it
754
- if ( prototype.hasOwnProperty(id) &&
755
- !prototype[id].$$donated &&
756
- !prototype[id].$$stub) {
757
- continue;
758
- }
759
-
760
- prototype[id] = donator[id];
761
- prototype[id].$$donated = module;
947
+ Opal.update_includer(module, includer, '$' + methods[i])
762
948
  }
763
-
764
- Opal.donate_constants(module, klass);
765
949
  };
766
950
 
767
951
  // Table that holds all methods that have been defined on all objects
@@ -807,7 +991,8 @@
807
991
  // order important here, we have to bridge from the last ancestor to the
808
992
  // bridged class
809
993
  for (var i = ancestors.length - 1; i >= 0; i--) {
810
- Opal._bridge(constructor, ancestors[i]);
994
+ Opal_add_bridged_constructor(constructor, ancestors[i]);
995
+ Opal_bridge_methods_to_constructor(constructor, ancestors[i]);
811
996
  }
812
997
 
813
998
  for (var name in BasicObject_alloc.prototype) {
@@ -821,69 +1006,64 @@
821
1006
  return klass;
822
1007
  };
823
1008
 
824
- // When a source module is included into the target module, we must also copy
825
- // its constants to the target.
826
- //
827
- Opal.donate_constants = function(source_mod, target_mod) {
828
- var source_constants = source_mod.$$scope.constants,
829
- target_scope = target_mod.$$scope,
830
- target_constants = target_scope.constants;
831
-
832
- for (var i = 0, length = source_constants.length; i < length; i++) {
833
- target_constants.push(source_constants[i]);
834
- target_scope[source_constants[i]] = source_mod.$$scope[source_constants[i]];
835
- }
836
- };
837
-
838
- // Donate methods for a module.
839
- Opal.donate = function(module, jsid) {
840
- var included_in = module.$$dep,
841
- body = module.$$proto[jsid],
842
- i, length, includee, dest, current,
1009
+ // Update `jsid` method cache of all classes / modules including `module`.
1010
+ Opal.update_includer = function(module, includer, jsid) {
1011
+ var dest, current, body,
843
1012
  klass_includees, j, jj, current_owner_index, module_index;
844
1013
 
845
- if (!included_in) {
846
- return;
847
- }
1014
+ body = module.$$proto[jsid];
1015
+ dest = includer.$$proto;
1016
+ current = dest[jsid];
848
1017
 
849
- for (i = 0, length = included_in.length; i < length; i++) {
850
- includee = included_in[i];
851
- dest = includee.$$proto;
852
- current = dest[jsid];
853
-
854
- if (dest.hasOwnProperty(jsid) && !current.$$donated && !current.$$stub) {
855
- // target class has already defined the same method name - do nothing
856
- }
857
- else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
858
- // target class includes another module that has defined this method
859
- klass_includees = includee.$$inc;
1018
+ if (dest.hasOwnProperty(jsid) && !current.$$donated && !current.$$stub) {
1019
+ // target class has already defined the same method name - do nothing
1020
+ }
1021
+ else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
1022
+ // target class includes another module that has defined this method
1023
+ klass_includees = includer.$$inc;
860
1024
 
861
- for (j = 0, jj = klass_includees.length; j < jj; j++) {
862
- if (klass_includees[j] === current.$$donated) {
863
- current_owner_index = j;
864
- }
865
- if (klass_includees[j] === module) {
866
- module_index = j;
867
- }
1025
+ for (j = 0, jj = klass_includees.length; j < jj; j++) {
1026
+ if (klass_includees[j] === current.$$donated) {
1027
+ current_owner_index = j;
868
1028
  }
869
-
870
- // only redefine method on class if the module was included AFTER
871
- // the module which defined the current method body. Also make sure
872
- // a module can overwrite a method it defined before
873
- if (current_owner_index <= module_index) {
874
- dest[jsid] = body;
875
- dest[jsid].$$donated = module;
1029
+ if (klass_includees[j] === module) {
1030
+ module_index = j;
876
1031
  }
877
1032
  }
878
- else {
879
- // neither a class, or module included by class, has defined method
1033
+
1034
+ // only redefine method on class if the module was included AFTER
1035
+ // the module which defined the current method body. Also make sure
1036
+ // a module can overwrite a method it defined before
1037
+ if (current_owner_index <= module_index) {
880
1038
  dest[jsid] = body;
881
1039
  dest[jsid].$$donated = module;
882
1040
  }
1041
+ }
1042
+ else {
1043
+ // neither a class, or module included by class, has defined method
1044
+ dest[jsid] = body;
1045
+ dest[jsid].$$donated = module;
1046
+ }
883
1047
 
884
- if (includee.$$dep) {
885
- Opal.donate(includee, jsid);
886
- }
1048
+ // if the includer is a module, recursively update all of its includres.
1049
+ if (includer.$$included_in) {
1050
+ Opal.update_includers(includer, jsid);
1051
+ }
1052
+ };
1053
+
1054
+ // Update `jsid` method cache of all classes / modules including `module`.
1055
+ Opal.update_includers = function(module, jsid) {
1056
+ var i, ii, includee, included_in;
1057
+
1058
+ included_in = module.$$included_in;
1059
+
1060
+ if (!included_in) {
1061
+ return;
1062
+ }
1063
+
1064
+ for (i = 0, ii = included_in.length; i < ii; i++) {
1065
+ includee = included_in[i];
1066
+ Opal.update_includer(module, includee, jsid);
887
1067
  }
888
1068
  };
889
1069
 
@@ -891,14 +1071,14 @@
891
1071
  Opal.ancestors = function(module_or_class) {
892
1072
  var parent = module_or_class,
893
1073
  result = [],
894
- modules;
1074
+ modules, i, ii, j, jj;
895
1075
 
896
1076
  while (parent) {
897
1077
  result.push(parent);
898
- for (var i=0; i < parent.$$inc.length; i++) {
1078
+ for (i = parent.$$inc.length-1; i >= 0; i--) {
899
1079
  modules = Opal.ancestors(parent.$$inc[i]);
900
1080
 
901
- for(var j = 0; j < modules.length; j++) {
1081
+ for(j = 0, jj = modules.length; j < jj; j++) {
902
1082
  result.push(modules[j]);
903
1083
  }
904
1084
  }
@@ -951,19 +1131,23 @@
951
1131
  var subscriber, subscribers = Opal.stub_subscribers,
952
1132
  i, ilength = stubs.length,
953
1133
  j, jlength = subscribers.length,
954
- method_name, stub;
1134
+ method_name, stub,
1135
+ opal_stubs = Opal.stubs;
955
1136
 
956
1137
  for (i = 0; i < ilength; i++) {
957
1138
  method_name = stubs[i];
958
- // Save method name to populate other subscribers with this stub
959
- Opal.stubs[method_name] = true;
960
- stub = Opal.stub_for(method_name);
961
1139
 
962
- for (j = 0; j < jlength; j++) {
963
- subscriber = subscribers[j];
1140
+ if(!opal_stubs.hasOwnProperty(method_name)) {
1141
+ // Save method name to populate other subscribers with this stub
1142
+ opal_stubs[method_name] = true;
1143
+ stub = Opal.stub_for(method_name);
1144
+
1145
+ for (j = 0; j < jlength; j++) {
1146
+ subscriber = subscribers[j];
964
1147
 
965
- if (!(method_name in subscriber)) {
966
- subscriber[method_name] = stub;
1148
+ if (!(method_name in subscriber)) {
1149
+ subscriber[method_name] = stub;
1150
+ }
967
1151
  }
968
1152
  }
969
1153
  }
@@ -1044,11 +1228,11 @@
1044
1228
  var inspect = "`block in " + context + "'";
1045
1229
 
1046
1230
  throw Opal.ArgumentError.$new(inspect + ': wrong number of arguments (' + actual + ' for ' + expected + ')');
1047
- }
1231
+ };
1048
1232
 
1049
1233
  // Super dispatcher
1050
- Opal.find_super_dispatcher = function(obj, jsid, current_func, defcheck, defs) {
1051
- var dispatcher;
1234
+ Opal.find_super_dispatcher = function(obj, mid, current_func, defcheck, defs) {
1235
+ var dispatcher, super_method;
1052
1236
 
1053
1237
  if (defs) {
1054
1238
  if (obj.$$is_class || obj.$$is_module) {
@@ -1059,17 +1243,17 @@
1059
1243
  }
1060
1244
  }
1061
1245
  else {
1062
- dispatcher = Opal.find_obj_super_dispatcher(obj, jsid, current_func);
1246
+ dispatcher = Opal.find_obj_super_dispatcher(obj, mid, current_func);
1063
1247
  }
1064
1248
 
1065
- dispatcher = dispatcher['$' + jsid];
1249
+ super_method = dispatcher['$' + mid];
1066
1250
 
1067
- if (!defcheck && dispatcher.$$stub && Opal.Kernel.$method_missing === obj.$method_missing) {
1251
+ if (!defcheck && super_method.$$stub && Opal.Kernel.$method_missing === obj.$method_missing) {
1068
1252
  // method_missing hasn't been explicitly defined
1069
- throw Opal.NoMethodError.$new('super: no superclass method `'+jsid+"' for "+obj, jsid);
1253
+ throw Opal.NoMethodError.$new('super: no superclass method `'+mid+"' for "+obj, mid);
1070
1254
  }
1071
1255
 
1072
- return dispatcher;
1256
+ return super_method;
1073
1257
  };
1074
1258
 
1075
1259
  // Iter dispatcher for super in a block
@@ -1091,7 +1275,7 @@
1091
1275
  return Opal.find_super_dispatcher(obj, call_jsid, current_func, defcheck);
1092
1276
  };
1093
1277
 
1094
- Opal.find_obj_super_dispatcher = function(obj, jsid, current_func) {
1278
+ Opal.find_obj_super_dispatcher = function(obj, mid, current_func) {
1095
1279
  var klass = obj.$$meta || obj.$$class;
1096
1280
 
1097
1281
  // first we need to find the class/module current_func is located on
@@ -1101,8 +1285,7 @@
1101
1285
  throw new Error("could not find current class for super()");
1102
1286
  }
1103
1287
 
1104
- jsid = '$' + jsid;
1105
- return Opal.find_super_func(klass, jsid, current_func);
1288
+ return Opal.find_super_func(klass, '$' + mid, current_func);
1106
1289
  };
1107
1290
 
1108
1291
  Opal.find_owning_class = function(klass, current_func) {
@@ -1233,6 +1416,9 @@
1233
1416
  return result;
1234
1417
  }
1235
1418
  }
1419
+ else if (candidate === Opal.JS.Error) {
1420
+ return candidate;
1421
+ }
1236
1422
  else if (candidate['$==='](exception)) {
1237
1423
  return candidate;
1238
1424
  }
@@ -1242,19 +1428,15 @@
1242
1428
  };
1243
1429
 
1244
1430
  Opal.is_a = function(object, klass) {
1245
- if (object.$$meta === klass) {
1431
+ if (object.$$meta === klass || object.$$class === klass) {
1246
1432
  return true;
1247
1433
  }
1248
1434
 
1249
- var i, length, ancestors = Opal.ancestors(object.$$class);
1250
-
1251
- for (i = 0, length = ancestors.length; i < length; i++) {
1252
- if (ancestors[i] === klass) {
1253
- return true;
1254
- }
1435
+ if (object.$$is_number && klass.$$is_number_class) {
1436
+ return true;
1255
1437
  }
1256
1438
 
1257
- ancestors = Opal.ancestors(object.$$meta);
1439
+ var i, length, ancestors = Opal.ancestors(object.$$is_class ? Opal.get_singleton_class(object) : (object.$$meta || object.$$class));
1258
1440
 
1259
1441
  for (i = 0, length = ancestors.length; i < length; i++) {
1260
1442
  if (ancestors[i] === klass) {
@@ -1383,47 +1565,40 @@
1383
1565
  return Opal.hash2(keys, map);
1384
1566
  };
1385
1567
 
1386
- // Call a ruby method on a ruby object with some arguments:
1568
+ // Calls passed method on a ruby object with arguments and block:
1569
+ //
1570
+ // Can take a method or a method name.
1571
+ //
1572
+ // 1. When method name gets passed it invokes it by its name
1573
+ // and calls 'method_missing' when object doesn't have this method.
1574
+ // Used internally by Opal to invoke method that takes a block or a splat.
1575
+ // 2. When method (i.e. method body) gets passed, it doesn't trigger 'method_missing'
1576
+ // because it doesn't know the name of the actual method.
1577
+ // Used internally by Opal to invoke 'super'.
1387
1578
  //
1388
1579
  // @example
1389
1580
  // var my_array = [1, 2, 3, 4]
1390
- // Opal.send(my_array, 'length') # => 4
1391
- // Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
1392
- //
1393
- // A missing method will be forwarded to the object via
1394
- // method_missing.
1581
+ // Opal.send(my_array, 'length') # => 4
1582
+ // Opal.send(my_array, my_array.$length) # => 4
1395
1583
  //
1396
- // The result of either call with be returned.
1584
+ // Opal.send(my_array, 'reverse!') # => [4, 3, 2, 1]
1585
+ // Opal.send(my_array, my_array['$reverse!']') # => [4, 3, 2, 1]
1397
1586
  //
1398
- // @param recv [Object] the ruby object
1399
- // @param mid [String] ruby method to call
1400
- // @return [Object] forwards the return value of the method (or of method_missing)
1401
- Opal.send = function(recv, mid) {
1402
- var args_ary = new Array(Math.max(arguments.length - 2, 0));
1403
- for(var i = 0, l = args_ary.length; i < l; i++) { args_ary[i] = arguments[i + 2]; }
1587
+ // @param recv [Object] ruby object
1588
+ // @param method [Function, String] method body or name of the method
1589
+ // @param args [Array] arguments that will be passed to the method call
1590
+ // @param block [Function] ruby block
1591
+ // @return [Object] returning value of the method call
1592
+ Opal.send = function(recv, method, args, block) {
1593
+ var body = (typeof(method) === 'string') ? recv['$'+method] : method;
1404
1594
 
1405
- var func = recv['$' + mid];
1406
-
1407
- if (func) {
1408
- return func.apply(recv, args_ary);
1595
+ if (body != null) {
1596
+ body.$$p = block;
1597
+ return body.apply(recv, args);
1409
1598
  }
1410
1599
 
1411
- return recv.$method_missing.apply(recv, [mid].concat(args_ary));
1412
- };
1413
-
1414
- Opal.block_send = function(recv, mid, block) {
1415
- var args_ary = new Array(Math.max(arguments.length - 3, 0));
1416
- for(var i = 0, l = args_ary.length; i < l; i++) { args_ary[i] = arguments[i + 3]; }
1417
-
1418
- var func = recv['$' + mid];
1419
-
1420
- if (func) {
1421
- func.$$p = block;
1422
- return func.apply(recv, args_ary);
1423
- }
1424
-
1425
- return recv.$method_missing.apply(recv, [mid].concat(args_ary));
1426
- };
1600
+ return recv.$method_missing.apply(recv, [method].concat(args));
1601
+ }
1427
1602
 
1428
1603
  // Used to define methods on an object. This is a helper method, used by the
1429
1604
  // compiled source to define methods on special case objects when the compiler
@@ -1461,29 +1636,40 @@
1461
1636
  // @param body [JS.Function] the literal JavaScript function used as method
1462
1637
  // @return [null]
1463
1638
  //
1639
+ Opal.def = function(obj, jsid, body) {
1640
+ // if instance_eval is invoked on a module/class, it sets inst_eval_mod
1641
+ if (!obj.$$eval && (obj.$$is_class || obj.$$is_module)) {
1642
+ Opal.defn(obj, jsid, body);
1643
+ }
1644
+ else {
1645
+ Opal.defs(obj, jsid, body);
1646
+ }
1647
+ };
1648
+
1649
+ // Define method on a module or class (see Opal.def).
1464
1650
  Opal.defn = function(obj, jsid, body) {
1465
1651
  obj.$$proto[jsid] = body;
1466
1652
  // for super dispatcher, etc.
1467
1653
  body.$$owner = obj;
1468
1654
 
1655
+ // is it a module?
1469
1656
  if (obj.$$is_module) {
1470
- Opal.donate(obj, jsid);
1657
+ Opal.update_includers(obj, jsid);
1471
1658
 
1472
1659
  if (obj.$$module_function) {
1473
1660
  Opal.defs(obj, jsid, body);
1474
1661
  }
1475
1662
  }
1476
1663
 
1477
- if (obj.$__id__ && !obj.$__id__.$$stub) {
1478
- var bridged = bridges[obj.$__id__()];
1479
-
1480
- if (bridged) {
1481
- for (var i = bridged.length - 1; i >= 0; i--) {
1482
- Opal.bridge_method(bridged[i], obj, jsid, body);
1483
- }
1664
+ // is it a bridged class?
1665
+ var bridged = obj.$__id__ && !obj.$__id__.$$stub && BridgedClasses[obj.$__id__()];
1666
+ if (bridged) {
1667
+ for (var i = bridged.length - 1; i >= 0; i--) {
1668
+ Opal.bridge_method(bridged[i], obj, jsid, body);
1484
1669
  }
1485
1670
  }
1486
1671
 
1672
+ // method_added/singleton_method_added hooks
1487
1673
  var singleton_of = obj.$$singleton_of;
1488
1674
  if (obj.$method_added && !obj.$method_added.$$stub && !singleton_of) {
1489
1675
  obj.$method_added(jsid.substr(1));
@@ -1495,24 +1681,14 @@
1495
1681
  return nil;
1496
1682
  };
1497
1683
 
1498
- // Define a singleton method on the given object.
1684
+ // Define a singleton method on the given object (see Opal.def).
1499
1685
  Opal.defs = function(obj, jsid, body) {
1500
1686
  Opal.defn(Opal.get_singleton_class(obj), jsid, body)
1501
1687
  };
1502
1688
 
1503
- Opal.def = function(obj, jsid, body) {
1504
- // if instance_eval is invoked on a module/class, it sets inst_eval_mod
1505
- if (!obj.$$eval && (obj.$$is_class || obj.$$is_module)) {
1506
- Opal.defn(obj, jsid, body);
1507
- }
1508
- else {
1509
- Opal.defs(obj, jsid, body);
1510
- }
1511
- };
1512
-
1513
1689
  // Called from #remove_method.
1514
1690
  Opal.rdef = function(obj, jsid) {
1515
- // TODO: remove from bridges as well
1691
+ // TODO: remove from BridgedClasses as well
1516
1692
 
1517
1693
  if (!$hasOwn.call(obj.$$proto, jsid)) {
1518
1694
  throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
@@ -1555,9 +1731,10 @@
1555
1731
  Opal.alias = function(obj, name, old) {
1556
1732
  var id = '$' + name,
1557
1733
  old_id = '$' + old,
1558
- body = obj.$$proto['$' + old];
1734
+ body = obj.$$proto['$' + old],
1735
+ alias;
1559
1736
 
1560
- // instance_eval is being run on a class/module, so that need to alias class methods
1737
+ // When running inside #instance_eval the alias refers to class methods.
1561
1738
  if (obj.$$eval) {
1562
1739
  return Opal.alias(Opal.get_singleton_class(obj), name, old);
1563
1740
  }
@@ -1575,7 +1752,35 @@
1575
1752
  }
1576
1753
  }
1577
1754
 
1578
- Opal.defn(obj, id, body);
1755
+ // If the body is itself an alias use the original body
1756
+ // to keep the max depth at 1.
1757
+ if (body.$$alias_of) body = body.$$alias_of;
1758
+
1759
+ // We need a wrapper because otherwise method $$owner and other properties
1760
+ // would be ovrewritten on the original body.
1761
+ alias = function() {
1762
+ var block = alias.$$p, args, i, ii;
1763
+
1764
+ args = new Array(arguments.length);
1765
+ for(i = 0, ii = arguments.length; i < ii; i++) {
1766
+ args[i] = arguments[i];
1767
+ }
1768
+
1769
+ if (block != null) { alias.$$p = null }
1770
+
1771
+ return Opal.send(this, body, args, block);
1772
+ };
1773
+
1774
+ // Try to make the browser pick the right name
1775
+ alias.displayName = name;
1776
+ alias.length = body.length;
1777
+ alias.$$arity = body.$$arity;
1778
+ alias.$$parameters = body.$$parameters;
1779
+ alias.$$source_location = body.$$source_location;
1780
+ alias.$$alias_of = body;
1781
+ alias.$$alias_name = name;
1782
+
1783
+ Opal.defn(obj, id, alias);
1579
1784
 
1580
1785
  return obj;
1581
1786
  };
@@ -1598,8 +1803,8 @@
1598
1803
  // ------
1599
1804
 
1600
1805
  Opal.hash_init = function(hash) {
1601
- hash.$$smap = {};
1602
- hash.$$map = {};
1806
+ hash.$$smap = Object.create(null);
1807
+ hash.$$map = Object.create(null);
1603
1808
  hash.$$keys = [];
1604
1809
  };
1605
1810
 
@@ -1607,11 +1812,11 @@
1607
1812
  to_hash.$$none = from_hash.$$none;
1608
1813
  to_hash.$$proc = from_hash.$$proc;
1609
1814
 
1610
- for (var i = 0, keys = from_hash.$$keys, length = keys.length, key, value; i < length; i++) {
1611
- key = from_hash.$$keys[i];
1815
+ for (var i = 0, keys = from_hash.$$keys, smap = from_hash.$$smap, len = keys.length, key, value; i < len; i++) {
1816
+ key = keys[i];
1612
1817
 
1613
1818
  if (key.$$is_string) {
1614
- value = from_hash.$$smap[key];
1819
+ value = smap[key];
1615
1820
  } else {
1616
1821
  value = key.value;
1617
1822
  key = key.key;
@@ -1623,16 +1828,17 @@
1623
1828
 
1624
1829
  Opal.hash_put = function(hash, key, value) {
1625
1830
  if (key.$$is_string) {
1626
- if (!hash.$$smap.hasOwnProperty(key)) {
1831
+ if (!$hasOwn.call(hash.$$smap, key)) {
1627
1832
  hash.$$keys.push(key);
1628
1833
  }
1629
1834
  hash.$$smap[key] = value;
1630
1835
  return;
1631
1836
  }
1632
1837
 
1633
- var key_hash = key.$hash(), bucket, last_bucket;
1838
+ var key_hash, bucket, last_bucket;
1839
+ key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
1634
1840
 
1635
- if (!hash.$$map.hasOwnProperty(key_hash)) {
1841
+ if (!$hasOwn.call(hash.$$map, key_hash)) {
1636
1842
  bucket = {key: key, key_hash: key_hash, value: value};
1637
1843
  hash.$$keys.push(bucket);
1638
1844
  hash.$$map[key_hash] = bucket;
@@ -1660,15 +1866,16 @@
1660
1866
 
1661
1867
  Opal.hash_get = function(hash, key) {
1662
1868
  if (key.$$is_string) {
1663
- if (hash.$$smap.hasOwnProperty(key)) {
1869
+ if ($hasOwn.call(hash.$$smap, key)) {
1664
1870
  return hash.$$smap[key];
1665
1871
  }
1666
1872
  return;
1667
1873
  }
1668
1874
 
1669
- var key_hash = key.$hash(), bucket;
1875
+ var key_hash, bucket;
1876
+ key_hash = hash.$$by_identity ? Opal.id(key) : key.$hash();
1670
1877
 
1671
- if (hash.$$map.hasOwnProperty(key_hash)) {
1878
+ if ($hasOwn.call(hash.$$map, key_hash)) {
1672
1879
  bucket = hash.$$map[key_hash];
1673
1880
 
1674
1881
  while (bucket) {
@@ -1684,7 +1891,7 @@
1684
1891
  var i, keys = hash.$$keys, length = keys.length, value;
1685
1892
 
1686
1893
  if (key.$$is_string) {
1687
- if (!hash.$$smap.hasOwnProperty(key)) {
1894
+ if (!$hasOwn.call(hash.$$smap, key)) {
1688
1895
  return;
1689
1896
  }
1690
1897
 
@@ -1702,7 +1909,7 @@
1702
1909
 
1703
1910
  var key_hash = key.$hash();
1704
1911
 
1705
- if (!hash.$$map.hasOwnProperty(key_hash)) {
1912
+ if (!$hasOwn.call(hash.$$map, key_hash)) {
1706
1913
  return;
1707
1914
  }
1708
1915
 
@@ -1777,7 +1984,7 @@
1777
1984
 
1778
1985
  hash.$$keys[i].key_hash = key_hash;
1779
1986
 
1780
- if (!hash.$$map.hasOwnProperty(key_hash)) {
1987
+ if (!$hasOwn.call(hash.$$map, key_hash)) {
1781
1988
  hash.$$map[key_hash] = hash.$$keys[i];
1782
1989
  continue;
1783
1990
  }
@@ -1831,7 +2038,7 @@
1831
2038
  if (arguments_length === 1) {
1832
2039
  args = arguments[0];
1833
2040
  for (key in args) {
1834
- if (args.hasOwnProperty(key)) {
2041
+ if ($hasOwn.call(args, key)) {
1835
2042
  value = args[key];
1836
2043
 
1837
2044
  Opal.hash_put(hash, key, value);
@@ -1855,16 +2062,16 @@
1855
2062
  return hash;
1856
2063
  };
1857
2064
 
1858
- // hash2 is a faster creator for hashes that just use symbols and
2065
+ // A faster Hash creator for hashes that just use symbols and
1859
2066
  // strings as keys. The map and keys array can be constructed at
1860
2067
  // compile time, so they are just added here by the constructor
1861
- // function
2068
+ // function.
1862
2069
  //
1863
2070
  Opal.hash2 = function(keys, smap) {
1864
2071
  var hash = new Opal.Hash.$$alloc();
1865
2072
 
1866
2073
  hash.$$smap = smap;
1867
- hash.$$map = {};
2074
+ hash.$$map = Object.create(null);
1868
2075
  hash.$$keys = keys;
1869
2076
 
1870
2077
  return hash;
@@ -1882,6 +2089,9 @@
1882
2089
  return range;
1883
2090
  };
1884
2091
 
2092
+ // Get the ivar name for a given name.
2093
+ // Mostly adds a trailing $ to reserved names.
2094
+ //
1885
2095
  Opal.ivar = function(name) {
1886
2096
  if (
1887
2097
  // properties
@@ -1904,6 +2114,21 @@
1904
2114
  };
1905
2115
 
1906
2116
 
2117
+ // Regexps
2118
+ // -------
2119
+
2120
+ // Escape Regexp special chars letting the resulting string be used to build
2121
+ // a new Regexp.
2122
+ //
2123
+ Opal.escape_regexp = function(str) {
2124
+ return str.replace(/([-[\]\/{}()*+?.^$\\| ])/g, '\\$1')
2125
+ .replace(/[\n]/g, '\\n')
2126
+ .replace(/[\r]/g, '\\r')
2127
+ .replace(/[\f]/g, '\\f')
2128
+ .replace(/[\t]/g, '\\t');
2129
+ }
2130
+
2131
+
1907
2132
  // Require system
1908
2133
  // --------------
1909
2134
 
@@ -1997,10 +2222,15 @@
1997
2222
  Opal.Module = Module = Opal.setup_class_object('Module', Module_alloc, 'Object', _Object.constructor);
1998
2223
  Opal.Class = Class = Opal.setup_class_object('Class', Class_alloc, 'Module', Module.constructor);
1999
2224
 
2000
- Opal.constants.push("BasicObject");
2001
- Opal.constants.push("Object");
2002
- Opal.constants.push("Module");
2003
- Opal.constants.push("Class");
2225
+ // BasicObject can reach itself, avoid const_set to skip the $$base_module logic
2226
+ BasicObject.$$const["BasicObject"] = BasicObject;
2227
+
2228
+ // Assign basic constants
2229
+ Opal.const_set(_Object, "BasicObject", BasicObject);
2230
+ Opal.const_set(_Object, "Object", _Object);
2231
+ Opal.const_set(_Object, "Module", Module);
2232
+ Opal.const_set(_Object, "Class", Class);
2233
+
2004
2234
 
2005
2235
  // Fix booted classes to use their metaclass
2006
2236
  BasicObject.$$class = Class;
@@ -2019,15 +2249,6 @@
2019
2249
  Module.$$parent = _Object;
2020
2250
  Class.$$parent = Module;
2021
2251
 
2022
- Opal.base = _Object;
2023
- BasicObject.$$scope = _Object.$$scope = Opal;
2024
- BasicObject.$$orig_scope = _Object.$$orig_scope = Opal;
2025
-
2026
- Module.$$scope = _Object.$$scope;
2027
- Module.$$orig_scope = _Object.$$orig_scope;
2028
- Class.$$scope = _Object.$$scope;
2029
- Class.$$orig_scope = _Object.$$orig_scope;
2030
-
2031
2252
  // Forward .toString() to #to_s
2032
2253
  _Object.$$proto.toString = function() {
2033
2254
  return this.$to_s();
@@ -2050,13 +2271,3 @@
2050
2271
 
2051
2272
  TypeError.$$super = Error;
2052
2273
  }).call(this);
2053
-
2054
- if (typeof(global) !== 'undefined') {
2055
- global.Opal = this.Opal;
2056
- Opal.global = global;
2057
- }
2058
-
2059
- if (typeof(window) !== 'undefined') {
2060
- window.Opal = this.Opal;
2061
- Opal.global = window;
2062
- }