opal 0.9.4 → 0.10.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +2 -3
  4. data/.gitmodules +5 -2
  5. data/.jshintrc +1 -8
  6. data/.rspec +1 -1
  7. data/.travis.yml +15 -23
  8. data/CHANGELOG.md +511 -326
  9. data/CODE_OF_CONDUCT.md +13 -15
  10. data/CONTRIBUTING.md +26 -216
  11. data/Gemfile +20 -12
  12. data/Guardfile +2 -2
  13. data/HACKING.md +230 -0
  14. data/README.md +6 -7
  15. data/bin/opal-mspec +1 -1
  16. data/config.ru +2 -2
  17. data/docs/faq.md +1 -1
  18. data/docs/source_maps.md +1 -1
  19. data/lib/opal.rb +1 -0
  20. data/lib/opal/builder.rb +1 -1
  21. data/lib/opal/cli.rb +30 -28
  22. data/lib/opal/cli_options.rb +3 -0
  23. data/lib/opal/cli_runners.rb +14 -1
  24. data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
  25. data/lib/opal/cli_runners/nashorn.rb +2 -2
  26. data/lib/opal/cli_runners/nodejs.rb +2 -2
  27. data/lib/opal/cli_runners/phantom.js +24 -0
  28. data/lib/opal/cli_runners/phantomjs.rb +10 -10
  29. data/lib/opal/cli_runners/server.rb +3 -3
  30. data/lib/opal/compiler.rb +43 -4
  31. data/lib/opal/config.rb +3 -1
  32. data/lib/opal/errors.rb +13 -0
  33. data/lib/opal/fragment.rb +0 -13
  34. data/lib/opal/nodes.rb +10 -0
  35. data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
  36. data/lib/opal/nodes/args/kwarg.rb +29 -0
  37. data/lib/opal/nodes/args/kwoptarg.rb +29 -0
  38. data/lib/opal/nodes/args/kwrestarg.rb +39 -0
  39. data/lib/opal/nodes/args/mlhsarg.rb +79 -0
  40. data/lib/opal/nodes/args/normarg.rb +26 -0
  41. data/lib/opal/nodes/args/optarg.rb +27 -0
  42. data/lib/opal/nodes/args/post_args.rb +200 -0
  43. data/lib/opal/nodes/args/post_kwargs.rb +31 -0
  44. data/lib/opal/nodes/args/restarg.rb +33 -0
  45. data/lib/opal/nodes/base.rb +12 -0
  46. data/lib/opal/nodes/call.rb +92 -33
  47. data/lib/opal/nodes/def.rb +26 -169
  48. data/lib/opal/nodes/hash.rb +10 -4
  49. data/lib/opal/nodes/helpers.rb +6 -3
  50. data/lib/opal/nodes/inline_args.rb +61 -0
  51. data/lib/opal/nodes/iter.rb +73 -82
  52. data/lib/opal/nodes/logic.rb +12 -2
  53. data/lib/opal/nodes/masgn.rb +1 -2
  54. data/lib/opal/nodes/node_with_args.rb +141 -0
  55. data/lib/opal/nodes/rescue.rb +121 -43
  56. data/lib/opal/nodes/scope.rb +24 -5
  57. data/lib/opal/nodes/super.rb +122 -54
  58. data/lib/opal/nodes/top.rb +0 -12
  59. data/lib/opal/nodes/yield.rb +2 -13
  60. data/lib/opal/parser.rb +67 -39
  61. data/lib/opal/parser/grammar.rb +3319 -2961
  62. data/lib/opal/parser/grammar.y +234 -46
  63. data/lib/opal/parser/lexer.rb +105 -17
  64. data/lib/opal/parser/sexp.rb +4 -0
  65. data/lib/opal/paths.rb +4 -0
  66. data/lib/opal/regexp_anchors.rb +19 -1
  67. data/lib/opal/sprockets.rb +21 -18
  68. data/lib/opal/sprockets/environment.rb +0 -8
  69. data/lib/opal/sprockets/processor.rb +13 -16
  70. data/lib/opal/sprockets/server.rb +6 -12
  71. data/lib/opal/version.rb +1 -1
  72. data/opal.gemspec +1 -0
  73. data/opal/corelib/array.rb +209 -131
  74. data/opal/corelib/basic_object.rb +7 -3
  75. data/opal/corelib/class.rb +11 -17
  76. data/opal/corelib/constants.rb +2 -2
  77. data/opal/corelib/enumerable.rb +178 -355
  78. data/opal/corelib/enumerator.rb +3 -46
  79. data/opal/corelib/error.rb +2 -2
  80. data/opal/corelib/file.rb +13 -1
  81. data/opal/corelib/hash.rb +26 -56
  82. data/opal/corelib/helpers.rb +10 -0
  83. data/opal/corelib/kernel.rb +6 -3
  84. data/opal/corelib/module.rb +62 -31
  85. data/opal/corelib/number.rb +7 -16
  86. data/opal/corelib/proc.rb +24 -9
  87. data/opal/corelib/range.rb +4 -13
  88. data/opal/corelib/runtime.js +515 -378
  89. data/opal/corelib/string.rb +21 -49
  90. data/opal/corelib/struct.rb +50 -35
  91. data/opal/corelib/unsupported.rb +18 -30
  92. data/opal/opal.rb +0 -1
  93. data/opal/opal/mini.rb +1 -0
  94. data/spec/README.md +6 -4
  95. data/spec/filters/bugs/array.rb +0 -42
  96. data/spec/filters/bugs/basicobject.rb +0 -2
  97. data/spec/filters/bugs/bigdecimal.rb +160 -0
  98. data/spec/filters/bugs/class.rb +0 -5
  99. data/spec/filters/bugs/date.rb +1 -48
  100. data/spec/filters/bugs/enumerable.rb +4 -12
  101. data/spec/filters/bugs/enumerator.rb +0 -1
  102. data/spec/filters/bugs/exception.rb +4 -3
  103. data/spec/filters/bugs/float.rb +4 -2
  104. data/spec/filters/bugs/kernel.rb +25 -10
  105. data/spec/filters/bugs/language.rb +119 -68
  106. data/spec/filters/bugs/method.rb +135 -0
  107. data/spec/filters/bugs/module.rb +13 -28
  108. data/spec/filters/bugs/proc.rb +18 -8
  109. data/spec/filters/bugs/range.rb +0 -3
  110. data/spec/filters/bugs/rational.rb +4 -0
  111. data/spec/filters/bugs/regexp.rb +68 -36
  112. data/spec/filters/bugs/string.rb +1 -1
  113. data/spec/filters/bugs/struct.rb +0 -12
  114. data/spec/filters/bugs/time.rb +1 -0
  115. data/spec/filters/bugs/unboundmethod.rb +2 -1
  116. data/spec/filters/unsupported/freeze.rb +3 -1
  117. data/spec/filters/unsupported/language.rb +0 -7
  118. data/spec/filters/unsupported/privacy.rb +7 -6
  119. data/spec/filters/unsupported/string.rb +10 -0
  120. data/spec/filters/unsupported/struct.rb +3 -0
  121. data/spec/filters/unsupported/symbol.rb +9 -0
  122. data/spec/filters/unsupported/taint.rb +0 -3
  123. data/spec/filters/unsupported/thread.rb +1 -0
  124. data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
  125. data/spec/lib/cli_spec.rb +42 -1
  126. data/spec/lib/compiler/call_spec.rb +700 -0
  127. data/spec/lib/compiler_spec.rb +46 -28
  128. data/spec/lib/config_spec.rb +13 -0
  129. data/spec/lib/parser/call_spec.rb +18 -0
  130. data/spec/lib/parser/def_spec.rb +29 -0
  131. data/spec/lib/parser/iter_spec.rb +15 -15
  132. data/spec/lib/parser/lambda_spec.rb +153 -12
  133. data/spec/lib/parser/string_spec.rb +5 -0
  134. data/spec/lib/parser/undef_spec.rb +1 -1
  135. data/spec/lib/parser/variables_spec.rb +24 -0
  136. data/spec/lib/paths_spec.rb +12 -5
  137. data/spec/lib/spec_helper.rb +5 -0
  138. data/spec/lib/sprockets/processor_spec.rb +6 -5
  139. data/spec/lib/sprockets_spec.rb +8 -0
  140. data/spec/mspec-opal/formatters.rb +188 -0
  141. data/spec/mspec-opal/runner.rb +193 -0
  142. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  143. data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
  144. data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
  145. data/spec/opal/core/kernel/loop_spec.rb +1 -1
  146. data/spec/opal/core/kernel/raise_spec.rb +1 -1
  147. data/spec/opal/core/language/heredoc_spec.rb +42 -0
  148. data/spec/opal/core/language/rescue_spec.rb +18 -0
  149. data/spec/opal/core/language_spec.rb +22 -0
  150. data/spec/opal/core/module/const_defined_spec.rb +1 -2
  151. data/spec/opal/core/module/name_spec.rb +6 -0
  152. data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
  153. data/spec/opal/core/runtime/rescue_spec.rb +12 -2
  154. data/spec/opal/core/runtime/super_spec.rb +1 -0
  155. data/spec/opal/core/string_spec.rb +21 -0
  156. data/spec/opal/stdlib/js_spec.rb +1 -1
  157. data/spec/opal/stdlib/native/hash_spec.rb +7 -0
  158. data/spec/opal/stdlib/promise/always_spec.rb +24 -5
  159. data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
  160. data/spec/opal/stdlib/promise/then_spec.rb +13 -5
  161. data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
  162. data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
  163. data/spec/ruby_specs +122 -0
  164. data/spec/spec_helper.rb +3 -15
  165. data/stdlib/base64.rb +51 -121
  166. data/stdlib/bigdecimal.rb +231 -0
  167. data/stdlib/bigdecimal/bignumber.js.rb +11 -0
  168. data/stdlib/bigdecimal/kernel.rb +5 -0
  169. data/stdlib/date.rb +252 -10
  170. data/stdlib/native.rb +38 -38
  171. data/stdlib/nodejs/dir.rb +8 -6
  172. data/stdlib/nodejs/file.rb +28 -3
  173. data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
  174. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
  175. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
  176. data/stdlib/nodejs/require.rb +1 -1
  177. data/stdlib/nodejs/yaml.rb +3 -2
  178. data/stdlib/opal-parser.rb +7 -2
  179. data/stdlib/pathname.rb +23 -1
  180. data/stdlib/phantomjs.rb +10 -0
  181. data/stdlib/promise.rb +38 -23
  182. data/tasks/building.rake +3 -3
  183. data/tasks/testing.rake +27 -14
  184. data/tasks/testing/mspec_special_calls.rb +1 -1
  185. data/tasks/testing/sprockets-phantomjs.js +4 -0
  186. data/test/opal/test_keyword.rb +110 -110
  187. data/test/opal/unsupported_and_bugs.rb +30 -0
  188. data/vendored-minitest/minitest/assertions.rb +1 -1
  189. metadata +65 -15
  190. data/.spectator +0 -2
  191. data/.spectator-mspec +0 -3
  192. data/opal/corelib/array/inheritance.rb +0 -127
  193. data/spec/rubyspecs +0 -139
