@@ -8,28 +8,99 @@ module Types
88
99 singleton_class . attr_reader :rbs_builder , :rbs_load_error
1010
11+ class Loader
12+ attr_reader :load_started , :rbs_load_error
13+
14+ def initialize ( thread : false , &block )
15+ @load_callback = block
16+ @gems = { }
17+ @loaded_features = [ ]
18+ if thread
19+ @queue = Thread ::Queue . new
20+ Thread . new { run }
21+ else
22+ run
23+ end
24+ end
25+
26+ def added_gems
27+ features = $LOADED_FEATURES. dup
28+ loaded_gems = ( features - ( @loaded_features || [ ] ) ) . filter_map do |lf |
29+ next unless %r{(?<gem_path>.*/gems/(?<gem_name>[a-zA-Z0-9_-]+)-(?<version>\d +\. \d [\d \. a-zA-Z_]+)/)} =~ lf
30+ next if @gems [ gem_name ]
31+
32+ [ gem_name , [ gem_path , version ] ]
33+ end . to_h
34+ @gems . merge! ( loaded_gems )
35+ @loaded_featues = features
36+ loaded_gems
37+ end
38+
39+ def reload
40+ @queue &.enq ( :reload )
41+ end
42+
43+ def terminate
44+ @queue &.enq ( :terminate )
45+ end
46+
47+ def update_loader ( loader )
48+ new_gems = added_gems
49+ new_gems . each do |library , ( path , version ) |
50+ loader . add ( library : library , version : version ) if Dir . exist? ( "#{ path } sig" )
51+ end
52+ new_gems . any?
53+ end
54+
55+ def load ( loader )
56+ @load_callback . call ( RBS ::DefinitionBuilder . new env : RBS ::Environment . from_loader ( loader ) . resolve_type_names )
57+ end
58+
59+ def run
60+ require 'rbs'
61+ require 'rbs/cli'
62+ loader = RBS ::CLI ::LibraryOptions . new . loader
63+ loader . add path : Pathname ( 'sig' )
64+ update_loader ( loader )
65+ load ( loader )
66+ return unless @queue
67+
68+ loop do
69+ break if @queue . deq == :terminate
70+ next unless update_loader ( loader )
71+
72+ load ( loader )
73+ end
74+ rescue LoadError , StandardError => e
75+ @rbs_load_error = e
76+ nil
77+ end
78+ end
79+
1180 def self . rbs_load_started?
12- !!@load_started
81+ !!@loader
1382 end
1483
1584 def self . preload_rbs_builder
1685 return if rbs_load_started?
17- @load_started = true
18- Thread . new do
19- load_rbs_builder
86+
87+ @loader ||= Loader . new ( thread : true ) do | builder |
88+ @rbs_builder = builder
2089 end
2190 end
2291
92+ def self . rbs_load_error
93+ @loader &.rbs_load_error
94+ end
95+
2396 def self . load_rbs_builder
24- @load_started = true
25- require 'rbs'
26- require 'rbs/cli'
27- loader = RBS ::CLI ::LibraryOptions . new . loader
28- loader . add path : Pathname ( 'sig' )
29- @rbs_builder = RBS ::DefinitionBuilder . new env : RBS ::Environment . from_loader ( loader ) . resolve_type_names
30- rescue LoadError , StandardError => e
31- @rbs_load_error = e
32- nil
97+ @loader ||= Loader . new do |builder |
98+ @rbs_builder = builder
99+ end
100+ end
101+
102+ def self . reload_rbs_builder
103+ @loader . reload
33104 end
34105
35106 def self . class_name_of ( klass )
0 commit comments