ruby2js 1.15.0 → 1.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,8 @@ module Ruby2JS
16
16
  :=== => :'!=='
17
17
  }
18
18
 
19
+ GROUP_OPERATORS = [:begin, :dstr, :dsym, :and, :or]
20
+
19
21
  attr_accessor :binding, :ivars
20
22
 
21
23
  def initialize( ast, vars = {} )
@@ -48,14 +48,14 @@ module Ruby2JS
48
48
  if receiver
49
49
  group_receiver = receiver.type == :send &&
50
50
  op_index < operator_index( receiver.children[1] ) if receiver
51
- group_receiver ||= [:begin, :dstr, :dsym].include? receiver.type
51
+ group_receiver ||= GROUP_OPERATORS.include? receiver.type
52
52
  group_receiver = false if receiver.children[1] == :[]
53
53
  end
54
54
 
55
55
  if target
56
56
  group_target = target.type == :send &&
57
57
  op_index < operator_index( target.children[1] )
58
- group_target ||= (target.type == :begin)
58
+ group_target ||= GROUP_OPERATORS.include? target.type
59
59
  end
60
60
 
61
61
  if method == :!
@@ -13,6 +13,7 @@
13
13
  # * @x becomes this.state.x
14
14
  # * @@x becomes this.props.x
15
15
  # * ~x becomes this.refs.x.getDOMNode()
16
+ # * ~"x" becomes document.querySelector("x")
16
17
  #
17
18
  require 'ruby2js'
18
19
 
@@ -87,6 +88,13 @@ module Ruby2JS
87
88
  body.select {|child| child.type == :def}.each do |child|
88
89
  mname, args, *block = child.children
89
90
  @reactMethod = mname
91
+ @reactProps = s(:attr, s(:self), :props)
92
+
93
+ # analyze ivar usage
94
+ @reactIvars = {pre: [], post: [], asgn: [], ref: []}
95
+ react_walk(child) unless mname == :initialize
96
+ @reactIvars[:capture] =
97
+ (@reactIvars[:pre] + @reactIvars[:post]).uniq
90
98
 
91
99
  if mname == :initialize
92
100
  mname = :getInitialState
@@ -133,6 +141,41 @@ module Ruby2JS
133
141
  block = [s(:return,
134
142
  s(:block, s(:send, nil, :_span), s(:args), *block))]
135
143
  end
144
+
145
+ elsif mname == :componentWillReceiveProps
146
+ if args.children.length == 0
147
+ args = s(:args, s(:arg, :"$$props"))
148
+ child = s(:def, mname, args, *block)
149
+ @reactProps = s(:lvar, :"$$props")
150
+ else
151
+ @reactProps = s(:lvar, args.children.first.children.last)
152
+ end
153
+ end
154
+
155
+ # drill down if necessary to find the block
156
+ while block.length==1 and block.first and block.first.type==:begin
157
+ block = block.first.children.dup
158
+ end
159
+
160
+ # capture ivars that are both set and referenced
161
+ @reactIvars[:pre].uniq.sort.reverse.each do |ivar|
162
+ block.unshift(s(:lvasgn, "$#{ivar.to_s[1..-1]}",
163
+ s(:attr, s(:attr, s(:self), :state), ivar.to_s[1..-1])))
164
+ end
165
+
166
+ # update ivars that are set and later referenced
167
+ unless @reactIvars[:post].empty?
168
+ updates = @reactIvars[:post].uniq.sort.reverse.map do |ivar|
169
+ s(:pair, s(:lvar, ivar.to_s[1..-1]),
170
+ s(:lvar, "$#{ivar.to_s[1..-1]}"))
171
+ end
172
+ update = s(:send, s(:self), :setState, s(:hash, *updates))
173
+
174
+ if block.last.type == :return
175
+ block.insert(block.length-1, update)
176
+ else
177
+ block.push(update)
178
+ end
136
179
  end
137
180
 
138
181
  # add method to class
@@ -240,9 +283,12 @@ module Ruby2JS
240
283
  end
241
284
  pairs -= classes
242
285
  if expr
243
- value = s(:if, expr,
244
- s(:send, s(:str, values.join(' ')), :+, expr),
245
- s(:str, values.join(' ').strip))
286
+ if values.length > 1
287
+ value = s(:send, s(:str, values.join(' ')), :+,
288
+ s(:or, expr, s(:str, '')))
289
+ else
290
+ value = s(:or, expr, s(:str, ''))
291
+ end
246
292
  else
