ruby2js 3.0.4 → 3.0.5

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.
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.