@@ -0,0 +1,31 @@
1
+ require 'opal/nodes/base'
2
+
3
+ module Opal
4
+ module Nodes
5
+ # A node responsible for extracting
6
+ # keyword arguments list
7
+ #
8
+ # If a method/block arguments have splat we can't
9
+ # find the place where **exactly** starts keyword arguments.
10
+ #
11
+ # @see PostArgsNode
12
+ #
13
+ class PostKwargsNode < Base
14
+ handle :post_kwargs
15
+
16
+ def compile
17
+ return if children.empty?
18
+
19
+ initialize_kw_args
20
+
21
+ children.each do |arg|
22
+ push process(arg)
23
+ end
24
+ end
25
+
26
+ def initialize_kw_args
27
+ line "$kwargs = Opal.extract_kwargs(#{scope.working_arguments});"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'opal/nodes/base'
2
+
3
+ module Opal
4
+ module Nodes
5
+ # A node responsible for extracting a rest argument
6
+ # (or splat argument)
7
+ #
8
+ # def m(*rest)
9
+ #
10
+ class RestargNode < Base
11
+ handle :restarg
12
+
13
+ def compile
14
+ restarg_name = @sexp[1]
15
+ return unless restarg_name
16
+ var_name = variable(restarg_name.to_sym)
17
+
18
+ add_temp var_name
19
+
20
+ if @sexp.meta[:post]
21
+ # post restarg case (in mlhs or in deoptimized arguments)
22
+ # splat is always the last item in scope.working_arguments
23
+ line "#{var_name} = #{scope.working_arguments};"
24
+ else
25
+ # inline restarg case
26
+ offset = @sexp.meta[:offset]
27
+ # restarg value should be taken directly from parameters
28
+ line "#{var_name} = $slice.call(arguments, #{offset}, arguments.length);"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -150,6 +150,18 @@ module Opal
150
150
  def while_loop
