ruby2js 3.1.1 → 3.3.2

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -11
  3. data/lib/ruby2js.rb +14 -2
  4. data/lib/ruby2js/converter.rb +11 -3
  5. data/lib/ruby2js/converter/args.rb +1 -1
  6. data/lib/ruby2js/converter/block.rb +2 -2
  7. data/lib/ruby2js/converter/class.rb +4 -3
  8. data/lib/ruby2js/converter/class2.rb +38 -9
  9. data/lib/ruby2js/converter/cvar.rb +1 -1
  10. data/lib/ruby2js/converter/cvasgn.rb +1 -1
  11. data/lib/ruby2js/converter/def.rb +2 -2
  12. data/lib/ruby2js/converter/for.rb +7 -0
  13. data/lib/ruby2js/converter/hash.rb +3 -3
  14. data/lib/ruby2js/converter/if.rb +13 -2
  15. data/lib/ruby2js/converter/import.rb +38 -0
  16. data/lib/ruby2js/converter/logical.rb +46 -1
  17. data/lib/ruby2js/converter/opasgn.rb +5 -2
  18. data/lib/ruby2js/converter/regexp.rb +27 -2
  19. data/lib/ruby2js/converter/return.rb +1 -1
  20. data/lib/ruby2js/converter/send.rb +53 -27
  21. data/lib/ruby2js/converter/super.rb +15 -9
  22. data/lib/ruby2js/converter/xnode.rb +89 -0
  23. data/lib/ruby2js/es2021.rb +5 -0
  24. data/lib/ruby2js/es2021/strict.rb +3 -0
  25. data/lib/ruby2js/filter/cjs.rb +2 -2
  26. data/lib/ruby2js/filter/esm.rb +72 -0
  27. data/lib/ruby2js/filter/functions.rb +191 -41
  28. data/lib/ruby2js/filter/matchAll.rb +49 -0
  29. data/lib/ruby2js/filter/node.rb +18 -10
  30. data/lib/ruby2js/filter/nokogiri.rb +13 -13
  31. data/lib/ruby2js/filter/react.rb +190 -30
  32. data/lib/ruby2js/filter/require.rb +1 -4
  33. data/lib/ruby2js/filter/rubyjs.rb +4 -4
  34. data/lib/ruby2js/filter/vue.rb +40 -15
  35. data/lib/ruby2js/filter/wunderbar.rb +63 -0
  36. data/lib/ruby2js/serializer.rb +25 -11
  37. data/lib/ruby2js/version.rb +2 -2
  38. data/ruby2js.gemspec +2 -11
  39. metadata +24 -4
@@ -17,7 +17,7 @@ module Ruby2JS
17
17
  end
18
18
 
19
19
  def on_send(node)
20
- if
20
+ if \
21
21
  not @require_expr and # only statements
22
22
  node.children.length == 3 and
23
23
  node.children[0] == nil and
@@ -39,9 +39,6 @@ module Ruby2JS
39
39
  filename = File.join(dirname, basename)
40
40
 
41
41
  segments = basename.split(/[\/\\]/)
42
- if segments.all? {|path| path =~ @@valid_path and path != '..'}
43
- filename.untaint
44
- end
45
42
 
46
43
  if not File.file? filename and File.file? filename+".rb"
47
44
  filename += '.rb'
@@ -20,7 +20,7 @@ module Ruby2JS
20
20
  target = target.children.first
21
21
  end
22
22
 
23
- if
23
+ if \
24
24
  [:capitalize, :center, :chomp, :ljust, :lstrip, :rindex, :rjust,
25
25
  :rstrip, :scan, :swapcase, :tr].include? method
26
26
  then
@@ -28,7 +28,7 @@ module Ruby2JS
28
28
  s(:send, s(:lvar, :_s), method,
29
29
  *process_all([node.children[0], *node.children[2..-1]]))
30
30
 
31
- elsif
31
+ elsif \
32
32
  [:at, :compact, :compact!, :delete_at, :delete_at, :flatten, :insert,
33
33
  :reverse, :reverse!, :rotate, :rotate, :rotate!, :shift, :shuffle,
34
34
  :shuffle!, :slice, :slice!, :transpose, :union, :uniq, :uniq!]
