ruby2js 1.15.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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