Class: Opal::Nodes::NodeWithArgs
  
  
  
  Constant Summary
  
    
      - SEXP_TO_PARAMETERS =
        
      
- {
  arg: :req,
  mlhs: :req,
  optarg: :opt,
  restarg: :rest,
  kwarg: :keyreq,
  kwoptarg: :key,
  kwrestarg: :keyrest
}
Constants included
     from Helpers
  Helpers::BASIC_IDENTIFIER_RULES, Helpers::ES3_RESERVED_WORD_EXCLUSIVE, Helpers::ES51_RESERVED_WORD, Helpers::IMMUTABLE_PROPS, Helpers::PROTO_SPECIAL_METHODS, Helpers::PROTO_SPECIAL_PROPS, Helpers::RESERVED_FUNCTION_NAMES
  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, #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
  #current_indent, #empty_line, #indent, #ivar, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #valid_ivar_name?, #valid_name?, #variable
  Constructor Details
  
    
  
  
    Returns a new instance of NodeWithArgs
   
 
  
  
    | 
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 15
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
   
 
  
  
    | 
13
14
15 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 13
def inline_args
  @inline_args
end | 
 
    
      
      
      
  
  
    #kwargs_initialized  ⇒ Object 
  
  
  
  
    Returns the value of attribute kwargs_initialized
   
 
  
  
    | 
11
12
13 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 11
def kwargs_initialized
  @kwargs_initialized
end | 
 
    
      
      
      
  
  
    #mlhs_args  ⇒ Object 
  
  
  
  
    Returns the value of attribute mlhs_args
   
 
  
  
    | 
6
7
8 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 6
def mlhs_args
  @mlhs_args
end | 
 
    
      
      
      
  
  
    #mlhs_mapping  ⇒ Object 
  
  
  
  
    Returns the value of attribute mlhs_mapping
   
 
  
  
    | 
8
9
10 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 8
def mlhs_mapping
  @mlhs_mapping
end | 
 
    
      
      
      
  
  
    #post_args  ⇒ Object  
  
  
  
  
    Returns the value of attribute post_args
   
 
  
  
    | 
13
14
15 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 13
def post_args
  @post_args
end | 
 
    
      
      
      
  
  
    #used_kwargs  ⇒ Object 
  
  
  
  
    Returns the value of attribute used_kwargs
   
 
  
  
    | 
7
8
9 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 7
def used_kwargs
  @used_kwargs
end | 
 
    
      
      
      
  
  
    #working_arguments  ⇒ Object 
  
  
  
  
    Returns the value of attribute working_arguments
   
 
  
  
    | 
9
10
11 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 9
def working_arguments
  @working_arguments
end | 
 
    
   
  
    Instance Method Details
    
      
  
  
    #arity  ⇒ Object 
  
  
  
  
    | 
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
   
 
  
  
    | 
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
239
240
241 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 214
def arity_checks
  return @arity_checks if @arity_checks
  arity = args.size - 1
  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
    aritycode = "var $arity = arguments.length;"
  @arity_checks = []
  if arity < 0     min_arity = -(arity + 1)
    max_arity = args.size - 1
    @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 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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 "#{scope_name}.$$p = null;"
  end
end | 
 
    
      
  
  
    #compile_inline_args  ⇒ Object 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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 
  
  
  
  
    | 
127
128
129 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 127
def in_mlhs?
  @in_mlhs
end | 
 
    
      
  
  
    #inline_args_sexp  ⇒ Object 
  
  
  
  
    | 
83
84
85 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 83
def inline_args_sexp
  s(:inline_args, *args[1..-1])
end | 
 
    
      
  
  
    #keyword_args  ⇒ Object 
  
  
  
  
    | 
77
78
79
80
81 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 77
def keyword_args
  @keyword_args ||= args[1..-1].select do |arg|
    [:kwarg, :kwoptarg, :kwrestarg].include? arg.first
  end
end | 
 
    
      
  
  
    #negative_arity  ⇒ Object 
  
  
  
  
    | 
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 
  
  
  
  
    | 
69
70
71 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 69
def opt_args
  @opt_args ||= args[1..-1].select { |arg| arg.first == :optarg }
end | 
 
    
      
  
  
    #optimize_args!  ⇒ Object 
  
  
  
  
    | 
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 
  
  
  
  
    | 
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[1]
    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 
  
  
  
  
    | 
172
173
174
175
176
177
178
179 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 172
def positive_arity
  result = args.size - 1
  result -= keyword_args.size
  result += 1 if keyword_args.any?
  result
end | 
 
    
      
  
  
    #post_args_sexp  ⇒ Object 
  
  
  
  
    | 
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 
  
  
  
  
    | 
73
74
75 | # File 'opal/lib/opal/nodes/node_with_args.rb', line 73
def rest_arg
  @rest_arg ||= args[1..-1].find { |arg| arg.first == :restarg }
end | 
 
    
      
  
  
    #split_args  ⇒ Object 
  
  
  
  
    | 
31
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 31
def split_args
  args = self.args[1..-1]
  args.each_with_index do |arg, idx|
    last_argument = (idx == args.length - 1)
    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.each do |inline_arg|
    inline_arg.meta[:inline] = true
  end
  optimize_args!
end | 
 
    
      
  
  
    #with_inline_args(args)  ⇒ Object 
  
  
  
  
    | 
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 |