typeprof 0.15.0 → 0.20.0
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 +4 -4
- data/.github/workflows/main.yml +1 -1
- data/Gemfile.lock +4 -4
- data/exe/typeprof +5 -1
- data/lib/typeprof/analyzer.rb +261 -66
- data/lib/typeprof/arguments.rb +1 -0
- data/lib/typeprof/builtin.rb +30 -22
- data/lib/typeprof/cli.rb +22 -2
- data/lib/typeprof/code-range.rb +177 -0
- data/lib/typeprof/config.rb +43 -18
- data/lib/typeprof/container-type.rb +10 -1
- data/lib/typeprof/export.rb +199 -20
- data/lib/typeprof/import.rb +30 -4
- data/lib/typeprof/iseq.rb +504 -200
- data/lib/typeprof/lsp.rb +865 -0
- data/lib/typeprof/method.rb +17 -13
- data/lib/typeprof/type.rb +46 -38
- data/lib/typeprof/utils.rb +18 -1
- data/lib/typeprof/version.rb +1 -1
- data/lib/typeprof.rb +3 -0
- data/smoke/array15.rb +1 -1
- data/smoke/array6.rb +2 -2
- data/smoke/array8.rb +1 -1
- data/smoke/block-args2.rb +3 -3
- data/smoke/block-args3.rb +4 -4
- data/smoke/break2.rb +1 -1
- data/smoke/gvar2.rb +0 -3
- data/smoke/hash-bot.rb +1 -1
- data/smoke/hash4.rb +1 -1
- data/smoke/identifier_keywords.rb +17 -0
- data/smoke/next2.rb +1 -1
- data/smoke/or_raise.rb +18 -0
- data/smoke/parameterizedd-self.rb +2 -2
- data/smoke/pattern-match1.rb +1 -6
- data/smoke/rbs-vars.rb +0 -3
- data/testbed/ao.rb +1 -1
- data/typeprof-lsp +3 -0
- data/typeprof.gemspec +1 -1
- data/vscode/.gitignore +5 -0
- data/vscode/.vscode/launch.json +16 -0
- data/vscode/.vscodeignore +7 -0
- data/vscode/README.md +22 -0
- data/vscode/development.md +31 -0
- data/vscode/package-lock.json +2211 -0
- data/vscode/package.json +71 -0
- data/vscode/sandbox/test.rb +24 -0
- data/vscode/src/extension.ts +285 -0
- data/vscode/tsconfig.json +15 -0
- metadata +20 -5
data/lib/typeprof/export.rb
CHANGED
@@ -26,7 +26,7 @@ module TypeProf
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def show_message(terminated, output)
|
29
|
-
if Config.options[:show_typeprof_version]
|
29
|
+
if Config.current.options[:show_typeprof_version]
|
30
30
|
output.puts "# TypeProf #{ VERSION }"
|
31
31
|
output.puts
|
32
32
|
end
|
@@ -38,7 +38,7 @@ module TypeProf
|
|
38
38
|
|
39
39
|
def show_error(errors, backward_edge, output)
|
40
40
|
return if errors.empty?
|
41
|
-
return unless Config.options[:show_errors]
|
41
|
+
return unless Config.current.options[:show_errors]
|
42
42
|
|
43
43
|
output.puts "# Errors"
|
44
44
|
errors.each do |ep, msg|
|
@@ -69,14 +69,17 @@ module TypeProf
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def show_gvars(scratch, gvars, output)
|
72
|
+
gvars = gvars.dump.filter_map do |gvar_name, entry|
|
73
|
+
if entry.type != Type.bot && !entry.rbs_declared
|
74
|
+
[gvar_name, entry]
|
75
|
+
end
|
76
|
+
end
|
72
77
|
# A signature for global variables is not supported in RBS
|
73
|
-
return if gvars.
|
78
|
+
return if gvars.empty?
|
74
79
|
|
75
80
|
output.puts "# Global variables"
|
76
|
-
gvars.
|
77
|
-
|
78
|
-
s = entry.rbs_declared ? "#" : ""
|
79
|
-
output.puts s + "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
|
81
|
+
gvars.each do |gvar_name, entry|
|
82
|
+
output.puts "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
|
80
83
|
end
|
81
84
|
output.puts
|
82
85
|
end
|
@@ -107,16 +110,17 @@ module TypeProf
|
|
107
110
|
@scratch.namespace = class_def.name
|
108
111
|
|
109
112
|
consts = {}
|
110
|
-
class_def.consts.each do |name, (ty,
|
113
|
+
class_def.consts.each do |name, (ty, loc)|
|
114
|
+
next unless loc
|
111
115
|
next if ty.is_a?(Type::Class)
|
112
|
-
next if
|
116
|
+
next if Config.current.check_dir_filter(loc[0]) == :exclude
|
113
117
|
consts[name] = ty.screen_name(@scratch)
|
114
118
|
end
|
115
119
|
|
116
120
|
modules = class_def.modules.to_h do |kind, mods|
|
117
121
|
mods = mods.to_h do |singleton, mods|
|
118
122
|
mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
|
119
|
-
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
123
|
+
next if absolute_paths.all? {|path| !path || Config.current.check_dir_filter(path) == :exclude }
|
120
124
|
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
121
125
|
end
|
122
126
|
[singleton, mods]
|
@@ -139,7 +143,7 @@ module TypeProf
|
|
139
143
|
|
140
144
|
ctx = ctxs.find {|ctx| ctx.mid == mid } || ctxs.first
|
141
145
|
|
142
|
-
next if Config.check_dir_filter(ctx.iseq.absolute_path) == :exclude
|
146
|
+
next if Config.current.check_dir_filter(ctx.iseq.absolute_path) == :exclude
|
143
147
|
|
144
148
|
method_name = mid
|
145
149
|
method_name = "self.#{ method_name }" if singleton
|
@@ -149,7 +153,7 @@ module TypeProf
|
|
149
153
|
source_locations[key] ||= ctx.iseq.source_location(0)
|
150
154
|
(methods[key] ||= []) << @scratch.show_method_signature(ctx)
|
151
155
|
when AliasMethodDef
|
152
|
-
next if mdef.def_ep && Config.check_dir_filter(mdef.def_ep.source_location) == :exclude
|
156
|
+
next if mdef.def_ep && Config.current.check_dir_filter(mdef.def_ep.source_location) == :exclude
|
153
157
|
alias_name, orig_name = mid, mdef.orig_mid
|
154
158
|
if singleton
|
155
159
|
alias_name = "self.#{ alias_name }"
|
@@ -162,7 +166,7 @@ module TypeProf
|
|
162
166
|
when AttrMethodDef
|
163
167
|
next if !mdef.def_ep
|
164
168
|
absolute_path = mdef.def_ep.ctx.iseq.absolute_path
|
165
|
-
next if !absolute_path || Config.check_dir_filter(absolute_path) == :exclude
|
169
|
+
next if !absolute_path || Config.current.check_dir_filter(absolute_path) == :exclude
|
166
170
|
mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
|
167
171
|
method_name = mid
|
168
172
|
method_name = "self.#{ mid }" if singleton
|
@@ -185,13 +189,14 @@ module TypeProf
|
|
185
189
|
key = [:rbs, method_name]
|
186
190
|
methods[key] = sigs
|
187
191
|
visibilities[key] ||= mdef.pub_meth
|
192
|
+
source_locations[key] ||= mdef.iseq&.source_location(0)
|
188
193
|
end
|
189
194
|
end
|
190
195
|
end
|
191
196
|
end
|
192
197
|
|
193
198
|
ivars = ivars.map do |(singleton, var), entry|
|
194
|
-
next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
|
199
|
+
next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
|
195
200
|
ty = entry.type
|
196
201
|
next unless var.to_s.start_with?("@")
|
197
202
|
var = "self.#{ var }" if singleton
|
@@ -201,12 +206,12 @@ module TypeProf
|
|
201
206
|
end.compact
|
202
207
|
|
203
208
|
cvars = cvars.map do |var, entry|
|
204
|
-
next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
|
209
|
+
next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
|
205
210
|
next if entry.rbs_declared
|
206
211
|
[var, entry.type.screen_name(@scratch)]
|
207
212
|
end.compact
|
208
213
|
|
209
|
-
if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
|
214
|
+
if !class_def.absolute_path || Config.current.check_dir_filter(class_def.absolute_path) == :exclude
|
210
215
|
if methods.keys.all? {|type,| type == :rbs }
|
211
216
|
return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty? && inner_classes.empty?
|
212
217
|
end
|
@@ -229,8 +234,182 @@ module TypeProf
|
|
229
234
|
)
|
230
235
|
end
|
231
236
|
|
237
|
+
def conv_class_lsp(namespace, class_def)
|
238
|
+
@scratch.namespace = namespace
|
239
|
+
|
240
|
+
if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
|
241
|
+
omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
|
242
|
+
superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
|
243
|
+
type_args = class_def.klass_obj.superclass_type_args
|
244
|
+
if type_args && !type_args.empty?
|
245
|
+
superclass += "[#{ type_args.map {|ty| ty.screen_name(@scratch) }.join(", ") }]"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
@scratch.namespace = class_def.name
|
250
|
+
|
251
|
+
consts = {}
|
252
|
+
class_def.consts.each do |name, (ty, loc)|
|
253
|
+
next unless loc
|
254
|
+
next if ty.is_a?(Type::Class)
|
255
|
+
next if Config.current.check_dir_filter(loc[0]) == :exclude
|
256
|
+
consts[name] = ty.screen_name(@scratch)
|
257
|
+
end
|
258
|
+
|
259
|
+
modules = class_def.modules.to_h do |kind, mods|
|
260
|
+
mods = mods.to_h do |singleton, mods|
|
261
|
+
mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
|
262
|
+
next if absolute_paths.all? {|path| !path || Config.current.check_dir_filter(path) == :exclude }
|
263
|
+
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
264
|
+
end
|
265
|
+
[singleton, mods]
|
266
|
+
end
|
267
|
+
[kind, mods]
|
268
|
+
end
|
269
|
+
|
270
|
+
visibilities = {}
|
271
|
+
source_locations = {}
|
272
|
+
methods = {}
|
273
|
+
ivars = class_def.ivars.dump
|
274
|
+
cvars = class_def.cvars.dump
|
275
|
+
|
276
|
+
class_def.methods.each do |(singleton, mid), mdefs|
|
277
|
+
mdefs.each do |mdef|
|
278
|
+
case mdef
|
279
|
+
when ISeqMethodDef
|
280
|
+
ctxs = @iseq_method_to_ctxs[mdef]
|
281
|
+
next unless ctxs
|
282
|
+
|
283
|
+
ctx = ctxs.find {|ctx| ctx.mid == mid } || ctxs.first
|
284
|
+
|
285
|
+
next if Config.current.check_dir_filter(ctx.iseq.absolute_path) == :exclude
|
286
|
+
|
287
|
+
method_name = mid
|
288
|
+
method_name = "self.#{ method_name }" if singleton
|
289
|
+
|
290
|
+
key = [:iseq, method_name]
|
291
|
+
visibilities[key] ||= mdef.pub_meth
|
292
|
+
source_locations[key] ||= [ctx.iseq.source_location(0)]
|
293
|
+
sig = @scratch.show_method_signature(ctx)
|
294
|
+
(methods[key] ||= []) << sig if sig
|
295
|
+
when AliasMethodDef
|
296
|
+
alias_name, orig_name = mid, mdef.orig_mid
|
297
|
+
if singleton
|
298
|
+
alias_name = "self.#{ alias_name }"
|
299
|
+
orig_name = "self.#{ orig_name }"
|
300
|
+
end
|
301
|
+
key = [:alias, alias_name]
|
302
|
+
visibilities[key] ||= mdef.pub_meth
|
303
|
+
source_locations[key] ||= [mdef.def_ep&.source_location]
|
304
|
+
methods[key] = orig_name
|
305
|
+
when AttrMethodDef
|
306
|
+
next if !mdef.def_ep
|
307
|
+
absolute_path = mdef.def_ep.ctx.iseq.absolute_path
|
308
|
+
next if !absolute_path || Config.current.check_dir_filter(absolute_path) == :exclude
|
309
|
+
mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
|
310
|
+
method_name = mid
|
311
|
+
method_name = "self.#{ mid }" if singleton
|
312
|
+
method_name = [method_name, :"@#{ mid }" != mdef.ivar]
|
313
|
+
key = [:attr, method_name]
|
314
|
+
visibilities[key] ||= mdef.pub_meth
|
315
|
+
source_locations[key] ||= [mdef.def_ep.source_location]
|
316
|
+
if methods[key]
|
317
|
+
if methods[key][0] != mdef.kind
|
318
|
+
methods[key][0] = :accessor
|
319
|
+
end
|
320
|
+
else
|
321
|
+
entry = ivars[[singleton, mdef.ivar]]
|
322
|
+
ty = entry ? entry.type : Type.any
|
323
|
+
methods[key] = [mdef.kind, ty.screen_name(@scratch), ty.include_untyped?(@scratch)]
|
324
|
+
end
|
325
|
+
when TypedMethodDef
|
326
|
+
if mdef.rbs_source
|
327
|
+
method_name, sigs, rbs_code_range = mdef.rbs_source
|
328
|
+
key = [:rbs, method_name]
|
329
|
+
methods[key] = sigs
|
330
|
+
visibilities[key] ||= mdef.pub_meth
|
331
|
+
source_locations[key] ||= [mdef.iseq&.source_location(0), rbs_code_range]
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
ivars = ivars.map do |(singleton, var), entry|
|
338
|
+
next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
|
339
|
+
ty = entry.type
|
340
|
+
next unless var.to_s.start_with?("@")
|
341
|
+
var = "self.#{ var }" if singleton
|
342
|
+
next if methods[[:attr, [singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]]
|
343
|
+
next if entry.rbs_declared
|
344
|
+
[var, ty.screen_name(@scratch)]
|
345
|
+
end.compact
|
346
|
+
|
347
|
+
cvars = cvars.map do |var, entry|
|
348
|
+
next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
|
349
|
+
next if entry.rbs_declared
|
350
|
+
[var, entry.type.screen_name(@scratch)]
|
351
|
+
end.compact
|
352
|
+
|
353
|
+
if !class_def.absolute_path || Config.current.check_dir_filter(class_def.absolute_path) == :exclude
|
354
|
+
if methods.keys.all? {|type,| type == :rbs }
|
355
|
+
return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty?
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
@scratch.namespace = nil
|
360
|
+
|
361
|
+
ClassData.new(
|
362
|
+
kind: class_def.kind,
|
363
|
+
name: class_def.name,
|
364
|
+
superclass: superclass,
|
365
|
+
consts: consts,
|
366
|
+
modules: modules,
|
367
|
+
ivars: ivars,
|
368
|
+
cvars: cvars,
|
369
|
+
methods: methods,
|
370
|
+
visibilities: visibilities,
|
371
|
+
source_locations: source_locations,
|
372
|
+
)
|
373
|
+
end
|
374
|
+
|
232
375
|
ClassData = Struct.new(:kind, :name, :superclass, :consts, :modules, :ivars, :cvars, :methods, :visibilities, :source_locations, :inner_classes, keyword_init: true)
|
233
376
|
|
377
|
+
def show_lsp
|
378
|
+
res = []
|
379
|
+
@class_defs.each_value do |class_def|
|
380
|
+
class_data = conv_class_lsp([], class_def)
|
381
|
+
next unless class_data
|
382
|
+
class_data.methods.each do |key, arg|
|
383
|
+
source_location, rbs_code_range = class_data.source_locations[key]
|
384
|
+
type, (method_name, hidden) = key
|
385
|
+
case type
|
386
|
+
when :attr
|
387
|
+
kind, ty, untyped = *arg
|
388
|
+
line = "attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }"
|
389
|
+
when :rbs
|
390
|
+
sigs = arg.sort.join(" | ")
|
391
|
+
line = "# def #{ method_name }: #{ sigs }"
|
392
|
+
when :iseq
|
393
|
+
sigs = []
|
394
|
+
untyped = false
|
395
|
+
arg.each do |sig, untyped0|
|
396
|
+
sigs << sig
|
397
|
+
untyped ||= untyped0
|
398
|
+
end
|
399
|
+
sigs = sigs.sort.join(" | ")
|
400
|
+
line = "def #{ method_name }: #{ sigs }"
|
401
|
+
when :alias
|
402
|
+
orig_name = arg
|
403
|
+
line = "alias #{ method_name } #{ orig_name }"
|
404
|
+
end
|
405
|
+
if source_location =~ /:(\d+)$/
|
406
|
+
res << [$`, $1.to_i, line, rbs_code_range, class_data.kind, class_data.name]
|
407
|
+
end
|
408
|
+
end
|
409
|
+
end
|
410
|
+
res
|
411
|
+
end
|
412
|
+
|
234
413
|
def show(stat_eps, output)
|
235
414
|
# make the class hierarchy
|
236
415
|
root = {}
|
@@ -267,7 +446,7 @@ module TypeProf
|
|
267
446
|
coverage = {}
|
268
447
|
stat_eps.each do |ep|
|
269
448
|
path = ep.ctx.iseq.path
|
270
|
-
lineno = ep.ctx.iseq.
|
449
|
+
lineno = ep.ctx.iseq.insns[ep.pc].lineno - 1
|
271
450
|
(coverage[path] ||= [])[lineno] ||= 0
|
272
451
|
(coverage[path] ||= [])[lineno] += 1
|
273
452
|
end
|
@@ -337,7 +516,7 @@ module TypeProf
|
|
337
516
|
prev_vis = vis
|
338
517
|
end
|
339
518
|
source_location = class_data.source_locations[key]
|
340
|
-
if Config.options[:show_source_locations] && source_location
|
519
|
+
if Config.current.options[:show_source_locations] && source_location
|
341
520
|
lines << nil
|
342
521
|
lines << (indent + " # #{ source_location }")
|
343
522
|
end
|
@@ -345,7 +524,7 @@ module TypeProf
|
|
345
524
|
case type
|
346
525
|
when :attr
|
347
526
|
kind, ty, untyped = *arg
|
348
|
-
exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
527
|
+
exclude = Config.current.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
349
528
|
lines << (indent + "#{ exclude } attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
|
350
529
|
when :rbs
|
351
530
|
sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
|
@@ -358,7 +537,7 @@ module TypeProf
|
|
358
537
|
untyped ||= untyped0
|
359
538
|
end
|
360
539
|
sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
|
361
|
-
exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
540
|
+
exclude = Config.current.options[:exclude_untyped] && untyped ? "#" : " " # XXX
|
362
541
|
lines << (indent + "#{ exclude } def #{ method_name }: #{ sigs }")
|
363
542
|
when :alias
|
364
543
|
orig_name = arg
|
data/lib/typeprof/import.rb
CHANGED
@@ -4,9 +4,14 @@ module TypeProf
|
|
4
4
|
class RBSReader
|
5
5
|
def initialize
|
6
6
|
@repo = RBS::Repository.new
|
7
|
-
Config.gem_repo_dirs.each do |dir|
|
7
|
+
Config.current.gem_repo_dirs.each do |dir|
|
8
8
|
@repo.add(Pathname(dir))
|
9
9
|
end
|
10
|
+
collection_path = Config.current.collection_path
|
11
|
+
if collection_path&.exist?
|
12
|
+
collection_lock = RBS::Collection::Config.lockfile_of(collection_path)
|
13
|
+
@repo.add(collection_lock.repo_path)
|
14
|
+
end
|
10
15
|
@env, @builtin_env_json = RBSReader.get_builtin_env
|
11
16
|
end
|
12
17
|
|
@@ -66,6 +71,14 @@ module TypeProf
|
|
66
71
|
RBSReader.load_rbs(@env, new_decls)
|
67
72
|
end
|
68
73
|
|
74
|
+
def load_rbs_collection(collection_path)
|
75
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
76
|
+
collection_lock = RBS::Collection::Config.lockfile_of(collection_path)
|
77
|
+
loader.add_collection(collection_lock)
|
78
|
+
new_decls = loader.load(env: @env).map {|decl,| decl }
|
79
|
+
RBSReader.load_rbs(@env, new_decls)
|
80
|
+
end
|
81
|
+
|
69
82
|
def self.load_rbs(env, new_decls)
|
70
83
|
all_env = env.resolve_type_names
|
71
84
|
resolver = RBS::TypeNameResolver.from_env(all_env)
|
@@ -157,7 +170,11 @@ module TypeProf
|
|
157
170
|
end
|
158
171
|
|
159
172
|
method_def = conv_method_def(method_types, visibility)
|
160
|
-
rbs_source = [
|
173
|
+
rbs_source = [
|
174
|
+
(member.kind == :singleton ? "self." : "") + member.name.to_s,
|
175
|
+
member.types.map {|type| type.location.source },
|
176
|
+
[member.location.name, CodeRange.from_rbs(member.location)],
|
177
|
+
]
|
161
178
|
if member.instance?
|
162
179
|
methods[[false, name]] = method_def
|
163
180
|
rbs_sources[[false, name]] = rbs_source
|
@@ -459,6 +476,8 @@ module TypeProf
|
|
459
476
|
end
|
460
477
|
when RBS::Types::Union
|
461
478
|
[:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
|
479
|
+
when RBS::Types::Intersection
|
480
|
+
[:intersection, ty.types.map {|ty2| conv_type(ty2) }.compact]
|
462
481
|
when RBS::Types::Optional
|
463
482
|
[:optional, conv_type(ty.type)]
|
464
483
|
when RBS::Types::Interface
|
@@ -512,6 +531,10 @@ module TypeProf
|
|
512
531
|
Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
|
513
532
|
end
|
514
533
|
|
534
|
+
def self.import_rbs_collection(scratch, collection_path)
|
535
|
+
Import.new(scratch, scratch.rbs_reader.load_rbs_collection(collection_path)).import(true)
|
536
|
+
end
|
537
|
+
|
515
538
|
def initialize(scratch, json)
|
516
539
|
@scratch = scratch
|
517
540
|
@json = json
|
@@ -527,7 +550,7 @@ module TypeProf
|
|
527
550
|
superclass = path_to_klass(superclass) if superclass
|
528
551
|
base_klass = path_to_klass(classpath[0..-2])
|
529
552
|
|
530
|
-
klass = @scratch.get_constant(base_klass, name)
|
553
|
+
klass, = @scratch.get_constant(base_klass, name)
|
531
554
|
if klass.is_a?(Type::Any)
|
532
555
|
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
|
533
556
|
|
@@ -729,6 +752,9 @@ module TypeProf
|
|
729
752
|
when :union
|
730
753
|
tys = ty[1]
|
731
754
|
Type::Union.create(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # XXX: Array and Hash support
|
755
|
+
when :intersection
|
756
|
+
tys = ty[1]
|
757
|
+
conv_type(tys.first) # XXX: This is wrong! We need to support intersection type
|
732
758
|
when :var
|
733
759
|
Type::Var.new(ty[1])
|
734
760
|
when :proc
|
@@ -743,7 +769,7 @@ module TypeProf
|
|
743
769
|
def path_to_klass(path)
|
744
770
|
klass = Type::Builtin[:obj]
|
745
771
|
path.each do |name|
|
746
|
-
klass = @scratch.get_constant(klass, name)
|
772
|
+
klass, = @scratch.get_constant(klass, name)
|
747
773
|
if klass == Type.any
|
748
774
|
raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
|
749
775
|
end
|