@@ -62,14 +62,14 @@ module Ruby2JS
62
62
  method = call.children[1]
63
63
  return super if excluded?(method)
64
64
 
65
- if
65
+ if \
66
66
  [:collect_concat, :count, :cycle, :delete_if, :drop_while,
67
67
  :each_index, :each_slice, :each_with_index, :each_with_object,
68
68
  :find, :find_all, :flat_map, :inject, :grep, :group_by, :keep_if,
69
69
  :map, :max_by, :min_by, :one?, :partition, :reject, :reverse_each,
70
70
  :select!, :sort_by, :take_while].include? method
71
71
  then
72
- if
72
+ if \
73
73
  [:collect_concat, :count, :delete_if, :drop_while, :find,
74
74
  :find_all, :flat_map, :grep, :group_by, :keep_if, :map, :max_by,
75
75
  :min_by, :one?, :partition, :reject, :select!, :sort_by,
@@ -31,6 +31,8 @@ module Ruby2JS
31
31
  @vue_reactive = []
32
32
  @vue_filter_functions = false
33
33
 
34
+ @vue_setup = false
35
+
34
36
  super
35
37
 
36
38
  @exclude_methods << @vue_methods
@@ -41,7 +43,7 @@ module Ruby2JS
41
43
  @vue_h ||= options[:vue_h]
42
44
  filters = options[:filters] || Filter::DEFAULTS
43
45
 
44
- if
46
+ if \
45
47
  defined? Ruby2JS::Filter::Functions and
46
48
  filters.include? Ruby2JS::Filter::Functions
47
49
  then
@@ -49,6 +51,29 @@ module Ruby2JS
49
51
  end
50
52
  end
51
53
 
54
+ # if options[:vue_h] is set, return an array of nodes
55
+ def process(node)
56
+ return super if @vue_setup
57
+ @vue_setup = true
58
+ if @vue_h
59
+ if node.type == :begin
60
+ begin
61
+ @vue_apply = true
62
+ process s(:send, s(:block, s(:send, nil, :proc),
63
+ s(:args, s(:shadowarg, :$_)),
64
+ s(:begin, s(:lvasgn, :$_, s(:array)), process(node),
65
+ s(:return, s(:gvar, :$_)))), :[])
66
+ ensure
67
+ @vue_apply = nil
68
+ end
69
+ else
70
+ process s(:array, node)
71
+ end
72
+ else
73
+ process node
74
+ end
75
+ end
76
+
52
77
  # Example conversion
53
78
  # before:
54
79
  # (class (const nil :Foo) (const nil :Vue) nil)
@@ -115,7 +140,7 @@ module Ruby2JS
115
140
  end
116
141
  end
117
142
 
118
- elsif
143
+ elsif \
119
144
  statement.type == :send and statement.children[0] == cname and
120
145
  statement.children[1].to_s.end_with? '='
121
146
  then
@@ -136,13 +161,13 @@ module Ruby2JS
136
161
  hash << s(:pair, s(:sym, statement.children[1]),
137
162
  statement.children[2])
138
163
 
139
- elsif
164
+ elsif \
140
165
  statement.children[1] == :options and
141
166
  statement.children[2].type == :hash
142
167
  then
143
168
  options += statement.children[2].children
144
169
 
145
- elsif
170
+ elsif \
146
171
  statement.children[1] == :el and
147
172
  statement.children[2].type == :str
148
173
  then
@@ -165,7 +190,7 @@ module Ruby2JS
165
190
 
166
191
  block = s(:begin, block) unless block and block.type == :begin
167
192
 
168
- if
193
+ if \
169
194
  (block.children.length != 1 and
170
195
  not vue_wunderbar_free(block.children[0..-2])) or
171
196
 
@@ -378,7 +403,7 @@ module Ruby2JS
378
403
  end
379
404
  end
380
405
 
381
- elsif
406
+ elsif \
382
407
  class_methods.any? do |other_method|
383
408
  other_method.children[1].to_s == "#{method.children[1]}="
384
409
  end
@@ -520,7 +545,7 @@ module Ruby2JS
520
545
  *values.join(' ').split(' ').
521
546
  map {|str| s(:pair, s(:str, str), s(:true))})
522
547
  else
