ruby2js 3.0.4 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e00c31d4c3008e16e720676fe6170e741e647dbc
4
- data.tar.gz: d3882d4c1a946655055af40fc41028f096238101
2
+ SHA256:
3
+ metadata.gz: 96bf18688d1c3a685449b4e8404cb6a8c13f989031c61f950bfb69e5adf7855f
4
+ data.tar.gz: 39abc46c793667b6b3bd502986ad0aec2dd8f912eca79d94d870095a5d0aeb64
5
5
  SHA512:
6
- metadata.gz: da8fb9a021cc0037d31bcc1bb2d83fbb52f686640d0247dda4d030869ae148ad4a271f6c93aa78f2fe2211ea0c82275807897bf86dc1223ae6cb56ea32567b1c
7
- data.tar.gz: d843723f447de12fa82ebb5402dd74302a4390ee216b1cf1a711cf78526311672e4f3968db8cf9d54a51a94a1265c816a56c1c2fa27e015b24a239c850c9fbe1
6
+ metadata.gz: 70a47951f48b3a389c497f393eb9a112e5b702f006efb3191fa7c99a36d7cd44dade1baef64925951a4c9158a2d7e3b2f5e27e24d03c4502c00af9056b0a1779
7
+ data.tar.gz: 1f785124a3ad1dea8028f29c728953396eb7e2b34d51d8fdd634cffada1d63f574a21132a11337a3d08aff693668ef33132fe74f743a02f37c299027d8e017b9
@@ -1,6 +1,15 @@
1
1
  require 'ruby2js/serializer'
2
2
 
3
3
  module Ruby2JS
4
+ class Error < NotImplementedError
5
+ def initialize(message, ast)
6
+ message += ' at ' + ast.loc.expression.source_buffer.name.to_s
7
+ message += ':' + ast.loc.expression.line.inspect
8
+ message += ':' + ast.loc.expression.column.to_s
9
+ super(message)
10
+ end
11
+ end
12
+
4
13
  class Converter < Serializer
5
14
  attr_accessor :ast
6
15
 
@@ -146,7 +155,7 @@ module Ruby2JS
146
155
  handler = @handlers[ast.type]
147
156
 
148
157
  unless handler
149
- raise NotImplementedError, "unknown AST type #{ ast.type }"
158
+ raise Error.new("unknown AST type #{ ast.type }", ast)
150
159
  end
151
160
 
152
161
  if state == :statement and not @comments[ast].empty?
@@ -171,7 +180,11 @@ module Ruby2JS
171
180
  end
172
181
 
173
182
  def group( ast )
174
- put '('; parse ast; put ')'
183
+ if [:dstr, :dsym].include? ast.type and es2015
184
+ parse ast
185
+ else
186
+ put '('; parse ast; put ')'
187
+ end
175
188
  end
176
189
 
177
190
  def timestamp(file)
@@ -7,14 +7,14 @@ module Ruby2JS
7
7
  # NOTE: process_all appends a nil child for unknown reasons
8
8
 
9
9
  handle :arg, :blockarg do |arg, unknown=nil|
10
- raise NotImplementedError, "argument #{ unknown.inspect }" if unknown
10
+ raise Error.new("argument #{ unknown.inspect }", @ast) if unknown
11
11
  put arg
12
12
  end
13
13
 
14
14
  # (shadowarg :a)
15
15
 
16
16
  handle :shadowarg do |arg, unknown=nil|
17
- raise NotImplementedError, "argument #{ unknown.inspect }" if unknown
17
+ raise Error.new("argument #{ unknown.inspect }", @ast) if unknown
18
18
  nil
19
19
  end
20
20
  end
@@ -16,7 +16,7 @@ module Ruby2JS
16
16
  parse_all(*args, join: ', ')
17
17
  put ']'
18
18
  else
19
- raise NotImplementedError, "destructuring requires ES2015"
19
+ raise Error.new("destructuring requires ES2015", @ast)
20
20
  end
21
21
  end
22
22
  end
@@ -7,7 +7,7 @@ module Ruby2JS
7
7
 
8
8
  handle :array do |*items|
9
9
  splat = items.rindex { |a| a.type == :splat }
10
- if splat
10
+ if splat and (items.length == 1 or not es2015)
11
11
  item = items[splat].children.first
12
12
  if items.length == 1
13
13
  parse item
@@ -5,8 +5,8 @@ module Ruby2JS
5
5
  # (int 1))
6
6
 
7
7
  handle :break do |n=nil|