247
293
  value = s(:str, values.join(' '))
248
294
  end
@@ -487,6 +533,13 @@ module Ruby2JS
487
533
  super
488
534
  end
489
535
 
536
+ elsif
537
+ node.children[0] and node.children[0].type == :self and
538
+ node.children.length == 2 and
539
+ node.children[1] == :componentWillReceiveProps
540
+ then
541
+ s(:send, *node.children, s(:attr, s(:self), :props))
542
+
490
543
  else
491
544
  super
492
545
  end
@@ -550,16 +603,25 @@ module Ruby2JS
550
603
  # convert instance variables to state
551
604
  def on_ivar(node)
552
605
  return super unless @reactClass
553
- s(:attr, s(:attr, s(:self), :state), node.children.first.to_s[1..-1])
606
+ if @reactMethod and @reactIvars[:capture].include? node.children.first
607
+ s(:lvar, "$#{node.children.first[1..-1]}")
608
+ else
609
+ s(:attr, s(:attr, s(:self), :state), node.children.first.to_s[1..-1])
610
+ end
554
611
  end
555
612
 
556
613
  # convert instance variable assignments to setState calls
557
614
  def on_ivasgn(node)
558
615
  return super unless @react
559
616
 
617
+ if @reactMethod and @reactIvars[:capture].include? node.children.first
618
+ return s(:lvasgn, "$#{node.children.first[1..-1]}",
619
+ *process_all(node.children[1..-1]))
620
+ end
621
+
560
622
  vars = [node.children.first]
561
623
 
562
- while node.children[1].type == :ivasgn
624
+ while node.children.length > 1 and node.children[1].type == :ivasgn
563
625
  node = node.children[1]
564
626
  vars << node.children.first
565
627
  end
@@ -574,10 +636,73 @@ module Ruby2JS
574
636
  end
575
637
  end
576
638
 
639
+ # prevent attempts to assign to React properties
640
+ def on_cvasgn(node)
641
+ return super unless @reactMethod
642
+ raise NotImplementedError, "setting a React property"
643
+ end
644
+
577
645
  # convert class variables to props
578
- def on_cvar(node)
646
+ def on_op_asgn(node)
579
647
  return super unless @react
580
- s(:attr, s(:attr, s(:self), :props), node.children.first.to_s[2..-1])
648
+ return super unless node.children.first.type == :ivasgn
649
+ var = node.children.first.children.first
650
+ if @reactMethod and @reactIvars[:capture].include? var
651
+ process s(:op_asgn, s(:lvasgn, "$#{var[1..-1]}"),
652
+ *node.children[1..-1])
653
+ elsif @reactMethod == :initialize
654
+ process s(:op_asgn, s(:attr, s(:attr, s(:self), :state),
655
+ var[1..-1]), *node.children[1..-1])
656
+ else
657
+ process s(:ivasgn, var, s(:send, s(:ivar, var),
658
+ *node.children[1..-1]))
659
+ end
660
+ end
661
+
662
+ # convert class variables to props
663
+ def on_cvar(node)
664
+ return super unless @reactMethod
665
+ s(:attr, @reactProps, node.children.first.to_s[2..-1])
666
+ end
667
+
668
+ # analyze ivar usage
669
+ def react_walk(node)
670
+ child = node.children.first
671
+
672
+ node.children.each do |child|
673
+ react_walk(child) if Parser::AST::Node === child
674
+ end
675
+
676
+ case node.type
677
+ when :ivar
678
+ if @reactIvars[:asgn].include? child
679
+ @reactIvars[:post] << child
680
+ @reactIvars[:pre] << child if @reactIvars[:ref].include? child
681
+ end
682
+ @reactIvars[:ref] << child
683
+
684
+ when :ivasgn
685
+ @reactIvars[:asgn] << child
686
+
687
+ when :op_asgn
688
+ if child.type == :ivasgn
689
+ gchild = child.children.first
690
+ if @reactIvars[:ref].include? gchild
691
+ @reactIvars[:pre] << gchild
692
+ @reactIvars[:post] << gchild
693
+ end
694
+ @reactIvars[:ref] << gchild
695
+ @reactIvars[:asgn] << gchild
696
+ end
697
+
698
+ when :send
699
+ if
700
+ child and child.type == :self and node.children.length == 2 and
701
+ node.children[1] == :componentWillReceiveProps
702
+ then
703
+ @reactIvars[:post] += @reactIvars[:asgn]
704
+ end
705
+ end
581
706
  end
