Class: ADSL::Extract::Rails::ActionBlockBuilder
- Defined in:
- lib/adsl/extract/rails/action_block_builder.rb
Instance Attribute Summary collapse
-
#branch_choices ⇒ Object
Returns the value of attribute branch_choices.
-
#root_paths ⇒ Object
Returns the value of attribute root_paths.
-
#stmt_frames ⇒ Object
Returns the value of attribute stmt_frames.
Instance Method Summary collapse
- #adsl_ast ⇒ Object
- #all_stmts_so_far ⇒ Object
- #append_stmt(stmt, options = {}) ⇒ Object (also: #<<)
- #branch_choice(if_id) ⇒ Object
- #common_return_value ⇒ Object
- #common_supertype_of_objset_arrays(values) ⇒ Object
- #common_supertype_of_objsets(values) ⇒ Object
- #do_raise(*args) ⇒ Object
- #do_return(return_value = nil) ⇒ Object
- #explore_all_choices ⇒ Object
- #has_more_executions? ⇒ Boolean
- #in_stmt_frame(*args) ⇒ Object
- #included_already?(where, what) ⇒ Boolean
- #increment_branch_choice ⇒ Object
-
#initialize ⇒ ActionBlockBuilder
constructor
A new instance of ActionBlockBuilder.
- #pop_frame ⇒ Object
- #push_frame ⇒ Object
- #reset ⇒ Object
- #root_lvl_adsl_ast ⇒ Object
Constructor Details
#initialize ⇒ ActionBlockBuilder
Returns a new instance of ActionBlockBuilder.
12 13 14 15 16 17 18 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 12 def initialize @root_paths = [] @stmt_frames = [[]] @branch_choices = [] @return_values = [] @has_returned_or_raised = false end |
Instance Attribute Details
#branch_choices ⇒ Object
Returns the value of attribute branch_choices.
10 11 12 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 10 def branch_choices @branch_choices end |
#root_paths ⇒ Object
Returns the value of attribute root_paths.
10 11 12 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 10 def root_paths @root_paths end |
#stmt_frames ⇒ Object
Returns the value of attribute stmt_frames.
10 11 12 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 10 def stmt_frames @stmt_frames end |
Instance Method Details
#adsl_ast ⇒ Object
212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 212 def adsl_ast blocks = @root_paths.map do |root_path| ::ADSL::Parser::ASTBlock.new :statements => root_path end if blocks.empty? ::ADSL::Parser::ASTBlock.new :statements => [] elsif blocks.length == 1 blocks.first else ::ADSL::Parser::ASTBlock.new :statements => [::ADSL::Parser::ASTEither.new(:blocks => blocks)] end end |
#all_stmts_so_far ⇒ Object
185 186 187 188 189 190 191 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 185 def all_stmts_so_far stmts = [] @stmt_frames.each do |frame| stmts += frame end stmts end |
#append_stmt(stmt, options = {}) ⇒ Object Also known as: <<
39 40 41 42 43 44 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 39 def append_stmt(stmt, = {}) return stmt if @has_returned_or_raised && ![:ignore_has_returned] return stmt if included_already? @stmt_frames.last, stmt @stmt_frames.last << stmt stmt end |
#branch_choice(if_id) ⇒ Object
47 48 49 50 51 52 53 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 47 def branch_choice(if_id) @branch_choices.each do |iter_if_id, choice| return choice if iter_if_id == if_id end @branch_choices << [if_id, true] true end |
#common_return_value ⇒ Object
144 145 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 175 176 177 178 179 180 181 182 183 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 144 def common_return_value uniq = @return_values.dup # avoid include? because it uses :== and metaobjects override the == operator if uniq.map(&:nil?).include? true uniq.delete_if{ |e| e.nil? } uniq << nil end if uniq.length == 1 uniq.first elsif ct = common_supertype_of_objsets(uniq) objsets = uniq.map(&:adsl_ast).map{ |r| r.is_a?(ADSL::Parser::ASTObjsetStmt) ? r.objset : r } ct.new(:adsl_ast => ADSL::Parser::ASTOneOfObjset.new(:objsets => objsets)) elsif ct = common_supertype_of_objset_arrays(uniq) highest_length = uniq.map(&:length).max combined_objsets = [] highest_length.times do |index| objsets = uniq.map{|u| u[index]}.map(&:adsl_ast).map{ |r| r.is_a?(ADSL::Parser::ASTObjsetStmt) ? r.objset : r } combined_objsets << ct[index].new(:objset => ADSL::Parser::ASTOneOfObjset.new(:objsets => objsets)) end combined_objsets else # append all return values to root paths # cause they won't be returned and handled by the caller # if an array is returned, assume the 'return 1, 2, 3' syntax @return_values.length.times do |index| Array.wrap(@return_values[index]).flatten.each do |ret_value| stmt = ADSL::Extract::Rails::ActionInstrumenter.extract_stmt_from_expr ret_value @root_paths[index] << stmt unless ( stmt.nil? || !stmt.class.is_statement? || included_already?(@root_paths[index], stmt) ) end end ADSL::Extract::Rails::MetaUnknown.new end end |
#common_supertype_of_objset_arrays(values) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 127 def common_supertype_of_objset_arrays(values) return false if values.empty? values.each do |value| return false unless value.is_a? Array end return_value = [] highest_length = values.map(&:length).max highest_length.times do |index| ct = compatible_types(values.map{ |v| v[index] }) return false unless ct return_value << ct end return_value end |
#common_supertype_of_objsets(values) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 96 def common_supertype_of_objsets(values) return false if values.empty? values.each do |value| return false if value.is_a?(MetaUnknown) || !value.respond_to?(:adsl_ast) end adsl_asts = values.reject{ |v| v.nil? }.map(&:adsl_ast) adsl_asts = adsl_asts.map{ |v| v.is_a?(ADSL::Parser::ASTObjsetStmt) ? v.objset : v } adsl_asts.each do |adsl_ast| return false unless adsl_ast.class.is_objset? # side effects should trigger only if the selection is chosen; # but the translation does not do this return false if adsl_ast.objset_has_side_effects? end common_supertype = nil values.each do |value| next if value.nil? if common_supertype.nil? common_supertype = value.class elsif value.class <= common_supertype # all is fine elsif common_supertype <= value.class common_supertype = value.class else return false end end common_supertype end |
#do_raise(*args) ⇒ Object
202 203 204 205 206 207 208 209 210 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 202 def do_raise(*args) unless @has_returned_or_raised # appending nothing to root paths @root_paths << [::ADSL::Parser::ASTDummyStmt.new(:type => :raise)] @return_values << nil @has_returned_or_raised = true end return *args end |
#do_return(return_value = nil) ⇒ Object
193 194 195 196 197 198 199 200 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 193 def do_return(return_value = nil) unless @has_returned_or_raised @root_paths << all_stmts_so_far @return_values << return_value @has_returned_or_raised = true end return_value end |
#explore_all_choices ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 77 def explore_all_choices while true begin reset increment_branch_choice return_value = yield do_return return_value unless @has_returned_or_raised rescue Exception => e #puts "Exception: #{e}" #puts e.backtrace.first 20 #do_raise unless @has_returned_or_raised ensure return common_return_value unless has_more_executions? end end end |
#has_more_executions? ⇒ Boolean
55 56 57 58 59 60 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 55 def has_more_executions? @branch_choices.each do |if_id, choice| return true if choice == true end false end |
#in_stmt_frame(*args) ⇒ Object
23 24 25 26 27 28 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 23 def in_stmt_frame(*args) push_frame yield *args ensure return pop_frame end |
#included_already?(where, what) ⇒ Boolean
30 31 32 33 34 35 36 37 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 30 def included_already?(where, what) return where.map{ |e| e.equal? what }.include?(true) || ( where.last.is_a?(ADSL::Parser::ASTObjsetStmt) && what.is_a?(ADSL::Parser::ASTObjsetStmt) && where.last.objset == what.objset ) end |
#increment_branch_choice ⇒ Object
62 63 64 65 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 62 def increment_branch_choice @branch_choices.pop while !@branch_choices.empty? && @branch_choices.last[1] == false @branch_choices.last[1] = false unless @branch_choices.empty? end |
#pop_frame ⇒ Object
21 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 21 def pop_frame; @stmt_frames.pop; end |
#push_frame ⇒ Object
20 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 20 def push_frame; @stmt_frames << []; end |
#reset ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/adsl/extract/rails/action_block_builder.rb', line 67 def reset unless has_more_executions? @root_paths = [] @branch_choices = [] @return_values = [] end @has_returned_or_raised = false @stmt_frames = [[]] end |