ruby2js 3.5.1 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -662
- data/lib/ruby2js.rb +61 -10
- data/lib/ruby2js/converter.rb +10 -4
- data/lib/ruby2js/converter/assign.rb +159 -0
- data/lib/ruby2js/converter/begin.rb +7 -2
- data/lib/ruby2js/converter/case.rb +7 -2
- data/lib/ruby2js/converter/class.rb +77 -21
- data/lib/ruby2js/converter/class2.rb +102 -31
- data/lib/ruby2js/converter/def.rb +7 -3
- data/lib/ruby2js/converter/dstr.rb +8 -3
- data/lib/ruby2js/converter/hash.rb +9 -5
- data/lib/ruby2js/converter/hide.rb +13 -0
- data/lib/ruby2js/converter/if.rb +10 -2
- data/lib/ruby2js/converter/import.rb +35 -4
- data/lib/ruby2js/converter/kwbegin.rb +9 -2
- data/lib/ruby2js/converter/literal.rb +14 -2
- data/lib/ruby2js/converter/module.rb +41 -4
- data/lib/ruby2js/converter/opasgn.rb +8 -0
- data/lib/ruby2js/converter/send.rb +45 -5
- data/lib/ruby2js/converter/vasgn.rb +5 -0
- data/lib/ruby2js/converter/xstr.rb +1 -1
- data/lib/ruby2js/demo.rb +53 -0
- data/lib/ruby2js/es2022.rb +5 -0
- data/lib/ruby2js/es2022/strict.rb +3 -0
- data/lib/ruby2js/filter.rb +9 -1
- data/lib/ruby2js/filter/active_functions.rb +44 -0
- data/lib/ruby2js/filter/camelCase.rb +4 -3
- data/lib/ruby2js/filter/cjs.rb +2 -0
- data/lib/ruby2js/filter/esm.rb +133 -7
- data/lib/ruby2js/filter/functions.rb +107 -98
- data/lib/ruby2js/filter/{wunderbar.rb → jsx.rb} +29 -7
- data/lib/ruby2js/filter/node.rb +95 -74
- data/lib/ruby2js/filter/nokogiri.rb +15 -41
- data/lib/ruby2js/filter/react.rb +191 -56
- data/lib/ruby2js/filter/require.rb +100 -5
- data/lib/ruby2js/filter/return.rb +15 -1
- data/lib/ruby2js/filter/securerandom.rb +33 -0
- data/lib/ruby2js/filter/stimulus.rb +185 -0
- data/lib/ruby2js/filter/vue.rb +9 -0
- data/lib/ruby2js/jsx.rb +291 -0
- data/lib/ruby2js/namespace.rb +75 -0
- data/lib/ruby2js/rails.rb +15 -9
- data/lib/ruby2js/serializer.rb +3 -1
- data/lib/ruby2js/version.rb +3 -3
- data/ruby2js.gemspec +1 -1
- metadata +14 -5
- data/lib/ruby2js/filter/esm_migration.rb +0 -72
- data/lib/ruby2js/filter/fast-deep-equal.rb +0 -23
@@ -0,0 +1,75 @@
|
|
1
|
+
# Instances of this class keep track of both classes and modules that we have
|
2
|
+
# seen before, as well as the methods and properties that are defined in each.
|
3
|
+
#
|
4
|
+
# Use cases this enables:
|
5
|
+
#
|
6
|
+
# * detection of "open" classes and modules, i.e., redefining a class or
|
7
|
+
# module that was previously declared in order to add or modify methods
|
8
|
+
# or properties.
|
9
|
+
#
|
10
|
+
# * knowing when to prefix method or property access with `this.` and
|
11
|
+
# when to add `.bind(this)` for methods and properties that were defined
|
12
|
+
# outside of this class.
|
13
|
+
#
|
14
|
+
module Ruby2JS
|
15
|
+
class Namespace
|
16
|
+
def initialize
|
17
|
+
@active = [] # current scope
|
18
|
+
@seen = {} # history of all definitions seen previously
|
19
|
+
end
|
20
|
+
|
21
|
+
# convert an AST name which is represented as a set of nested
|
22
|
+
# s(:const, # ...) into an array of symbols that represent
|
23
|
+
# the relative path.
|
24
|
+
def resolve(token, result = [])
|
25
|
+
return [] unless token&.type == :const
|
26
|
+
resolve(token.children.first, result)
|
27
|
+
result.push(token.children.last)
|
28
|
+
end
|
29
|
+
|
30
|
+
# return the active scope as a flat array of symbols
|
31
|
+
def active
|
32
|
+
@active.flatten.compact
|
33
|
+
end
|
34
|
+
|
35
|
+
# enter a new scope, which may be a nested subscope. Mark the new scope
|
36
|
+
# as seen, and return any previous definition that may have been seen
|
37
|
+
# before.
|
38
|
+
def enter(name)
|
39
|
+
@active.push resolve(name)
|
40
|
+
previous = @seen[active]
|
41
|
+
@seen[active] ||= {}
|
42
|
+
previous
|
43
|
+
end
|
44
|
+
|
45
|
+
# return the set of known properties (and methods) for either the current
|
46
|
+
# scope or a named subscope.
|
47
|
+
def getOwnProps(name = nil)
|
48
|
+
@seen[active + resolve(name)]&.dup || {}
|
49
|
+
end
|
50
|
+
|
51
|
+
# add new props (and methods) to the current scope.
|
52
|
+
def defineProps(props, namespace=active)
|
53
|
+
@seen[namespace] ||= {}
|
54
|
+
@seen[namespace].merge! props || {}
|
55
|
+
end
|
56
|
+
|
57
|
+
# find a named scope which may be relative to any point in the ancestry of
|
58
|
+
# the current scope. Return the properties for that scope.
|
59
|
+
def find(name)
|
60
|
+
name = resolve(name)
|
61
|
+
prefix = active
|
62
|
+
while prefix.pop
|
63
|
+
result = @seen[prefix + name]
|
64
|
+
return result if result
|
65
|
+
end
|
66
|
+
{}
|
67
|
+
end
|
68
|
+
|
69
|
+
# leave a given scope. Note that the scope may be compound (e.g., M::N),
|
70
|
+
# and if so, it will pop the entire resolved name.
|
71
|
+
def leave()
|
72
|
+
@active.pop
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/ruby2js/rails.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Example usage:
|
2
2
|
#
|
3
|
-
# $ echo gem 'ruby2js', require: 'ruby2js/rails'
|
3
|
+
# $ echo "gem 'ruby2js', require: 'ruby2js/rails'" >> Gemfile
|
4
4
|
# $ bundle update
|
5
5
|
# $ rails generate controller Say hello
|
6
6
|
# $ echo 'alert "Hello world!"' > app/views/say/hello.js.rb
|
@@ -13,8 +13,8 @@
|
|
13
13
|
#
|
14
14
|
# Asset Pipeline:
|
15
15
|
#
|
16
|
-
# Ruby2JS registers ".
|
17
|
-
# You can add "ruby_thing.js.
|
16
|
+
# Ruby2JS registers ".rb.js" extension.
|
17
|
+
# You can add "ruby_thing.js.rb" to your app/javascript folder
|
18
18
|
# and '= require ruby_thing' from other js sources.
|
19
19
|
#
|
20
20
|
# (options are not yet supported, but by requiring the appropriate files
|
@@ -26,15 +26,17 @@ module Ruby2JS
|
|
26
26
|
class Template
|
27
27
|
cattr_accessor :default_format
|
28
28
|
self.default_format = Mime[:js]
|
29
|
-
def self.call(template)
|
30
|
-
"Ruby2JS.convert(#{template.source.inspect}).to_s"
|
29
|
+
def self.call(template, source)
|
30
|
+
"Ruby2JS.convert(#{template.source.inspect}, file: source).to_s"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
34
|
+
ActiveSupport.on_load(:action_view) do
|
35
|
+
ActionView::Template.register_template_handler :rb, Template
|
36
|
+
end
|
35
37
|
|
36
38
|
class SprocketProcessor
|
37
|
-
def initialize(
|
39
|
+
def initialize(file = nil)
|
38
40
|
@file = file
|
39
41
|
end
|
40
42
|
def render(context , _)
|
@@ -46,10 +48,14 @@ module Ruby2JS
|
|
46
48
|
class Engine < ::Rails::Engine
|
47
49
|
engine_name "ruby2js"
|
48
50
|
|
51
|
+
config.app_generators.javascripts true
|
52
|
+
config.app_generators.javascript_engine :rb
|
53
|
+
|
49
54
|
config.assets.configure do |env|
|
50
|
-
env.
|
55
|
+
env.register_mime_type 'text/ruby', extensions: ['.js.rb', '.rb']
|
56
|
+
env.register_transformer 'text/ruby', 'text/javascript', SprocketProcessor
|
57
|
+
env.register_preprocessor 'text/javascript', SprocketProcessor
|
51
58
|
end
|
52
|
-
|
53
59
|
end
|
54
60
|
|
55
61
|
end
|
data/lib/ruby2js/serializer.rb
CHANGED
@@ -42,6 +42,7 @@ module Ruby2JS
|
|
42
42
|
|
43
43
|
class Serializer
|
44
44
|
attr_reader :timestamps
|
45
|
+
attr_accessor :file_name
|
45
46
|
|
46
47
|
def initialize
|
47
48
|
@sep = '; '
|
@@ -56,6 +57,7 @@ module Ruby2JS
|
|
56
57
|
@timestamps = {}
|
57
58
|
|
58
59
|
@ast = nil
|
60
|
+
@file_name = ''
|
59
61
|
end
|
60
62
|
|
61
63
|
def timestamp(file)
|
@@ -363,7 +365,7 @@ module Ruby2JS
|
|
363
365
|
|
364
366
|
@sourcemap = {
|
365
367
|
version: 3,
|
366
|
-
file: @
|
368
|
+
file: @file_name,
|
367
369
|
sources: sources.map(&:name),
|
368
370
|
mappings: @mappings
|
369
371
|
}
|
data/lib/ruby2js/version.rb
CHANGED
data/ruby2js.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
11
11
|
s.require_paths = ["lib".freeze]
|
12
|
-
s.authors = ["Sam Ruby".freeze]
|
12
|
+
s.authors = ["Sam Ruby".freeze, "Jared White".freeze]
|
13
13
|
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".freeze
|
14
14
|
s.email = "rubys@intertwingly.net".freeze
|
15
15
|
s.files = %w(ruby2js.gemspec README.md) + Dir.glob("{lib}/**/*")
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby2js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Ruby
|
8
|
+
- Jared White
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: parser
|
@@ -54,6 +55,7 @@ files:
|
|
54
55
|
- lib/ruby2js/converter/arg.rb
|
55
56
|
- lib/ruby2js/converter/args.rb
|
56
57
|
- lib/ruby2js/converter/array.rb
|
58
|
+
- lib/ruby2js/converter/assign.rb
|
57
59
|
- lib/ruby2js/converter/begin.rb
|
58
60
|
- lib/ruby2js/converter/block.rb
|
59
61
|
- lib/ruby2js/converter/blockpass.rb
|
@@ -73,6 +75,7 @@ files:
|
|
73
75
|
- lib/ruby2js/converter/fileline.rb
|
74
76
|
- lib/ruby2js/converter/for.rb
|
75
77
|
- lib/ruby2js/converter/hash.rb
|
78
|
+
- lib/ruby2js/converter/hide.rb
|
76
79
|
- lib/ruby2js/converter/if.rb
|
77
80
|
- lib/ruby2js/converter/import.rb
|
78
81
|
- lib/ruby2js/converter/in.rb
|
@@ -105,6 +108,7 @@ files:
|
|
105
108
|
- lib/ruby2js/converter/xnode.rb
|
106
109
|
- lib/ruby2js/converter/xstr.rb
|
107
110
|
- lib/ruby2js/converter/yield.rb
|
111
|
+
- lib/ruby2js/demo.rb
|
108
112
|
- lib/ruby2js/es2015.rb
|
109
113
|
- lib/ruby2js/es2015/strict.rb
|
110
114
|
- lib/ruby2js/es2016.rb
|
@@ -119,15 +123,17 @@ files:
|
|
119
123
|
- lib/ruby2js/es2020/strict.rb
|
120
124
|
- lib/ruby2js/es2021.rb
|
121
125
|
- lib/ruby2js/es2021/strict.rb
|
126
|
+
- lib/ruby2js/es2022.rb
|
127
|
+
- lib/ruby2js/es2022/strict.rb
|
122
128
|
- lib/ruby2js/execjs.rb
|
123
129
|
- lib/ruby2js/filter.rb
|
130
|
+
- lib/ruby2js/filter/active_functions.rb
|
124
131
|
- lib/ruby2js/filter/camelCase.rb
|
125
132
|
- lib/ruby2js/filter/cjs.rb
|
126
133
|
- lib/ruby2js/filter/esm.rb
|
127
|
-
- lib/ruby2js/filter/esm_migration.rb
|
128
|
-
- lib/ruby2js/filter/fast-deep-equal.rb
|
129
134
|
- lib/ruby2js/filter/functions.rb
|
130
135
|
- lib/ruby2js/filter/jquery.rb
|
136
|
+
- lib/ruby2js/filter/jsx.rb
|
131
137
|
- lib/ruby2js/filter/matchAll.rb
|
132
138
|
- lib/ruby2js/filter/minitest-jasmine.rb
|
133
139
|
- lib/ruby2js/filter/node.rb
|
@@ -135,11 +141,14 @@ files:
|
|
135
141
|
- lib/ruby2js/filter/react.rb
|
136
142
|
- lib/ruby2js/filter/require.rb
|
137
143
|
- lib/ruby2js/filter/return.rb
|
144
|
+
- lib/ruby2js/filter/securerandom.rb
|
145
|
+
- lib/ruby2js/filter/stimulus.rb
|
138
146
|
- lib/ruby2js/filter/tagged_templates.rb
|
139
147
|
- lib/ruby2js/filter/underscore.rb
|
140
148
|
- lib/ruby2js/filter/vue.rb
|
141
|
-
- lib/ruby2js/filter/wunderbar.rb
|
142
149
|
- lib/ruby2js/haml.rb
|
150
|
+
- lib/ruby2js/jsx.rb
|
151
|
+
- lib/ruby2js/namespace.rb
|
143
152
|
- lib/ruby2js/rails.rb
|
144
153
|
- lib/ruby2js/serializer.rb
|
145
154
|
- lib/ruby2js/sinatra.rb
|
@@ -1,72 +0,0 @@
|
|
1
|
-
require 'ruby2js'
|
2
|
-
|
3
|
-
module Ruby2JS
|
4
|
-
module Filter
|
5
|
-
module ESMMigration
|
6
|
-
include SEXP
|
7
|
-
|
8
|
-
def initialize(*args)
|
9
|
-
@esm_include = nil
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
def process(node)
|
14
|
-
return super if @esm_include
|
15
|
-
@esm_include = Set.new
|
16
|
-
@esm_exclude = Set.new
|
17
|
-
@esm_export = nil
|
18
|
-
result = super
|
19
|
-
|
20
|
-
esm_walk(result)
|
21
|
-
|
22
|
-
inventory = (@esm_include - @esm_exclude).to_a.sort
|
23
|
-
|
24
|
-
if inventory.empty? and not @esm_export
|
25
|
-
result
|
26
|
-
else
|
27
|
-
list = inventory.map do |name|
|
28
|
-
if name == "React" and defined? Ruby2JS::Filter::React
|
29
|
-
s(:import, "#{name.downcase}", s(:const, nil, name))
|
30
|
-
elsif not %w(JSON Object).include? name
|
31
|
-
s(:import, "./#{name.downcase}.js", s(:const, nil, name))
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
list.push result
|
36
|
-
|
37
|
-
if @esm_export
|
38
|
-
list.push s(:export, :default, s(:const, nil, @esm_export))
|
39
|
-
end
|
40
|
-
|
41
|
-
s(:begin, *list.compact)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# gather constants
|
46
|
-
def esm_walk(node)
|
47
|
-
# extract ivars and cvars
|
48
|
-
if node.type == :const and node.children.first == nil
|
49
|
-
@esm_include << node.children.last.to_s
|
50
|
-
elsif node.type == :xnode
|
51
|
-
name = node.children.first
|
52
|
-
@esm_include << name unless name.empty? or name =~ /^[a-z]/
|
53
|
-
elsif node.type == :casgn and node.children.first == nil
|
54
|
-
@esm_exclude << node.children[1].to_s
|
55
|
-
elsif node.type == :class and node.children.first.type == :const
|
56
|
-
if node.children.first.children.first == nil
|
57
|
-
name = node.children.first.children.last.to_s
|
58
|
-
@esm_exclude << name
|
59
|
-
@esm_export ||= name
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# recurse
|
64
|
-
node.children.each do |child|
|
65
|
-
esm_walk(child) if Parser::AST::Node === child
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
DEFAULTS.push ESMMigration
|
71
|
-
end
|
72
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'ruby2js'
|
2
|
-
|
3
|
-
module Ruby2JS
|
4
|
-
module Filter
|
5
|
-
module Fast_Deep_Equal
|
6
|
-
include SEXP
|
7
|
-
|
8
|
-
SCALAR = [ :float, :int, :nil, :str ]
|
9
|
-
|
10
|
-
def on_send(node)
|
11
|
-
return super unless node.children.length == 3
|
12
|
-
left, method, right = node.children
|
13
|
-
return super unless method == :==
|
14
|
-
return super if SCALAR.include? left.type
|
15
|
-
return super if SCALAR.include? right.type
|
16
|
-
|
17
|
-
node.updated nil, [nil, :$eq, left, right]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
DEFAULTS.push Fast_Deep_Equal
|
22
|
-
end
|
23
|
-
end
|