im 0.1.4 → 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: 99d5cc6d355489148cd6f39fee0e50ce1a25d0e770e4f06c4918fdd41b05935b
4
- data.tar.gz: ec2372445636beac68c84c0249b68e7e454dda3b0c49293bea4e8f14bfa52053
3
+ metadata.gz: 707475c4bc1ad6a6bf6207ca9f892a92b72a911f2fcb3cf0561e203041ede864
4
+ data.tar.gz: c4ad0fc4bb0f0da2dc2b31d64ba904db9f8c3f3e87fb97def63dbbdc91cd3cf8
5
5
  SHA512:
6
- metadata.gz: f9099a8d43b9772952916c21bd84da42da3eeac2541c0b4fe675fd7c373988d00a9522fc7dc2ce662ea7d0f3231ec4aec11941ab8f079350529d6476e535a19f
7
- data.tar.gz: 764b1d2454d0158deba3cd4244453aab0d194036b0fe4104c0cb40bced64d5a0bdb6099db3f5c0b9d98cf75c1417707949f353524b8061c5db18ef96ea0aad2d
6
+ metadata.gz: 4bd14ecfb9804594795da0db412840cc5cb8a11500a335f66dbb88424575e04bfb6b4ead19480edcdf3f68fa957be0665a3c3a317c6c832a043fb645044bfa16
7
+ data.tar.gz: '0048891c47b3f9bd6785141c71412c10f2ce63d746dbed8ac4e515b968e26dfe26a524ddbf8e9629eb2aa4b8fe11ef9c26ced56fa0ba6fa7d401185036e99aa8'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.5] - 2022-09-22
4
+ - Rename Im::Dependency -> Im::Require
5
+ - Handle dynamic requires (require called from method body after file has been imported)
6
+ - Refactor: move require/autoload patch logic to Im handler methods
7
+
8
+
3
9
  ## [0.1.4] - 2022-09-19
4
10
  - Correctly assign constants imported via recursive requires
5
11
 
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gemspec
7
7
 
8
8
  gem "rspec", "~> 3.0"
9
9
  gem "rails"
