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 +5 -5
- data/lib/ruby2js/converter.rb +15 -2
- data/lib/ruby2js/converter/arg.rb +2 -2
- data/lib/ruby2js/converter/args.rb +1 -1
- data/lib/ruby2js/converter/array.rb +1 -1
- data/lib/ruby2js/converter/break.rb +2 -2
- data/lib/ruby2js/converter/class.rb +1 -1
- data/lib/ruby2js/converter/def.rb +1 -1
- data/lib/ruby2js/converter/hash.rb +1 -1
- data/lib/ruby2js/converter/kwbegin.rb +4 -4
- data/lib/ruby2js/converter/next.rb +1 -1
- data/lib/ruby2js/converter/send.rb +1 -1
- data/lib/ruby2js/converter/super.rb +1 -1
- data/lib/ruby2js/filter/functions.rb +14 -2
- data/lib/ruby2js/filter/react.rb +1 -1
- data/lib/ruby2js/filter/vue.rb +119 -38
- data/lib/ruby2js/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 96bf18688d1c3a685449b4e8404cb6a8c13f989031c61f950bfb69e5adf7855f
|
4
|
+
data.tar.gz: 39abc46c793667b6b3bd502986ad0aec2dd8f912eca79d94d870095a5d0aeb64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70a47951f48b3a389c497f393eb9a112e5b702f006efb3191fa7c99a36d7cd44dade1baef64925951a4c9158a2d7e3b2f5e27e24d03c4502c00af9056b0a1779
|
7
|
+
data.tar.gz: 1f785124a3ad1dea8028f29c728953396eb7e2b34d51d8fdd634cffada1d63f574a21132a11337a3d08aff693668ef33132fe74f743a02f37c299027d8e017b9
|
data/lib/ruby2js/converter.rb
CHANGED
@@ -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
|
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
|
-
|
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
|
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
|
17
|
+
raise Error.new("argument #{ unknown.inspect }", @ast) if unknown
|
18
18
|
nil
|
19
19
|
end
|
20
20
|
end
|
@@ -5,8 +5,8 @@ module Ruby2JS
|
|
5
5
|
# (int 1))
|
6
6
|
|
7
7
|
handle :break do |n=nil|
|
8
|
-
raise
|
9
|
-
raise
|
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
|
148
|
+
raise Error.new("class #{ m.type }", @ast)
|
149
149
|
end
|
150
150
|
|
151
151
|
# associate comments
|
@@ -13,7 +13,7 @@ module Ruby2JS
|
|
13
13
|
(singleton ? put('{') : puts('{'))
|
14
14
|
|
15
15
|
pairs.each_with_index do |node, index|
|
16
|
-
raise
|
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
|
30
|
+
raise Error.new("block else", @ast) if otherwise
|
31
31
|
|
32
32
|
if recovers.any? {|recover| not recover.children[1]}
|
33
|
-
raise
|
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
|
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
|
@@ -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
|
221
|
+
raise Error.new("use of JavaScript keyword new", @ast)
|
222
222
|
end
|
223
223
|
|
224
224
|
elsif method == :raise and receiver == nil
|
@@ -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
|
-
|
146
|
-
|
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)
|
data/lib/ruby2js/filter/react.rb
CHANGED
@@ -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
|
826
|
+
raise Error.new("setting a React property", node)
|
827
827
|
end
|
828
828
|
|
829
829
|
# convert instance variables to state: "@x ||= y"
|
data/lib/ruby2js/filter/vue.rb
CHANGED
@@ -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
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
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?
|
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
|
-
|
742
|
-
|
743
|
-
|
744
|
-
s(:
|
745
|
-
|
746
|
-
|
747
|
-
|
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
|
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
|
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)
|
data/lib/ruby2js/version.rb
CHANGED
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
|
+
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-
|
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
|
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.
|