typeprof 0.10.0 → 0.14.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +1 -1
- data/Gemfile.lock +10 -10
- data/doc/demo.md +2 -2
- data/doc/todo.md +133 -0
- data/lib/typeprof/analyzer.rb +120 -46
- data/lib/typeprof/block.rb +7 -6
- data/lib/typeprof/builtin.rb +49 -7
- data/lib/typeprof/cli.rb +5 -0
- data/lib/typeprof/config.rb +18 -14
- data/lib/typeprof/container-type.rb +24 -0
- data/lib/typeprof/export.rb +30 -15
- data/lib/typeprof/import.rb +37 -11
- data/lib/typeprof/iseq.rb +100 -41
- data/lib/typeprof/type.rb +34 -0
- data/lib/typeprof/version.rb +1 -1
- data/smoke/break4.rb +17 -0
- data/smoke/class_eval.rb +22 -0
- data/smoke/define_method7.rb +18 -0
- data/smoke/extended.rb +38 -0
- data/smoke/flow11.rb +17 -0
- data/smoke/included.rb +38 -0
- data/smoke/inherited.rb +26 -0
- data/smoke/instance_eval.rb +1 -1
- data/smoke/instance_eval4.rb +12 -0
- data/smoke/struct-keyword_init.rb +1 -1
- data/smoke/struct.rb +1 -1
- data/smoke/struct2.rb +1 -1
- data/smoke/struct3.rb +1 -1
- data/smoke/struct4.rb +1 -1
- data/smoke/struct5.rb +1 -1
- data/smoke/struct6.rb +1 -1
- data/smoke/struct7.rb +1 -1
- data/testbed/goodcheck-Gemfile.lock +1 -1
- data/typeprof.gemspec +1 -1
- metadata +14 -5
data/lib/typeprof/block.rb
CHANGED
@@ -27,7 +27,7 @@ module TypeProf
|
|
27
27
|
self
|
28
28
|
end
|
29
29
|
|
30
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
|
30
|
+
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
31
31
|
blk_env = scratch.return_envs[@outer_ep]
|
32
32
|
if replace_recv_ty
|
33
33
|
replace_recv_ty = scratch.globalize_type(replace_recv_ty, caller_env, caller_ep)
|
@@ -46,7 +46,8 @@ module TypeProf
|
|
46
46
|
return
|
47
47
|
end
|
48
48
|
|
49
|
-
|
49
|
+
cref = replace_cref || @outer_ep.ctx.cref
|
50
|
+
nctx = Context.new(@iseq, cref, nil)
|
50
51
|
callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
|
51
52
|
nenv = Env.new(blk_env.static_env, locals, [], nil)
|
52
53
|
alloc_site = AllocationSite.new(callee_ep)
|
@@ -87,7 +88,7 @@ module TypeProf
|
|
87
88
|
TypedBlock.new(msig, ret_ty)
|
88
89
|
end
|
89
90
|
|
90
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
|
91
|
+
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
91
92
|
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
92
93
|
subst = aargs.consistent_with_method_signature?(@msig)
|
93
94
|
unless subst
|
@@ -119,7 +120,7 @@ module TypeProf
|
|
119
120
|
self
|
120
121
|
end
|
121
122
|
|
122
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
|
123
|
+
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
123
124
|
if aargs.lead_tys.size >= 1
|
124
125
|
recv = aargs.lead_tys[0]
|
125
126
|
recv = Type.any if recv == Type.bot
|
@@ -157,7 +158,7 @@ module TypeProf
|
|
157
158
|
self
|
158
159
|
end
|
159
160
|
|
160
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
|
161
|
+
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
161
162
|
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
162
163
|
|
163
164
|
dummy_ctx = TypedContext.new(@caller_ep, @mid)
|
@@ -165,7 +166,7 @@ module TypeProf
|
|
165
166
|
scratch.add_block_signature!(self, aargs.to_block_signature)
|
166
167
|
scratch.add_block_to_ctx!(self, dummy_ctx)
|
167
168
|
|
168
|
-
@blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty) do |ret_ty, ep, env|
|
169
|
+
@blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty, replace_cref: replace_cref) do |ret_ty, ep, env|
|
169
170
|
scratch.add_return_value!(dummy_ctx, ret_ty)
|
170
171
|
ctn[ret_ty, ep, env]
|
171
172
|
end
|
data/lib/typeprof/builtin.rb
CHANGED
@@ -158,7 +158,43 @@ module TypeProf
|
|
158
158
|
naargs = ActualArguments.new([recv], nil, {}, Type.nil)
|
159
159
|
nrecv = recv
|
160
160
|
nrecv = nrecv.base_type if nrecv.is_a?(Type::ContainerType)
|
161
|
-
scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv) do |
|
161
|
+
scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv) do |ret_ty, ep|
|
162
|
+
ctn[ret_ty, ep, env]
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def module_eqq(recv, mid, aargs, ep, env, scratch, &ctn)
|
167
|
+
if aargs.lead_tys.size == 1
|
168
|
+
aargs.lead_tys[0].each_child do |aarg|
|
169
|
+
aarg = aarg.base_type if aarg.is_a?(Type::Symbol) # XXX
|
170
|
+
if aarg.is_a?(Type::Instance)
|
171
|
+
if aarg.klass == recv # XXX: inheritance
|
172
|
+
true_val = Type::Instance.new(Type::Builtin[:true])
|
173
|
+
ctn[true_val, ep, env]
|
174
|
+
else
|
175
|
+
false_val = Type::Instance.new(Type::Builtin[:false])
|
176
|
+
ctn[false_val, ep, env]
|
177
|
+
end
|
178
|
+
else
|
179
|
+
ctn[Type.bool, ep, env]
|
180
|
+
end
|
181
|
+
end
|
182
|
+
else
|
183
|
+
ctn[Type.bool, ep, env]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def object_module_eval(recv, mid, aargs, ep, env, scratch, &ctn)
|
188
|
+
if aargs.lead_tys.size >= 1
|
189
|
+
scratch.warn(ep, "class_eval with arguments is ignored")
|
190
|
+
ctn[Type.any, ep, env]
|
191
|
+
return
|
192
|
+
end
|
193
|
+
naargs = ActualArguments.new([recv], nil, {}, Type.nil)
|
194
|
+
nrecv = recv
|
195
|
+
nrecv = nrecv.base_type if nrecv.is_a?(Type::ContainerType)
|
196
|
+
ncref = ep.ctx.cref.extend(nrecv, true)
|
197
|
+
scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv, replace_cref: ncref) do |_ret_ty, ep|
|
162
198
|
ctn[recv, ep, env]
|
163
199
|
end
|
164
200
|
end
|
@@ -176,7 +212,7 @@ module TypeProf
|
|
176
212
|
end
|
177
213
|
|
178
214
|
elem_ty = Type.bot
|
179
|
-
enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &blk_ctn|
|
215
|
+
enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &blk_ctn|
|
180
216
|
if aargs.lead_tys.size >= 1
|
181
217
|
elem_ty = elem_ty.union(aargs.lead_tys[0])
|
182
218
|
else
|
@@ -235,9 +271,12 @@ module TypeProf
|
|
235
271
|
return ctn[Type.any, ep, env]
|
236
272
|
end
|
237
273
|
|
274
|
+
# support multiple arguments: include M1, M2
|
238
275
|
arg = aargs.lead_tys[0]
|
239
276
|
arg.each_child do |arg|
|
240
277
|
if arg.is_a?(Type::Class)
|
278
|
+
aargs = ActualArguments.new([recv], nil, {}, Type.nil)
|
279
|
+
scratch.do_send(arg, :included, aargs, ep, env) {|_ret_ty, _ep| }
|
241
280
|
scratch.mix_module(:after, recv, arg, nil, ep.ctx.cref.singleton, ep)
|
242
281
|
end
|
243
282
|
end
|
@@ -259,6 +298,8 @@ module TypeProf
|
|
259
298
|
arg = aargs.lead_tys[0]
|
260
299
|
arg.each_child do |arg|
|
261
300
|
if arg.is_a?(Type::Class)
|
301
|
+
aargs = ActualArguments.new([recv], nil, {}, Type.nil)
|
302
|
+
scratch.do_send(arg, :extended, aargs, ep, env) {|_ret_ty, _ep| }
|
262
303
|
# if ep.ctx.cref.singleton is true, the meta-meta level is ignored. Should we warn?
|
263
304
|
scratch.mix_module(:after, recv, arg, nil, true, ep)
|
264
305
|
end
|
@@ -557,8 +598,6 @@ module TypeProf
|
|
557
598
|
end
|
558
599
|
|
559
600
|
def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
|
560
|
-
# TODO: keyword_init
|
561
|
-
|
562
601
|
keyword_init = false
|
563
602
|
if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
|
564
603
|
if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
|
@@ -806,9 +845,12 @@ module TypeProf
|
|
806
845
|
scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public), false)
|
807
846
|
scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private), false)
|
808
847
|
scratch.set_custom_method(klass_module, :define_method, Builtin.method(:module_define_method))
|
809
|
-
scratch.set_custom_method(klass_module, :
|
810
|
-
scratch.set_custom_method(klass_module, :
|
811
|
-
scratch.set_custom_method(klass_module, :
|
848
|
+
scratch.set_custom_method(klass_module, :attr_accessor, Builtin.method(:module_attr_accessor))
|
849
|
+
scratch.set_custom_method(klass_module, :attr_reader, Builtin.method(:module_attr_reader))
|
850
|
+
scratch.set_custom_method(klass_module, :attr_writer, Builtin.method(:module_attr_writer))
|
851
|
+
scratch.set_custom_method(klass_module, :class_eval, Builtin.method(:object_module_eval))
|
852
|
+
scratch.set_custom_method(klass_module, :module_eval, Builtin.method(:object_module_eval))
|
853
|
+
scratch.set_custom_method(klass_module, :===, Builtin.method(:module_eqq))
|
812
854
|
|
813
855
|
scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
|
814
856
|
scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
|
data/lib/typeprof/cli.rb
CHANGED
@@ -20,6 +20,7 @@ module TypeProf
|
|
20
20
|
options = {}
|
21
21
|
dir_filter = nil
|
22
22
|
gem_rbs_features = []
|
23
|
+
gem_repo_dirs = []
|
23
24
|
show_version = false
|
24
25
|
max_sec = max_iter = nil
|
25
26
|
|
@@ -31,6 +32,7 @@ module TypeProf
|
|
31
32
|
opt.on("--version", "Display typeprof version") { show_version = true }
|
32
33
|
opt.on("-I DIR", "Add DIR to the load/require path") {|v| $LOAD_PATH << v }
|
33
34
|
opt.on("-r FEATURE", "Require RBS of the FEATURE gem") {|v| gem_rbs_features << v }
|
35
|
+
opt.on("--repo DIR", "Add DIR to the RBS repository") {|v| gem_repo_dirs << v }
|
34
36
|
|
35
37
|
opt.separator ""
|
36
38
|
opt.separator "Analysis output options:"
|
@@ -46,6 +48,8 @@ module TypeProf
|
|
46
48
|
dir_filter ||= ConfigData::DEFAULT_DIR_FILTER
|
47
49
|
dir_filter << [:exclude, File.expand_path(dir)]
|
48
50
|
end
|
51
|
+
opt.on("--exclude-untyped", "Exclude (comment out) all entries including untyped") {|v| options[:exclude_untyped] = v }
|
52
|
+
opt.on("--[no-]show-typeprof-version", "Display TypeProf version in a header") {|v| options[:show_typeprof_version] = v }
|
49
53
|
opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| options[:show_errors] = v }
|
50
54
|
opt.on("--[no-]show-untyped", "Display \"Foo | untyped\" instead of \"Foo\"") {|v| options[:show_untyped] = v }
|
51
55
|
opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| options[:show_parameter_names] = v }
|
@@ -87,6 +91,7 @@ module TypeProf
|
|
87
91
|
rbs_files: rbs_files,
|
88
92
|
output: output,
|
89
93
|
gem_rbs_features: gem_rbs_features,
|
94
|
+
gem_repo_dirs: gem_repo_dirs,
|
90
95
|
verbose: verbose,
|
91
96
|
dir_filter: dir_filter,
|
92
97
|
max_sec: max_sec,
|
data/lib/typeprof/config.rb
CHANGED
@@ -6,6 +6,7 @@ module TypeProf
|
|
6
6
|
:rbs_files,
|
7
7
|
:output,
|
8
8
|
:gem_rbs_features,
|
9
|
+
:gem_repo_dirs,
|
9
10
|
:verbose,
|
10
11
|
:dir_filter,
|
11
12
|
:max_iter,
|
@@ -25,10 +26,13 @@ module TypeProf
|
|
25
26
|
def initialize(**opt)
|
26
27
|
opt[:output] ||= $stdout
|
27
28
|
opt[:gem_rbs_features] ||= []
|
29
|
+
opt[:gem_repo_dirs] ||= []
|
28
30
|
opt[:dir_filter] ||= DEFAULT_DIR_FILTER
|
29
31
|
opt[:verbose] ||= 0
|
30
32
|
opt[:options] ||= {}
|
31
33
|
opt[:options] = {
|
34
|
+
exclude_untyped: false,
|
35
|
+
show_typeprof_version: true,
|
32
36
|
show_indicator: true,
|
33
37
|
show_untyped: false,
|
34
38
|
show_errors: false,
|
@@ -76,9 +80,19 @@ module TypeProf
|
|
76
80
|
Import.import_library(scratch, feature)
|
77
81
|
end
|
78
82
|
|
79
|
-
|
80
|
-
|
81
|
-
|
83
|
+
rbs_files = []
|
84
|
+
rbs_codes = []
|
85
|
+
Config.rbs_files.each do |rbs|
|
86
|
+
if rbs.is_a?(Array) # [String name, String content]
|
87
|
+
rbs_codes << rbs
|
88
|
+
else
|
89
|
+
rbs_files << rbs
|
90
|
+
end
|
91
|
+
end
|
92
|
+
Import.import_rbs_files(scratch, rbs_files)
|
93
|
+
rbs_codes.each do |name, content|
|
94
|
+
Import.import_rbs_code(scratch, name, content)
|
95
|
+
end
|
82
96
|
|
83
97
|
Config.rb_files.each do |rb|
|
84
98
|
if rb.is_a?(Array) # [String name, String content]
|
@@ -86,17 +100,7 @@ module TypeProf
|
|
86
100
|
else
|
87
101
|
iseq = ISeq.compile(rb)
|
88
102
|
end
|
89
|
-
|
90
|
-
scratch.merge_env(ep, env)
|
91
|
-
scratch.add_callsite!(ep.ctx, prologue_ep, prologue_env) {|ty, ep| }
|
92
|
-
end
|
93
|
-
|
94
|
-
Config.rbs_files.each do |rbs|
|
95
|
-
if rbs.is_a?(Array) # [String name, String content]
|
96
|
-
Import.import_rbs_code(scratch, *rbs)
|
97
|
-
else
|
98
|
-
Import.import_rbs_file(scratch, rbs)
|
99
|
-
end
|
103
|
+
scratch.add_entrypoint(iseq)
|
100
104
|
end
|
101
105
|
|
102
106
|
result = scratch.type_profile
|
@@ -45,6 +45,12 @@ module TypeProf
|
|
45
45
|
Type::Cell.new(Type::Cell::Elements.new([Type.bot] * klass.type_params.size), base_type)
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
def include_untyped?(scratch)
|
50
|
+
return true if @base_type.include_untyped?(scratch)
|
51
|
+
return true if @elems.include_untyped?(scratch)
|
52
|
+
false
|
53
|
+
end
|
48
54
|
end
|
49
55
|
|
50
56
|
# The most basic container type for default type parameter class
|
@@ -196,6 +202,10 @@ module TypeProf
|
|
196
202
|
end
|
197
203
|
Elements.new(elems)
|
198
204
|
end
|
205
|
+
|
206
|
+
def include_untyped?(scratch)
|
207
|
+
return @elems.any? {|ty| ty.include_untyped?(scratch) }
|
208
|
+
end
|
199
209
|
end
|
200
210
|
end
|
201
211
|
|
@@ -531,6 +541,12 @@ module TypeProf
|
|
531
541
|
return rest_ary_ty, following_tys
|
532
542
|
end
|
533
543
|
end
|
544
|
+
|
545
|
+
def include_untyped?(scratch)
|
546
|
+
return true if @lead_tys.any? {|ty| ty.include_untyped?(scratch) }
|
547
|
+
return true if @rest_ty.include_untyped?(scratch)
|
548
|
+
false
|
549
|
+
end
|
534
550
|
end
|
535
551
|
end
|
536
552
|
|
@@ -790,6 +806,14 @@ module TypeProf
|
|
790
806
|
end
|
791
807
|
kw_tys
|
792
808
|
end
|
809
|
+
|
810
|
+
def include_untyped?(scratch)
|
811
|
+
@map_tys.each do |key, val|
|
812
|
+
return true if key.include_untyped?(scratch)
|
813
|
+
return true if val.include_untyped?(scratch)
|
814
|
+
end
|
815
|
+
false
|
816
|
+
end
|
793
817
|
end
|
794
818
|
end
|
795
819
|
|
data/lib/typeprof/export.rb
CHANGED
@@ -26,6 +26,10 @@ module TypeProf
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def show_message(terminated, output)
|
29
|
+
if Config.options[:show_typeprof_version]
|
30
|
+
output.puts "# TypeProf #{ VERSION }"
|
31
|
+
output.puts
|
32
|
+
end
|
29
33
|
if terminated
|
30
34
|
output.puts "# CAUTION: Type profiling was terminated prematurely because of the limitation"
|
31
35
|
output.puts
|
@@ -94,6 +98,10 @@ module TypeProf
|
|
94
98
|
if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
|
95
99
|
omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
|
96
100
|
superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
|
101
|
+
type_args = class_def.klass_obj.superclass_type_args
|
102
|
+
if type_args && !type_args.empty?
|
103
|
+
superclass += "[#{ type_args.map {|ty| ty.screen_name(@scratch) }.join(", ") }]"
|
104
|
+
end
|
97
105
|
end
|
98
106
|
|
99
107
|
@scratch.namespace = class_def.name
|
@@ -129,18 +137,17 @@ module TypeProf
|
|
129
137
|
ctxs = @iseq_method_to_ctxs[mdef]
|
130
138
|
next unless ctxs
|
131
139
|
|
132
|
-
ctxs.
|
133
|
-
next if mid != ctx.mid
|
134
|
-
next if Config.check_dir_filter(ctx.iseq.absolute_path) == :exclude
|
140
|
+
ctx = ctxs.find {|ctx| ctx.mid == mid } || ctxs.first
|
135
141
|
|
136
|
-
|
137
|
-
method_name = "self.#{ method_name }" if singleton
|
142
|
+
next if Config.check_dir_filter(ctx.iseq.absolute_path) == :exclude
|
138
143
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
+
method_name = mid
|
145
|
+
method_name = "self.#{ method_name }" if singleton
|
146
|
+
|
147
|
+
key = [:iseq, method_name]
|
148
|
+
visibilities[key] ||= mdef.pub_meth
|
149
|
+
source_locations[key] ||= ctx.iseq.source_location(0)
|
150
|
+
(methods[key] ||= []) << @scratch.show_method_signature(ctx)
|
144
151
|
when AliasMethodDef
|
145
152
|
alias_name, orig_name = mid, mdef.orig_mid
|
146
153
|
if singleton
|
@@ -169,7 +176,7 @@ module TypeProf
|
|
169
176
|
else
|
170
177
|
entry = ivars[[singleton, mdef.ivar]]
|
171
178
|
ty = entry ? entry.type : Type.any
|
172
|
-
methods[key] = [mdef.kind, ty.screen_name(@scratch)]
|
179
|
+
methods[key] = [mdef.kind, ty.screen_name(@scratch), ty.include_untyped?(@scratch)]
|
173
180
|
end
|
174
181
|
when TypedMethodDef
|
175
182
|
if mdef.rbs_source
|
@@ -336,14 +343,22 @@ module TypeProf
|
|
336
343
|
type, (method_name, hidden) = key
|
337
344
|
case type
|
338
345
|
when :attr
|
339
|
-
kind, ty = *arg
|
340
|
-
|
346
|
+
kind, ty, untyped = *arg
|
347
|
+
exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
348
|
+
lines << (indent + "#{ exclude } attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
|
341
349
|
when :rbs
|
342
350
|
sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
|
343
351
|
lines << (indent + "# def #{ method_name }: #{ sigs }")
|
344
352
|
when :iseq
|
345
|
-
sigs =
|
346
|
-
|
353
|
+
sigs = []
|
354
|
+
untyped = false
|
355
|
+
arg.each do |sig, untyped0|
|
356
|
+
sigs << sig
|
357
|
+
untyped ||= untyped0
|
358
|
+
end
|
359
|
+
sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
|
360
|
+
exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
361
|
+
lines << (indent + "#{ exclude } def #{ method_name }: #{ sigs }")
|
347
362
|
when :alias
|
348
363
|
orig_name = arg
|
349
364
|
lines << (indent + " alias #{ method_name } #{ orig_name }")
|
data/lib/typeprof/import.rb
CHANGED
@@ -3,6 +3,10 @@ require "rbs"
|
|
3
3
|
module TypeProf
|
4
4
|
class RBSReader
|
5
5
|
def initialize
|
6
|
+
@repo = RBS::Repository.new
|
7
|
+
Config.gem_repo_dirs.each do |dir|
|
8
|
+
@repo.add(Pathname(dir))
|
9
|
+
end
|
6
10
|
@env, @builtin_env_json = RBSReader.get_builtin_env
|
7
11
|
end
|
8
12
|
|
@@ -11,7 +15,7 @@ module TypeProf
|
|
11
15
|
unless @builtin_env
|
12
16
|
@builtin_env = RBS::Environment.new
|
13
17
|
|
14
|
-
loader = RBS::EnvironmentLoader.new
|
18
|
+
loader = RBS::EnvironmentLoader.new(repository: @repo)
|
15
19
|
new_decls = loader.load(env: @builtin_env).map {|decl,| decl }
|
16
20
|
@builtin_env_json = load_rbs(@builtin_env, new_decls)
|
17
21
|
end
|
@@ -24,22 +28,30 @@ module TypeProf
|
|
24
28
|
end
|
25
29
|
|
26
30
|
def load_library(lib)
|
27
|
-
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
31
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
|
28
32
|
loader.add(library: lib)
|
29
33
|
|
30
34
|
case lib
|
35
|
+
when 'bigdecimal-math'
|
36
|
+
loader.add(library: 'bigdecimal')
|
31
37
|
when "yaml"
|
32
38
|
loader.add(library: "pstore")
|
33
39
|
loader.add(library: "dbm")
|
40
|
+
when "logger"
|
41
|
+
loader.add(library: "monitor")
|
42
|
+
when "csv"
|
43
|
+
loader.add(library: "forwardable")
|
44
|
+
when "prime"
|
45
|
+
loader.add(library: "singleton")
|
34
46
|
end
|
35
47
|
|
36
48
|
new_decls = loader.load(env: @env).map {|decl,| decl }
|
37
49
|
RBSReader.load_rbs(@env, new_decls)
|
38
50
|
end
|
39
51
|
|
40
|
-
def
|
41
|
-
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
42
|
-
loader.add(path: path)
|
52
|
+
def load_paths(paths)
|
53
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
|
54
|
+
paths.each {|path| loader.add(path: path) }
|
43
55
|
new_decls = loader.load(env: @env).map {|decl,| decl }
|
44
56
|
RBSReader.load_rbs(@env, new_decls)
|
45
57
|
end
|
@@ -69,6 +81,7 @@ module TypeProf
|
|
69
81
|
class RBS2JSON
|
70
82
|
def initialize(all_env, cur_env)
|
71
83
|
@all_env, @cur_env = all_env, cur_env
|
84
|
+
@alias_resolution_stack = {}
|
72
85
|
end
|
73
86
|
|
74
87
|
def dump_json
|
@@ -176,11 +189,15 @@ module TypeProf
|
|
176
189
|
when RBS::AST::Members::Include
|
177
190
|
name = member.name
|
178
191
|
if name.kind == :class
|
192
|
+
# including a module
|
179
193
|
mod = conv_type_name(name)
|
180
194
|
type_args = member.args.map {|type| conv_type(type) }
|
181
195
|
modules[:include] << [mod, type_args]
|
182
196
|
else
|
183
|
-
# including an interface
|
197
|
+
# including an interface
|
198
|
+
mod = conv_type_name(name)
|
199
|
+
type_args = member.args.map {|type| conv_type(type) }
|
200
|
+
modules[:include] << [mod, type_args]
|
184
201
|
end
|
185
202
|
|
186
203
|
when RBS::AST::Members::Extend
|
@@ -424,8 +441,17 @@ module TypeProf
|
|
424
441
|
raise NotImplementedError
|
425
442
|
end
|
426
443
|
when RBS::Types::Alias
|
427
|
-
|
428
|
-
|
444
|
+
if @alias_resolution_stack[ty.name]
|
445
|
+
[:any]
|
446
|
+
else
|
447
|
+
begin
|
448
|
+
@alias_resolution_stack[ty.name] = true
|
449
|
+
alias_decl = @all_env.alias_decls[ty.name]
|
450
|
+
alias_decl ? conv_type(alias_decl.decl.type) : [:any]
|
451
|
+
ensure
|
452
|
+
@alias_resolution_stack.delete(ty.name)
|
453
|
+
end
|
454
|
+
end
|
429
455
|
when RBS::Types::Union
|
430
456
|
[:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
|
431
457
|
when RBS::Types::Optional
|
@@ -472,9 +498,9 @@ module TypeProf
|
|
472
498
|
Import.new(scratch, json).import
|
473
499
|
end
|
474
500
|
|
475
|
-
def self.
|
476
|
-
|
477
|
-
Import.new(scratch, scratch.rbs_reader.
|
501
|
+
def self.import_rbs_files(scratch, rbs_paths)
|
502
|
+
rbs_paths = rbs_paths.map {|rbs_path| Pathname(rbs_path) }
|
503
|
+
Import.new(scratch, scratch.rbs_reader.load_paths(rbs_paths)).import(true)
|
478
504
|
end
|
479
505
|
|
480
506
|
def self.import_rbs_code(scratch, rbs_name, rbs_code)
|