opal 0.8.1 → 0.9.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (331) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.gitmodules +3 -3
  4. data/.jshintrc +17 -20
  5. data/.travis.yml +22 -11
  6. data/CHANGELOG.md +51 -1
  7. data/CODE_OF_CONDUCT.md +15 -0
  8. data/CONTRIBUTING.md +125 -9
  9. data/Gemfile +1 -1
  10. data/Guardfile +2 -2
  11. data/README.md +95 -29
  12. data/Rakefile +1 -1
  13. data/benchmark/benchmarks +103 -0
  14. data/benchmark/bm_array_flatten.rb +9 -0
  15. data/benchmark/bm_array_intersection_numbers.rb +7 -0
  16. data/benchmark/bm_array_intersection_objects.rb +7 -0
  17. data/benchmark/bm_array_intersection_strings.rb +7 -0
  18. data/benchmark/bm_array_join_ary.rb +9 -0
  19. data/benchmark/bm_array_minus_numbers.rb +7 -0
  20. data/benchmark/bm_array_minus_objects.rb +7 -0
  21. data/benchmark/bm_array_minus_strings.rb +7 -0
  22. data/benchmark/bm_array_union_numbers.rb +7 -0
  23. data/benchmark/bm_array_union_objects.rb +7 -0
  24. data/benchmark/bm_array_union_strings.rb +7 -0
  25. data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
  26. data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
  27. data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
  28. data/benchmark/bm_array_uniq_numbers.rb +5 -0
  29. data/benchmark/bm_array_uniq_objects.rb +5 -0
  30. data/benchmark/bm_array_uniq_strings.rb +5 -0
  31. data/benchmark/bm_dispatch_bind_table.rb +57 -0
  32. data/benchmark/bm_dispatch_code_gen.rb +65 -0
  33. data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
  34. data/benchmark/bm_dispatch_hardcoded.rb +44 -0
  35. data/benchmark/bm_dispatch_send.rb +38 -0
  36. data/benchmark/bm_dispatch_send_table.rb +57 -0
  37. data/benchmark/bm_hash_assoc_object.rb +11 -0
  38. data/benchmark/bm_hash_assoc_string.rb +9 -0
  39. data/benchmark/bm_hash_clone_object.rb +9 -0
  40. data/benchmark/bm_hash_clone_string.rb +9 -0
  41. data/benchmark/bm_hash_delete_object.rb +11 -0
  42. data/benchmark/bm_hash_delete_string.rb +9 -0
  43. data/benchmark/bm_hash_each_key_object.rb +9 -0
  44. data/benchmark/bm_hash_each_key_string.rb +9 -0
  45. data/benchmark/bm_hash_each_object.rb +9 -0
  46. data/benchmark/bm_hash_each_string.rb +9 -0
  47. data/benchmark/bm_hash_each_value_object.rb +9 -0
  48. data/benchmark/bm_hash_each_value_string.rb +9 -0
  49. data/benchmark/bm_hash_element_reference_object.rb +11 -0
  50. data/benchmark/bm_hash_element_reference_string.rb +9 -0
  51. data/benchmark/bm_hash_element_set_object.rb +5 -0
  52. data/benchmark/bm_hash_element_set_string.rb +5 -0
  53. data/benchmark/bm_hash_equal_value_object.rb +14 -0
  54. data/benchmark/bm_hash_equal_value_string.rb +11 -0
  55. data/benchmark/bm_hash_fetch_object.rb +11 -0
  56. data/benchmark/bm_hash_fetch_string.rb +9 -0
  57. data/benchmark/bm_hash_flatten_object.rb +9 -0
  58. data/benchmark/bm_hash_flatten_string.rb +9 -0
  59. data/benchmark/bm_hash_has_key_object.rb +11 -0
  60. data/benchmark/bm_hash_has_key_string.rb +9 -0
  61. data/benchmark/bm_hash_has_value_object.rb +9 -0
  62. data/benchmark/bm_hash_has_value_string.rb +9 -0
  63. data/benchmark/bm_hash_hash_object.rb +9 -0
  64. data/benchmark/bm_hash_hash_string.rb +9 -0
  65. data/benchmark/bm_hash_inspect_object.rb +9 -0
  66. data/benchmark/bm_hash_inspect_string.rb +9 -0
  67. data/benchmark/bm_hash_invert_object.rb +9 -0
  68. data/benchmark/bm_hash_invert_string.rb +9 -0
  69. data/benchmark/bm_hash_keep_if_object.rb +9 -0
  70. data/benchmark/bm_hash_keep_if_string.rb +9 -0
  71. data/benchmark/bm_hash_key_object.rb +9 -0
  72. data/benchmark/bm_hash_key_string.rb +9 -0
  73. data/benchmark/bm_hash_keys_object.rb +9 -0
  74. data/benchmark/bm_hash_keys_string.rb +9 -0
  75. data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
  76. data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
  77. data/benchmark/bm_hash_literal_object_large.rb +4 -0
  78. data/benchmark/bm_hash_literal_object_small.rb +3 -0
  79. data/benchmark/bm_hash_literal_string_large.rb +4 -0
  80. data/benchmark/bm_hash_literal_string_small.rb +3 -0
  81. data/benchmark/bm_hash_merge_object.rb +22 -0
  82. data/benchmark/bm_hash_merge_string.rb +18 -0
  83. data/benchmark/bm_hash_rassoc_object.rb +9 -0
  84. data/benchmark/bm_hash_rassoc_string.rb +9 -0
  85. data/benchmark/bm_hash_rehash_object.rb +9 -0
  86. data/benchmark/bm_hash_rehash_string.rb +9 -0
  87. data/benchmark/bm_hash_reject_bang_object.rb +9 -0
  88. data/benchmark/bm_hash_reject_bang_string.rb +9 -0
  89. data/benchmark/bm_hash_reject_object.rb +9 -0
  90. data/benchmark/bm_hash_reject_string.rb +9 -0
  91. data/benchmark/bm_hash_replace_object.rb +18 -0
  92. data/benchmark/bm_hash_replace_string.rb +14 -0
  93. data/benchmark/bm_hash_select_bang_object.rb +9 -0
  94. data/benchmark/bm_hash_select_bang_string.rb +9 -0
  95. data/benchmark/bm_hash_select_object.rb +9 -0
  96. data/benchmark/bm_hash_select_string.rb +9 -0
  97. data/benchmark/bm_hash_shift_object.rb +10 -0
  98. data/benchmark/bm_hash_shift_string.rb +10 -0
  99. data/benchmark/bm_hash_to_a_object.rb +9 -0
  100. data/benchmark/bm_hash_to_a_string.rb +9 -0
  101. data/benchmark/bm_hash_to_h_object.rb +10 -0
  102. data/benchmark/bm_hash_to_h_string.rb +10 -0
  103. data/benchmark/bm_hash_values_object.rb +9 -0
  104. data/benchmark/bm_hash_values_string.rb +9 -0
  105. data/benchmark/run.rb +48 -0
  106. data/bin/opal-mspec +1 -1
  107. data/bin/opal-repl +4 -4
  108. data/docs/compiled_ruby.md +214 -56
  109. data/docs/configuring_gems.md +2 -2
  110. data/docs/faq.md +2 -2
  111. data/docs/getting_started.md +19 -2
  112. data/docs/jquery.md +5 -5
  113. data/docs/opal_parser.md +53 -0
  114. data/docs/unsupported_features.md +2 -2
  115. data/docs/upgrading.md +22 -0
  116. data/docs/using_sprockets.md +15 -0
  117. data/examples/rack/config.ru +13 -0
  118. data/examples/sinatra/config.ru +4 -5
  119. data/lib/mspec/opal/runner.rb +54 -11
  120. data/lib/opal.rb +1 -1
  121. data/lib/opal/builder.rb +1 -1
  122. data/lib/opal/builder_processors.rb +1 -1
  123. data/lib/opal/cli.rb +17 -13
  124. data/lib/opal/cli_options.rb +1 -1
  125. data/lib/opal/compiler.rb +12 -0
  126. data/lib/opal/config.rb +4 -0
  127. data/lib/opal/nodes/arglist.rb +5 -7
  128. data/lib/opal/nodes/call.rb +6 -1
  129. data/lib/opal/nodes/call_special.rb +74 -0
  130. data/lib/opal/nodes/def.rb +35 -28
  131. data/lib/opal/nodes/definitions.rb +3 -5
  132. data/lib/opal/nodes/for.rb +13 -0
  133. data/lib/opal/nodes/helpers.rb +15 -1
  134. data/lib/opal/nodes/if.rb +5 -5
  135. data/lib/opal/nodes/iter.rb +6 -1
  136. data/lib/opal/nodes/literal.rb +1 -1
  137. data/lib/opal/nodes/logic.rb +2 -2
  138. data/lib/opal/nodes/masgn.rb +1 -2
  139. data/lib/opal/nodes/module.rb +2 -1
  140. data/lib/opal/nodes/rescue.rb +10 -1
  141. data/lib/opal/nodes/scope.rb +8 -2
  142. data/lib/opal/nodes/singleton_class.rb +1 -1
  143. data/lib/opal/nodes/top.rb +11 -0
  144. data/lib/opal/nodes/variables.rb +4 -4
  145. data/lib/opal/parser.rb +21 -3
  146. data/lib/opal/parser/grammar.rb +3115 -2961
  147. data/lib/opal/parser/grammar.y +29 -6
  148. data/lib/opal/parser/lexer.rb +18 -8
  149. data/lib/opal/sprockets.rb +85 -0
  150. data/lib/opal/sprockets/processor.rb +11 -35
  151. data/lib/opal/sprockets/server.rb +3 -15
  152. data/lib/opal/version.rb +2 -2
  153. data/opal.gemspec +4 -4
  154. data/opal/README.md +9 -0
  155. data/opal/corelib/array.rb +433 -181
  156. data/opal/corelib/basic_object.rb +48 -4
  157. data/opal/corelib/boolean.rb +15 -6
  158. data/opal/corelib/class.rb +6 -5
  159. data/opal/corelib/comparable.rb +12 -0
  160. data/opal/corelib/complex.rb +282 -0
  161. data/opal/corelib/constants.rb +9 -0
  162. data/opal/corelib/enumerable.rb +83 -34
  163. data/opal/corelib/enumerator.rb +3 -1
  164. data/opal/corelib/error.rb +49 -10
  165. data/opal/corelib/file.rb +1 -0
  166. data/opal/corelib/hash.rb +353 -577
  167. data/opal/corelib/helpers.rb +20 -0
  168. data/opal/corelib/kernel.rb +114 -59
  169. data/opal/corelib/math.rb +470 -0
  170. data/opal/corelib/method.rb +11 -2
  171. data/opal/corelib/module.rb +96 -96
  172. data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
  173. data/opal/corelib/number.rb +751 -0
  174. data/opal/corelib/numeric.rb +77 -437
  175. data/opal/corelib/proc.rb +81 -1
  176. data/opal/corelib/process.rb +27 -0
  177. data/opal/corelib/rational.rb +358 -0
  178. data/opal/corelib/regexp.rb +156 -27
  179. data/opal/corelib/runtime.js +724 -335
  180. data/opal/corelib/string.rb +93 -104
  181. data/opal/corelib/string/encoding.rb +177 -0
  182. data/opal/corelib/string/inheritance.rb +2 -0
  183. data/opal/corelib/struct.rb +105 -18
  184. data/opal/corelib/time.rb +267 -146
  185. data/opal/corelib/unsupported.rb +216 -0
  186. data/opal/corelib/variables.rb +0 -6
  187. data/opal/opal.rb +8 -22
  188. data/opal/opal/base.rb +9 -0
  189. data/opal/opal/mini.rb +17 -0
  190. data/spec/README.md +1 -1
  191. data/spec/filters/bugs/array.rb +38 -136
  192. data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
  193. data/spec/filters/bugs/class.rb +6 -12
  194. data/spec/filters/bugs/complex.rb +3 -0
  195. data/spec/filters/bugs/date.rb +162 -10
  196. data/spec/filters/bugs/enumerable.rb +31 -58
  197. data/spec/filters/bugs/enumerator.rb +42 -0
  198. data/spec/filters/bugs/exception.rb +66 -10
  199. data/spec/filters/bugs/float.rb +17 -0
  200. data/spec/filters/bugs/hash.rb +11 -97
  201. data/spec/filters/bugs/inheritance.rb +5 -0
  202. data/spec/filters/bugs/integer.rb +28 -0
  203. data/spec/filters/bugs/kernel.rb +304 -12
  204. data/spec/filters/bugs/language.rb +133 -399
  205. data/spec/filters/bugs/language_opal.rb +88 -0
  206. data/spec/filters/bugs/module.rb +203 -62
  207. data/spec/filters/bugs/numeric.rb +32 -0
  208. data/spec/filters/bugs/proc.rb +39 -0
  209. data/spec/filters/bugs/range.rb +148 -0
  210. data/spec/filters/bugs/regexp.rb +168 -0
  211. data/spec/filters/bugs/set.rb +46 -3
  212. data/spec/filters/bugs/singleton.rb +1 -2
  213. data/spec/filters/bugs/string.rb +59 -90
  214. data/spec/filters/bugs/strscan.rb +80 -0
  215. data/spec/filters/bugs/struct.rb +10 -20
  216. data/spec/filters/bugs/time.rb +17 -184
  217. data/spec/filters/bugs/unboundmethod.rb +22 -0
  218. data/spec/filters/unsupported/array.rb +163 -0
  219. data/spec/filters/unsupported/basicobject.rb +14 -0
  220. data/spec/filters/unsupported/bignum.rb +46 -0
  221. data/spec/filters/unsupported/class.rb +4 -0
  222. data/spec/filters/unsupported/delegator.rb +5 -0
  223. data/spec/filters/unsupported/enumerable.rb +11 -0
  224. data/spec/filters/unsupported/enumerator.rb +8 -9
  225. data/spec/filters/unsupported/fixnum.rb +14 -0
  226. data/spec/filters/unsupported/float.rb +41 -7
  227. data/spec/filters/unsupported/freeze.rb +45 -0
  228. data/spec/filters/unsupported/hash.rb +50 -0
  229. data/spec/filters/unsupported/integer.rb +3 -0
  230. data/spec/filters/unsupported/kernel.rb +31 -0
  231. data/spec/filters/unsupported/language.rb +17 -0
  232. data/spec/filters/unsupported/matchdata.rb +30 -0
  233. data/spec/filters/unsupported/math.rb +3 -0
  234. data/spec/filters/unsupported/module.rb +5 -3
  235. data/spec/filters/unsupported/pathname.rb +3 -0
  236. data/spec/filters/unsupported/privacy.rb +136 -0
  237. data/spec/filters/unsupported/proc.rb +3 -0
  238. data/spec/filters/unsupported/regexp.rb +59 -0
  239. data/spec/filters/unsupported/set.rb +4 -0
  240. data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
  241. data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
  242. data/spec/filters/unsupported/struct.rb +3 -0
  243. data/spec/filters/unsupported/symbol.rb +5 -0
  244. data/spec/filters/unsupported/taint.rb +16 -0
  245. data/spec/filters/unsupported/thread.rb +5 -0
  246. data/spec/filters/unsupported/time.rb +197 -16
  247. data/spec/lib/cli_spec.rb +14 -4
  248. data/spec/lib/compiler_spec.rb +9 -1
  249. data/spec/lib/parser/call_spec.rb +18 -0
  250. data/spec/lib/parser/not_spec.rb +2 -8
  251. data/spec/lib/sprockets_spec.rb +24 -0
  252. data/spec/opal/core/array/intersection_spec.rb +38 -0
  253. data/spec/opal/core/array/minus_spec.rb +38 -0
  254. data/spec/opal/core/array/union_spec.rb +38 -0
  255. data/spec/opal/core/array/uniq_spec.rb +49 -0
  256. data/spec/opal/core/exception_spec.rb +7 -0
  257. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  261. data/spec/opal/core/hash/internals_spec.rb +332 -0
  262. data/spec/opal/core/helpers_spec.rb +14 -0
  263. data/spec/opal/core/kernel/freeze_spec.rb +1 -1
  264. data/spec/opal/core/kernel/raise_spec.rb +13 -0
  265. data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
  266. data/spec/opal/core/language/class_spec.rb +55 -0
  267. data/spec/opal/core/language/fixtures/send.rb +1 -0
  268. data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
  269. data/spec/opal/core/language/send_spec.rb +5 -0
  270. data/spec/opal/core/method/to_proc_spec.rb +28 -0
  271. data/spec/opal/core/module/name_spec.rb +0 -17
  272. data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
  273. data/spec/opal/core/runtime/eval_spec.rb +1 -1
  274. data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
  275. data/spec/opal/core/runtime_spec.rb +51 -0
  276. data/spec/opal/stdlib/js_spec.rb +66 -0
  277. data/spec/opal/stdlib/native/hash_spec.rb +36 -0
  278. data/spec/rubyspecs +152 -273
  279. data/spec/spec_helper.rb +10 -11
  280. data/stdlib/base64.rb +9 -9
  281. data/stdlib/benchmark.rb +551 -4
  282. data/stdlib/console.rb +94 -0
  283. data/stdlib/date.rb +1 -1
  284. data/stdlib/encoding.rb +1 -170
  285. data/stdlib/js.rb +56 -0
  286. data/stdlib/json.rb +9 -14
  287. data/stdlib/math.rb +1 -370
  288. data/stdlib/native.rb +133 -63
  289. data/stdlib/nodejs/file.rb +5 -0
  290. data/stdlib/nodejs/fileutils.rb +13 -6
  291. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
  292. data/stdlib/opal-parser.rb +1 -2
  293. data/stdlib/ostruct.rb +65 -6
  294. data/stdlib/pp.rb +2 -4
  295. data/stdlib/rbconfig.rb +1 -3
  296. data/stdlib/strscan.rb +164 -28
  297. data/tasks/benchmarking.rake +88 -0
  298. data/tasks/testing.rake +181 -55
  299. data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
  300. data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
  301. data/test/opal/test_keyword.rb +590 -0
  302. data/vendored-minitest/minitest.rb +2 -2
  303. data/vendored-minitest/test/unit.rb +5 -0
  304. metadata +229 -62
  305. data/benchmarks/operators.rb +0 -11
  306. data/benchmarks/prova.js.rb +0 -13
  307. data/docs/libraries.md +0 -36
  308. data/lib/mspec/opal/new.html.erb +0 -1
  309. data/lib/mspec/opal/rake_task.rb +0 -248
  310. data/opal/corelib/match_data.rb +0 -128
  311. data/spec/filters/bugs/math.rb +0 -95
  312. data/spec/filters/bugs/nil.rb +0 -7
  313. data/spec/filters/bugs/opal.rb +0 -9
  314. data/spec/filters/bugs/regular_expressions.rb +0 -41
  315. data/spec/filters/bugs/stringscanner.rb +0 -33
  316. data/spec/filters/unsupported/encoding.rb +0 -102
  317. data/spec/filters/unsupported/frozen.rb +0 -92
  318. data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
  319. data/spec/filters/unsupported/integer_size.rb +0 -59
  320. data/spec/filters/unsupported/method_added.rb +0 -10
  321. data/spec/filters/unsupported/private_constants.rb +0 -30
  322. data/spec/filters/unsupported/private_methods.rb +0 -55
  323. data/spec/filters/unsupported/random.rb +0 -4
  324. data/spec/filters/unsupported/rational_numbers.rb +0 -4
  325. data/spec/filters/unsupported/regular_expressions.rb +0 -137
  326. data/spec/filters/unsupported/ruby_exe.rb +0 -5
  327. data/spec/filters/unsupported/symbols.rb +0 -17
  328. data/spec/filters/unsupported/tainted.rb +0 -180
  329. data/spec/filters/unsupported/trusted.rb +0 -88
  330. data/stdlib/process.rb +0 -10
  331. data/tasks/documenting.rake +0 -37