151
151
  @compiler.instance_variable_get(:@while_loop)
152
152
  end
153
+
154
+ def has_rescue_else?
155
+ scope.has_rescue_else?
156
+ end
157
+
158
+ def in_ensure(&block)
159
+ scope.in_ensure(&block)
160
+ end
161
+
162
+ def in_ensure?
163
+ scope.in_ensure?
164
+ end
153
165
  end
154
166
  end
155
167
  end
@@ -36,63 +36,122 @@ module Opal
36
36
  default_compile
37
37
  end
38
38
 
39
- def record_method?
40
- true
41
- end
39
+ private
42
40
 
43
41
  def default_compile
42
+ # blocks need to be assigned to temp variables in order to pass them
43
+ block_temp = scope.new_temp if block_being_passed
44
+
45
+ # can't use self for splats or blocks
46
+ temporary_receiver = scope.new_temp if splat? || block_temp
47
+
48
+ # must do this after assigning temp variables
49
+ has_break = compiler.has_break? { @block_being_passed = expr(@block_being_passed) } if block_being_passed
44
50
 
45
- mid = mid_to_jsid meth.to_s
51
+ add_method temporary_receiver
46
52
 
47
- splat = arglist[1..-1].any? { |a| a.first == :splat }
53
+ add_block block_temp if block_temp
48
54
 
