Module: Ruby2JS::Filter::AngularRB
- Includes:
- SEXP
- Defined in:
- lib/ruby2js/filter/angularrb.rb
Instance Method Summary collapse
- #extract_uses(block) ⇒ Object
- #initialize(*args) ⇒ Object
-
#ng_controller(node) ⇒ Object
input: controller :name do ...
-
#ng_factory(node) ⇒ Object
input: factory :name do |uses| ...
-
#ng_filter(node) ⇒ Object
input: filter :name do |input| ...
-
#on_block(node) ⇒ Object
input: filter :name { ... } controller :name { ... } factory :name { ... } directive :name { ... }.
-
#on_casgn(node) ⇒ Object
input: Constant = ...
-
#on_class(node) ⇒ Object
input: class name ....
- #on_const(node) ⇒ Object
- #on_gvar(node) ⇒ Object
-
#on_module(node) ⇒ Object
input: module Angular::AppName use :Dependency ...
Methods included from SEXP
Instance Method Details
#extract_uses(block) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/ruby2js/filter/angularrb.rb', line 243 def extract_uses(block) # find the block while block.length == 1 and block.first and block.first.type == :begin block.push *block.shift.children end # find use class method calls uses = block.find_all do |node| node and node.type == :send and node.children[0..1] == [nil, :use] end # convert use calls into dependencies depends = [] uses.each do |use| use.children[2..-1].each do |node| depends << node if [:str, :sym].include? node.type end block.delete use end depends end |
#initialize(*args) ⇒ Object
9 10 11 12 13 14 15 |
# File 'lib/ruby2js/filter/angularrb.rb', line 9 def initialize(*args) @ngApp = nil @ngAppUses = [] @ngClassUses = [] @ngClassOmit = [] super end |
#ng_controller(node) ⇒ Object
input: controller :name do ... end
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/ruby2js/filter/angularrb.rb', line 133 def ng_controller(node) target = node.children.first target = target.updated(nil, [s(:lvar, @ngApp), *target.children[1..-1]]) block = process_all(node.children[2..-1]) # convert use calls into args @ngClassUses -= @ngClassOmit args = node.children[1].children args += @ngClassUses.map {|sym| s(:arg, sym)} + extract_uses(block) args = args.map {|node| node.children.first.to_sym}.uniq. map {|sym| s(:arg, sym)} @ngClassUses, @ngClassOmit = [], [] node.updated :block, [target, s(:args, *args), s(:begin, *block)] end |
#ng_factory(node) ⇒ Object
input:
factory :name do |uses|
...
end
output:
AppName.factory :name, [uses, lambda {|uses| ...}]
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/ruby2js/filter/angularrb.rb', line 187 def ng_factory(node) call = node.children.first call = call.updated(nil, [s(:lvar, @ngApp), *call.children[1..-1]]) # insert return block = process_all(node.children[2..-1]) tail = [block.pop || s(:nil)] while tail.length == 1 and tail.first.type == :begin tail = tail.first.children.dup end tail.push s(:return, tail.pop) unless tail.last.type == :return block.push (tail.length == 1 ? tail.first : s(:begin, *tail)) # extract dependencies @ngClassUses.delete call.children[2].children[0] args = process_all(node.children[1].children) args += @ngClassUses.map {|sym| s(:arg, sym)} + extract_uses(block) args = args.map {|node| node.children.first.to_sym}.uniq. map {|sym| s(:arg, sym)} # construct a function function = s(:block, s(:send, nil, :lambda), s(:args, *args), *block) array = args.map {|arg| s(:str, arg.children.first.to_s)} s(:send, *call.children, s(:array, *array, function)) end |
#ng_filter(node) ⇒ Object
input:
filter :name do |input|
...
end
output:
AppName.filter :name do
return lambda {|input| return ... }
end
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/ruby2js/filter/angularrb.rb', line 160 def ng_filter(node) call = node.children.first # insert return args = process_all(node.children[1].children) block = process_all(node.children[2..-1]) tail = [block.pop || s(:nil)] while tail.length == 1 and tail.first.type == :begin tail = tail.first.children.dup end tail.push s(:return, tail.pop) unless tail.last.type == :return block.push (tail.length == 1 ? tail.first : s(:begin, *tail)) # construct a function returning a function inner = s(:block, s(:send, nil, :lambda), s(:args, *args), *block) outer = s(:send, s(:lvar, @ngApp), :filter, *call.children[2..-1]) node.updated nil, [outer, s(:args), s(:return, inner)] end |
#on_block(node) ⇒ Object
input:
filter :name { ... }
controller :name { ... }
factory :name { ... }
directive :name { ... }
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/ruby2js/filter/angularrb.rb', line 109 def on_block(node) return super unless @ngApp call = node.children.first return super if call.children.first case call.children[1] when :controller ng_controller(node) when :factory ng_factory(node) when :filter ng_filter(node) when :directive ng_controller(node) # reuse template else super end end |
#on_casgn(node) ⇒ Object
input:
Constant = ...
output:
AppName.factory :name, [uses, lambda {|uses| ...}]
219 220 221 222 223 224 225 |
# File 'lib/ruby2js/filter/angularrb.rb', line 219 def on_casgn(node) return super if node.children[0] @ngClassOmit << node.children[1] return super unless @ngApp and @ngChildren.include? node ng_factory s(:block, s(:send, nil, :factory, s(:sym, node.children[1])), s(:args), process(node.children[2])) end |
#on_class(node) ⇒ Object
input:
class name {...}
output: app.factory(uses) do ... end
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/ruby2js/filter/angularrb.rb', line 81 def on_class(node) return super unless @ngApp and @ngChildren.include? node name = node.children.first if name.children.first == nil block = [node.children.last] uses = extract_uses(block) node = process s(:class, name, node.children[1], s(:begin, *block)) @ngClassUses -= @ngClassOmit + [name.children.last] args = @ngClassUses.map {|sym| s(:arg, sym)} + uses args = args.map {|node| node.children.first.to_sym}.uniq. map {|sym| s(:arg, sym)} @ngClassUses, @ngClassOmit = [], [] s(:block, s(:send, s(:lvar, @ngApp), :factory, s(:sym, name.children.last)), s(:args, *args), s(:begin, node, s(:return, s(:const, nil, name.children.last)))) else super end end |
#on_const(node) ⇒ Object
235 236 237 238 239 240 241 |
# File 'lib/ruby2js/filter/angularrb.rb', line 235 def on_const(node) if @ngClassUses @ngClassUses << node.children.last if not node.children.first end super end |
#on_gvar(node) ⇒ Object
227 228 229 230 231 232 233 |
# File 'lib/ruby2js/filter/angularrb.rb', line 227 def on_gvar(node) if @ngClassUses @ngClassUses << node.children.first end super end |
#on_module(node) ⇒ Object
input:
module Angular::AppName
use :Dependency
...
end
output:
AppName = angular.module("AppName", ["Dependency"])
...
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 68 69 70 71 72 |
# File 'lib/ruby2js/filter/angularrb.rb', line 27 def on_module(node) module_name = node.children[0] parent_name = module_name.children[0] return super unless parent_name and parent_name.type == :const return super unless parent_name.children == [nil, :Angular] @ngApp = module_name.children[1] @ngChildren = node.children[1..-1] while @ngChildren.length == 1 and @ngChildren.first and @ngChildren.first.type == :begin @ngChildren = @ngChildren.first.children.dup end @ngAppUses = [] block = process_all(node.children[1..-1]) # convert use calls into dependencies depends = @ngAppUses.map {|sym| s(:sym, sym)} + extract_uses(block) depends = depends.map {|node| node.children.first.to_s}.uniq. map {|sym| s(:str, sym)} name, @ngApp, @ngChildren = @ngApp, nil, nil # construct app app = s(:send, s(:lvar, :angular), :module, s(:str, name.to_s), s(:array, *depends.uniq)) # return a single chained statement when there is only one call block.compact! if block.length == 0 return app elsif block.length == 1 call = block.first.children.first if block.first.type == :send and call == s(:lvar, name) return block.first.updated nil, [app, *block.first.children[1..-1]] elsif block.first.type == :block and call.children.first == s(:lvar, name) call = call.updated nil, [app, *call.children[1..-1]] return block.first.updated nil, [call, *block.first.children[1..-1]] end end # replace module with a constant assign followed by the module # contents all wrapped in an anonymous function s(:send, s(:block, s(:send, nil, :lambda), s(:args), s(:begin, s(:casgn, nil, name, app), *block)), :[]) end |