582
707
  end
583
708
 
@@ -2,7 +2,7 @@ module Ruby2JS
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
4
  MINOR = 15
5
- TINY = 0
5
+ TINY = 1
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "ruby2js"
5
- s.version = "1.15.0"
5
+ s.version = "1.15.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Sam Ruby"]
9
- s.date = "2015-03-07"
9
+ s.date = "2015-03-09"
10
10
  s.description = " The base package maps Ruby syntax to JavaScript semantics.\n Filters may be provided to add Ruby-specific or framework specific\n behavior.\n"
11
11
  s.email = "rubys@intertwingly.net"
12
12
  s.files = ["ruby2js.gemspec", "README.md", "lib/ruby2js", "lib/ruby2js/execjs.rb", "lib/ruby2js/converter.rb", "lib/ruby2js/version.rb", "lib/ruby2js/filter", "lib/ruby2js/filter/jquery.rb", "lib/ruby2js/filter/return.rb", "lib/ruby2js/filter/underscore.rb", "lib/ruby2js/filter/require.rb", "lib/ruby2js/filter/angularrb.rb", "lib/ruby2js/filter/minitest-jasmine.rb", "lib/ruby2js/filter/camelCase.rb", "lib/ruby2js/filter/rubyjs.rb", "lib/ruby2js/filter/strict.rb", "lib/ruby2js/filter/functions.rb", "lib/ruby2js/filter/angular-resource.rb", "lib/ruby2js/filter/react.rb", "lib/ruby2js/filter/angular-route.rb", "lib/ruby2js/sinatra.rb", "lib/ruby2js/rails.rb", "lib/ruby2js/cgi.rb", "lib/ruby2js/converter", "lib/ruby2js/converter/self.rb", "lib/ruby2js/converter/arg.rb", "lib/ruby2js/converter/dstr.rb", "lib/ruby2js/converter/xstr.rb", "lib/ruby2js/converter/sym.rb", "lib/ruby2js/converter/return.rb", "lib/ruby2js/converter/break.rb", "lib/ruby2js/converter/for.rb", "lib/ruby2js/converter/defined.rb", "lib/ruby2js/converter/cvasgn.rb", "lib/ruby2js/converter/whilepost.rb", "lib/ruby2js/converter/logical.rb", "lib/ruby2js/converter/in.rb", "lib/ruby2js/converter/args.rb", "lib/ruby2js/converter/def.rb", "lib/ruby2js/converter/prototype.rb", "lib/ruby2js/converter/class.rb", "lib/ruby2js/converter/nthref.rb", "lib/ruby2js/converter/opasgn.rb", "lib/ruby2js/converter/module.rb", "lib/ruby2js/converter/kwbegin.rb", "lib/ruby2js/converter/send.rb", "lib/ruby2js/converter/boolean.rb", "lib/ruby2js/converter/masgn.rb", "lib/ruby2js/converter/hash.rb", "lib/ruby2js/converter/cvar.rb", "lib/ruby2js/converter/ivasgn.rb", "lib/ruby2js/converter/case.rb", "lib/ruby2js/converter/const.rb", "lib/ruby2js/converter/vasgn.rb", "lib/ruby2js/converter/untilpost.rb", "lib/ruby2js/converter/begin.rb", "lib/ruby2js/converter/ivar.rb", "lib/ruby2js/converter/while.rb", "lib/ruby2js/converter/next.rb", "lib/ruby2js/converter/nil.rb", "lib/ruby2js/converter/blockpass.rb", "lib/ruby2js/converter/super.rb", "lib/ruby2js/converter/defs.rb", "lib/ruby2js/converter/array.rb", "lib/ruby2js/converter/block.rb", "lib/ruby2js/converter/if.rb", "lib/ruby2js/converter/until.rb", "lib/ruby2js/converter/regexp.rb", "lib/ruby2js/converter/casgn.rb", "lib/ruby2js/converter/undef.rb", "lib/ruby2js/converter/literal.rb", "lib/ruby2js/converter/var.rb", "lib/ruby2js.rb"]
metadata CHANGED
@@ -2,14 +2,14 @@
2
2
  name: ruby2js
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.15.0
5
+ version: 1.15.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Sam Ruby
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-07 00:00:00.000000000 Z
12
+ date: 2015-03-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  version_requirements: !ruby/object:Gem::Requirement