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.
- checksums.yaml +4 -4
- data/MIT-LICENSE +20 -20
- data/README.md +1073 -466
- data/lib/opal/zeitwerk/version.rb +6 -6
- data/lib/opal-zeitwerk.rb +4 -4
- data/opal/zeitwerk/error.rb +10 -10
- data/opal/zeitwerk/explicit_namespace.rb +78 -71
- data/opal/zeitwerk/gem_inflector.rb +15 -0
- data/opal/zeitwerk/inflector.rb +44 -47
- data/opal/zeitwerk/kernel.rb +64 -32
- data/opal/zeitwerk/loader/callbacks.rb +88 -58
- data/opal/zeitwerk/loader/config.rb +301 -0
- data/opal/zeitwerk/loader/helpers.rb +115 -0
- data/opal/zeitwerk/loader.rb +170 -435
- data/opal/zeitwerk/real_mod_name.rb +20 -21
- data/opal/zeitwerk/registry.rb +143 -121
- data/opal/zeitwerk.rb +14 -13
- metadata +16 -7
@@ -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
|
-
# @
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
data/opal/zeitwerk/registry.rb
CHANGED
@@ -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
|
-
# @
|
9
|
-
attr_reader :loaders
|
10
|
-
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
# This
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
|
58
|
-
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# @
|
63
|
-
# @
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
# @private
|
69
|
-
# @
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
# @
|
87
|
-
# @
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
# @
|
111
|
-
|
112
|
-
|
113
|
-
inceptions
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
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/
|
12
|
-
require_relative "zeitwerk/
|
13
|
-
|
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.
|
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:
|
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.
|
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.
|
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.
|
79
|
+
rubygems_version: 3.3.7
|
71
80
|
signing_key:
|
72
81
|
specification_version: 4
|
73
82
|
summary: Opal constant autoloader using Zeitwerk
|