49
- if Sexp === arglist.last and arglist.last.type == :block_pass
50
- block = arglist.pop
51
- elsif iter
52
- block = iter
55
+ add_invocation temporary_receiver
56
+
57
+ if has_break
58
+ unshift 'return '
59
+ unshift '(function(){var $brk = Opal.new_brk(); try {'
60
+ line '} catch (err) { if (err === $brk) { return err.$v } else { throw err } }})()'
53
61
  end
54
62
 
55
- blktmp = scope.new_temp if block
56
- tmprecv = scope.new_temp if splat || blktmp
63
+ scope.queue_temp block_temp if block_temp
64
+ end
57
65
 
58
- # must do this after assigning temp variables
59
- block = expr(block) if block
66
+ def redefine_this?(temporary_receiver)
67
+ temporary_receiver != nil
68
+ end
60
69
 
61
- recv_code = recv(recv_sexp)
62
- call_recv = s(:js_tmp, tmprecv || recv_code)
70
+ def apply_call_target(temporary_receiver)
71
+ temporary_receiver || receiver_fragment
72
+ end
63
73
 
64
- if blktmp and !splat
65
- arglist.insert 1, call_recv
66
- end
74
+ def arguments_array?
75
+ splat?
76
+ end
67
77
 
68
- args = expr(arglist)
78
+ def add_invocation(temporary_receiver)
79
+ args = arguments_fragment
80
+ if redefine_this?(temporary_receiver) || arguments_array?
81
+ if arguments_array?
82
+ push ".apply("
83
+ else
84
+ push ".call("
85
+ end
69
86
 
70
- if tmprecv
71
- push "(#{tmprecv} = ", recv_code, ")#{mid}"
72
- else
73
- push recv_code, mid
74
- end
87
+ push apply_call_target(temporary_receiver)
75
88
 
76
- if blktmp
77
- unshift "(#{blktmp} = "
78
- push ", #{blktmp}.$$p = ", block, ", #{blktmp})"
79
- end
89
+ if args.any?
90
+ push ", ", args
91
+ end
80
92
 
81
- if splat
82
- push ".apply(", (tmprecv || recv_code), ", ", args, ")"
83
- elsif blktmp
84
- push ".call(", args, ")"
93
+ push ")"
85
94
  else
