ruby2js 3.5.1 → 4.0.0

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -662
  3. data/lib/ruby2js.rb +61 -10
  4. data/lib/ruby2js/converter.rb +10 -4
  5. data/lib/ruby2js/converter/assign.rb +159 -0
  6. data/lib/ruby2js/converter/begin.rb +7 -2
  7. data/lib/ruby2js/converter/case.rb +7 -2
  8. data/lib/ruby2js/converter/class.rb +77 -21
  9. data/lib/ruby2js/converter/class2.rb +102 -31
  10. data/lib/ruby2js/converter/def.rb +7 -3
  11. data/lib/ruby2js/converter/dstr.rb +8 -3
  12. data/lib/ruby2js/converter/hash.rb +9 -5
  13. data/lib/ruby2js/converter/hide.rb +13 -0
  14. data/lib/ruby2js/converter/if.rb +10 -2
  15. data/lib/ruby2js/converter/import.rb +35 -4
  16. data/lib/ruby2js/converter/kwbegin.rb +9 -2
  17. data/lib/ruby2js/converter/literal.rb +14 -2
  18. data/lib/ruby2js/converter/module.rb +41 -4
  19. data/lib/ruby2js/converter/opasgn.rb +8 -0
  20. data/lib/ruby2js/converter/send.rb +45 -5
  21. data/lib/ruby2js/converter/vasgn.rb +5 -0
  22. data/lib/ruby2js/converter/xstr.rb +1 -1
  23. data/lib/ruby2js/demo.rb +53 -0
  24. data/lib/ruby2js/es2022.rb +5 -0
  25. data/lib/ruby2js/es2022/strict.rb +3 -0
  26. data/lib/ruby2js/filter.rb +9 -1
  27. data/lib/ruby2js/filter/active_functions.rb +44 -0
  28. data/lib/ruby2js/filter/camelCase.rb +4 -3
  29. data/lib/ruby2js/filter/cjs.rb +2 -0
  30. data/lib/ruby2js/filter/esm.rb +133 -7
  31. data/lib/ruby2js/filter/functions.rb +107 -98
  32. data/lib/ruby2js/filter/{wunderbar.rb → jsx.rb} +29 -7
  33. data/lib/ruby2js/filter/node.rb +95 -74
  34. data/lib/ruby2js/filter/nokogiri.rb +15 -41
  35. data/lib/ruby2js/filter/react.rb +191 -56
  36. data/lib/ruby2js/filter/require.rb +100 -5
  37. data/lib/ruby2js/filter/return.rb +15 -1
  38. data/lib/ruby2js/filter/securerandom.rb +33 -0
  39. data/lib/ruby2js/filter/stimulus.rb +185 -0
  40. data/lib/ruby2js/filter/vue.rb +9 -0
  41. data/lib/ruby2js/jsx.rb +291 -0
  42. data/lib/ruby2js/namespace.rb +75 -0
  43. data/lib/ruby2js/rails.rb +15 -9
  44. data/lib/ruby2js/serializer.rb +3 -1
  45. data/lib/ruby2js/version.rb +3 -3
  46. data/ruby2js.gemspec +1 -1
  47. metadata +14 -5
  48. data/lib/ruby2js/filter/esm_migration.rb +0 -72
  49. 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' > Gemfile
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 ".rbs" (RuBy Script) extension.
17
- # You can add "ruby_thing.js.rbs" to your javascript folder
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
- ActionView::Template.register_template_handler :rb, Template
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( file)
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.register_engine '.rbs', SprocketProcessor, mime_type: 'text/javascript', silence_deprecation: true
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
@@ -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: @ast.loc.expression.source_buffer.name,
368
+ file: @file_name,
367
369
  sources: sources.map(&:name),
368
370
  mappings: @mappings
369
371
  }
@@ -1,8 +1,8 @@
1
1
  module Ruby2JS
2
2
  module VERSION #:nodoc:
3
- MAJOR = 3
4
- MINOR = 5
5
- TINY = 1
3
+ MAJOR = 4
4
+ MINOR = 0
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
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: 3.5.1
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: 2020-11-02 00:00:00.000000000 Z
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