Class: Opal::Nodes::BlockNode
- Defined in:
- opal/lib/opal/nodes/definitions.rb
Constant Summary
Constants included from Helpers
Helpers::BASIC_IDENTIFIER_RULES, Helpers::ES3_RESERVED_WORD_EXCLUSIVE, Helpers::ES51_RESERVED_WORD, Helpers::IMMUTABLE_PROPS
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
- #child_is_expr?(child) ⇒ Boolean
- #compile ⇒ Object
-
#find_inline_yield(stmt) ⇒ Sexp
When a block sexp gets generated, any inline yields (i.e. yield statements that are not direct members of the block) need to be generated as a top level member.
- #raw_expression?(child) ⇒ Boolean
- #stmt_join ⇒ 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, #helper, #in_while?, #initialize, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, #unshift, #while_loop, #with_temp, #wrap
Methods included from Helpers
#current_indent, #empty_line, #indent, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #valid_name?, #variable
Constructor Details
This class inherits a constructor from Opal::Nodes::Base
Instance Method Details
#child_is_expr?(child) ⇒ Boolean
108 109 110 |
# File 'opal/lib/opal/nodes/definitions.rb', line 108 def child_is_expr?(child) raw_expression?(child) and [:stmt, :stmt_closure].include?(@level) end |
#compile ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'opal/lib/opal/nodes/definitions.rb', line 88 def compile return push "nil" if children.empty? children.each_with_index do |child, idx| push stmt_join unless idx == 0 if yasgn = find_inline_yield(child) push compiler.process(yasgn, @level) push ";" end push compiler.process(child, @level) push ";" if child_is_expr?(child) end end |
#find_inline_yield(stmt) ⇒ Sexp
When a block sexp gets generated, any inline yields (i.e. yield statements that are not direct members of the block) need to be generated as a top level member. This is because if a yield is returned by a break statement, then the method must return.
As inline expressions in javascript cannot return, the block must be rewritten.
For example, a yield inside an array:
[1, 2, 3, yield(4)]
Must be rewitten into:
tmp = yield 4
[1, 2, 3, tmp]
This rewriting happens on sexps directly.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'opal/lib/opal/nodes/definitions.rb', line 137 def find_inline_yield(stmt) found = nil case stmt.first when :js_return if found = find_inline_yield(stmt[1]) found = found[2] end when :array stmt[1..-1].each_with_index do |el, idx| if el.first == :yield found = el stmt[idx+1] = s(:js_tmp, '$yielded') end end when :call arglist = stmt[3] arglist[1..-1].each_with_index do |el, idx| if el.first == :yield found = el arglist[idx+1] = s(:js_tmp, '$yielded') end end end if found scope.add_temp '$yielded' unless scope.has_temp? '$yielded' s(:yasgn, '$yielded', found) end end |
#raw_expression?(child) ⇒ Boolean
112 113 114 |
# File 'opal/lib/opal/nodes/definitions.rb', line 112 def raw_expression?(child) ![:xstr, :dxstr].include?(child.type) end |
#stmt_join ⇒ Object
104 105 106 |
# File 'opal/lib/opal/nodes/definitions.rb', line 104 def stmt_join scope.class_scope? ? "\n\n#{current_indent}" : "\n#{current_indent}" end |