86
95
  push "(", args, ")"
87
96
  end
97
+ end
98
+
99
+ def add_method(temporary_receiver)
100
+ if temporary_receiver
101
+ push "(#{temporary_receiver} = ", receiver_fragment, ")#{method_jsid}"
102
+ else
103
+ push receiver_fragment, method_jsid
104
+ end
105
+ end
106
+
107
+ def add_block(block_temp)
108
+ unshift "(#{block_temp} = "
109
+ push ", #{block_temp}.$$p = ", block_being_passed, ", #{block_temp})"
110
+ end
88
111
 
89
- scope.queue_temp blktmp if blktmp
112
+ def splat?
113
+ arguments_without_block.any? { |a| a.first == :splat }
90
114
  end
91
115
 
92
116
  def recv_sexp
93
117
  recvr || s(:self)
94
118
  end
95
119
 
120
+ def receiver_fragment
121
+ recv recv_sexp
122
+ end
123
+
124
+ def arguments_fragment
125
+ expr arguments_sexp
126
+ end
127
+
128
+ def arguments_sexp
129
+ # arguments_without_block is an array, not an sexp
130
+ only_args = arguments_without_block
131
+ s(:arglist, *only_args)
132
+ end
133
+
134
+ def arguments_without_block
135
+ @arguments_without_block ||= begin
136
+ arglist[1..-1]
137
+ end
138
+ end
139
+
140
+ def block_being_passed
141
+ @block_being_passed ||= begin
142
+ args = arguments_without_block
143
+ Sexp === args.last && args.last.type == :block_pass ? args.pop : iter
144
+ end
145
+ end
146
+
147
+ def method_jsid
148
+ mid_to_jsid meth.to_s
149
+ end
150
+
151
+ def record_method?
152
+ true
153
+ end
154
+
96
155
  def attr_assignment?
97
156
  @assignment ||= meth.to_s =~ /#{REGEXP_START}[\da-z]+\=#{REGEXP_END}/i
98
157
  end
@@ -1,31 +1,21 @@
1
- require 'opal/nodes/scope'
1
+ require 'opal/nodes/node_with_args'
2
2
 
3
3
  module Opal
4
4
  module Nodes
5
5
  # FIXME: needs rewrite
6
- class DefNode < ScopeNode
6
+ class DefNode < NodeWithArgs
7
7
  handle :def
8
8
 
9
9
  children :recvr, :mid, :args, :stmts
10
10
 
11
- def opt_args
12
- @opt_args ||= args[1..-1].select { |arg| arg.first == :optarg }
13
- end
14
-
15
- def rest_arg
16
- @rest_arg ||= args[1..-1].find { |arg| arg.first == :restarg }
17
- end
11
+ attr_accessor :block_arg
18
12
 
19
- def keyword_args
20
- @keyword_args ||= args[1..-1].select do |arg|
21
- [:kwarg, :kwoptarg, :kwrestarg].include? arg.first
13
+ def extract_block_arg
14
+ if args.last.is_a?(Sexp) && args.last.type == :blockarg
15
+ @block_arg = args.pop
22
16
  end
23
17
  end
24
18
 
25
- def block_arg
26
- @block_arg ||= args[1..-1].find { |arg| arg.first == :blockarg }
27
- end
28
-
29
19
  def argc
30
20
  return @argc if @argc
31
21
 
@@ -38,7 +28,10 @@ module Opal
38
28
  end
39
29
 
40
30
  def compile
41
- params = nil
31
+ extract_block_arg
32
+ split_args
33
+
34
+ inline_params = nil
42
35
  scope_name = nil
43
36
 
44
37
  # block name (&block)
@@ -61,29 +54,27 @@ module Opal
61
54
 
62
55
  scope.block_name = block_name || '$yield'
63
56
 
64
- params = process(args)
57
+ inline_params = process(inline_args_sexp)
65
58
  stmt_code = stmt(compiler.returns(stmts))
66
59
 
67
60
  add_temp 'self = this'
68
61
 
69
- compile_rest_arg
70
- compile_opt_args
71
- compile_keyword_args
62
+ compile_inline_args
63
+ compile_post_args
72
64
 
