opal 0.8.1 → 0.9.0.beta1

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