ruby2js 3.5.1 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
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