73
- # must do this after opt args incase opt arg uses yield
74
65
  scope_name = scope.identity
75
66
 
76
67
  compile_block_arg
77
68
 
78
- if rest_arg
79
- scope.locals.delete(rest_arg[1])
80
- end
69
+ line arity_code if arity_code
81
70
 
82
71
  if scope.uses_zuper
83
72
  add_local '$zuper'
84
73
  add_local '$zuper_index'
74
+ add_local '$zuper_length'
85
75
 
86
76
  line "$zuper = [];"
77
+ line
87
78
  line "for($zuper_index = 0; $zuper_index < arguments.length; $zuper_index++) {"
88
79
  line " $zuper[$zuper_index] = arguments[$zuper_index];"
89
80
  line "}"
@@ -91,8 +82,6 @@ module Opal
91
82
 
92
83
  unshift "\n#{current_indent}", scope.to_vars
93
84
 
94
- line arity_code if arity_code
95
-
96
85
  line stmt_code
97
86
 
98
87
  if scope.catch_return
@@ -102,9 +91,12 @@ module Opal
102
91
  end
103
92
  end
104
93
 
94
+ # This is a special utf8 char ---v
95
+ function_name = valid_name?(mid) ? " ː#{mid}" : ''
96
+
105
97
  unshift ") {"
106
- unshift(params)
107
- unshift "function("
98
+ unshift(inline_params)
99
+ unshift "function#{function_name}("
108
100
  unshift "#{scope_name} = " if scope_name
109
101
  line "}"
110
102
 
@@ -122,6 +114,9 @@ module Opal
122
114
  unshift "Opal.defn(self, '$#{mid}', "
123
115
  end
124
116
  push ')'
117
+ elsif compiler.eval?
118
+ unshift "Opal.def(self, '$#{mid}', "
119
+ push ')'
125
120
  elsif scope.top?
126
121
  unshift "Opal.defn(Opal.Object, '$#{mid}', "
127
122
  push ')'
@@ -132,109 +127,6 @@ module Opal
132
127
  wrap '(', ", nil) && '#{mid}'" if expr?
133
128
  end
134
129
 