10
+ gem "sqlite3"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- im (0.1.3)
4
+ im (0.1.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -155,6 +155,8 @@ GEM
155
155
  diff-lcs (>= 1.2.0, < 2.0)
156
156
  rspec-support (~> 3.11.0)
157
157
  rspec-support (3.11.0)
158
+ sqlite3 (1.5.0)
159
+ mini_portile2 (~> 2.8.0)
158
160
  strscan (3.0.4)
159
161
  thor (1.2.1)
160
162
  timeout (0.3.0)
@@ -174,6 +176,7 @@ DEPENDENCIES
174
176
  rake (~> 13.0)
175
177
  rake-compiler
176
178
  rspec (~> 3.0)
179
+ sqlite3
177
180
 
178
181
  BUNDLED WITH
179
182
  2.4.0.dev
data/lib/im/kernel.rb CHANGED
@@ -4,42 +4,16 @@ module Kernel
4
4
  alias_method :im_original_require, :require
5
5
 
6
6
  def require(path)
7
- if Im.autoloads.key?(path)
8
- return Im.with_import(Im.autoloads.delete(path)) do |_context|
9
- !!Im.import(path)
10
- end
7
+ Im.handle_require(path, caller_locations(1, 1).first.path) do
8
+ im_original_require(path)
11
9
  end
10
+ end
12
11
 
13
- if Im.importing? && (resolved = $LOAD_PATH.resolve_feature_path(path))
14
- resolved_path = resolved[1]
15
- Im.registry[resolved_path] ||= Im::Dependency.new(resolved_path, Im.current_import)
16
- end
17
-
18
- loaded = im_original_require(path)
19
- return loaded unless Im.importing?
20
-
21
- if resolved
22
- dependency = Im.registry[resolved_path]
23
-
24
- if loaded && Im.registry.key?(location = caller_locations(1, 1).first.path)
25
- Im.registry[location].dependencies << dependency
26
- end
27
-
28
- dependency.dependencies.each { |d| require d.path }
29
-
30
- dependency.modules.each do |m|
31
- name = m.name
32
-
33
- # Do not assign constants that are aliased to root namespace
34
- root = name.split("::", 2)[0]
35
- next if Object.const_defined?(root) &&
36
- Im.current_import.const_defined?(root, false) &&
37
- Object.const_get(root) == Im.current_import.const_get(root)
12
+ alias_method :im_original_autoload, :autoload
38
13
 
39
- Im.current_import.const_set(name, m) unless Im.current_import.const_defined?(name, false)
40
- end
14
+ def autoload(name, path)
15
+ Im.handle_autoload(path) do
16
+ im_original_autoload(name, path)
41
17
  end
42
-
43
- return loaded
44
18
  end
45
19
  end
data/lib/im/module.rb CHANGED
@@ -2,7 +2,8 @@ class Module
2
2
  alias_method :im_original_autoload, :autoload
3
3
 
4
4
  def autoload(name, path)
5
- Im.autoloads[path] = Im.current_import if Im.importing?
6
- im_original_autoload(name, path)
5
+ Im.handle_autoload(path) do
6
+ im_original_autoload(name, path)
7
+ end
7
8
  end
8
9
  end
data/lib/im/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Im
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
data/lib/im.rb CHANGED
@@ -2,15 +2,20 @@
2
2
 
3
3
  module Im
4
4
  load $LOAD_PATH.resolve_feature_path("im/ruby_version_check")[1], true
5
+
6
+ @constants = Object.constants.reject { |c| Kernel.autoload?(c) }.dup
7
+ @autoloads = {}
8
+ @registry = {}
9
+
5
10
  require "im/version"
6
11
  require "im/kernel"
7
12
 
8
13
  class << self
9
- attr_reader :current_import
14
+ attr_reader :current_import, :registry, :autoloads, :constants
10
15
 
11
16
  def with_import(import)
12
17
  original_import = current_import
13
- @current_import = import
18
+ @current_import = import || Im.current_import
14
19
 
15
20
  unless tracer_originally_enabled = @tracer.enabled?
16
21
  @tracer.enable
@@ -23,16 +28,67 @@ module Im
23
28
  @tracer.disable unless tracer_originally_enabled
24
29
  end
25
30
 
26
- def registry
27
- @registry ||= {}
31
+ def importing?
32
+ !!Im.current_import
28
33
  end
29
34
 
30
- def autoloads
31
- @autoloads ||= {}
35
+ def handle_require(path, caller_path)
36
+ resolved_path = resolve_path(path)
37
+
38
+ return yield unless resolved_path
39
+
40
+ if autoloaded = autoloads.delete(resolved_path)
41
+ return with_import(autoloaded) do |_import|
42
+ !!import(path)
43
+ end
44
+ end
45
+
46
+ if importing?
47
+ registry[resolved_path] ||= Require.new(resolved_path, current_import)
48
+ elsif registry.key?(caller_path)
49
+ return with_import(registry[caller_path].import) do |_import|
50
+ !!import(resolved_path)
51
+ end
52
+ end
53
+
54
+ loaded = yield # super
55
+
56
+ if required = registry[resolved_path]
57
+ if loaded && registry.key?(caller_path)
58
+ registry[caller_path].requires << required
59
+ end
60
+
61
+ required.requires.each { |r| require r.path }
62
+ import = current_import || Object
63
+
64
+ required.modules.each do |m|
65
+ name = m.name
66
+
67
+ # Do not assign constants that are aliased to root namespace
68
+ root = name.split("::", 2)[0]
69
+ next if Object.const_defined?(root) &&
70
+ import.const_defined?(root, false) &&
71
+ Object.const_get(root) == import.const_get(root)
72
+
73
+ begin
74
+ import.const_set(name, m) unless import.const_defined?(name, false)
75
+ rescue NameError
76
+ end
77
+ end
78
+ end
79
+
80
+ loaded
32
81
  end
33
82
 
34
- def importing?
35
- !!Im.current_import
83
+ def handle_autoload(path)
84
+ if resolved_path = resolve_path(path)
85
+ Im.autoloads[resolved_path] = Im.current_import
86
+ end
87
+ yield
88
+ end
89
+
90
+ def resolve_path(path)
91
+ (resolved = $LOAD_PATH.resolve_feature_path(path)) && resolved[1]
36
92
  end
37
93
  end
38
94
 
@@ -40,8 +96,10 @@ module Im
40
96
  def initialize(root)
41
97
  @root = root
42
98
  super()
43
- Im::CONSTANTS.each do |const|
44
- self.const_set(const, Object.const_get(const))
99
+ Im.with_import(self) do
100
+ Im.constants.each do |const|
101
+ self.const_set(const, Object.const_get(const))
102
+ end
45
103
  end
46
104
  end
47
105
 
@@ -50,9 +108,9 @@ module Im
50
108
  end
51
109
  end
52
110
 
53
- Dependency = Struct.new(:path, :import, :modules, :dependencies) do
54
- def initialize(path, import, modules = [], dependencies = [])
55
- super(path, import, modules, dependencies)
111
+ Require = Struct.new(:path, :import, :modules, :requires) do
112
+ def initialize(path, import, modules = [], requires = [])
113
+ super(path, import, modules, requires)
56
114
  end
57
115
  end
58
116
 
@@ -71,7 +129,7 @@ module Im
71
129
  $LOADED_FEATURES << resolved_path
72
130
 
73
131
  import = Im.current_import || Import.new(path)
74
- (Im.registry[resolved_path] ||= Dependency.new(resolved_path, import)).tap do
132
+ (Im.registry[resolved_path] ||= Require.new(resolved_path, import)).tap do
75
133
  Im.with_import(import) do
76
134
  load resolved_path, import
77
135
  end
@@ -102,21 +160,19 @@ module Im
102
160
 
103
161
  @tracer = TracePoint.new(:class) do |event|
104
162
  next unless (name = event.self.name)
105
- next if Im::CONSTANTS.include?(name.to_sym)
163
+ next if Im.constants.include?(name.to_sym)
106
164
 
107
165
  if resolved = $LOAD_PATH.resolve_feature_path(event.path)
108
166
  resolved_path = resolved[1]
109
167
  if Im.registry.key?(resolved_path)
110
168
  (Im.registry[resolved_path].modules << event.self).uniq!
111
169
  else
112
- Im.registry[resolved_path] = Dependency.new(resolved_path, Im.current_import, [event.self])
170
+ Im.registry[resolved_path] = Require.new(resolved_path, Im.current_import, [event.self])
113
171
  end
114
172
  end
115
173
  end
116
174
 
117
175
  require "im/module"
118
- require "im/autoload"
119
- require "im/constants"
120
176
 
121
177
  extend self
122
178
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: im
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Salzberg
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-09-19 00:00:00.000000000 Z
11
+ date: 2022-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -66,8 +66,6 @@ files:
66
66
  - README.md
67
67
  - Rakefile
68
68
  - lib/im.rb
69
- - lib/im/autoload.rb
70
- - lib/im/constants.rb
71
69
  - lib/im/kernel.rb
72
70
  - lib/im/module.rb
73
71
  - lib/im/ruby_version_check.rb
data/lib/im/autoload.rb DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Im
4
- module Autoload
5
- def autoload(name, path)
6
- Im.autoloads[path] = Im.current_import if Im.importing?
7
- super(name, path)
8
- end
9
- end
10
- end
data/lib/im/constants.rb DELETED
@@ -1,104 +0,0 @@
1
- module Im
2
- # It's faster to just hard-code constants than to introspect them at runtime
3
- CONSTANTS = [
4
- :ArgumentError,
5
- :Array,
6
- :BasicObject,
7
- :Binding,
8
- :Class,
9
- :ClosedQueueError,
10
- :Comparable,
11
- :Complex,
12
- :ConditionVariable,
13
- :DidYouMean,
14
- :Dir,
15
- :Encoding,
16
- :EncodingError,
17
- :Enumerable,
18
- :Enumerator,
19
- :EOFError,
20
- :Errno,
21
- :ErrorHighlight,
22
- :Exception,
23
- :FalseClass,
24
- :Fiber,
25
- :FiberError,
26
- :File,
27
- :FileTest,
28
- :Float,
29
- :FloatDomainError,
30
- :FrozenError,
31
- :GC,
32
- :Gem,
33
- :Hash,
34
- :IndexError,
35
- :Integer,
36
- :Interrupt,
37
- :IO,
38
- :IOError,
39
- :Kernel,
40
- :KeyError,
41
- :LoadError,
42
- :LocalJumpError,
43
- :Marshal,
44
- :MatchData,
45
- :Math,
46
- :Method,
47
- :Module,
48
- :Monitor,
49
- :MonitorMixin,
50
- :Mutex,
51
- :NameError,
52
- :NilClass,
53
- :NoMatchingPatternError,
54
- :NoMatchingPatternKeyError,
55
- :NoMemoryError,
56
- :NoMethodError,
57
- :NotImplementedError,
58
- :Numeric,
59
- :Object,
60
- :ObjectSpace,
61
- :Proc,
62
- :Process,
63
- :Queue,
64
- :Ractor,
65
- :Random,
66
- :Range,
67
- :RangeError,
68
- :Rational,
69
- :RbConfig,
70
- :Refinement,
71
- :Regexp,
72
- :RegexpError,
73
- :RubyVM,
74
- :RuntimeError,
75
- :ScriptError,
76
- :SecurityError,
77
- :Set,
78
- :Signal,
79
- :SignalException,
80
- :SizedQueue,
81
- :StandardError,
82
- :StopIteration,
83
- :String,
84
- :Struct,
85
- :Symbol,
86
- :SyntaxError,
87
- :SystemCallError,
88
- :SystemExit,
89
- :SystemStackError,
90
- :Thread,
91
- :ThreadError,
92
- :ThreadGroup,
93
- :Time,
94
- :TracePoint,
95
- :TrueClass,
96
- :TypeError,
97
- :UnboundMethod,
98
- :UncaughtThrowError,
99
- :UnicodeNormalize,
100
- :URI,
101
- :Warning,
102
- :ZeroDivisionError,
103
- ]
104
- end