Class: StyleScript::IfNode

Inherits:
Node
  • Object
show all
Defined in:
lib/style_script/nodes.rb

Overview

If/else statements. Switch/whens get compiled into these. Acts as an expression by pushing down requested returns to the expression bodies. Single-expression IfNodes are compiled into ternary operators if possible, because ternaries are first-class returnable assignable expressions.

Constant Summary

Constants inherited from Node

Node::TAB

Instance Method Summary collapse

Methods inherited from Node

#children, children, #compile, #compile_closure, #contains?, #idt, statement, statement_only, #statement_only?, top_sensitive, #top_sensitive?, #unwrap, #write

Constructor Details

#initialize(condition, body, else_body = nil, tags = {}) ⇒ IfNode

Returns a new instance of IfNode.



993
994
995
996
997
998
999
1000
# File 'lib/style_script/nodes.rb', line 993

def initialize(condition, body, else_body=nil, tags={})
  @condition = condition
  @body      = body && body.unwrap
  @else_body = else_body && else_body.unwrap
  @tags      = tags
  @multiple  = true if @condition.is_a?(Array)
  @condition = OpNode.new("!", ParentheticalNode.new(@condition)) if @tags[:invert]
end

Instance Method Details

#<<(else_body) ⇒ Object



1002
1003
1004
1005
1006
# File 'lib/style_script/nodes.rb', line 1002

def <<(else_body)
  eb = else_body.unwrap
  @else_body ? @else_body << eb : @else_body = eb
  self
end

#add_comment(comment) ⇒ Object



1008
1009
1010
1011
# File 'lib/style_script/nodes.rb', line 1008

def add_comment(comment)
  @comment = comment
  self
end

#add_else(exprs) ⇒ Object

Rewrite a chain of IfNodes to add a default case as the final else.



1027
1028
1029
1030
# File 'lib/style_script/nodes.rb', line 1027

def add_else(exprs)
  chain? ? @else_body.add_else(exprs) : @else_body = (exprs && exprs.unwrap)
  self
end

#chain?Boolean

If the else_body is an IfNode itself, then we’ve got an if-else chain.

Returns:

  • (Boolean)


1033
1034
1035
# File 'lib/style_script/nodes.rb', line 1033

def chain?
  @chain ||= @else_body && @else_body.is_a?(IfNode)
end

#compile_condition(o) ⇒ Object



1043
1044
1045
# File 'lib/style_script/nodes.rb', line 1043

def compile_condition(o)
  [@condition].flatten.map {|c| c.compile(o) }.join(' || ')
end

#compile_node(o) ⇒ Object



1047
1048
1049
# File 'lib/style_script/nodes.rb', line 1047

def compile_node(o)
  write(statement? ? compile_statement(o) : compile_ternary(o))
end

#compile_statement(o) ⇒ Object

Compile the IfNode as a regular if-else statement. Flattened chains force sub-else bodies into statement form.



1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
# File 'lib/style_script/nodes.rb', line 1053

def compile_statement(o)
  child       = o.delete(:chain_child)
  cond_o      = o.dup
  cond_o.delete(:return)
  o[:indent]  = idt(1)
  o[:top]     = true
  if_dent     = child ? '' : idt
  com_dent    = child ? idt : ''
  prefix      = @comment ? @comment.compile(cond_o) + "\n#{com_dent}" : ''
  body        = Expressions.wrap(@body).compile(o)
  if_part     = "#{prefix}#{if_dent}if (#{compile_condition(cond_o)}) {\n#{body}\n#{idt}}"
  return if_part unless @else_body
  else_part = chain? ?
    " else #{@else_body.compile(o.merge(:indent => idt, :chain_child => true))}" :
    " else {\n#{Expressions.wrap(@else_body).compile(o)}\n#{idt}}"
  if_part + else_part
end

#compile_ternary(o) ⇒ Object

Compile the IfNode into a ternary operator.



1072
1073
1074
1075
1076
# File 'lib/style_script/nodes.rb', line 1072

def compile_ternary(o)
  if_part   = "#{@condition.compile(o)} ? #{@body.compile(o)}"
  else_part = @else_body ? "#{@else_body.compile(o)}" : 'null'
  "#{if_part} : #{else_part}"
end

#force_statementObject



1013
1014
1015
1016
# File 'lib/style_script/nodes.rb', line 1013

def force_statement
  @tags[:statement] = true
  self
end

#rewrite_condition(expression) ⇒ Object

Rewrite a chain of IfNodes with their switch condition for equality.



1019
1020
1021
1022
1023
1024
# File 'lib/style_script/nodes.rb', line 1019

def rewrite_condition(expression)
  @condition = @multiple ? @condition.map {|c| OpNode.new("is", expression, c) } :
                           OpNode.new("is", expression, @condition)
  @else_body.rewrite_condition(expression) if chain?
  self
end

#statement?Boolean

The IfNode only compiles into a statement if either of the bodies needs to be a statement.

Returns:

  • (Boolean)


1039
1040
1041
# File 'lib/style_script/nodes.rb', line 1039

def statement?
  @is_statement ||= !!(@comment || @tags[:statement] || @body.statement? || (@else_body && @else_body.statement?))
end