Class: Opal::Nodes::IfNode
  
  
  
  
  
    - Inherits:
- 
      Base
      
        
          - Object
- Base
- Opal::Nodes::IfNode
 show all
    - Defined in:
- opal/lib/opal/nodes/if.rb
 
  Instance Attribute Summary
  
  Attributes inherited from Base
  #compiler, #sexp, #type
  
    
      Instance Method Summary
      collapse
    
    
  
  
  
  
  
  
  
  
  
  Methods inherited from Base
  #add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #class_variable_owner, #class_variable_owner_nesting_level, #comments, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #has_rescue_else?, #helper, #in_ensure, #in_ensure?, #in_resbody, #in_resbody?, #in_rescue, #in_while?, #initialize, #process, #push, #recv, #recv?, #s, #scope, #source_location, #stmt, #stmt?, #top_scope, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap
  
  
  
  
  
  
  
  
  Methods included from Helpers
  #conditional_send, #current_indent, #empty_line, #indent, #js_truthy, #js_truthy_optimize, #line, #mid_to_jsid, #property, #valid_name?
  
    Instance Method Details
    
      
  
  
    #compile  ⇒ Object 
  
  
  
  
    | 
12
13
14
15
16
17
18
19
20
21
22
23
24 | # File 'opal/lib/opal/nodes/if.rb', line 12
def compile
  if should_compile_as_simple_expression?
    if true_body == s(:true)
      compile_with_binary_or
    elsif false_body == s(:false)
      compile_with_binary_and
    else
      compile_with_ternary
    end
  else
    compile_with_if
  end
end | 
 
    
      
  
  
    #compile_with_binary_and  ⇒ Object 
  
  
  
  
    | 
117
118
119
120
121
122
123
124
125
126
127
128 | # File 'opal/lib/opal/nodes/if.rb', line 117
def compile_with_binary_and
  if sexp.meta[:do_js_truthy_on_true_body]
    truthy = js_truthy(true_body || s(:nil))
  else
    truthy = expr(true_body || s(:nil))
  end
  push '('
  push js_truthy(test), ' && '
  push '(', truthy, ')'
  push ')'
end | 
 
    
      
  
  
    #compile_with_binary_or  ⇒ Object 
  
  
  
  
    | 
130
131
132
133
134
135
136
137
138
139
140
141 | # File 'opal/lib/opal/nodes/if.rb', line 130
def compile_with_binary_or
  if sexp.meta[:do_js_truthy_on_false_body]
    falsy = js_truthy(false_body || s(:nil))
  else
    falsy = expr(false_body || s(:nil))
  end
  push '('
  push js_truthy(test), ' || '
  push '(', falsy, ')'
  push ')'
end | 
 
    
      
  
  
    #compile_with_if  ⇒ Object 
  
  
  
  
    | 
26
27
28
29
30
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/if.rb', line 26
def compile_with_if
  truthy = self.truthy
  falsy = self.falsy
  if falsy && !truthy
        push 'if (!', js_truthy(test), ') {'
    falsy, truthy = truthy, falsy
  else
    push 'if (', js_truthy(test), ') {'
  end
    indent { line stmt(truthy) } if truthy
  if falsy
    if falsy.type == :if
      line '} else ', stmt(falsy)
    else
      line '} else {'
      indent do
        line stmt(falsy)
      end
      line '}'
    end
  else
    line '}'
            line 'return nil;' if expects_expression?
  end
  if expects_expression?
    if scope.await_encountered
      wrap '(await (async function() {', '})())'
    else
      wrap '(function() {', '})()'
    end
  end
end | 
 
    
      
  
  
    #compile_with_ternary  ⇒ Object 
  
  
  
  
    | 
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 | # File 'opal/lib/opal/nodes/if.rb', line 99
def compile_with_ternary
  truthy = true_body
  falsy = false_body
  push '('
  push js_truthy(test), ' ? '
  push '(', expr(truthy || s(:nil)), ') : '
  if !falsy || falsy.type == :if
    push expr(falsy || s(:nil))
  else
    push '(', expr(falsy || s(:nil)), ')'
  end
  push ')'
end | 
 
    
      
  
  
    #expects_expression?  ⇒ Boolean 
  
  
  
  
    | 
85
86
87 | # File 'opal/lib/opal/nodes/if.rb', line 85
def expects_expression?
  expr? || recv?
end | 
 
    
      
  
  
    #falsy  ⇒ Object 
  
  
  
  
    | 
73
74
75 | # File 'opal/lib/opal/nodes/if.rb', line 73
def falsy
  returnify(false_body)
end | 
 
    
      
  
  
    #returnify(body)  ⇒ Object 
  
  
  
  
    | 
77
78
79
80
81
82
83 | # File 'opal/lib/opal/nodes/if.rb', line 77
def returnify(body)
  if expects_expression? && body
    compiler.returns(body)
  else
    body
  end
end | 
 
    
      
  
  
    #should_compile_as_simple_expression?  ⇒ Boolean 
  
  
  
  
    There was a particular case in the past, that when we
expected an expression from if, we always had to closure
it. This produced an ugly code that was hard to minify.
This addition tries to make a few cases compiled with
a ternary operator instead and possibly a binary operator
even?
   
 
  
    | 
95
96
97 | # File 'opal/lib/opal/nodes/if.rb', line 95
def should_compile_as_simple_expression?
  expects_expression? && simple?(true_body) && simple?(false_body)
end | 
 
    
      
  
  
    #simple?(body)  ⇒ Boolean 
  
  
  
  
    Let's ensure there are no control flow statements inside.
   
 
  
    | 
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 | # File 'opal/lib/opal/nodes/if.rb', line 144
def simple?(body)
  case body
  when AST::Node
    case body.type
    when :return, :js_return, :break, :next, :redo, :retry
      false
    when :xstr
      XStringNode.single_line?(
        XStringNode.strip_empty_children(body.children)
      )
    else
      body.children.all? { |i| simple?(i) }
    end
  else
    true
  end
end | 
 
    
      
  
  
    #truthy  ⇒ Object 
  
  
  
  
    | 
69
70
71 | # File 'opal/lib/opal/nodes/if.rb', line 69
def truthy
  returnify(true_body)
end |