Class: Opal::Nodes::PostArgsNode
- Defined in:
- opal/lib/opal/nodes/args/post_args.rb
Overview
Node responsible for extracting post-splat args
There can be some arguments after the splat, this is why this node exist. In this case if: a. JS arguments length > args sexp length - then our splat has some items and we know how many of them should come to splat b. JS arguments length < args sexp length - then our splat is blank
Super important: a) optional arg always goes BEFORE the rest arg b) optional args always appear in the sequence (i.e. you can't have def m(a=1,b,c=1)) c) precedence order: 1. required arg (norm arg, mlhs arg) 2. optional argument (optarg) 3. splat/rest argument (restarg) These statements simplify everything, keep them in mind.
post_args here always have the same structure:
- list of required arguments (only for mlhs, can be blank)
- list of optargs (only for post-args, can be blank)
- restarg (for both mlhs/post-args, can be nil)
- list of required args (for both mlhs/post-args, can be blank)
Instance Attribute Summary collapse
-
#kwargs ⇒ Object
readonly
kwargs contains the list of all post-kw* arguments all of them can be processed in the first oder.
-
#optargs ⇒ Object
readonly
optargs contains the list of optarg arguments all of them must be populated depending on the "arguments.length" if we have enough arguments - we fill them, if not - we populate it with its default value For post-args: can be provided from def m(a=1, *b) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b)] optargs = [(:optarg, :a, (:int, 1))] For mlhs: always blank.
-
#required_left_args ⇒ Object
readonly
required_left_args contains the list of required post args like normarg or mlhs For post-args: always blank (post args always start with optarg/restarg) For mlhs: can be provided from mlhs = (a, b, c) required_left_args = [(:arg, :a), (:arg, :b)].
-
#required_right_args ⇒ Object
readonly
required_right_args contains the list of required post args like normarg and mlhs arg For post-args: can be provided from def m(a=1,*b,c) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b), (:arg, :c)] required_right_args = [(:arg, :c)] For mlhs: can be provided from (*a, b) required_right_args = [(:arg, :b)].
-
#restarg ⇒ Object
readonly
returns a restarg sexp if we have enough "arguments" - we fill it if not - we populate it with "[]" For post-args: can be provided from def m(a=1, *b) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b)] restarg (:restarg, :b).
Attributes inherited from Base
Instance Method Summary collapse
- #compile ⇒ Object
- #compile_optarg(optarg) ⇒ Object
- #compile_required_arg(arg) ⇒ Object
- #compile_restarg ⇒ Object
- #extract_arguments ⇒ Object
- #extract_blank_restarg ⇒ Object
- #extract_restarg ⇒ Object
-
#initialize ⇒ PostArgsNode
constructor
A new instance of PostArgsNode.
- #kwargs_sexp ⇒ Object
Methods inherited from Base
#add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #class_variable_owner, #closest_module_node, #comments, #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
#initialize ⇒ PostArgsNode
Returns a new instance of PostArgsNode
73 74 75 76 77 78 79 80 81 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 73 def initialize(*) super @kwargs = [] @required_left_args = [] @optargs = [] @restarg = nil @required_right_args = [] end |
Instance Attribute Details
#kwargs ⇒ Object (readonly)
kwargs contains the list of all post-kw* arguments all of them can be processed in the first oder
32 33 34 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 32 def kwargs @kwargs end |
#optargs ⇒ Object (readonly)
optargs contains the list of optarg arguments all of them must be populated depending on the "arguments.length" if we have enough arguments - we fill them, if not - we populate it with its default value For post-args: can be provided from def m(a=1, *b) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b)] optargs = [(:optarg, :a, (:int, 1))] For mlhs: always blank
51 52 53 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 51 def optargs @optargs end |
#required_left_args ⇒ Object (readonly)
required_left_args contains the list of required post args like normarg or mlhs For post-args: always blank (post args always start with optarg/restarg) For mlhs: can be provided from mlhs = (a, b, c) required_left_args = [(:arg, :a), (:arg, :b)]
40 41 42 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 40 def required_left_args @required_left_args end |
#required_right_args ⇒ Object (readonly)
required_right_args contains the list of required post args like normarg and mlhs arg For post-args: can be provided from def m(a=1,*b,c) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b), (:arg, :c)] required_right_args = [(:arg, :c)] For mlhs: can be provided from (*a, b) required_right_args = [(:arg, :b)]
71 72 73 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 71 def required_right_args @required_right_args end |
#restarg ⇒ Object (readonly)
returns a restarg sexp if we have enough "arguments" - we fill it if not - we populate it with "[]" For post-args: can be provided from def m(a=1, *b) post-args = [(:optarg, :a, (:int, 1)), (:restarg, :b)] restarg (:restarg, :b)
60 61 62 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 60 def restarg @restarg end |
Instance Method Details
#compile ⇒ Object
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 108 def compile return if children.empty? old_working_arguments = scope.working_arguments if @sexp.[:js_source] js_source = @sexp.[:js_source] scope.working_arguments = "#{js_source}_args" else js_source = "arguments" scope.working_arguments = "$post_args" end add_temp "#{scope.working_arguments}" line "#{scope.working_arguments} = Opal.slice.call(#{js_source}, #{scope.inline_args.size}, #{js_source}.length);" extract_arguments push process(kwargs_sexp) required_left_args.each do |arg| compile_required_arg(arg) end optargs.each do |optarg| compile_optarg(optarg) end compile_restarg required_right_args.each do |arg| compile_required_arg(arg) end scope.working_arguments = old_working_arguments end |
#compile_optarg(optarg) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 145 def compile_optarg(optarg) var_name, _ = *optarg add_temp var_name line "if (#{required_right_args.size} < #{scope.working_arguments}.length) {" indent do line "#{var_name} = #{scope.working_arguments}.splice(0,1)[0];" end line "}" push process(optarg) end |
#compile_required_arg(arg) ⇒ Object
157 158 159 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 157 def compile_required_arg(arg) push process(arg) end |
#compile_restarg ⇒ Object
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 161 def compile_restarg return unless restarg line "if (#{required_right_args.size} < #{scope.working_arguments}.length) {" indent do # there are some items coming to the splat, extracting them extract_restarg end line "} else {" indent do # splat is empty extract_blank_restarg end line "}" end |
#extract_arguments ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 83 def extract_arguments found_opt_or_rest = false children.each do |arg| arg.[:post] = true case arg.type when :kwarg, :kwoptarg, :kwrestarg @kwargs << arg when :restarg @restarg = arg found_opt_or_rest = true when :optarg @optargs << arg found_opt_or_rest = true when :arg, :mlhs if found_opt_or_rest @required_right_args << arg else @required_left_args << arg end end end end |
#extract_blank_restarg ⇒ Object
188 189 190 191 192 193 194 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 188 def extract_blank_restarg var_name, _ = *restarg if var_name add_temp var_name line "#{var_name} = [];" end end |
#extract_restarg ⇒ Object
177 178 179 180 181 182 183 184 185 186 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 177 def extract_restarg extract_code = "#{scope.working_arguments}.splice(0, #{scope.working_arguments}.length - #{required_right_args.size});" var_name, _ = *restarg if var_name add_temp var_name line "#{var_name} = #{extract_code}" else line extract_code end end |
#kwargs_sexp ⇒ Object
196 197 198 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 196 def kwargs_sexp s(:post_kwargs, *kwargs) end |