data/lib/opal/compiler.rb CHANGED
@@ -84,6 +84,18 @@ module Opal
84
84
  # @return [Boolean]
85
85
  compiler_option :arity_check, false, :as => :arity_check?
86
86
 
87
+ # @!method freezing?
88
+ #
89
+ # stubs out #freeze and #frozen?
90
+ #
91
+ # @return [Boolean]
92
+ compiler_option :freezing, true, :as => :freezing?
93
+
94
+ # @!method tainting?
95
+ #
96
+ # stubs out #taint, #untaint and #tainted?
97
+ compiler_option :tainting, true, :as => :tainting?
98
+
87
99
  # @!method irb?
88
100
  #
89
101
  # compile top level local vars with support for irb style vars
data/lib/opal/config.rb CHANGED
@@ -6,6 +6,8 @@ module Opal
6
6
  {
7
7
  method_missing_enabled: true,
8
8
  arity_check_enabled: false,
9
+ freezing_stubs_enabled: true,
10
+ tainting_stubs_enabled: true,
9
11
  const_missing_enabled: true,
10
12
  dynamic_require_severity: :error, # :error, :warning or :ignore
11
13
  irb_enabled: false,
@@ -25,6 +27,8 @@ module Opal
25
27
  COMPILER_KEYS = {
26
28
  method_missing: :method_missing_enabled,
27
29
  arity_check: :arity_check_enabled,
30
+ freezing: :freezing_stubs_enabled,
31
+ tainting: :tainting_stubs_enabled,
28
32
  const_missing: :const_missing_enabled,
29
33
  dynamic_require_severity: :dynamic_require_severity,
30
34
  irb: :irb_enabled,
@@ -11,25 +11,23 @@ module Opal
11
11
 
12
12
  children.each do |current|
13
13
  splat = current.first == :splat
14
- arg = expr(current)
14
+ arg = expr(current)
15
15
 
16
16
  if splat
17
17
  if work.empty?
18
18
  if code.empty?
19
- code << fragment("[].concat(")
20
19
  code << arg
21
- code << fragment(")")
22
20
  else
23
- code += ".concat(#{arg})"
21
+ code << fragment(".concat(") << arg << fragment(")")
24
22
  end
25
23
  else
26
24
  if code.empty?
27
- code << [fragment("["), work, fragment("]")]
25
+ code << fragment("[") << work << fragment("]")
28
26
  else
29
- code << [fragment(".concat(["), work, fragment("])")]
27
+ code << fragment(".concat([") << work << fragment("])")
30
28
  end
31
29
 
32
- code << [fragment(".concat("), arg, fragment(")")]
30
+ code << fragment(".concat(") << arg << fragment(")")
33
31
  end
34
32
 
35
33
  work = []
@@ -28,7 +28,7 @@ module Opal
28
28
  # some special methods need to skip compilation
29
29
  return unless compile_default?
30
30
 
31
- compiler.method_calls << meth.to_sym
31
+ compiler.method_calls << meth.to_sym if record_method?
32
32
 
33
33
  # if trying to access an lvar in irb mode
34
34
  return compile_irb_var if using_irb?
@@ -36,6 +36,10 @@ module Opal
36
36
  default_compile
37
37
  end
38
38
 
39
+ def record_method?
40
+ true
41
+ end
42
+
39
43
  def default_compile
40
44
 
41
45
  mid = mid_to_jsid meth.to_s
@@ -147,6 +151,7 @@ module Opal
147
151
  OPERATORS.each do |operator, name|
148
152
  add_special(operator.to_sym) do
149
153
  if compiler.inline_operators?
154
+ compiler.method_calls << operator.to_sym if record_method?
150
155
  compiler.operator_helpers << operator.to_sym
151
156
  lhs, rhs = expr(recvr), expr(arglist[1])
152
157
 
@@ -27,6 +27,80 @@ module Opal
27
27
  end
28
28
  end
29
29
 
30
+ # recv.JS[1] = rhs
31
+ class JsAttrAssignNode < CallNode
32
+ handle :jsattrasgn
33
+
34
+ def record_method?
35
+ false
36
+ end
37
+
38
+ def default_compile
39
+ push recv(recv_sexp), '[', expr(arglist[1]), ']', '=', expr(arglist[2])
40
+ end
41
+ end
42
+
43
+ # recv.JS.prop
44
+ # recv.JS[1]
45
+ # recv.JS.meth(arg1, arg2)
46
+ class JsCallNode < CallNode
47
+ handle :jscall
48
+
49
+ def record_method?
50
+ false
51
+ end
52
+
53
+ def default_compile
54
+ if meth == :[]
55
+ push recv(recv_sexp), '[', expr(arglist), ']'
56
+ else
57
+ mid = ".#{meth}"
58
+
59
+ splat = arglist[1..-1].any? { |a| a.first == :splat }
60
+
61
+ if Sexp === arglist.last and arglist.last.type == :block_pass
62
+ block = arglist.pop
63
+ elsif iter
64
+ block = iter
65
+ end
66
+
67
+ blktmp = scope.new_temp if block
68
+ tmprecv = scope.new_temp if splat
69
+
70
+ # must do this after assigning temp variables
71
+ block = expr(block) if block
72
+
73
+ recv_code = recv(recv_sexp)
74
+ call_recv = s(:js_tmp, blktmp || recv_code)
75
+
76
+ if blktmp
77
+ arglist.push call_recv
78
+ end
79
+
80
+ args = expr(arglist)
81
+
82
+ if tmprecv
83
+ push "(#{tmprecv} = ", recv_code, ")#{mid}"
84
+ else
85
+ push recv_code, mid
86
+ end
87
+
88
+ if blktmp
89
+ unshift "(#{blktmp} = ", block, ", "
90
+ push ")"
91
+ end
92
+
93
+ if splat
94
+ push ".apply(", tmprecv, ", ", args, ")"
95
+ else
96
+ push "(", args, ")"
97
+ end
98
+
99
+ scope.queue_temp blktmp if blktmp
100
+ end
101
+ end
102
+ end
103
+
30
104
  # lhs =~ rhs
31
105
  # s(:match3, lhs, rhs)
32
106
  class Match3Node < Base
@@ -38,7 +38,6 @@ module Opal
38
38
  end
39
39
 
40
40
  def compile
41
- jsid = mid_to_jsid mid.to_s
42
41
  params = nil
43
42
  scope_name = nil
44
43
 
@@ -76,6 +75,10 @@ module Opal
76
75
 
77
76
  compile_block_arg
78
77
 
78
+ if rest_arg
79
+ scope.locals.delete(rest_arg[1])
80
+ end
81
+
79
82
  unshift "\n#{current_indent}", scope.to_vars
80
83
  line stmt_code
81
84
 
@@ -99,16 +102,22 @@ module Opal
99
102
  if recvr
100
103
  unshift 'Opal.defs(', recv(recvr), ", '$#{mid}', "
101
104
  push ')'
102
- elsif uses_defn?(scope)
105
+ elsif scope.iter?
106
+ wrap "Opal.def(self, '$#{mid}', ", ')'
107
+ elsif scope.module? || scope.class?
103
108
  wrap "Opal.defn(self, '$#{mid}', ", ')'
104
- elsif scope.class?
105
- unshift "#{scope.proto}#{jsid} = "
106
109
  elsif scope.sclass?
107
- unshift "self.$$proto#{jsid} = "
110
+ if scope.defs
111
+ unshift "Opal.defs(self, '$#{mid}', "
112
+ else
113
+ unshift "Opal.defn(self, '$#{mid}', "
114
+ end
115
+ push ')'
108
116
  elsif scope.top?
109
- unshift "Opal.Object.$$proto#{jsid} = "
117
+ unshift "Opal.defn(Opal.Object, '$#{mid}', "
118
+ push ')'
110
119
  else
111
- unshift "def#{jsid} = "
120
+ raise "Unsupported use of `def`; please file a bug at https://github.com/opal/opal reporting this message."
112
121
  end
113
122
 
114
123
  wrap '(', ", nil) && '#{mid}'" if expr?
@@ -129,7 +138,12 @@ module Opal
129
138
  def compile_rest_arg
130
139
  if rest_arg and rest_arg[1]
131
140
  splat = variable(rest_arg[1].to_sym)
132
- line "#{splat} = $slice.call(arguments, #{argc});"
141
+ line "var array_size = arguments.length - #{argc};"
142
+ line "if(array_size < 0) array_size = 0;"
143
+ line "var #{splat} = new Array(array_size);"
144
+ line "for(var arg_index = 0; arg_index < array_size; arg_index++) {"
145
+ line " #{splat}[arg_index] = arguments[arg_index + #{argc}];"
146
+ line "}"
133
147
  end
134
148
  end
135
149
 
@@ -165,6 +179,9 @@ module Opal
165
179
  line " $kwargs = #{opt_arg_name};"
166
180
  line " #{opt_arg_name} = ", expr(last_opt_arg[2]), ";"
167
181
  line "}"
182
+ line "else if ($kwargs == null) {"
183
+ line " $kwargs = $hash2([], {});"
184
+ line "}"
168
185
  else
169
186
  line "if ($kwargs == null) {"
170
187
  line " $kwargs = $hash2([], {});"
@@ -208,22 +225,6 @@ module Opal
208
225
  end
209
226
  end
210
227
 
211
- # Simple helper to check whether this method should be defined through
212
- # `Opal.defn()` runtime helper.
213
- #
214
- # @param [Opal::Scope] scope
215
- # @returns [Boolean]
216
- #
217
- def uses_defn?(scope)
218
- if scope.iter? or scope.module?
219
- true
220
- elsif scope.class? and %w(Object BasicObject).include?(scope.name)
221
- true
222
- else
223
- false
224
- end
225
- end
226
-
227
228
  # Returns code used in debug mode to check arity of method call
228
229
  def arity_check(args, opt, splat, kwargs, block_name, mid)
229
230
  meth = mid.to_s.inspect
@@ -255,18 +256,24 @@ module Opal
255
256
 
256
257
  def compile
257
258
  done_kwargs = false
258
- children.each_with_index do |child, idx|
259
- next if :blockarg == child.first
260
- next if :restarg == child.first and child[1].nil?
259
+ have_rest = false
261
260
 
261
+ children.each_with_index do |child, idx|
262
262
  case child.first
263
263
  when :kwarg, :kwoptarg, :kwrestarg
264
264
  unless done_kwargs
265
265
  done_kwargs = true
266
- push ', ' unless idx == 0
266
+ push ', ' unless idx == 0 || have_rest
267
267
  scope.add_arg '$kwargs'
268
268
  push '$kwargs'
269
269
  end
270
+
271
+ when :blockarg
272
+ # we ignore it because we don't need it
273
+
274
+ when :restarg
275
+ have_rest = true
276
+
270
277
  else
271
278
  child = child[1].to_sym
272
279
  push ', ' unless idx == 0
@@ -18,9 +18,8 @@ module Opal
18
18
 
19
19
  children :mid
20
20
 
21
- # FIXME: we should be setting method to a stub method here
22
21
  def compile
23
- push "delete #{scope.proto}#{mid_to_jsid mid[1].to_s}"
22
+ push "Opal.udef(self, '$#{mid[1].to_s}');"
24
23
  end
25
24
  end
26
25
 
@@ -40,10 +39,9 @@ module Opal
40
39
  def compile
41
40
  if scope.class? or scope.module?
42
41
  scope.methods << "$#{new_name[1]}"
43
- push "Opal.defn(self, '$#{new_name[1]}', #{scope.proto}#{old_mid})"
44
- else
45
- push "self.$$proto#{new_mid} = self.$$proto#{old_mid}"
46
42
  end
43
+
44
+ push "Opal.alias(self, '#{new_name[1]}', '#{old_name[1]}')"
47
45
  end
48
46
  end
49
47
 
@@ -25,6 +25,19 @@ module Opal
25
25
  end
26
26
  end
27
27
 
28
+ assign.children.each do |sexp|
29
+ case sexp[0]
30
+ when :lasgn
31
+ add_local sexp[1]
32
+ when :masgn
33
+ if sexp[1][0] == :array
34
+ sexp[1][1].each do |sexp|
35
+ add_local sexp[1] if sexp[0] == :lasgn
36
+ end
37
+ end
38
+ end
39
+ end
40
+
28
41
  iter = s(:iter, s(:lasgn, loop_var), assign)
29
42
  sexp = s(:call, value, :each, s(:arglist), iter)
30
43
  push expr(sexp)
@@ -11,6 +11,12 @@ module Opal
11
11
  # ES3 reserved words that aren’t ES5.1 reserved words
12
12
  ES3_RESERVED_WORD_EXCLUSIVE = /#{REGEXP_START}(?:int|byte|char|goto|long|final|float|short|double|native|throws|boolean|abstract|volatile|transient|synchronized)#{REGEXP_END}/
13
13
 
14
+ # Prototype special properties.
15
+ PROTO_SPECIAL_PROPS = /#{REGEXP_START}(?:constructor|__proto__|__parent__|__noSuchMethod__|__count__)#{REGEXP_END}/
16
+
17
+ # Prototype special methods.
18
+ PROTO_SPECIAL_METHODS = /#{REGEXP_START}(?:hasOwnProperty|valueOf)#{REGEXP_END}/
19
+
14
20
  # Immutable properties of the global object
15
21
  IMMUTABLE_PROPS = /#{REGEXP_START}(?:NaN|Infinity|undefined)#{REGEXP_END}/
16
22
 
@@ -34,6 +40,14 @@ module Opal
34
40
  valid_name?(name.to_s) ? name : "#{name}$"
35
41
  end
36
42
 
43
+ def valid_ivar_name?(name)
44
+ not (PROTO_SPECIAL_PROPS =~ name or PROTO_SPECIAL_METHODS =~ name)
45
+ end
46
+
47
+ def ivar(name)
48
+ valid_ivar_name?(name.to_s) ? name : "#{name}$"
49
+ end
50
+
37
51
  # Converts a ruby lvar/arg name to a js identifier. Not all ruby names
38
52
  # are valid in javascript. A $ suffix is added to non-valid names.
39
53
  # varibales
@@ -48,7 +62,7 @@ module Opal
48
62
  # have a '.' prefix (for dot-calling), otherwise it will be
49
63
  # wrapped in brackets to use reference notation calling.
50
64
  def mid_to_jsid(mid)
51
- if /\=|\+|\-|\*|\/|\!|\?|\<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
65
+ if /\=|\+|\-|\*|\/|\!|\?|<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s
52
66
  "['$#{mid}']"
53
67
  else
54
68
  '.$' + mid
data/lib/opal/nodes/if.rb CHANGED
@@ -10,14 +10,14 @@ module Opal
10
10
  RUBY_ENGINE_CHECK = [:call, [:const, :RUBY_ENGINE],
11
11
  :==, [:arglist, [:str, "opal"]]]
12
12
 
13
+ RUBY_ENGINE_CHECK_NOT = [:call, [:const, :RUBY_ENGINE],
14
+ :!=, [:arglist, [:str, "opal"]]]
15
+
13
16
  RUBY_PLATFORM_CHECK = [:call, [:const, :RUBY_PLATFORM],
14
17
  :==, [:arglist, [:str, "opal"]]]
15
18
 
16
- RUBY_ENGINE_CHECK_NOT = [:call, [:call, [:const, :RUBY_ENGINE], :==,
17
- [:arglist, [:str, "opal"]]], :'!', [:arglist]]
18
-
19
- RUBY_PLATFORM_CHECK_NOT = [:call, [:call, [:const, :RUBY_PLATFORM], :==,
20
- [:arglist, [:str, "opal"]]], :'!', [:arglist]]
19
+ RUBY_PLATFORM_CHECK_NOT = [:call, [:const, :RUBY_PLATFORM],
20
+ :!=, [:arglist, [:str, "opal"]]]
21
21
 
22
22
  def compile
23
23
  truthy, falsy = self.truthy, self.falsy
@@ -65,10 +65,14 @@ module Opal
65
65
  push "if (#{arg} == null) #{arg} = nil;"
66
66
  end
67
67
  elsif arg.type == :array
68
+ vars = {}
68
69
  arg[1..-1].each_with_index do |_arg, _idx|
69
70
  _arg = variable(_arg[1])
70
- push "var #{_arg} = #{params[idx]}[#{_idx}];"
71
+ unless vars.has_key?(_arg) || params.include?(_arg)
72
+ vars[_arg] = "#{params[idx]}[#{_idx}]"
73
+ end
71
74
  end
75
+ push "var #{ vars.map{|k, v| "#{k} = #{v}"}.join(', ') };"
72
76
  else
73
77
  raise "Bad block arg type"
74
78
  end
@@ -115,6 +119,7 @@ module Opal
115
119
  sexp.each do |arg|
116
120
  if arg[0] == :lasgn
117
121
  ref = variable(arg[1])
122
+ next if ref == :_ && result.include?(ref)
118
123
  self.add_arg ref
119
124
  result << ref
120
125
  elsif arg[0] == :array
@@ -67,7 +67,7 @@ module Opal
67
67
  case value
68
68
  when ''
69
69
  push('/(?:)/')
70
- when %r{\?\<\w+\>}
70
+ when %r{\?<\w+\>}
71
71
  message = "named captures are not supported in javascript: #{value.inspect}"
72
72
  push "self.$raise(new SyntaxError('#{message}'))"
73
73
  else
@@ -96,7 +96,7 @@ module Opal
96
96
  elsif value.type == :sym
97
97
  push '[', expr(value), ']'
98
98
  else
99
- push recv(value)
99
+ push "Opal.to_a(", recv(value), ")"
100
100
  end
101
101
  end
102
102
  end
@@ -130,7 +130,7 @@ module Opal
130
130
  push "((#{tmp} = ", truthy_opt
131
131
  push ") ? "
132
132
  push expr(rhs)
133
- push " : #{tmp})"
133
+ push " : ", expr(lhs), ")"
134
134
  else
135
135
  push "(#{tmp} = "
136
136
  push expr(lhs)