opal-optimizer 0.1.1 → 0.1.5

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