[フレーム]

Class: Opal::Nodes::BlockNode

Inherits:
Base
  • Object
  • Base
  • Opal::Nodes::BlockNode
show all
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 , Helpers::PROTO_SPECIAL_METHODS , Helpers::PROTO_SPECIAL_PROPS

Instance Attribute Summary

Attributes inherited from Base

#compiler , #type

Instance Method Summary collapse

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? , 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

This class inherits a constructor from Opal::Nodes::Base

Instance Method Details

#child_is_expr?(child) ⇒ Boolean

Returns:

  • (Boolean)
117
118
119
# File 'opal/lib/opal/nodes/definitions.rb', line 117
def child_is_expr?(child)
 raw_expression?(child) and [:stmt, :stmt_closure].include?(@level)
end

#compileObject

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'opal/lib/opal/nodes/definitions.rb', line 97
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.

Parameters:

  • stmt (Sexp )

    sexps to (maybe) rewrite

Returns:

146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'opal/lib/opal/nodes/definitions.rb', line 146
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

Returns:

  • (Boolean)
121
122
123
# File 'opal/lib/opal/nodes/definitions.rb', line 121
def raw_expression?(child)
 ![:xstr, :dxstr].include?(child.type)
end

#stmt_joinObject

113
114
115
# File 'opal/lib/opal/nodes/definitions.rb', line 113
def stmt_join
 scope.class_scope? ? "\n\n#{current_indent}" : "\n#{current_indent}"
end

AltStyle によって変換されたページ (->オリジナル) /