opal-zeitwerk 0.2.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,21 +1,20 @@
1
- module Zeitwerk::RealModName
2
- UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
3
- private_constant :UNBOUND_METHOD_MODULE_NAME
4
-
5
- # Returns the real name of the class or module, as set after the first
6
- # constant to which it was assigned (or nil).
7
- #
8
- # The name method can be overridden, hence the indirection in this method.
9
- #
10
- # @param mod [Class, Module]
11
- # @return [String, nil]
12
- if UnboundMethod.method_defined?(:bind_call)
13
- def real_mod_name(mod)
14
- UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
15
- end
16
- else
17
- def real_mod_name(mod)
18
- UNBOUND_METHOD_MODULE_NAME.bind(mod).call
19
- end
20
- end
21
- end
1
+ module Zeitwerk::RealModName
2
+ UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
3
+ private_constant :UNBOUND_METHOD_MODULE_NAME
4
+
5
+ # Returns the real name of the class or module, as set after the first
6
+ # constant to which it was assigned (or nil).
7
+ #
8
+ # The name method can be overridden, hence the indirection in this method.
9
+ #
10
+ # @sig (Module) -> String?
11
+ if UnboundMethod.method_defined?(:bind_call)
12
+ def real_mod_name(mod)
13
+ UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
14
+ end
15
+ else
16
+ def real_mod_name(mod)
17
+ UNBOUND_METHOD_MODULE_NAME.bind(mod).call
18
+ end
19
+ end
20
+ end
@@ -1,121 +1,143 @@
1
- module Zeitwerk
2
- module Registry # :nodoc: all
3
- class << self
4
- # Keeps track of all loaders. Useful to broadcast messages and to prevent
5
- # them from being garbage collected.
6
- #
7
- # @private
8
- # @return [<Zeitwerk::Loader>]
9
- attr_reader :loaders
10
-
11
- # Maps real paths to the loaders responsible for them.
12
- #
13
- # This information is used by our decorated `Kernel#require` to be able to
14
- # invoke callbacks and autovivify modules.
15
- #
16
- # @private
17
- # @return [{String => Zeitwerk::Loader}]
18
- attr_reader :autoloads
19
-
20
- # This hash table addresses an edge case in which an autoload is ignored.
21
- #
22
- # For example, let's suppose we want to autoload in a gem like this:
23
- #
24
- # # lib/my_gem.rb
25
- # loader = Zeitwerk::Loader.new
26
- # loader.push_dir(__dir__)
27
- # loader.setup
28
- #
29
- # module MyGem
30
- # end
31
- #
32
- # if you require "my_gem", as Bundler would do, this happens while setting
33
- # up autoloads:
34
- #
35
- # 1. Object.autoload?(:MyGem) returns `nil` because the autoload for
36
- # the constant is issued by Zeitwerk while the same file is being
37
- # required.
38
- # 2. The constant `MyGem` is undefined while setup runs.
39
- #
40
- # Therefore, a directory `lib/my_gem` would autovivify a module according to
41
- # the existing information. But that would be wrong.
42
- #
43
- # To overcome this fundamental limitation, we keep track of the constant
44
- # paths that are in this situation ---in the example above, "MyGem"--- and
45
- # take this collection into account for the autovivification logic.
46
- #
47
- # Note that you cannot generally address this by moving the setup code
48
- # below the constant definition, because we want libraries to be able to
49
- # use managed constants in the module body:
50
- #
51
- # module MyGem
52
- # include MyConcern
53
- # end
54
- #
55
- # @private
56
- # @return [{String => (String, Zeitwerk::Loader)}]
57
- attr_reader :inceptions
58
-
59
- # Registers a loader.
60
- #
61
- # @private
62
- # @param loader [Zeitwerk::Loader]
63
- # @return [void]
64
- def register_loader(loader)
65
- loaders << loader
66
- end
67
-
68
- # @private
69
- # @param loader [Zeitwerk::Loader]
70
- # @param realpath [String]
71
- # @return [void]
72
- def register_autoload(loader, realpath)
73
- autoloads[realpath] = loader
74
- end
75
-
76
- # @private
77
- # @param realpath [String]
78
- # @return [void]
79
- def unregister_autoload(realpath)
80
- autoloads.delete(realpath)
81
- end
82
-
83
- # @private
84
- # @param cpath [String]
85
- # @param realpath [String]
86
- # @param loader [Zeitwerk::Loader]
87
- # @return [void]
88
- def register_inception(cpath, realpath, loader)
89
- inceptions[cpath] = [realpath, loader]
90
- end
91
-
92
- # @private
93
- # @param cpath [String]
94
- # @return [String, nil]
95
- def inception?(cpath)
96
- if pair = inceptions[cpath]
97
- pair.first
98
- end
99
- end
100
-
101
- # @private
102
- # @param path [String]
103
- # @return [Zeitwerk::Loader, nil]
104
- def loader_for(path)
105
- autoloads[path]
106
- end
107
-
108
- # @private
109
- # @param loader [Zeitwerk::Loader]
110
- # @return [void]
111
- def on_unload(loader)
112
- autoloads.delete_if { |_path, object| object == loader }
113
- inceptions.delete_if { |_cpath, (_path, object)| object == loader }
114
- end
115
- end
116
-
117
- @loaders = []
118
- @autoloads = {}
119
- @inceptions = {}
120
- end
121
- end
1
+ module Zeitwerk
2
+ module Registry # :nodoc: all
3
+ class << self
4
+ # Keeps track of all loaders. Useful to broadcast messages and to prevent
5
+ # them from being garbage collected.
6
+ #
7
+ # @private
8
+ # @sig Array[Zeitwerk::Loader]
9
+ attr_reader :loaders
10
+
11
+ # Registers loaders created with `for_gem` to make the method idempotent
12
+ # in case of reload.
13
+ #
14
+ # @private
15
+ # @sig Hash[String, Zeitwerk::Loader]
16
+ attr_reader :loaders_managing_gems
17
+
18
+ # Maps absolute paths to the loaders responsible for them.
19
+ #
20
+ # This information is used by our decorated `Kernel#require` to be able to
21
+ # invoke callbacks and autovivify modules.
22
+ #
23
+ # @private
24
+ # @sig Hash[String, Zeitwerk::Loader]
25
+ attr_reader :autoloads
26
+
27
+ # This hash table addresses an edge case in which an autoload is ignored.
28
+ #
29
+ # For example, let's suppose we want to autoload in a gem like this:
30
+ #
31
+ # # lib/my_gem.rb
32
+ # loader = Zeitwerk::Loader.new
33
+ # loader.push_dir(__dir__)
34
+ # loader.setup
35
+ #
36
+ # module MyGem
37
+ # end
38
+ #
39
+ # if you require "my_gem", as Bundler would do, this happens while setting
40
+ # up autoloads:
41
+ #
42
+ # 1. Object.autoload?(:MyGem) returns `nil` because the autoload for
43
+ # the constant is issued by Zeitwerk while the same file is being
44
+ # required.
45
+ # 2. The constant `MyGem` is undefined while setup runs.
46
+ #
47
+ # Therefore, a directory `lib/my_gem` would autovivify a module according to
48
+ # the existing information. But that would be wrong.
49
+ #
50
+ # To overcome this fundamental limitation, we keep track of the constant
51
+ # paths that are in this situation ---in the example above, "MyGem"--- and
52
+ # take this collection into account for the autovivification logic.
53
+ #
54
+ # Note that you cannot generally address this by moving the setup code
55
+ # below the constant definition, because we want libraries to be able to
56
+ # use managed constants in the module body:
57
+ #
58
+ # module MyGem
59
+ # include MyConcern
60
+ # end
61
+ #
62
+ # @private
63
+ # @sig Hash[String, [String, Zeitwerk::Loader]]
64
+ attr_reader :inceptions
65
+
66
+ # Registers a loader.
67
+ #
68
+ # @private
69
+ # @sig (Zeitwerk::Loader) -> void
70
+ def register_loader(loader)
71
+ loaders << loader
72
+ end
73
+
74
+ # @private
75
+ # @sig (Zeitwerk::Loader) -> void
76
+ def unregister_loader(loader)
77
+ loaders.delete(loader)
78
+ loaders_managing_gems.delete_if { |_, l| l == loader }
79
+ autoloads.delete_if { |_, l| l == loader }
80
+ inceptions.delete_if { |_, (_, l)| l == loader }
81
+ end
82
+
83
+ # This method returns always a loader, the same instance for the same root
84
+ # file. That is how Zeitwerk::Loader.for_gem is idempotent.
85
+ #
86
+ # @private
87
+ # @sig (String) -> Zeitwerk::Loader
88
+ def loader_for_gem(root_file)
89
+ loaders_managing_gems[root_file] ||= begin
90
+ Loader.new.tap do |loader|
91
+ loader.tag = File.basename(root_file, ".rb")
92
+ loader.inflector = GemInflector.new(root_file)
93
+ loader.push_dir(File.dirname(root_file))
94
+ end
95
+ end
96
+ end
97
+
98
+ # @private
99
+ # @sig (Zeitwerk::Loader, String) -> String
100
+ def register_autoload(loader, abspath)
101
+ autoloads[abspath] = loader
102
+ end
103
+
104
+ # @private
105
+ # @sig (String) -> void
106
+ def unregister_autoload(abspath)
107
+ autoloads.delete(abspath)
108
+ end
109
+
110
+ # @private
111
+ # @sig (String, String, Zeitwerk::Loader) -> void
112
+ def register_inception(cpath, abspath, loader)
113
+ inceptions[cpath] = [abspath, loader]
114
+ end
115
+
116
+ # @private
117
+ # @sig (String) -> String?
118
+ def inception?(cpath)
119
+ if pair = inceptions[cpath]
120
+ pair.first
121
+ end
122
+ end
123
+
124
+ # @private
125
+ # @sig (String) -> Zeitwerk::Loader?
126
+ def loader_for(path)
127
+ autoloads[path]
128
+ end
129
+
130
+ # @private
131
+ # @sig (Zeitwerk::Loader) -> void
132
+ def on_unload(loader)
133
+ autoloads.delete_if { |_path, object| object == loader }
134
+ inceptions.delete_if { |_cpath, (_path, object)| object == loader }
135
+ end
136
+ end
137
+
138
+ @loaders = []
139
+ @loaders_managing_gems = {}
140
+ @autoloads = {}
141
+ @inceptions = {}
142
+ end
143
+ end
data/opal/zeitwerk.rb CHANGED
@@ -1,13 +1,14 @@
1
- require 'opal'
2
- require 'corelib/trace_point'
3
- require 'securerandom'
4
-
5
- module Zeitwerk
6
- require_relative "zeitwerk/real_mod_name"
7
- require_relative "zeitwerk/loader"
8
- require_relative "zeitwerk/registry"
9
- require_relative "zeitwerk/explicit_namespace"
10
- require_relative "zeitwerk/inflector"
11
- require_relative "zeitwerk/kernel"
12
- require_relative "zeitwerk/error"
13
- end
1
+ require 'opal'
2
+ require 'corelib/trace_point'
3
+ require 'securerandom'
4
+
5
+ module Zeitwerk
6
+ require_relative "zeitwerk/real_mod_name"
7
+ require_relative "zeitwerk/loader"
8
+ require_relative "zeitwerk/registry"
9
+ require_relative "zeitwerk/explicit_namespace"
10
+ require_relative "zeitwerk/inflector"
11
+ require_relative "zeitwerk/gem_inflector"
12
+ require_relative "zeitwerk/kernel"
13
+ require_relative "zeitwerk/error"
14
+ end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal-zeitwerk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Biedermann
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-31 00:00:00.000000000 Z
11
+ date: 2022-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opal
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.3.0
19
+ version: 1.4.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 1.6.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.4.0
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: 1.3.0
32
+ version: 1.6.0
27
33
  description: |2