523
- if
548
+ if \
524
549
  expr.type == :if and expr.children[1] and
525
550
  expr.children[1].type == :str
526
551
  then
@@ -822,7 +847,7 @@ module Ruby2JS
822
847
  s(:splat, s(:array, *process_all(node.children[2..-1])))
823
848
  end
824
849
 
825
- elsif
850
+ elsif \
826
851
  node.children[1] == :createElement and
827
852
  node.children[0] == s(:const, nil, :Vue)
828
853
  then
@@ -842,7 +867,7 @@ module Ruby2JS
842
867
  element
843
868
  end
844
869
 
845
- elsif
870
+ elsif \
846
871
  @vue_self and VUE_METHODS.include? node.children[1] and
847
872
  node.children[0] == s(:const, nil, :Vue)
848
873
  then
@@ -904,7 +929,7 @@ module Ruby2JS
904
929
  prev = nil
905
930
  (node.children.length-1).downto(0) do |i|
906
931
  child = node.children[i]
907
- if
932
+ if \
908
933
  child.type == :send and child.children[0] == s(:gvar, :$_) and
909
934
  child.children[1] == :push
910
935
  then
@@ -943,7 +968,7 @@ module Ruby2JS
943
968
  child = node.children.first
944
969
 
945
970
  # map Vue.render(el, &block) to Vue.new(el: el, render: block)
946
- if
971
+ if \
947
972
  child.children[1] == :render and
948
973
  child.children[0] == s(:const, nil, :Vue)
949
974
  then
@@ -954,7 +979,7 @@ module Ruby2JS
954
979
  block = node.children[2]
955
980
  block = s(:begin, block) unless block and block.type == :begin
956
981
 
957
- if
982
+ if \
958
983
  block.children.length != 1 or not block.children.last or
959
984
  not [:send, :block].include? block.children.first.type
960
985
  then
@@ -974,7 +999,7 @@ module Ruby2JS
974
999
 
975
1000
  return super unless @vue_h
976
1001
 
977
- if
1002
+ if \
978
1003
  child.children[1] == :createElement and
979
1004
  child.children[0] == s(:const, nil, :Vue)
980
1005
  then
@@ -1034,7 +1059,7 @@ module Ruby2JS
1034
1059
  *node.children[1..-1]))
1035
1060
  end
1036
1061
 
1037
- elsif
1062
+ elsif \
1038
1063
  node.children.first.children.last == :forEach and
1039
1064
  vue_element?(node.children.last)
1040
1065
  then
@@ -1119,7 +1144,7 @@ module Ruby2JS
1119
1144
  node.children[0].children[0].to_s[1..-1]),
1120
1145
  node.children[1], process(node.children[2])]
1121
1146
 
1122
- elsif
1147
+ elsif \
1123
1148
  node.children.first.type == :lvasgn and
1124
1149
  @vue_props.include? node.children[0].children[0]
1125
1150
  then
@@ -0,0 +1,63 @@
1
+ require 'ruby2js'
2
+
3
+ module Ruby2JS
4
+ module Filter
5
+ module Wunderbar
6
+ include SEXP
7
+
8
+ def on_send(node)
9
+ target, method, *attrs = node.children
10
+
11
+ if target == s(:const, nil, :Wunderbar)
12
+ if [:debug, :info, :warn, :error, :fatal].include? method
13
+ method = :error if method == :fatal
14
+ return node.updated(nil, [s(:const, nil, :console), method, *attrs])
15
+ end
16
+ end
17
+
18
+ stack = []
19
+ while target!=nil and target.type==:send and target.children.length==2
20
+ name = method.to_s
21
+ if name.end_with? '!'
22
+ stack << s(:hash, s(:pair, s(:sym, :id), s(:str, name[0..-2])))
23
+ else
24
+ stack << s(:hash, s(:pair, s(:sym, :class), s(:str, name)))
25
+ end
26
+ target, method = target.children
27
+ end
28
+
29
+ if target == nil and method.to_s.start_with? "_"
30
+ S(:xnode, *method.to_s[1..-1], *stack, *process_all(attrs))
31
+ else
32
+ super
33
+ end
34
+ end
35
+
36
+ def on_block(node)
37
+ send, args, *block = node.children
38
+ target, method, *_ = send.children
39
+ while target!=nil and target.type==:send and target.children.length==2
40
+ target, method = target.children
41
+ end
42
+
43
+ if target == nil and method.to_s.start_with? "_"
44
+ if args.children.empty?
45
+ # append block as a standalone proc
46
+ process send.updated(nil, [*send.children, *process_all(block)])
47
+ else
48
+ # iterate over Enumerable arguments if there are args present
49
+ send = send.children
50
+ return super if send.length < 3
51
+ process s(:block, s(:send, *send[0..1], *send[3..-1]),
52
+ s(:args), s(:block, s(:send, send[2], :map),
53
+ *node.children[1..-1]))
54
+ end
55
+ else
56
+ super
57
+ end
58
+ end
59
+ end
60
+
61
+ DEFAULTS.push Wunderbar
62
+ end
63
+ end
@@ -32,8 +32,10 @@ module Ruby2JS
32
32
  ''
