im 0.1.4 → 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: 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