8
- raise NotImplementedError, "break argument #{ n.inspect }" if n
9
- raise NotImplementedError, "break outside of loop" if @next_token == :return
8
+ raise Error.new("break argument #{ n.inspect }", @ast) if n
9
+ raise Error.new("break outside of loop", @ast) if @next_token == :return
10
10
  put 'break'
11
11
  end
12
12
  end
@@ -145,7 +145,7 @@ module Ruby2JS
145
145
  "#{m.children[0].children.first}=",
146
146
  s(:attr, s(:attr, name, :prototype), m.children[1].children.first))
147
147
  else
148
- raise NotImplementedError, "class #{ m.type }"
148
+ raise Error.new("class #{ m.type }", @ast)
149
149
  end
150
150
 
151
151
  # associate comments
@@ -9,7 +9,7 @@ module Ruby2JS
9
9
  handle :def, :defm, :async do |name, args, body=nil|
10
10
  body ||= s(:begin)
11
11
  if name =~ /[!?]$/
12
- raise NotImplementedError, "invalid method name #{ name }"
12
+ raise Error.new("invalid method name #{ name }", @ast)
13
13
  end
14
14
 
15
15
  vars = {}
@@ -13,7 +13,7 @@ module Ruby2JS
13
13
  (singleton ? put('{') : puts('{'))
14
14
 
15
15
  pairs.each_with_index do |node, index|
16
- raise NotImplementedError, "kwsplat" if node.type == :kwsplat
16
+ raise Error.new("kwsplat", @ast) if node.type == :kwsplat
17
17
 
18
18
  (singleton ? put(', ') : put(",#@ws")) unless index == 0
19
19
 
@@ -27,17 +27,17 @@ module Ruby2JS
27
27
 
28
28
  if block and block.type == :rescue
29
29
  body, *recovers, otherwise = block.children
30
- raise NotImplementedError, "block else" if otherwise
30
+ raise Error.new("block else", @ast) if otherwise
31
31
 
32
32
  if recovers.any? {|recover| not recover.children[1]}
33
- raise NotImplementedError, "recover without exception variable"
33
+ raise Error.new("recover without exception variable", @ast)
34
34
  end
35
35
 
36
36
  var = recovers.first.children[1]
37
37
 
38
38
  if recovers.any? {|recover| recover.children[1] != var}
39
- raise NotImplementedError,
40
- "multiple recovers with different exception variables"
39
+ raise Error.new(
40
+ "multiple recovers with different exception variables", @ast)
41
41
  end
42
42
  else
43
43
  body = block
@@ -5,7 +5,7 @@ module Ruby2JS
5
5
  # (int 1))
6
6
 
7
7
  handle :next do |n=nil|
8
- raise NotImplementedError, "next argument #{ n.inspect }" if n
8
+ raise Error.new("next argument #{ n.inspect }", @ast) if n
9
9
  put @next_token.to_s
10
10
  end
11
11
  end
@@ -218,7 +218,7 @@ module Ruby2JS
218
218
  parse s(:send, s(:const, nil, args.first.children[1]), :new,
219
219
  *args.first.children[2..-1], args.last), @state
220
220
  else
221
- raise NotImplementedError, "use of JavaScript keyword new"
221
+ raise Error.new("use of JavaScript keyword new", @ast)
222
222
  end
223
223
 
224
224
  elsif method == :raise and receiver == nil
@@ -7,7 +7,7 @@ module Ruby2JS
7
7
 
8
8
  handle :super, :zsuper do |*args|
9
9
  unless @instance_method and @class_parent
10
- raise NotImplementedError, "super outside of a method"
10
+ raise Error.new("super outside of a method", @ast)
11
11
  end
12
12
 
13
13
  # what to pass
@@ -142,8 +142,20 @@ module Ruby2JS
142
142
  S(:send, target, :push, s(:splat, node.children[2])))
143
143
 
144
144
  elsif method == :include? and args.length == 1
145
- process S(:send, S(:send, target, :indexOf, args.first), :!=,
146
- s(:int, -1))
145
+ while target.type == :begin and target.children.length == 1
146
+ target = target.children.first
147
+ end
148
+
149
+ if target.type == :irange
150
+ S(:and, s(:send, args.first, :>=, target.children.first),
151
+ s(:send, args.first, :<=, target.children.last))
152
+ elsif target.type == :erange
153
+ S(:and, s(:send, args.first, :>=, target.children.first),
154
+ s(:send, args.first, :<, target.children.last))
155
+ else
156
+ process S(:send, S(:send, target, :indexOf, args.first), :!=,
157
+ s(:int, -1))
158
+ end
147
159
 
148
160
  elsif method == :respond_to? and args.length == 1
149
161
  process S(:in?, args.first, target)
@@ -823,7 +823,7 @@ module Ruby2JS
823
823
  # prevent attempts to assign to React properties
