Class: StyleScript::IfNode
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
Instance Method Summary collapse
- #<<(else_body) ⇒ Object
- #add_comment(comment) ⇒ Object
-
#add_else(exprs) ⇒ Object
Rewrite a chain of IfNodes to add a default case as the final else.
-
#chain? ⇒ Boolean
If the else_body is an IfNode itself, then we’ve got an if-else chain.
- #compile_condition(o) ⇒ Object
- #compile_node(o) ⇒ Object
-
#compile_statement(o) ⇒ Object
Compile the IfNode as a regular if-else statement.
-
#compile_ternary(o) ⇒ Object
Compile the IfNode into a ternary operator.
- #force_statement ⇒ Object
-
#initialize(condition, body, else_body = nil, tags = {}) ⇒ IfNode
constructor
A new instance of IfNode.
-
#rewrite_condition(expression) ⇒ Object
Rewrite a chain of IfNodes with their switch condition for equality.
-
#statement? ⇒ Boolean
The IfNode only compiles into a statement if either of the bodies needs to be a statement.
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, ={}) @condition = condition @body = body && body.unwrap @else_body = else_body && else_body.unwrap @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.
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_statement ⇒ Object
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.
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 |