33
33
  elsif ['case ', 'default:'].include? self[0]
34
34
  ' ' * ([0,indent-2].max) + join
35
- else
35
+ elsif indent > 0
36
36
  ' ' * indent + join
37
+ else
38
+ join
37
39
  end
38
40
  end
39
41
  end
@@ -58,7 +60,6 @@ module Ruby2JS
58
60
 
59
61
  def timestamp(file)
60
62
  if file
61
- file = file.dup.untaint
62
63
  @timestamps[file] = File.mtime(file) if File.exist?(file)
63
64
  end
64
65
  end
@@ -87,9 +88,21 @@ module Ruby2JS
87
88
  first = line.find {|token| !token.empty?}
88
89
  if first
89
90
  last = line[line.rindex {|token| !token.empty?}]
90
- indent -= @indent if ')}]'.include? first[0] and indent >= @indent
91
- line.indent = indent
92
- indent += @indent if '({['.include? last[-1]
91
+ if (first.start_with? '<' and line.include? '>') or
92
+ (last.end_with? '>' and line.include? '<')
93
+ then
94
+ node = line.join[/.*?(<.*)/, 1]
95
+ indent -= @indent if node.start_with? '</'
96
+
97
+ line.indent = indent
98
+
99
+ node = line.join[/.*(<.*)/, 1]
100
+ indent += @indent unless node.include? '</' or node.include? '/>'
101
+ else
102
+ indent -= @indent if ')}]'.include? first[0] and indent >= @indent
103
+ line.indent = indent
104
+ indent += @indent if '({['.include? last[-1]
105
+ end
93
106
  else
94
107
  line.indent = indent
95
108
  end
@@ -102,24 +115,24 @@ module Ruby2JS
102
115
  reindent @lines
103
116
 
104
117
  (@lines.length-3).downto(0) do |i|
105
- if
118
+ if \
106
119
  @lines[i].length == 0
107
120
  then
108
121
  @lines.delete i
109
- elsif
122
+ elsif \
110
123
  @lines[i+1].comment? and not @lines[i].comment? and
111
124
  @lines[i].indent == @lines[i+1].indent
112
125
  then
113
126
  # before a comment
114
127
  @lines.insert i+1, Line.new
115
- elsif
128
+ elsif \
116
129
  @lines[i].indent == @lines[i+1].indent and
117
130
  @lines[i+1].indent < @lines[i+2].indent and
118
131
  not @lines[i].comment?
119
132
  then
120
133
  # start of indented block
121
134
  @lines.insert i+1, Line.new
122
- elsif
135
+ elsif \
123
136
  @lines[i].indent > @lines[i+1].indent and
124
137
  @lines[i+1].indent == @lines[i+2].indent and
125
138
  not @lines[i+2].empty?
@@ -136,7 +149,8 @@ module Ruby2JS
136
149
  @line << Token.new(string, @ast)
137
150
  else
138
151
  parts = string.split("\n")
139
- @line << Token.new(parts.shift, @ast)
152
+ first = parts.shift
153
+ @line << Token.new(first, @ast) if first
140
154
  @lines += parts.map {|part| Line.new(Token.new(part, @ast))}
141
155
  @lines << Line.new if string.end_with?("\n")
142
156
  @line = @lines.last
@@ -208,7 +222,7 @@ module Ruby2JS
208
222
  mark = output_location