824
824
  def on_cvasgn(node)
825
825
  return super unless @reactMethod
826
- raise NotImplementedError, "setting a React property"
826
+ raise Error.new("setting a React property", node)
827
827
  end
828
828
 
829
829
  # convert instance variables to state: "@x ||= y"
@@ -29,12 +29,21 @@ module Ruby2JS
29
29
  @vue_methods = []
30
30
  @vue_props = []
31
31
  @vue_reactive = []
32
+ @vue_filter_functions = false
32
33
  super
33
34
  end
34
35
 
35
36
  def options=(options)
36
37
  super
37
38
  @vue_h ||= options[:vue_h]
39
+ filters = options[:filters] || Filter::DEFAULTS
40
+
41
+ if
42
+ defined? Ruby2JS::Filter::Functions and
43
+ filters.include? Ruby2JS::Filter::Functions
44
+ then
45
+ @vue_filter_functions = true
46
+ end
38
47
  end
39
48
 
40
49
  # Example conversion
@@ -393,15 +402,15 @@ module Ruby2JS
393
402
  # expand 'wunderbar' like method calls
394
403
  def on_send(node)
395
404
  if not @vue_h
396
- if node.children.first == s(:const, nil, :Vue)
397
- # enable React filtering within Vue class method calls or
398
- # React component calls
399
- begin
400
- vue_h, @vue_h = @vue_h, [s(:self), :$createElement]
401
- return on_send(node)
402
- ensure
403
- @vue_h = vue_h
404
- end
405
+ if node.children.first == s(:const, nil, :Vue)
406
+ # enable React filtering within Vue class method calls or
407
+ # React component calls
408
+ begin
409
+ vue_h, @vue_h = @vue_h, [s(:self), :$createElement]
410
+ return on_send(node)
411
+ ensure
412
+ @vue_h = vue_h
413
+ end
405
414
 
406
415
  elsif node.children.first == s(:send, s(:const, nil, :Vue), :util)
407
416
  if node.children[1] == :defineReactive
@@ -588,18 +597,7 @@ module Ruby2JS
588
597
  end
589
598
 
590
599
  # check for normal case: only elements and text
591
- simple = statements.all? do |arg|
592
- # explicit call to Vue.createElement
593
- next true if arg.children[1] == :createElement and
594
- arg.children[0] == s(:const, nil, :Vue)
595
-
596
- # wunderbar style call
597
- arg = arg.children.first if arg.type == :block
598
- while arg.type == :send and arg.children.first != nil
599
- arg = arg.children.first
600
- end
601
- arg.type == :send and arg.children[1] =~ /^_/
602
- end
600
+ simple = statements.all? {|arg| vue_element?(arg)}
603
601
 
604
602
  if simple
605
603
  args << s(:array, *statements)
@@ -736,15 +734,50 @@ module Ruby2JS
736
734
  # return $_
737
735
  # }())
738
736
  #
737
+ @vue_apply = false
738
+
739
+ # gather non-element emitting statements in the front
740
+ prolog = []
741
+ while not complex_block.empty? and
742
+ vue_wunderbar_free([complex_block.first]) do
743
+ prolog << process(complex_block.shift)
744
+ end
745
+
746
+ # gather element emitting statements in the front
747
+ prefix = []
748
+ while vue_element?(complex_block.first) do
749
+ prefix << process(complex_block.shift)
750
+ end
751
+
752
+ # gather element emitting statements in the back
753
+ suffix = []
754
+ while vue_element?(complex_block.last) do
755
+ suffix.unshift process(complex_block.pop)
756
+ end
757
+
758
+ result = s(:lvar, :$_)
759
+
760
+ unless suffix.empty?
761
+ result = s(:send, result, :concat, s(:array, *suffix))
762
+ end
763
+
739
764
  @vue_apply = true
740
765
 
741
- element = node.updated :send, [nil, @vue_h,
742
- *process_all(args),
743
- s(:send, s(:block, s(:send, nil, :proc),
744
- s(:args, s(:shadowarg, :$_)), s(:begin,
745
- s(:lvasgn, :$_, s(:array)),
746
- *process_all(complex_block),
747
- s(:return, s(:lvar, :$_)))), :[])]
766
+ if suffix.empty? and complex_block.empty?
767
+ element = node.updated :send, [nil, @vue_h,
768
+ *process_all(args),
769
+ s(:send, s(:block, s(:send, nil, :proc),
770
+ s(:args), s(:begin, *prolog,
771
+ s(:return, s(:array, *prefix)))), :[])]
772
+ else
773
+ element = node.updated :send, [nil, @vue_h,
774
+ *process_all(args),
775
+ s(:send, s(:block, s(:send, nil, :proc),
776
+ s(:args, s(:shadowarg, :$_)), s(:begin, *prolog,
777
+ s(:lvasgn, :$_, s(:array, *prefix)),
778
+ *process_all(complex_block),
779
+ s(:return, result))), :[])]
780
+ end
748
781
  end
