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)
Constant Summary
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
-
#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, #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
#initialize ⇒ PostArgsNode
Returns a new instance of PostArgsNode
72 73 74 75 76 77 78 79 80 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 72 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
31 32 33 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 31 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
50 51 52 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 50 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)]
39 40 41 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 39 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)]
70 71 72 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 70 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)
59 60 61 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 59 def restarg @restarg end |
Instance Method Details
#compile ⇒ Object
107 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 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 107 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
144 145 146 147 148 149 150 151 152 153 154 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 144 def compile_optarg(optarg) var_name = variable(optarg[1].to_sym) 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
156 157 158 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 156 def compile_required_arg(arg) push process(arg) end |
#compile_restarg ⇒ Object
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 160 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
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 82 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
187 188 189 190 191 192 193 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 187 def extract_blank_restarg if restarg[1] var_name = variable(restarg[1].to_sym) add_temp var_name line "#{var_name} = [];" end end |
#extract_restarg ⇒ Object
176 177 178 179 180 181 182 183 184 185 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 176 def extract_restarg extract_code = "#{scope.working_arguments}.splice(0, #{scope.working_arguments}.length - #{required_right_args.size});" if restarg[1] var_name = variable(restarg[1].to_sym) add_temp var_name line "#{var_name} = #{extract_code}" else line extract_code end end |
#kwargs_sexp ⇒ Object
195 196 197 |
# File 'opal/lib/opal/nodes/args/post_args.rb', line 195 def kwargs_sexp s(:post_kwargs, *kwargs) end |