209
223
  yield
210
224
 
211
- if
225
+ if \
212
226
  @lines.length > mark.first+1 or
213
227
  @lines[mark.first-1].join.length + @line.join.length >= @width
214
228
  then
@@ -1,8 +1,8 @@
1
1
  module Ruby2JS
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
- MINOR = 1
5
- TINY = 1
4
+ MINOR = 3
5
+ TINY = 2
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -18,15 +18,6 @@ Gem::Specification.new do |s|
18
18
  s.required_ruby_version = Gem::Requirement.new(">= 1.9.3".freeze)
19
19
  s.summary = "Minimal yet extensible Ruby to JavaScript conversion.".freeze
20
20
 
21
- if s.respond_to? :specification_version then
22
- s.specification_version = 4
23
-
24
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
25
- s.add_runtime_dependency(%q<parser>.freeze, [">= 0"])
26
- else
27
- s.add_dependency(%q<parser>.freeze, [">= 0"])
28
- end
29
- else
30
- s.add_dependency(%q<parser>.freeze, [">= 0"])
31
- end
21
+ s.add_dependency('parser')
22
+ s.add_dependency('regexp_parser')
32
23
  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.1.1
4
+ version: 3.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Ruby
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2020-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: regexp_parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: |2
28
42
  The base package maps Ruby syntax to JavaScript semantics.
29
43
  Filters may be provided to add Ruby-specific or framework specific
@@ -60,6 +74,7 @@ files:
60
74
  - lib/ruby2js/converter/for.rb
61
75
  - lib/ruby2js/converter/hash.rb
62
76
  - lib/ruby2js/converter/if.rb
77
+ - lib/ruby2js/converter/import.rb
63
78
  - lib/ruby2js/converter/in.rb
64
79
  - lib/ruby2js/converter/ivar.rb
65
80
  - lib/ruby2js/converter/ivasgn.rb
@@ -86,6 +101,7 @@ files:
86
101
  - lib/ruby2js/converter/vasgn.rb
87
102
  - lib/ruby2js/converter/while.rb
88
103
  - lib/ruby2js/converter/whilepost.rb
104
+ - lib/ruby2js/converter/xnode.rb
89
105
  - lib/ruby2js/converter/xstr.rb
90
106
  - lib/ruby2js/es2015.rb
91
107
  - lib/ruby2js/es2015/strict.rb
@@ -99,12 +115,16 @@ files:
99
115
  - lib/ruby2js/es2019/strict.rb
100
116
  - lib/ruby2js/es2020.rb
101
117
  - lib/ruby2js/es2020/strict.rb
118
+ - lib/ruby2js/es2021.rb
119
+ - lib/ruby2js/es2021/strict.rb
102
120
  - lib/ruby2js/execjs.rb
103
121
  - lib/ruby2js/filter.rb
104
122
  - lib/ruby2js/filter/camelCase.rb
105
123
  - lib/ruby2js/filter/cjs.rb
124
+ - lib/ruby2js/filter/esm.rb
106
125
  - lib/ruby2js/filter/functions.rb
107
126
  - lib/ruby2js/filter/jquery.rb
127
+ - lib/ruby2js/filter/matchAll.rb
108
128
  - lib/ruby2js/filter/minitest-jasmine.rb
109
129
  - lib/ruby2js/filter/node.rb
110
130
  - lib/ruby2js/filter/nokogiri.rb
@@ -114,6 +134,7 @@ files:
114
134
  - lib/ruby2js/filter/rubyjs.rb
115
135
  - lib/ruby2js/filter/underscore.rb
116
136
  - lib/ruby2js/filter/vue.rb
137
+ - lib/ruby2js/filter/wunderbar.rb
117
138
  - lib/ruby2js/haml.rb
118
139
  - lib/ruby2js/rails.rb
119
140
  - lib/ruby2js/serializer.rb
@@ -140,8 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
140
161
  - !ruby/object:Gem::Version
141
162
  version: '0'
142
163
  requirements: []
143
- rubyforge_project:
144
- rubygems_version: 2.7.6
164
+ rubygems_version: 3.1.2
145
165
  signing_key:
146
166
  specification_version: 4
147
167
  summary: Minimal yet extensible Ruby to JavaScript conversion.