749
782
  ensure
750
783
  @vue_apply = vue_apply
@@ -951,6 +984,39 @@ module Ruby2JS
951
984
  s(:args), s(:block, s(:send, send[2], :forEach),
952
985
  *node.children[1..-1]))
953
986
  end
987
+
988
+ elsif
989
+ node.children.first.children.last == :forEach and
990
+ vue_element?(node.children.last)
991
+ then
992
+ # map forEach to map
993
+ map = node.children.first.updated(nil,
994
+ [*node.children.first.children[0..-2], :map])
995
+ node = node.updated(nil, [map, *node.children[1..-2],
996
+ s(:autoreturn, node.children[-1])])
997
+ begin
998
+ vue_apply, @vue_apply = @vue_apply, false
999
+ if vue_apply
1000
+ s(:send, s(:gvar, :$_), :push, s(:splat, process(node)))
1001
+ else
1002
+ s(:splat, process(node))
1003
+ end
1004
+ ensure
1005
+ @vue_apply = vue_apply
1006
+ end
1007
+ else
1008
+ super
1009
+ end
1010
+ end
1011
+
1012
+ # convert for_of back to forEach for conversion to map
1013
+ def on_for_of(node)
1014
+ if vue_element?(node.children.last)
1015
+ process node.updated(:block, [
1016
+ s(:send, node.children[1], :forEach),
1017
+ s(:args, s(:arg, node.children.first.children.last)),
1018
+ node.children.last
1019
+ ])
954
1020
  else
955
1021
  super
956
1022
  end
@@ -975,7 +1041,7 @@ module Ruby2JS
975
1041
  # prevent attempts to assign to Vue properties
976
1042
  def on_cvasgn(node)
977
1043
  return super unless @vue_self
978
- raise NotImplementedError, "setting a Vue property"
1044
+ raise Error.new("setting a Vue property", node)
979
1045
  end
980
1046
 
981
1047
  # expand @ to @vue_self
@@ -1036,20 +1102,35 @@ module Ruby2JS
1036
1102
  value.children[1]])]
1037
1103
  end
1038
1104
 
1105
+ # is this a "wunderbar" style call or createElement?
1106
+ def vue_element?(node)
1107
+ return false unless node
1108
+
1109
+ forEach = [:forEach]
1110
+ forEach << :each if @vue_filter_functions
1111
+
1112
+ return true if node.type == :block and
1113
+ forEach.include? node.children.first.children.last and
1114
+ vue_element?(node.children.last)
1115
+
1116
+ # explicit call to Vue.createElement
1117
+ return true if node.children[1] == :createElement and
1118
+ node.children[0] == s(:const, nil, :Vue)
1119
+
1120
+ # wunderbar style call
1121
+ node = node.children.first if node.type == :block
1122
+ while node.type == :send and node.children.first != nil
1123
+ node = node.children.first
1124
+ end
1125
+ node.type == :send and node.children[1].to_s.start_with? '_'
1126
+ end
1127
+
1039
1128
  # ensure that there are no "wunderbar" or "createElement" calls in
1040
1129
  # a set of statements.
1041
1130
  def vue_wunderbar_free(nodes)
1042
1131
  nodes.each do |node|
1043
1132
  if Parser::AST::Node === node
1044
- if node.type == :send
1045
- # wunderbar style calls
1046
- return false if node.children[0] == nil and
1047
- node.children[1].to_s.start_with? '_'
1048
-
1049
- # Vue.createElement calls
1050
- return false if node.children[0] == s(:const, nil, :Vue) and
1051
- node.children[1] == :createElement
1052
- end
1133
+ return false if vue_element?(node)
1053
1134
 
1054
1135
  # recurse
1055
1136
  return false unless vue_wunderbar_free(node.children)
@@ -2,7 +2,7 @@ module Ruby2JS
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
4
  MINOR = 0
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby2js
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.4
4
+ version: 3.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Ruby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-06 00:00:00.000000000 Z
11
+ date: 2018-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -130,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  version: '0'
131
131
  requirements: []
132
132
  rubyforge_project:
133
- rubygems_version: 2.6.11
133
+ rubygems_version: 2.7.6
134
134
  signing_key:
135
135
  specification_version: 4
136
136
  summary: Minimal yet extensible Ruby to JavaScript conversion.