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.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.gitignore +2 -3
- data/.gitmodules +5 -2
- data/.jshintrc +1 -8
- data/.rspec +1 -1
- data/.travis.yml +15 -23
- data/CHANGELOG.md +511 -326
- data/CODE_OF_CONDUCT.md +13 -15
- data/CONTRIBUTING.md +26 -216
- data/Gemfile +20 -12
- data/Guardfile +2 -2
- data/HACKING.md +230 -0
- data/README.md +6 -7
- data/bin/opal-mspec +1 -1
- data/config.ru +2 -2
- data/docs/faq.md +1 -1
- data/docs/source_maps.md +1 -1
- data/lib/opal.rb +1 -0
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/cli.rb +30 -28
- data/lib/opal/cli_options.rb +3 -0
- data/lib/opal/cli_runners.rb +14 -1
- data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
- data/lib/opal/cli_runners/nashorn.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +2 -2
- data/lib/opal/cli_runners/phantom.js +24 -0
- data/lib/opal/cli_runners/phantomjs.rb +10 -10
- data/lib/opal/cli_runners/server.rb +3 -3
- data/lib/opal/compiler.rb +43 -4
- data/lib/opal/config.rb +3 -1
- data/lib/opal/errors.rb +13 -0
- data/lib/opal/fragment.rb +0 -13
- data/lib/opal/nodes.rb +10 -0
- data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
- data/lib/opal/nodes/args/kwarg.rb +29 -0
- data/lib/opal/nodes/args/kwoptarg.rb +29 -0
- data/lib/opal/nodes/args/kwrestarg.rb +39 -0
- data/lib/opal/nodes/args/mlhsarg.rb +79 -0
- data/lib/opal/nodes/args/normarg.rb +26 -0
- data/lib/opal/nodes/args/optarg.rb +27 -0
- data/lib/opal/nodes/args/post_args.rb +200 -0
- data/lib/opal/nodes/args/post_kwargs.rb +31 -0
- data/lib/opal/nodes/args/restarg.rb +33 -0
- data/lib/opal/nodes/base.rb +12 -0
- data/lib/opal/nodes/call.rb +92 -33
- data/lib/opal/nodes/def.rb +26 -169
- data/lib/opal/nodes/hash.rb +10 -4
- data/lib/opal/nodes/helpers.rb +6 -3
- data/lib/opal/nodes/inline_args.rb +61 -0
- data/lib/opal/nodes/iter.rb +73 -82
- data/lib/opal/nodes/logic.rb +12 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/node_with_args.rb +141 -0
- data/lib/opal/nodes/rescue.rb +121 -43
- data/lib/opal/nodes/scope.rb +24 -5
- data/lib/opal/nodes/super.rb +122 -54
- data/lib/opal/nodes/top.rb +0 -12
- data/lib/opal/nodes/yield.rb +2 -13
- data/lib/opal/parser.rb +67 -39
- data/lib/opal/parser/grammar.rb +3319 -2961
- data/lib/opal/parser/grammar.y +234 -46
- data/lib/opal/parser/lexer.rb +105 -17
- data/lib/opal/parser/sexp.rb +4 -0
- data/lib/opal/paths.rb +4 -0
- data/lib/opal/regexp_anchors.rb +19 -1
- data/lib/opal/sprockets.rb +21 -18
- data/lib/opal/sprockets/environment.rb +0 -8
- data/lib/opal/sprockets/processor.rb +13 -16
- data/lib/opal/sprockets/server.rb +6 -12
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/corelib/array.rb +209 -131
- data/opal/corelib/basic_object.rb +7 -3
- data/opal/corelib/class.rb +11 -17
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerable.rb +178 -355
- data/opal/corelib/enumerator.rb +3 -46
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +13 -1
- data/opal/corelib/hash.rb +26 -56
- data/opal/corelib/helpers.rb +10 -0
- data/opal/corelib/kernel.rb +6 -3
- data/opal/corelib/module.rb +62 -31
- data/opal/corelib/number.rb +7 -16
- data/opal/corelib/proc.rb +24 -9
- data/opal/corelib/range.rb +4 -13
- data/opal/corelib/runtime.js +515 -378
- data/opal/corelib/string.rb +21 -49
- data/opal/corelib/struct.rb +50 -35
- data/opal/corelib/unsupported.rb +18 -30
- data/opal/opal.rb +0 -1
- data/opal/opal/mini.rb +1 -0
- data/spec/README.md +6 -4
- data/spec/filters/bugs/array.rb +0 -42
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/bigdecimal.rb +160 -0
- data/spec/filters/bugs/class.rb +0 -5
- data/spec/filters/bugs/date.rb +1 -48
- data/spec/filters/bugs/enumerable.rb +4 -12
- data/spec/filters/bugs/enumerator.rb +0 -1
- data/spec/filters/bugs/exception.rb +4 -3
- data/spec/filters/bugs/float.rb +4 -2
- data/spec/filters/bugs/kernel.rb +25 -10
- data/spec/filters/bugs/language.rb +119 -68
- data/spec/filters/bugs/method.rb +135 -0
- data/spec/filters/bugs/module.rb +13 -28
- data/spec/filters/bugs/proc.rb +18 -8
- data/spec/filters/bugs/range.rb +0 -3
- data/spec/filters/bugs/rational.rb +4 -0
- data/spec/filters/bugs/regexp.rb +68 -36
- data/spec/filters/bugs/string.rb +1 -1
- data/spec/filters/bugs/struct.rb +0 -12
- data/spec/filters/bugs/time.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +2 -1
- data/spec/filters/unsupported/freeze.rb +3 -1
- data/spec/filters/unsupported/language.rb +0 -7
- data/spec/filters/unsupported/privacy.rb +7 -6
- data/spec/filters/unsupported/string.rb +10 -0
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +9 -0
- data/spec/filters/unsupported/taint.rb +0 -3
- data/spec/filters/unsupported/thread.rb +1 -0
- data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
- data/spec/lib/cli_spec.rb +42 -1
- data/spec/lib/compiler/call_spec.rb +700 -0
- data/spec/lib/compiler_spec.rb +46 -28
- data/spec/lib/config_spec.rb +13 -0
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/def_spec.rb +29 -0
- data/spec/lib/parser/iter_spec.rb +15 -15
- data/spec/lib/parser/lambda_spec.rb +153 -12
- data/spec/lib/parser/string_spec.rb +5 -0
- data/spec/lib/parser/undef_spec.rb +1 -1
- data/spec/lib/parser/variables_spec.rb +24 -0
- data/spec/lib/paths_spec.rb +12 -5
- data/spec/lib/spec_helper.rb +5 -0
- data/spec/lib/sprockets/processor_spec.rb +6 -5
- data/spec/lib/sprockets_spec.rb +8 -0
- data/spec/mspec-opal/formatters.rb +188 -0
- data/spec/mspec-opal/runner.rb +193 -0
- data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
- data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
- data/spec/opal/core/kernel/loop_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +1 -1
- data/spec/opal/core/language/heredoc_spec.rb +42 -0
- data/spec/opal/core/language/rescue_spec.rb +18 -0
- data/spec/opal/core/language_spec.rb +22 -0
- data/spec/opal/core/module/const_defined_spec.rb +1 -2
- data/spec/opal/core/module/name_spec.rb +6 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
- data/spec/opal/core/runtime/rescue_spec.rb +12 -2
- data/spec/opal/core/runtime/super_spec.rb +1 -0
- data/spec/opal/core/string_spec.rb +21 -0
- data/spec/opal/stdlib/js_spec.rb +1 -1
- data/spec/opal/stdlib/native/hash_spec.rb +7 -0
- data/spec/opal/stdlib/promise/always_spec.rb +24 -5
- data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
- data/spec/opal/stdlib/promise/then_spec.rb +13 -5
- data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
- data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
- data/spec/ruby_specs +122 -0
- data/spec/spec_helper.rb +3 -15
- data/stdlib/base64.rb +51 -121
- data/stdlib/bigdecimal.rb +231 -0
- data/stdlib/bigdecimal/bignumber.js.rb +11 -0
- data/stdlib/bigdecimal/kernel.rb +5 -0
- data/stdlib/date.rb +252 -10
- data/stdlib/native.rb +38 -38
- data/stdlib/nodejs/dir.rb +8 -6
- data/stdlib/nodejs/file.rb +28 -3
- data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
- data/stdlib/nodejs/require.rb +1 -1
- data/stdlib/nodejs/yaml.rb +3 -2
- data/stdlib/opal-parser.rb +7 -2
- data/stdlib/pathname.rb +23 -1
- data/stdlib/phantomjs.rb +10 -0
- data/stdlib/promise.rb +38 -23
- data/tasks/building.rake +3 -3
- data/tasks/testing.rake +27 -14
- data/tasks/testing/mspec_special_calls.rb +1 -1
- data/tasks/testing/sprockets-phantomjs.js +4 -0
- data/test/opal/test_keyword.rb +110 -110
- data/test/opal/unsupported_and_bugs.rb +30 -0
- data/vendored-minitest/minitest/assertions.rb +1 -1
- metadata +65 -15
- data/.spectator +0 -2
- data/.spectator-mspec +0 -3
- data/opal/corelib/array/inheritance.rb +0 -127
- 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
|
data/lib/opal/nodes/base.rb
CHANGED
@@ -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
|
data/lib/opal/nodes/call.rb
CHANGED
@@ -36,63 +36,122 @@ module Opal
|
|
36
36
|
default_compile
|
37
37
|
end
|
38
38
|
|
39
|
-
|
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
|
-
|
51
|
+
add_method temporary_receiver
|
46
52
|
|
47
|
-
|
53
|
+
add_block block_temp if block_temp
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
56
|
-
|
63
|
+
scope.queue_temp block_temp if block_temp
|
64
|
+
end
|
57
65
|
|
58
|
-
|
59
|
-
|
66
|
+
def redefine_this?(temporary_receiver)
|
67
|
+
temporary_receiver != nil
|
68
|
+
end
|
60
69
|
|
61
|
-
|
62
|
-
|
70
|
+
def apply_call_target(temporary_receiver)
|
71
|
+
temporary_receiver || receiver_fragment
|
72
|
+
end
|
63
73
|
|
64
|
-
|
65
|
-
|
66
|
-
|
74
|
+
def arguments_array?
|
75
|
+
splat?
|
76
|
+
end
|
67
77
|
|
68
|
-
|
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
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
89
|
+
if args.any?
|
90
|
+
push ", ", args
|
91
|
+
end
|
80
92
|
|
81
|
-
|
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
|
-
|
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
|
data/lib/opal/nodes/def.rb
CHANGED
@@ -1,31 +1,21 @@
|
|
1
|
-
require 'opal/nodes/
|
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 <
|
6
|
+
class DefNode < NodeWithArgs
|
7
7
|
handle :def
|
8
8
|
|
9
9
|
children :recvr, :mid, :args, :stmts
|
10
10
|
|
11
|
-
|
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
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
70
|
-
|
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
|
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(
|
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
|