135
- def compile_block_arg
136
- if scope.uses_block?
137
- scope_name = scope.identity
138
- yielder = scope.block_name
139
-
140
- add_temp "$iter = #{scope_name}.$$p"
141
- add_temp "#{yielder} = $iter || nil"
142
-
143
- line "#{scope_name}.$$p = null;"
144
- end
145
- end
146
-
147
- def compile_rest_arg
148
- if rest_arg and rest_arg[1]
149
- splat = variable(rest_arg[1].to_sym)
150
- add_local '$splat_index'
151
- line "var array_size = arguments.length - #{argc};"
152
- line "if(array_size < 0) array_size = 0;"
153
- line "var #{splat} = new Array(array_size);"
154
- line "for($splat_index = 0; $splat_index < array_size; $splat_index++) {"
155
- line " #{splat}[$splat_index] = arguments[$splat_index + #{argc}];"
156
- line "}"
157
- end
158
- end
159
-
160
- def compile_opt_args
161
- opt_args.each do |arg|
162
- next if arg[2][2] == :undefined
163
- line "if (#{variable(arg[1])} == null) {"
164
- line " #{variable(arg[1])} = ", expr(arg[2])
165
- line "}"
166
- end
167
- end
168
-
169
- def compile_keyword_args
170
- return if keyword_args.empty?
171
- helper :hash2
172
-
173
- if rest_arg
174
- with_temp do |tmp|
175
- rest_arg_name = variable(rest_arg[1].to_sym)
176
- line "#{tmp} = #{rest_arg_name}[#{rest_arg_name}.length - 1];"
177
- line "if (#{tmp} == null || !#{tmp}.$$is_hash) {"
178
- line " $kwargs = $hash2([], {});"
179
- line "} else {"
180
- line " $kwargs = #{rest_arg_name}.pop();"
181
- line "}"
182
- end
183
- elsif last_opt_arg = opt_args.last
184
- opt_arg_name = variable(last_opt_arg[1])
185
- line "if (#{opt_arg_name} == null) {"
186
- line " $kwargs = $hash2([], {});"
187
- line "}"
188
- line "else if (#{opt_arg_name}.$$is_hash) {"
189
- line " $kwargs = #{opt_arg_name};"
190
- line " #{opt_arg_name} = ", expr(last_opt_arg[2]), ";"
191
- line "}"
192
- line "else if ($kwargs == null) {"
193
- line " $kwargs = $hash2([], {});"
194
- line "}"
195
- else
196
- line "if ($kwargs == null) {"
197
- line " $kwargs = $hash2([], {});"
198
- line "}"
199
- end
200
-
201
- line "if (!$kwargs.$$is_hash) {"
202
- line " throw Opal.ArgumentError.$new('expecting keyword args');"
203
- line "}"
204
-
205
- keyword_args.each do |kwarg|
206
- case kwarg.first
207
- when :kwoptarg
208
- arg_name = kwarg[1]
209
- var_name = variable(arg_name.to_s)
210
- add_local var_name
211
- line "if ((#{var_name} = $kwargs.$$smap['#{arg_name}']) == null) {"
212
- line " #{var_name} = ", expr(kwarg[2])
213
- line "}"
214
- when :kwarg
215
- arg_name = kwarg[1]
216
- var_name = variable(arg_name.to_s)
217
- add_local var_name
218
- line "if ((#{var_name} = $kwargs.$$smap['#{arg_name}']) == null) {"
219
- line " throw new Error('expecting keyword arg: #{arg_name}')"
220
- line "}"
221
- when :kwrestarg
222
- arg_name = kwarg[1]
223
- var_name = variable(arg_name.to_s)
224
- add_local var_name
225
-
226
- kwarg_names = keyword_args.select do |kw|
227
- [:kwoptarg, :kwarg].include? kw.first
228
- end.map { |kw| "#{kw[1].to_s.inspect}: true" }
229
-
230
- used_args = "{#{kwarg_names.join ','}}"
231
- line "#{var_name} = Opal.kwrestargs($kwargs, #{used_args});"
232
- else
233
- raise "unknown kwarg type #{kwarg.first}"
234
- end
235
- end
236
- end
237
-
238
130
  # Returns code used in debug mode to check arity of method call
239
131
  def arity_check(args, opt, splat, kwargs, block_name, mid)
240
132
  meth = mid.to_s.inspect
@@ -246,7 +138,7 @@ module Opal
246
138
 
247
139
  arity -= (kwargs.size)
248
140
 
249
- arity -= 1 if block_name
141
+ # arity -= 1 if block_name
250
142
  arity = -arity - 1 if !opt.empty? or !kwargs.empty? or splat
251
143
 
252
144
  # $arity will point to our received arguments count
@@ -255,7 +147,7 @@ module Opal
255
147
  if arity < 0 # splat or opt args
256
148
  min_arity = -(arity + 1)
257
149
  max_arity = args.size - 1
258
- max_arity -= 1 if block_name
150
+ # max_arity -= 1 if block_name
259
151
  checks = []
260
152
  checks << "$arity < #{min_arity}" if min_arity > 0
261
153
  checks << "$arity > #{max_arity}" if max_arity and not(splat)
@@ -265,40 +157,5 @@ module Opal
265
157
  end
266
158
  end
267
159
  end
268
-
269
- # def args list
270
- class ArgsNode < Base
271
- handle :args
272
-
273
- def compile
274
- done_kwargs = false
275
- have_rest = false
276
-
277
- children.each_with_index do |child, idx|
278
- case child.first
279
- when :kwarg, :kwoptarg, :kwrestarg
280
- unless done_kwargs
281
- done_kwargs = true
282
- push ', ' unless idx == 0 || have_rest
283
- scope.add_arg '$kwargs'
284
- push '$kwargs'
285
- end
286
-
287
- when :blockarg
288
- # we ignore it because we don't need it
289
-
290
- when :restarg
291
- have_rest = true
292
-
293
- else
294
- child = child[1].to_sym
295
- push ', ' unless idx == 0
296
- child = variable(child)
297
- scope.add_arg child.to_sym
298
- push child.to_s
299
- end
300
- end
301
- end
302
- end
303
160
  end
304
161
  end