Class: Opal::Nodes::NodeWithArgs
Constant Summary
- SEXP_TO_PARAMETERS =
{
arg: :req,
mlhs: :req,
optarg: :opt,
restarg: :rest,
kwarg: :keyreq,
kwoptarg: :key,
kwrestarg: :keyrest
}
Instance Attribute Summary collapse
Attributes inherited from ScopeNode
#block_name, #catch_return, #defs, #gvars, #has_break, #ivars, #locals, #methods, #mid, #name, #parent, #rescue_else_sexp, #scope_name, #uses_super, #uses_zuper
Attributes inherited from Base
#compiler, #type
Instance Method Summary
collapse
Methods inherited from ScopeNode
#add_arg, #add_proto_ivar, #add_scope_gvar, #add_scope_ivar, #add_scope_local, #add_scope_temp, #class?, #class_scope?, #def?, #def_in_class?, #find_parent_def, #get_super_chain, #has_local?, #has_rescue_else?, #has_temp?, #identify!, #identity, #in_ensure, #in_ensure?, #in_scope, #in_while?, #iter?, #module?, #new_temp, #next_temp, #pop_while, #proto, #push_while, #queue_temp, #sclass?, #to_vars, #top?, #uses_block!, #uses_block?
Methods inherited from Base
#add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #class_variable_owner, #closest_module_node, #comments, #compile, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #has_rescue_else?, #helper, #in_ensure, #in_ensure?, #in_while?, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap
Methods included from Helpers
#conditional_send, #current_indent, #empty_line, #indent, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #mid_to_jsid, #property, #valid_name?
Constructor Details
Returns a new instance of NodeWithArgs
[View source]
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 16
def initialize(*)
super
@mlhs_args = {}
@used_kwargs = []
@mlhs_mapping = {}
@working_arguments = nil
@in_mlhs = false
@kwargs_initialized = false
@inline_args = []
@post_args = []
@post_args_started = false
end
|
Instance Attribute Details
#inline_args ⇒ Object
Returns the value of attribute inline_args
14
15
16
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 14
def inline_args
@inline_args
end
|
#kwargs_initialized ⇒ Object
Returns the value of attribute kwargs_initialized
12
13
14
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 12
def kwargs_initialized
@kwargs_initialized
end
|
#mlhs_args ⇒ Object
Returns the value of attribute mlhs_args
7
8
9
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 7
def mlhs_args
@mlhs_args
end
|
#mlhs_mapping ⇒ Object
Returns the value of attribute mlhs_mapping
9
10
11
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 9
def mlhs_mapping
@mlhs_mapping
end
|
#post_args ⇒ Object
Returns the value of attribute post_args
14
15
16
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 14
def post_args
@post_args
end
|
#used_kwargs ⇒ Object
Returns the value of attribute used_kwargs
8
9
10
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 8
def used_kwargs
@used_kwargs
end
|
#working_arguments ⇒ Object
Returns the value of attribute working_arguments
10
11
12
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 10
def working_arguments
@working_arguments
end
|
Instance Method Details
#arity ⇒ Object
[View source]
148
149
150
151
152
153
154
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 148
def arity
if rest_arg || opt_args.any? || has_only_optional_kwargs?
negative_arity
else
positive_arity
end
end
|
#arity_checks ⇒ Object
Returns an array of JS conditions for raising and argument
error caused by arity check
[View source]
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 214
def arity_checks
return @arity_checks if defined?(@arity_checks)
arity = args.children.size
arity -= (opt_args.size)
arity -= 1 if rest_arg
arity -= (keyword_args.size)
arity = -arity - 1 if !opt_args.empty? or !keyword_args.empty? or rest_arg
@arity_checks = []
if arity < 0 min_arity = -(arity + 1)
max_arity = args.children.size
@arity_checks << "$arity < #{min_arity}" if min_arity > 0
@arity_checks << "$arity > #{max_arity}" if max_arity and not(rest_arg)
else
@arity_checks << "$arity !== #{arity}"
end
@arity_checks
end
|
#build_parameter(parameter_type, parameter_name) ⇒ Object
[View source]
181
182
183
184
185
186
187
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 181
def build_parameter(parameter_type, parameter_name)
if parameter_name
"['#{parameter_type}', '#{parameter_name}']"
else
"['#{parameter_type}']"
end
end
|
#compile_block_arg ⇒ Object
[View source]
101
102
103
104
105
106
107
108
109
110
111
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 101
def compile_block_arg
if scope.uses_block?
scope_name = scope.identity
yielder = scope.block_name
add_temp "$iter = #{scope_name}.$$p"
add_temp "#{yielder} = $iter || nil"
line "if ($iter) #{scope_name}.$$p = null;"
end
end
|
#compile_inline_args ⇒ Object
[View source]
91
92
93
94
95
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 91
def compile_inline_args
inline_args.each do |inline_arg|
push process(inline_arg)
end
end
|
#compile_post_args ⇒ Object
[View source]
97
98
99
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 97
def compile_post_args
push process(post_args_sexp)
end
|
#has_only_optional_kwargs? ⇒ Boolean
[View source]
140
141
142
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 140
def has_only_optional_kwargs?
keyword_args.any? && keyword_args.all? { |arg| [:kwoptarg, :kwrestarg].include?(arg.type) }
end
|
#has_required_kwargs? ⇒ Boolean
[View source]
144
145
146
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 144
def has_required_kwargs?
keyword_args.any? { |arg| arg.type == :kwarg }
end
|
#in_mlhs ⇒ Object
[View source]
120
121
122
123
124
125
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 120
def in_mlhs
old_mlhs = @in_mlhs
@in_mlhs = true
yield
@in_mlhs = old_mlhs
end
|
#in_mlhs? ⇒ Boolean
[View source]
127
128
129
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 127
def in_mlhs?
@in_mlhs
end
|
#inline_args_sexp ⇒ Object
[View source]
83
84
85
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 83
def inline_args_sexp
s(:inline_args, *args.children)
end
|
#keyword_args ⇒ Object
[View source]
77
78
79
80
81
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 77
def keyword_args
@keyword_args ||= args.children.select do |arg|
[:kwarg, :kwoptarg, :kwrestarg].include? arg.type
end
end
|
#negative_arity ⇒ Object
[View source]
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 156
def negative_arity
required_plain_args = args.children.select do |arg|
[:arg, :mlhs].include?(arg.type)
end
result = required_plain_args.size
if has_required_kwargs?
result += 1
end
result = -result - 1
result
end
|
#opt_args ⇒ Object
[View source]
69
70
71
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 69
def opt_args
@opt_args ||= args.children.select { |arg| arg.type == :optarg }
end
|
#optimize_args! ⇒ Object
[View source]
131
132
133
134
135
136
137
138
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 131
def optimize_args!
if post_args.length == 1 && post_args.first.type == :restarg
rest_arg = post_args.pop
rest_arg.meta[:offset] = inline_args.length
inline_args << rest_arg
end
end
|
#parameters_code ⇒ Object
[View source]
199
200
201
202
203
204
205
206
207
208
209
210
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 199
def parameters_code
stringified_parameters = args.children.map do |arg|
value = arg.type == :mlhs ? nil : arg.children[0]
build_parameter(SEXP_TO_PARAMETERS[arg.type], value)
end
if block_arg
stringified_parameters << "['block', '#{block_arg}']"
end
"[#{stringified_parameters.join(', ')}]"
end
|
#positive_arity ⇒ Object
[View source]
172
173
174
175
176
177
178
179
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 172
def positive_arity
result = args.children.size
result -= keyword_args.size
result += 1 if keyword_args.any?
result
end
|
#post_args_sexp ⇒ Object
[View source]
87
88
89
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 87
def post_args_sexp
s(:post_args, *post_args)
end
|
#rest_arg ⇒ Object
[View source]
73
74
75
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 73
def rest_arg
@rest_arg ||= args.children.find { |arg| arg.type == :restarg }
end
|
#split_args ⇒ Object
[View source]
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 32
def split_args
args = self.args.children
args.each_with_index do |arg, idx|
case arg.type
when :arg, :mlhs, :kwarg, :kwoptarg, :kwrestarg
if @post_args_started
@post_args << arg
else
@inline_args << arg
end
when :restarg
@post_args_started = true
@post_args << arg
when :optarg
if args[idx, args.length].any? { |next_arg| next_arg.type != :optarg && next_arg.type != :restarg }
@post_args_started = true
end
if @post_args_started
@post_args << arg
else
@inline_args << arg
end
end
end
inline_args.map! do |inline_arg|
inline_arg.updated(nil, nil, meta: { inline: true })
end
optimize_args!
end
|
#with_inline_args(args) ⇒ Object
[View source]
113
114
115
116
117
118
|
# File 'opal/lib/opal/nodes/node_with_args.rb', line 113
def with_inline_args(args)
old_inline_args = inline_args
self.inline_args = args
yield
self.inline_args = old_inline_args
end
|