28
34
  A port of the Zeitwerk autoloader to Opal.
29
35
  Zeitwerk implements constant autoloading with Ruby semantics. Each gem
@@ -41,10 +47,13 @@ files:
41
47
  - opal/zeitwerk.rb
42
48
  - opal/zeitwerk/error.rb
43
49
  - opal/zeitwerk/explicit_namespace.rb
50
+ - opal/zeitwerk/gem_inflector.rb
44
51
  - opal/zeitwerk/inflector.rb
45
52
  - opal/zeitwerk/kernel.rb
46
53
  - opal/zeitwerk/loader.rb
47
54
  - opal/zeitwerk/loader/callbacks.rb
55
+ - opal/zeitwerk/loader/config.rb
56
+ - opal/zeitwerk/loader/helpers.rb
48
57
  - opal/zeitwerk/real_mod_name.rb
49
58
  - opal/zeitwerk/registry.rb
50
59
  homepage: https://github.com/isomorfeus/opal-zeitwerk
@@ -67,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
76
  - !ruby/object:Gem::Version
68
77
  version: '0'
69
78
  requirements: []
70
- rubygems_version: 3.2.15
79
+ rubygems_version: 3.3.7
71
80
  signing_key:
72
81
  specification_version: 4
73
82
  summary: Opal constant autoloader using Zeitwerk