opal-optimizer 0.1.1 → 0.1.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bac974d0150297fd084bdc1a40e9eb41d859f2231545d543294de2e3de0ac073
4
- data.tar.gz: 0cda5d5d3ac92adef47a98e7c82b9c1233e7ff18d218e23bd4838cc812b82ae6
3
+ metadata.gz: 125dd4183eebeaf54651e1888dc9e662693e8f20c0b60f65a5f8dd132475033b
4
+ data.tar.gz: c8b571477260698fef8d6acbbf1914b2772dcb4c413916eeeff071d38fd3afd2
5
5
  SHA512:
6
- metadata.gz: cce52551506f12e9bdf5c0f05ee80df69b6c9c1d3887c57a316a019b108abe0441fb5b9f0a70bf02ef2fe2fe5fff637ec06563639b8e295ad4371b4567b8b2a1
7
- data.tar.gz: 11460f5faf89d08dc4965d5c788b216b0ef55c16125e0a1ea9a617ac7ce0111d3eb99f8b60334ff0cfc7cedd5f0883573d7583f408087b0f98b35a8e27973d86
6
+ metadata.gz: 64ca3cc44bce614557ae951e1b1b2d8bc57821d358ea6263a0cf9f587278af9c7150326706eb26f6194265814587c5b58899adf3a0a75f6af9d730611b3f70aa
7
+ data.tar.gz: ad54442d22a1a162e0d18371890c0dd7d1f15f80ecb1bc83741368b2c315eea3e657b5cae1960621923895c5ea9ae3046634cc7f62baf4a729c7616f26599a59
@@ -0,0 +1,63 @@
1
+ name: build
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - "*-stable"
8
+ - "*/ci-check"
9
+ pull_request: {}
10
+
11
+ jobs:
12
+ rake:
13
+ name: ${{ matrix.combo.name }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ combo:
18
+ - name: Opal-master
19
+ opal: master
20
+ - name: Opal-1.4
21
+ opal: 1.4
22
+ - name: Opal-1.3
23
+ opal: 1.3
24
+ - name: Opal-1.2
25
+ opal: 1.2
26
+ - name: Opal-1.1
27
+ opal: 1.1
28
+ - name: Opal-1.0
29
+ opal: '1.0'
30
+ - name: Ruby-head
31
+ ruby: head
32
+ - name: Windows
33
+ os: windows-latest
34
+ - name: macOS
35
+ os: macos-latest
36
+
37
+ runs-on: ${{ matrix.combo.os || 'ubuntu-latest' }}
38
+
39
+ steps:
40
+ - uses: actions/checkout@v2
41
+ - name: set environment variables
42
+ run: |
43
+ echo "OPAL_VERSION=${{ matrix.combo.opal || '1.3' }}" >> $GITHUB_ENV
44
+ - uses: ruby/setup-ruby@v1
45
+ with:
46
+ ruby-version: ${{ matrix.combo.ruby || '3.0' }}
47
+ - run: bundle lock
48
+ - uses: actions/cache@v2
49
+ with:
50
+ path: ./vendor/bundle
51
+ key: ${{ runner.os }}-${{ matrix.combo.ruby || '3.0' }}-gems-${{ matrix.combo.opal || '1.3' }}-${{ github.ref }}-${{ hashFiles('**/Gemfile.lock') }}
52
+ restore-keys: |
53
+ ${{ runner.os }}-${{ matrix.combo.ruby || '3.0' }}-gems-${{ matrix.combo.opal || '1.3' }}-${{ github.ref }}
54
+ ${{ runner.os }}-${{ matrix.combo.ruby || '3.0' }}-gems-${{ matrix.combo.opal || '1.3' }}-master
55
+ ${{ runner.os }}-${{ matrix.combo.ruby || '3.0' }}-gems-${{ matrix.combo.opal || '1.3' }}-
56
+ ${{ runner.os }}-${{ matrix.combo.ruby || '3.0' }}-gems-
57
+ - name: bundle install
58
+ run: |
59
+ bundle config path $PWD/vendor/bundle
60
+ bundle install --jobs 4 --retry 3
61
+ bundle clean
62
+ - run: bundle exec rake
63
+
data/.gitignore CHANGED
@@ -7,5 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
 
10
+ /Gemfile.lock
11
+
10
12
  # rspec failure tracking
11
13
  .rspec_status
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.1.5
2
+
3
+ * Opal 1.4 compatibility
data/Gemfile CHANGED
@@ -3,13 +3,20 @@ source "https://rubygems.org"
3
3
  # Specify your gem's dependencies in opal-optimizer.gemspec
4
4
  gemspec
5
5
 
6
- gem "rake", "~> 12.0"
7
- gem "rspec", "~> 3.0"
6
+ gem "rake"
7
+ gem "rspec"
8
8
 
9
- gem "opal", path: "../opal"
10
- gem "opal-sprockets", path: "../opal-sprockets"
11
- gem "opal-browser", path: "../opal-browser"
9
+ case ENV['OPAL_VERSION']
10
+ when nil
11
+ when /\A[0-9.]+\z/
12
+ gem 'opal', "~> #{ENV['OPAL_VERSION']}.0a"
13
+ else
14
+ gem 'opal', github: 'opal/opal', ref: ENV['OPAL_VERSION']
15
+ end
16
+ gem "opal-sprockets"
17
+ gem "opal-browser"
12
18
 
13
- gem "rkelly-remix"
19
+ gem "rkelly-turbo"
14
20
 
21
+ gem "ruby-prof"
15
22
  gem "pry"
data/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # Opal::Optimizer
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/opal/optimizer`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ A utility to optimize the JavaScript output from Opal with a help of RKelly-Turbo JavaScript parser.
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ As of now it contains two steps:
6
+
7
+ * Tree shaking for Opal methods - if a named method is not called anywhere in the code, it's removed
8
+ * Collapsing stubs
6
9
 
7
10
  ## Installation
8
11
 
@@ -22,7 +25,7 @@ Or install it yourself as:
22
25
 
23
26
  ## Usage
24
27
 
25
- TODO: Write usage instructions here
28
+ For Sprockets environments, all you need is to `require "opal/optimizer/sprockets"` in your pipeline.
26
29
 
27
30
  ## Development
28
31
 
@@ -32,7 +35,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
32
35
 
33
36
  ## Contributing
34
37
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/opal-optimizer.
38
+ Bug reports and pull requests are welcome on GitHub at https://github.com/hmdne/opal-optimizer.
36
39
 
37
40
 
38
41
  ## License
data/bin/opal-optimizer CHANGED
@@ -1,6 +1,2 @@
1
1
  #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "opal/optimizer"
5
-
6
- print Opal::Optimizer.new(ARGV[0] ? File.read(ARGV[0]) : STDIN.read).optimize
2
+ load __dir__+"/../exe/opal-optimizer"
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "opal/optimizer"
5
+
6
+ print Opal::Optimizer.new(ARGF.read).optimize
@@ -11,8 +11,12 @@ class CollapseStubs < Step
11
11
 
12
12
  nodes = corelib_calls["add_stubs"] || []
13
13
  nodes.each do |node|
14
- stubs += node.arguments.value.first.value.map do |i|
15
- i.value.value.gsub(/['"]/, '')
14
+ if opal_version >= 1.4
15
+ stubs += node.arguments.value.first.value[1..-2].split(',')
16
+ else
17
+ stubs += node.arguments.value.first.value.map do |i|
18
+ i.value.value.gsub(/['"]/, '')
19
+ end
16
20
  end
17
21
 
18
22
  node.destroy! "CollapseStubs"
@@ -26,7 +30,7 @@ class CollapseStubs < Step
26
30
  stubs -= ["$respond_to_missing?"] if opal_version >= 1.1
27
31
 
28
32
  new_stub_code = <<~end
29
- var stubs = '#{stubs.to_a.join('#')}'.split('#'), stubs_obj = {};
33
+ var stubs = '#{stubs.to_a.join(',')}'.split(','), stubs_obj = {};
30
34
  for (var i = 0; i < stubs.length; i++)
31
35
  stubs_obj[stubs[i]] = {value: Opal.stub_for(stubs[i]), enumerable: false, configurable: true, writable: true};
32
36
  Object.defineProperties(Opal.BasicObject.$$prototype, stubs_obj);
@@ -12,6 +12,7 @@ class TreeShaking < Step
12
12
  method_defs = corelib_calls["def"] +
13
13
  corelib_calls["defs"] +
14
14
  corelib_calls["defn"] +
15
+ corelib_calls["udef"] +
15
16
  aliases.keys
16
17
 
17
18
  method_calls = Set.new
@@ -23,7 +24,7 @@ class TreeShaking < Step
23
24
  StringNode === i.value.accessor &&
24
25
  i.value.accessor.value[1] == '$'
25
26
  i.value.accessor.value[1..-2]
26
- elsif i.value_path?(ResolveNode, "$send")
27
+ elsif i.value_path?(ResolveNode, ->(i) { %w[$send $send2 $refined_send].include? i })
27
28
  old = i.arguments.value[1]
28
29
  "$" + old.value[1..-2] if StringNode === old
29
30
  end
@@ -44,16 +45,30 @@ class TreeShaking < Step
44
45
  method_calls += aliases.values
45
46
 
46
47
  # Protected methods
47
- method_calls += ["$register", "$negative?"]
48
+ method_calls += []
48
49
 
49
50
  removed = Set.new
50
51
 
51
52
  method_defs.each do |m|
52
53
  name = m.arguments.value[1]
53
- next unless StringNode === name
54
-
55
- name = name.value[1..-2]
56
- name = "$" + name if m.value.accessor == "alias"
54
+ case name
55
+ when AddNode
56
+ if StringNode === name.left && StringNode === name.value
57
+ name = name.left.value[1..-2] + name.value.value[1..-2]
58
+ else
59
+ next
60
+ end
61
+ when StringNode
62
+ name = name.value[1..-2]
63
+ case m.value
64
+ when ResolveNode
65
+ name = "$" + name if m.value.value == "$alias"
66
+ when DotAccessorNode
67
+ name = "$" + name if m.value.accessor == "alias"
68
+ end
69
+ else
70
+ next
71
+ end
57
72
 
58
73
  next if method_calls.include? name
59
74
 
@@ -62,8 +77,17 @@ class TreeShaking < Step
62
77
  end
63
78
 
64
79
  corelib_calls["add_stubs"].each do |stubcall|
65
- stubcall.arguments.value.first.value.reject! do |i|
66
- removed.include? i.value.value[1..-2]
80
+ if opal_version >= 1.4
81
+ stubs = stubcall.arguments.value.first.value
82
+ new_stubs = stubs[1..-2].split(",").reject do |i|
83
+ removed.include? i
84
+ end.join(',')
85
+ new_stubs = "'#{new_stubs}'"
86
+ stubs.replace(new_stubs)
87
+ else
88
+ stubcall.arguments.value.first.value.reject! do |i|
89
+ removed.include? i.value.value[1..-2]
90
+ end
67
91
  end
68
92
  end
69
93
 
@@ -73,7 +97,7 @@ class TreeShaking < Step
73
97
  def run
74
98
  loop do
75
99
  removed = shake_methods
76
- #$stdout.puts removed.inspect
100
+ # $stdout.puts removed.inspect
77
101
  reload
78
102
  break if removed.length == 0
79
103
  end
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  class Optimizer
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.5"
4
4
  end
5
5
  end
@@ -14,22 +14,28 @@ module Opal
14
14
 
15
15
  attr_accessor :exports
16
16
 
17
- def initialize(code, exports: "")
17
+ def initialize(code, exports: "", force_corelib: true)
18
18
  @ast = parse_js(code)
19
19
 
20
20
  @corelib = @ast.value.find do |i|
21
- es = i.to_ecma
22
- if es.start_with?("(function(undefined) {\n var global_object") &&
23
- es.end_with?(").call(this);")
21
+ es = code[i.range.from.index..i.range.to.index]
22
+ if es.start_with?("(function(undefined) {\n // @note\n"\
23
+ " // A few conventions for the documentation of this file:") &&
24
+ es.end_with?("TypeError.$$super = Error;\n}).call(this);")
24
25
  @opal_version = 1.0
25
- elsif es.start_with?("(function(global_object) {\n \"use strict\";\n"+
26
- " var console;\n if(typeof (globalThis) !== "+
27
- "'undefined') {\n") &&
28
- es.end_with?(").call(this);")
29
- @opal_version = 1.1
26
+ elsif es.start_with?("(function(global_object) {\n \"use strict\";\n\n // @note\n "\
27
+ "// A few conventions for the documentation of this file:") &&
28
+ es.end_with?("TypeError.$$super = Error;\n}).call(this);")
29
+ if es.include? 'function $prop(object,'
30
+ @opal_version = 1.4
31
+ else
32
+ @opal_version = 1.1
33
+ end
30
34
  end
31
35
  end
32
36
 
37
+ raise ArgumentError, "Couldn't deduce Opal version based on this content" if force_corelib && !@corelib
38
+
33
39
  @corelib_source = @corelib.value.value.value.value.function_body.value if @corelib
34
40
 
35
41
  reload
@@ -38,14 +44,15 @@ module Opal
38
44
  unless [nil, ""].include?(exports) || exports.start_with?("(function(")
39
45
  exports = Opal::Compiler.new(exports).compile
40
46
  end
41
- @exports = Opal::Optimizer.new(exports, exports: nil) unless exports == nil
47
+ @exports = Opal::Optimizer.new(exports, exports: nil, force_corelib: false) unless exports == nil
42
48
  end
43
49
 
44
50
  def reload
45
51
  @function_calls = ast.pointcut(FunctionCallNode).matches
46
52
  @corelib_calls = @function_calls.select do |i|
47
- i.value_path?(DotAccessorNode, ResolveNode, "Opal")
48
- end.group_by { |i| i.value.accessor }
53
+ i.value_path?(DotAccessorNode, ResolveNode, "Opal") ||
54
+ i.value_path?(ResolveNode, /\A\$/)
55
+ end.group_by { |i| (i.value.value.is_a?(String) ? i.value.value : i.value.accessor).gsub('$', '') }
49
56
  @corelib_calls = Hash.new { [] }.merge(@corelib_calls)
50
57
  end
51
58
 
@@ -25,6 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ["lib"]
27
27
 
28
- spec.add_dependency "rkelly-remix"
28
+ spec.add_dependency "rkelly-turbo"
29
29
  spec.add_dependency "opal", ">= 1.0.0"
30
30
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-optimizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - hmdne
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-20 00:00:00.000000000 Z
11
+ date: 2021-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rkelly-remix
14
+ name: rkelly-turbo
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -38,23 +38,26 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.0.0
41
- description:
41
+ description:
42
42
  email: []
43
- executables: []
43
+ executables:
44
+ - opal-optimizer
44
45
  extensions: []
45
46
  extra_rdoc_files: []
46
47
  files:
48
+ - ".github/workflows/build.yml"
47
49
  - ".gitignore"
48
50
  - ".rspec"
49
51
  - ".travis.yml"
52
+ - CHANGELOG.md
50
53
  - Gemfile
51
- - Gemfile.lock
52
54
  - LICENSE.txt
53
55
  - README.md
54
56
  - Rakefile
55
57
  - bin/console
56
58
  - bin/opal-optimizer
57
59
  - bin/setup
60
+ - exe/opal-optimizer
58
61
  - lib/opal/optimizer.rb
59
62
  - lib/opal/optimizer/helpers.rb
60
63
  - lib/opal/optimizer/sprockets.rb
@@ -70,7 +73,7 @@ metadata:
70
73
  homepage_uri: https://github.com/hmdne/opal-optimizer
71
74
  source_code_uri: https://github.com/hmdne/opal-optimizer
72
75
  changelog_uri: https://github.com/hmdne/opal-optimizer/commits/master
73
- post_install_message:
76
+ post_install_message:
74
77
  rdoc_options: []
75
78
  require_paths:
76
79
  - lib
@@ -85,8 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
88
  - !ruby/object:Gem::Version
86
89
  version: '0'
87
90
  requirements: []
88
- rubygems_version: 3.1.4
89
- signing_key:
91
+ rubygems_version: 3.2.22
92
+ signing_key:
90
93
  specification_version: 4
91
94
  summary: Optimize Opal's resulting javascript code
92
95
  test_files: []
data/Gemfile.lock DELETED
@@ -1,79 +0,0 @@
1
- PATH
2
- remote: ../opal-browser
3
- specs:
4
- opal-browser (0.2.0)
5
- opal (>= 1.0, < 2.0)
6
- paggio
7
-
8
- PATH
9
- remote: ../opal-sprockets
10
- specs:
11
- opal-sprockets (0.5.0.1.0.4.0)
12
- opal (~> 1.0.0)
13
- sprockets (~> 4.0)
14
- tilt (>= 1.4)
15
-
16
- PATH
17
- remote: ../opal
18
- specs:
19
- opal (1.0.0)
20
- ast (>= 2.3.0)
21
- parser (~> 2.6)
22
-
23
- PATH
24
- remote: .
25
- specs:
26
- opal-optimizer (0.1.0)
27
- opal (>= 1.0.0)
28
- rkelly-remix
29
-
30
- GEM
31
- remote: https://rubygems.org/
32
- specs:
33
- ast (2.4.1)
34
- coderay (1.1.3)
35
- concurrent-ruby (1.1.7)
36
- diff-lcs (1.4.4)
37
- method_source (1.0.0)
38
- paggio (0.2.6)
39
- parser (2.7.1.4)
40
- ast (~> 2.4.1)
41
- pry (0.13.1)
42
- coderay (~> 1.1)
43
- method_source (~> 1.0)
44
- rack (2.2.3)
45
- rake (12.3.3)
46
- rkelly-remix (0.0.7)
47
- rspec (3.9.0)
48
- rspec-core (~> 3.9.0)
49
- rspec-expectations (~> 3.9.0)
50
- rspec-mocks (~> 3.9.0)
51
- rspec-core (3.9.2)
52
- rspec-support (~> 3.9.3)
53
- rspec-expectations (3.9.2)
54
- diff-lcs (>= 1.2.0, < 2.0)
55
- rspec-support (~> 3.9.0)
56
- rspec-mocks (3.9.1)
57
- diff-lcs (>= 1.2.0, < 2.0)
58
- rspec-support (~> 3.9.0)
59
- rspec-support (3.9.3)
60
- sprockets (4.0.2)
61
- concurrent-ruby (~> 1.0)
62
- rack (> 1, < 3)
63
- tilt (2.0.10)
64
-
65
- PLATFORMS
66
- ruby
67
-
68
- DEPENDENCIES
69
- opal!
70
- opal-browser!
71
- opal-optimizer!
72
- opal-sprockets!
73
- pry
74
- rake (~> 12.0)
75
- rkelly-remix
76
- rspec (~> 3.0)
77
-
78
- BUNDLED WITH
79
- 2.1.4