typeprof 0.21.11 → 0.30.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -31
  3. data/bin/typeprof +5 -0
  4. data/doc/doc.ja.md +134 -0
  5. data/doc/doc.md +136 -0
  6. data/lib/typeprof/cli/cli.rb +180 -0
  7. data/lib/typeprof/cli.rb +2 -133
  8. data/lib/typeprof/code_range.rb +112 -0
  9. data/lib/typeprof/core/ast/base.rb +263 -0
  10. data/lib/typeprof/core/ast/call.rb +251 -0
  11. data/lib/typeprof/core/ast/const.rb +126 -0
  12. data/lib/typeprof/core/ast/control.rb +432 -0
  13. data/lib/typeprof/core/ast/meta.rb +150 -0
  14. data/lib/typeprof/core/ast/method.rb +335 -0
  15. data/lib/typeprof/core/ast/misc.rb +263 -0
  16. data/lib/typeprof/core/ast/module.rb +123 -0
  17. data/lib/typeprof/core/ast/pattern.rb +140 -0
  18. data/lib/typeprof/core/ast/sig_decl.rb +471 -0
  19. data/lib/typeprof/core/ast/sig_type.rb +663 -0
  20. data/lib/typeprof/core/ast/value.rb +319 -0
  21. data/lib/typeprof/core/ast/variable.rb +315 -0
  22. data/lib/typeprof/core/ast.rb +472 -0
  23. data/lib/typeprof/core/builtin.rb +146 -0
  24. data/lib/typeprof/core/env/method.rb +137 -0
  25. data/lib/typeprof/core/env/method_entity.rb +55 -0
  26. data/lib/typeprof/core/env/module_entity.rb +408 -0
  27. data/lib/typeprof/core/env/static_read.rb +155 -0
  28. data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
  29. data/lib/typeprof/core/env/value_entity.rb +32 -0
  30. data/lib/typeprof/core/env.rb +360 -0
  31. data/lib/typeprof/core/graph/box.rb +991 -0
  32. data/lib/typeprof/core/graph/change_set.rb +224 -0
  33. data/lib/typeprof/core/graph/filter.rb +155 -0
  34. data/lib/typeprof/core/graph/vertex.rb +222 -0
  35. data/lib/typeprof/core/graph.rb +3 -0
  36. data/lib/typeprof/core/service.rb +522 -0
  37. data/lib/typeprof/core/type.rb +348 -0
  38. data/lib/typeprof/core/util.rb +81 -0
  39. data/lib/typeprof/core.rb +32 -0
  40. data/lib/typeprof/diagnostic.rb +35 -0
  41. data/lib/typeprof/lsp/messages.rb +430 -0
  42. data/lib/typeprof/lsp/server.rb +177 -0
  43. data/lib/typeprof/lsp/text.rb +69 -0
  44. data/lib/typeprof/lsp/util.rb +61 -0
  45. data/lib/typeprof/lsp.rb +4 -907
  46. data/lib/typeprof/version.rb +1 -1
  47. data/lib/typeprof.rb +4 -18
  48. data/typeprof.gemspec +5 -7
  49. metadata +48 -35
  50. data/.github/dependabot.yml +0 -6
  51. data/.github/workflows/main.yml +0 -39
  52. data/.gitignore +0 -9
  53. data/Gemfile +0 -17
  54. data/Gemfile.lock +0 -41
  55. data/Rakefile +0 -10
  56. data/exe/typeprof +0 -10
  57. data/lib/typeprof/analyzer.rb +0 -2598
  58. data/lib/typeprof/arguments.rb +0 -414
  59. data/lib/typeprof/block.rb +0 -176
  60. data/lib/typeprof/builtin.rb +0 -893
  61. data/lib/typeprof/code-range.rb +0 -177
  62. data/lib/typeprof/config.rb +0 -158
  63. data/lib/typeprof/container-type.rb +0 -912
  64. data/lib/typeprof/export.rb +0 -589
  65. data/lib/typeprof/import.rb +0 -852
  66. data/lib/typeprof/insns-def.rb +0 -65
  67. data/lib/typeprof/iseq.rb +0 -864
  68. data/lib/typeprof/method.rb +0 -355
  69. data/lib/typeprof/type.rb +0 -1140
  70. data/lib/typeprof/utils.rb +0 -212
  71. data/tools/coverage.rb +0 -14
  72. data/tools/setup-insns-def.rb +0 -30
  73. data/typeprof-lsp +0 -3
@@ -1,852 +0,0 @@
1
- require "rbs"
2
-
3
- module TypeProf
4
- class RBSReader
5
- def initialize
6
- @repo = RBS::Repository.new
7
- collection_path = Config.current.collection_path
8
- if collection_path&.exist?
9
- lock_path = RBS::Collection::Config.to_lockfile_path(collection_path)
10
- if lock_path.exist?
11
- collection_lock = RBS::Collection::Config.from_path(lock_path)
12
- @repo.add(collection_lock.repo_path)
13
- else
14
- raise "Please execute 'rbs collection install'"
15
- end
16
- end
17
- @env, @loaded_gems, @builtin_env_json = RBSReader.get_builtin_env
18
- end
19
-
20
- @builtin_env = @builtin_env_json = nil
21
- def self.get_builtin_env
22
- @loaded_gems = []
23
- unless @builtin_env
24
- @builtin_env = RBS::Environment.new
25
-
26
- loader = RBS::EnvironmentLoader.new
27
-
28
- # TODO: invalidate this cache when rbs_collection.yml was changed
29
- collection_path = Config.current.collection_path
30
- if collection_path&.exist?
31
- lock_path = RBS::Collection::Config.to_lockfile_path(collection_path)
32
- if lock_path.exist?
33
- collection_lock = RBS::Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path.to_s))
34
- collection_lock.gems.each_value {|gem| @loaded_gems << gem[:name] }
35
- loader.add_collection(collection_lock)
36
- else
37
- raise "Please execute 'rbs collection install'"
38
- end
39
- end
40
-
41
- new_decls = loader.load(env: @builtin_env).map {|decl,| decl }
42
- @builtin_env_json = load_rbs(@builtin_env, new_decls)
43
- end
44
-
45
- return @builtin_env.dup, @loaded_gems.dup, @builtin_env_json
46
- end
47
-
48
- def load_builtin
49
- @builtin_env_json
50
- end
51
-
52
- class RBSCollectionDefined < StandardError; end
53
-
54
- def load_library(lib)
55
- loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
56
- if @loaded_gems.include?(lib)
57
- raise RBSCollectionDefined
58
- end
59
- @loaded_gems << lib
60
- loader.add(library: lib)
61
-
62
- case lib
63
- when 'bigdecimal-math'
64
- loader.add(library: 'bigdecimal')
65
- when "yaml"
66
- loader.add(library: "pstore")
67
- loader.add(library: "dbm")
68
- when "logger"
69
- loader.add(library: "monitor")
70
- when "csv"
71
- loader.add(library: "forwardable")
72
- when "prime"
73
- loader.add(library: "singleton")
74
- end
75
-
76
- new_decls = loader.load(env: @env).map {|decl,| decl }
77
- RBSReader.load_rbs(@env, new_decls)
78
- end
79
-
80
- def load_paths(paths)
81
- loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
82
- paths.each {|path| loader.add(path: path) }
83
- new_decls = loader.load(env: @env).map {|decl,| decl }
84
- RBSReader.load_rbs(@env, new_decls)
85
- end
86
-
87
- def load_rbs_string(name, content)
88
- buffer = RBS::Buffer.new(name: name, content: content)
89
- new_decls = []
90
- ret = RBS::Parser.parse_signature(buffer)
91
- if ret[0].is_a?(RBS::Buffer)
92
- # rbs 3.0
93
- buffer, directives, decls = ret
94
- @env.add_signature(buffer: buffer, directives: directives, decls: decls)
95
- new_decls.concat(decls)
96
- else
97
- ret.each do |decl|
98
- @env << decl
99
- new_decls << decl
100
- end
101
- end
102
- RBSReader.load_rbs(@env, new_decls)
103
- end
104
-
105
- def self.load_rbs(env, new_decls)
106
- all_env = env.resolve_type_names
107
- cur_env = RBS::Environment.new
108
- if defined?(RBS::TypeNameResolver)
109
- resolver = RBS::TypeNameResolver.from_env(all_env)
110
- new_decls.each do |decl|
111
- cur_env << env.resolve_declaration(resolver, decl, outer: [], prefix: RBS::Namespace.root)
112
- end
113
- else
114
- resolver = RBS::Resolver::TypeNameResolver.new(all_env)
115
- table = RBS::Environment::UseMap::Table.new()
116
- table.compute_children
117
- map = RBS::Environment::UseMap.new(table: table)
118
- new_decls.each do |decl|
119
- cur_env << s = env.resolve_declaration(resolver, map, decl, outer: [], prefix: RBS::Namespace.root)
120
- end
121
- end
122
-
123
- RBS2JSON.new(all_env, cur_env).dump_json
124
- end
125
- end
126
-
127
- class RBS2JSON
128
- def initialize(all_env, cur_env)
129
- @all_env, @cur_env = all_env, cur_env
130
- @alias_resolution_stack = {}
131
- end
132
-
133
- def dump_json
134
- {
135
- classes: conv_classes,
136
- constants: conv_constants,
137
- globals: conv_globals,
138
- }
139
- end
140
-
141
- # constant_name = [Symbol]
142
- #
143
- # { constant_name => type }
144
- def conv_constants
145
- constants = {}
146
- @cur_env.constant_decls.each do |name, decl|
147
- klass = conv_type_name(name)
148
- constants[klass] = conv_type(decl.decl.type)
149
- end
150
- constants
151
- end
152
-
153
- # gvar_name = Symbol (:$gvar)
154
- #
155
- # { gvar_name => type }
156
- def conv_globals
157
- gvars = {}
158
- @cur_env.global_decls.each do |name, decl|
159
- decl = decl.decl
160
- gvars[name] = conv_type(decl.type)
161
- end
162
- gvars
163
- end
164
-
165
- AliasDecl = defined?(RBS::AST::Declarations::Alias) ? RBS::AST::Declarations::Alias : RBS::AST::Declarations::AliasDecl
166
- TypeAlias = defined?(RBS::AST::Declarations::TypeAlias) ? RBS::AST::Declarations::TypeAlias : nil
167
-
168
- def conv_classes
169
- json = {}
170
-
171
- each_class_decl do |name, decls|
172
- klass = conv_type_name(name)
173
- super_class_name, super_class_args = get_super_class(name, decls)
174
- if super_class_name
175
- name = conv_type_name(super_class_name)
176
- type_args = super_class_args.map {|type| conv_type(type) }
177
- superclass = [name, type_args]
178
- end
179
-
180
- type_params = nil
181
- modules = { include: [], extend: [], prepend: [] }
182
- methods = {}
183
- attr_methods = {}
184
- ivars = {}
185
- cvars = {}
186
- rbs_sources = {}
187
- visibility = true
188
-
189
- decls.each do |decl|
190
- decl = decl.decl
191
-
192
- type_params2 = decl.type_params
193
- # A hack to deal with the imcompatibility between rbs 1.8 and 2.0
194
- type_params2 = type_params2.params if type_params2.respond_to?(:params)
195
- type_params2 = type_params2.map {|param| [param.name, param.variance] }
196
- raise "inconsistent type parameter declaration" if type_params && type_params != type_params2
197
- type_params = type_params2
198
-
199
- decl.members.each do |member|
200
- case member
201
- when RBS::AST::Members::MethodDefinition
202
- name = member.name
203
-
204
- if member.respond_to?(:overloads)
205
- types = member.overloads.map {|overload| overload.method_type }
206
- else
207
- types = member.types
208
- end
209
- method_types = types.map do |method_type|
210
- case method_type
211
- when RBS::MethodType then method_type
212
- when :super then raise NotImplementedError
213
- end
214
- end
215
-
216
- method_def = conv_method_def(method_types, visibility)
217
- rbs_source = [
218
- (member.kind == :singleton ? "self." : "") + member.name.to_s,
219
- types.map {|type| type.location.source },
220
- [member.location.name, CodeRange.from_rbs(member.location)],
221
- ]
222
- if member.instance?
223
- methods[[false, name]] = method_def
224
- rbs_sources[[false, name]] = rbs_source
225
- end
226
- if member.singleton?
227
- methods[[true, name]] = method_def
228
- rbs_sources[[true, name]] = rbs_source
229
- end
230
- when RBS::AST::Members::AttrReader
231
- ty = conv_type(member.type)
232
- attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty, visibility)
233
- rbs_sources[[false, member.name]] = attr_rbs_source(member)
234
- when RBS::AST::Members::AttrWriter
235
- ty = conv_type(member.type)
236
- attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty, visibility)
237
- rbs_sources[[false, member.name]] = attr_rbs_source(member)
238
- when RBS::AST::Members::AttrAccessor
239
- ty = conv_type(member.type)
240
- attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty, visibility)
241
- rbs_sources[[false, member.name]] = attr_rbs_source(member)
242
- when RBS::AST::Members::Alias
243
- # XXX: an alias to attr methods?
244
- if member.instance?
245
- method_def = methods[[false, member.old_name]]
246
- methods[[false, member.new_name]] = method_def if method_def
247
- end
248
- if member.singleton?
249
- method_def = methods[[true, member.old_name]]
250
- methods[[true, member.new_name]] = method_def if method_def
251
- end
252
-
253
- when RBS::AST::Members::Include
254
- name = member.name
255
- if name.kind == :class
256
- # including a module
257
- mod = conv_type_name(name)
258
- type_args = member.args.map {|type| conv_type(type) }
259
- modules[:include] << [mod, type_args]
260
- else
261
- # including an interface
262
- mod = conv_type_name(name)
263
- type_args = member.args.map {|type| conv_type(type) }
264
- modules[:include] << [mod, type_args]
265
- end
266
-
267
- when RBS::AST::Members::Extend
268
- name = member.name
269
- if name.kind == :class
270
- mod = conv_type_name(name)
271
- type_args = member.args.map {|type| conv_type(type) }
272
- modules[:extend] << [mod, type_args]
273
- else
274
- # extending a module with an interface is not supported yet
275
- end
276
-
277
- when RBS::AST::Members::Prepend
278
- name = member.name
279
- if name.kind == :class
280
- mod = conv_type_name(name)
281
- type_args = member.args.map {|type| conv_type(type) }
282
- modules[:prepend] << [mod, type_args]
283
- else
284
- # extending a module with an interface is not supported yet
285
- end
286
-
287
- when RBS::AST::Members::InstanceVariable
288
- ivars[member.name] = conv_type(member.type)
289
- when RBS::AST::Members::ClassVariable
290
- cvars[member.name] = conv_type(member.type)
291
-
292
- when RBS::AST::Members::Public
293
- visibility = true
294
- when RBS::AST::Members::Private
295
- visibility = false
296
-
297
- # The following declarations are ignoreable because they are handled in other level
298
- when RBS::AST::Declarations::Constant
299
- when AliasDecl # type alias
300
- when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
301
- when RBS::AST::Declarations::Interface
302
- when TypeAlias
303
-
304
- else
305
- warn "Importing #{ member.class.name } is not supported yet"
306
- end
307
- end
308
- end
309
-
310
- json[klass] = {
311
- type_params: type_params,
312
- superclass: superclass,
313
- members: {
314
- modules: modules,
315
- methods: methods,
316
- attr_methods: attr_methods,
317
- ivars: ivars,
318
- cvars: cvars,
319
- rbs_sources: rbs_sources,
320
- },
321
- }
322
- end
323
-
324
- json
325
- end
326
-
327
- def each_class_decl
328
- # topological sort
329
- # * superclasses and modules appear earlier than their subclasses (Object is earlier than String)
330
- # * namespace module appers earlier than its children (Process is earlier than Process::Status)
331
- visited = {}
332
- queue = @cur_env.class_decls.keys.map {|name| [:visit, name] }.reverse
333
- until queue.empty?
334
- event, name = queue.pop
335
- case event
336
- when :visit
337
- if !visited[name]
338
- visited[name] = true
339
- queue << [:new, name]
340
- @all_env.class_decls[name].decls.each do |decl|
341
- decl = decl.decl
342
- next if decl.is_a?(RBS::AST::Declarations::Module)
343
- each_reference(decl) {|name| queue << [:visit, name] }
344
- end
345
- queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
346
- end
347
- when :new
348
- decls = @cur_env.class_decls[name]
349
- yield name, decls.decls if decls
350
- end
351
- end
352
-
353
- @cur_env.interface_decls.each do |name, decl|
354
- yield name, [decl]
355
- end
356
- end
357
-
358
- def each_reference(decl, &blk)
359
- yield decl.name
360
- if decl.super_class
361
- name = decl.super_class.name
362
- else
363
- name = RBS::BuiltinNames::Object.name
364
- end
365
- return if decl.name == RBS::BuiltinNames::BasicObject.name
366
- return if decl.name == name
367
- decls = @all_env.class_decls[name]
368
- if decls
369
- decls.decls.each do |decl|
370
- each_reference(decl.decl, &blk)
371
- end
372
- end
373
- end
374
-
375
- def get_super_class(name, decls)
376
- return nil if name == RBS::BuiltinNames::BasicObject.name
377
-
378
- decls.each do |decl|
379
- decl = decl.decl
380
- case decl
381
- when RBS::AST::Declarations::Class
382
- super_class = decl.super_class
383
- return super_class.name, super_class.args if super_class
384
- when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
385
- return nil
386
- else
387
- raise "unknown declaration: %p" % decl.class
388
- end
389
- end
390
-
391
- return RBS::BuiltinNames::Object.name, []
392
- end
393
-
394
- def conv_method_def(rbs_method_types, visibility)
395
- sig_rets = rbs_method_types.map do |method_type|
396
- conv_func(method_type.type_params, method_type.type, method_type.block)
397
- end
398
- {
399
- sig_rets: sig_rets,
400
- visibility: visibility,
401
- }
402
- end
403
-
404
- def conv_func(type_params, func, block)
405
- blk = block ? conv_block(block) : nil
406
-
407
- lead_tys = func.required_positionals.map {|type| conv_type(type.type) }
408
- opt_tys = func.optional_positionals.map {|type| conv_type(type.type) }
409
- rest_ty = func.rest_positionals
410
- rest_ty = conv_type(rest_ty.type) if rest_ty
411
- opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
412
- req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
413
- rest_kw_ty = func.rest_keywords
414
- rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
415
-
416
- ret_ty = conv_type(func.return_type)
417
-
418
- {
419
- type_params: type_params,
420
- lead_tys: lead_tys,
421
- opt_tys: opt_tys,
422
- rest_ty: rest_ty,
423
- req_kw_tys: req_kw_tys,
424
- opt_kw_tys: opt_kw_tys,
425
- rest_kw_ty: rest_kw_ty,
426
- blk: blk,
427
- ret_ty: ret_ty,
428
- }
429
- end
430
-
431
- def attr_method_def(kind, name, ty, visibility)
432
- {
433
- kind: kind,
434
- ivar: name,
435
- ty: ty,
436
- visibility: visibility,
437
- }
438
- end
439
-
440
- def attr_rbs_source(member)
441
- [
442
- member.name.to_s,
443
- member.type.location.source,
444
- [member.location.name, CodeRange.from_rbs(member.location)],
445
- ]
446
- end
447
-
448
- def conv_block(rbs_block)
449
- blk = rbs_block.type
450
-
451
- lead_tys = blk.required_positionals.map {|type| conv_type(type.type) }
452
- opt_tys = blk.optional_positionals.map {|type| conv_type(type.type) }
453
- rest_ty = blk.rest_positionals
454
- rest_ty = conv_type(rest_ty.type) if rest_ty
455
- opt_kw_tys = blk.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
456
- req_kw_tys = blk.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
457
- rest_kw_ty = blk.rest_keywords
458
- rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
459
-
460
- ret_ty = conv_type(blk.return_type)
461
-
462
- {
463
- required_block: rbs_block.required,
464
- lead_tys: lead_tys,
465
- opt_tys: opt_tys,
466
- rest_ty: rest_ty,
467
- req_kw_tys: req_kw_tys,
468
- opt_kw_tys: opt_kw_tys,
469
- rest_kw_ty: rest_kw_ty,
470
- blk: blk,
471
- ret_ty: ret_ty,
472
- }
473
- end
474
-
475
- def conv_type(ty)
476
- case ty
477
- when RBS::Types::ClassSingleton
478
- [:class, conv_type_name(ty.name)]
479
- when RBS::Types::ClassInstance
480
- klass = conv_type_name(ty.name)
481
- case klass
482
- when [:Array]
483
- raise if ty.args.size != 1
484
- [:array, [:Array], [], conv_type(ty.args.first)]
485
- when [:Hash]
486
- raise if ty.args.size != 2
487
- key, val = ty.args
488
- [:hash, [:Hash], [conv_type(key), conv_type(val)]]
489
- when [:Enumerator]
490
- raise if ty.args.size != 2
491
- [:array, [:Enumerator], [], conv_type(ty.args.first)]
492
- else
493
- if ty.args.empty?
494
- [:instance, klass]
495
- else
496
- [:cell, [:instance, klass], ty.args.map {|ty| conv_type(ty) }]
497
- end
498
- end
499
- when RBS::Types::Bases::Bool then [:bool]
500
- when RBS::Types::Bases::Any then [:any]
501
- when RBS::Types::Bases::Top then [:any]
502
- when RBS::Types::Bases::Void then [:void]
503
- when RBS::Types::Bases::Self then [:self]
504
- when RBS::Types::Bases::Nil then [:nil]
505
- when RBS::Types::Bases::Bottom then [:union, []]
506
- when RBS::Types::Variable then [:var, ty.name]
507
- when RBS::Types::Tuple
508
- tys = ty.types.map {|ty2| conv_type(ty2) }
509
- [:array, [:Array], tys, [:union, []]]
510
- when RBS::Types::Literal
511
- case ty.literal
512
- when Integer then [:int]
513
- when String then [:str]
514
- when true then [:true]
515
- when false then [:false]
516
- when Symbol then [:sym, ty.literal]
517
- else
518
- p ty.literal
519
- raise NotImplementedError
520
- end
521
- when RBS::Types::Alias
522
- if @alias_resolution_stack[ty.name]
523
- [:any]
524
- else
525
- begin
526
- @alias_resolution_stack[ty.name] = true
527
- alias_decl = (@all_env.respond_to?(:alias_decls) ? @all_env.alias_decls : @all_env.type_alias_decls)[ty.name]
528
- alias_decl ? conv_type(alias_decl.decl.type) : [:any]
529
- ensure
530
- @alias_resolution_stack.delete(ty.name)
531
- end
532
- end
533
- when RBS::Types::Union
534
- [:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
535
- when RBS::Types::Intersection
536
- [:intersection, ty.types.map {|ty2| conv_type(ty2) }.compact]
537
- when RBS::Types::Optional
538
- [:optional, conv_type(ty.type)]
539
- when RBS::Types::Interface
540
- # XXX: Currently, only a few builtin interfaces are supported
541
- case ty.to_s
542
- when "::_ToS" then [:str]
543
- when "::_ToStr" then [:str]
544
- when "::_ToInt" then [:int]
545
- when "::_ToAry[U]" then [:array, [:Array], [], [:var, :U]]
546
- else
547
- [:instance, conv_type_name(ty.name)]
548
- end
549
- when RBS::Types::Bases::Instance then [:any] # XXX: not implemented yet
550
- when RBS::Types::Bases::Class then [:any] # XXX: not implemented yet
551
- when RBS::Types::Record
552
- [:hash_record, [:Hash], ty.fields.map {|key, ty| [key, conv_type(ty)] }]
553
- when RBS::Types::Proc
554
- [:proc, conv_func(nil, ty.type, nil)]
555
- else
556
- warn "unknown RBS type: %p" % ty.class
557
- [:any]
558
- end
559
- end
560
-
561
- def conv_type_name(name)
562
- name.namespace.path + [name.name]
563
- end
564
- end
565
-
566
- class Import
567
- def self.import_builtin(scratch)
568
- Import.new(scratch, scratch.rbs_reader.load_builtin).import
569
- end
570
-
571
- def self.import_library(scratch, feature)
572
- begin
573
- json = scratch.rbs_reader.load_library(feature)
574
- rescue RBS::EnvironmentLoader::UnknownLibraryError
575
- return nil
576
- rescue RBS::DuplicatedDeclarationError, RBSReader::RBSCollectionDefined
577
- return true
578
- end
579
- # need cache?
580
- Import.new(scratch, json).import
581
- end
582
-
583
- def self.import_rbs_files(scratch, rbs_paths)
584
- rbs_paths = rbs_paths.map {|rbs_path| Pathname(rbs_path) }
585
- Import.new(scratch, scratch.rbs_reader.load_paths(rbs_paths)).import(true)
586
- end
587
-
588
- def self.import_rbs_code(scratch, rbs_name, rbs_code)
589
- Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
590
- end
591
-
592
- def initialize(scratch, json)
593
- @scratch = scratch
594
- @json = json
595
- end
596
-
597
- def import(explicit = false)
598
- classes = @json[:classes].map do |classpath, cdef|
599
- type_params = cdef[:type_params]
600
- superclass, superclass_type_args = cdef[:superclass]
601
- members = cdef[:members]
602
-
603
- name = classpath.last
604
- superclass = path_to_klass(superclass) if superclass
605
- base_klass = path_to_klass(classpath[0..-2])
606
-
607
- klass, = @scratch.get_constant(base_klass, name)
608
- if klass.is_a?(Type::Any)
609
- klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
610
-
611
- # There builtin classes are needed to interpret RBS declarations
612
- case classpath
613
- when [:NilClass] then Type::Builtin[:nil] = klass
614
- when [:TrueClass] then Type::Builtin[:true] = klass
615
- when [:FalseClass] then Type::Builtin[:false] = klass
616
- when [:Integer] then Type::Builtin[:int] = klass
617
- when [:String] then Type::Builtin[:str] = klass
618
- when [:Symbol] then Type::Builtin[:sym] = klass
619
- when [:Array] then Type::Builtin[:ary] = klass
620
- when [:Hash] then Type::Builtin[:hash] = klass
621
- when [:Proc] then Type::Builtin[:proc] = klass
622
- end
623
- end
624
-
625
- [klass, superclass_type_args, members]
626
- end
627
-
628
- classes.each do |klass, superclass_type_args, members|
629
- @scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
630
- modules = members[:modules]
631
- methods = members[:methods]
632
- attr_methods = members[:attr_methods]
633
- ivars = members[:ivars]
634
- cvars = members[:cvars]
635
- rbs_sources = members[:rbs_sources]
636
-
637
- modules.each do |kind, mods|
638
- mods.each do |mod, type_args|
639
- type_args = type_args&.map {|ty| conv_type(ty) }
640
- case kind
641
- when :include
642
- @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, false, nil)
643
- when :extend
644
- @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, true, nil)
645
- when :prepend
646
- @scratch.mix_module(:before, klass, path_to_klass(mod), type_args, false, nil)
647
- end
648
- end
649
- end
650
-
651
- methods.each do |(singleton, method_name), mdef|
652
- rbs_source = explicit ? rbs_sources[[singleton, method_name]] : nil
653
- mdef = conv_method_def(method_name, mdef, rbs_source)
654
- @scratch.add_method(klass, method_name, singleton, mdef)
655
- end
656
-
657
- attr_methods.each do |(singleton, method_name), mdef|
658
- rbs_source = explicit ? rbs_sources[[singleton, method_name]] : nil
659
- ty = conv_type(mdef[:ty]).remove_type_vars
660
- mdefs = conv_attr_defs(mdef, rbs_source)
661
- mdefs.each do |mdef|
662
- @scratch.add_typed_attr_method(klass, mdef)
663
- end
664
- @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ mdef[:ivar] }", ty, nil)
665
- end
666
-
667
- ivars.each do |ivar_name, ty|
668
- ty = conv_type(ty).remove_type_vars
669
- @scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
670
- end
671
-
672
- cvars.each do |ivar_name, ty|
673
- ty = conv_type(ty).remove_type_vars
674
- @scratch.add_cvar_write!(klass, ivar_name, ty, nil)
675
- end
676
- end
677
-
678
- @json[:constants].each do |classpath, value|
679
- base_klass = path_to_klass(classpath[0..-2])
680
- value = conv_type(value).remove_type_vars
681
- @scratch.add_constant(base_klass, classpath[-1], value, nil)
682
- end
683
-
684
- @json[:globals].each do |name, ty|
685
- ty = conv_type(ty).remove_type_vars
686
- @scratch.add_gvar_write!(name, ty, nil)
687
- end
688
-
689
- true
690
- end
691
-
692
- def conv_method_def(method_name, mdef, rbs_source)
693
- sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
694
- conv_func(sig_ret)
695
- end
696
-
697
- TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
698
- end
699
-
700
- def conv_attr_defs(mdef, rbs_source)
701
- ivar = :"@#{ mdef[:ivar] }"
702
- kind = mdef[:kind]
703
- pub_meth = mdef[:visibility]
704
-
705
- defs = []
706
- if kind == :reader || kind == :accessor
707
- defs << TypedAttrMethodDef.new(ivar, :reader, pub_meth, rbs_source)
708
- end
709
- if kind == :writer || kind == :accessor
710
- defs << TypedAttrMethodDef.new(ivar, :writer, pub_meth, rbs_source)
711
- end
712
- raise if defs.empty?
713
- defs
714
- end
715
-
716
- def conv_func(sig_ret)
717
- #type_params = sig_ret[:type_params] # XXX
718
- lead_tys = sig_ret[:lead_tys]
719
- opt_tys = sig_ret[:opt_tys]
720
- rest_ty = sig_ret[:rest_ty]
721
- req_kw_tys = sig_ret[:req_kw_tys]
722
- opt_kw_tys = sig_ret[:opt_kw_tys]
723
- rest_kw_ty = sig_ret[:rest_kw_ty]
724
- blk = sig_ret[:blk]
725
- ret_ty = sig_ret[:ret_ty]
726
-
727
- lead_tys = lead_tys.map {|ty| conv_type(ty) }
728
- opt_tys = opt_tys.map {|ty| conv_type(ty) }
729
- rest_ty = conv_type(rest_ty) if rest_ty
730
- kw_tys = []
731
- req_kw_tys.each {|key, ty| kw_tys << [true, key, conv_type(ty)] }
732
- opt_kw_tys.each {|key, ty| kw_tys << [false, key, conv_type(ty)] }
733
- if rest_kw_ty
734
- ty = conv_type(rest_kw_ty)
735
- kw_rest_ty = Type.gen_hash do |h|
736
- k_ty = Type::Instance.new(Type::Builtin[:sym])
737
- h[k_ty] = ty
738
- end
739
- end
740
-
741
- blks = conv_block(blk)
742
-
743
- ret_ty = conv_type(ret_ty)
744
-
745
- blks.map do |blk|
746
- [MethodSignature.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, blk), ret_ty]
747
- end
748
- end
749
-
750
- def conv_block(blk)
751
- return [Type.nil] unless blk
752
-
753
- required_block = blk[:required_block]
754
- lead_tys = blk[:lead_tys]
755
- opt_tys = blk[:opt_tys]
756
- rest_ty = blk[:rest_ty]
757
- req_kw_tys = blk[:req_kw_tys]
758
- opt_kw_tys = blk[:opt_kw_tys]
759
- rest_kw_ty = blk[:rest_kw_ty]
760
- ret_ty = blk[:ret_ty]
761
-
762
- lead_tys = lead_tys.map {|ty| conv_type(ty) }
763
- opt_tys = opt_tys.map {|ty| conv_type(ty) }
764
- rest_ty = conv_type(rest_ty) if rest_ty
765
- kw_tys = []
766
- req_kw_tys.each {|key, ty| kw_tys << [true, key, conv_type(ty)] }
767
- opt_kw_tys.each {|key, ty| kw_tys << [false, key, conv_type(ty)] }
768
- if rest_kw_ty
769
- ty = conv_type(rest_kw_ty)
770
- kw_rest_ty = Type.gen_hash do |h|
771
- k_ty = Type::Instance.new(Type::Builtin[:sym])
772
- h[k_ty] = ty
773
- end
774
- end
775
-
776
- msig = MethodSignature.new(lead_tys, opt_tys, rest_ty, [], kw_tys, kw_rest_ty, Type.nil)
777
-
778
- ret_ty = conv_type(ret_ty)
779
-
780
- ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
781
- ret << Type.nil unless required_block
782
- ret
783
- end
784
-
785
- def conv_type(ty)
786
- case ty.first
787
- when :class then path_to_klass(ty[1])
788
- when :instance then Type::Instance.new(path_to_klass(ty[1]))
789
- when :cell
790
- Type::Cell.new(Type::Cell::Elements.new(ty[2].map {|ty| conv_type(ty) }), conv_type(ty[1]))
791
- when :any then Type.any
792
- when :void then Type::Void.new
793
- when :nil then Type.nil
794
- when :optional then Type.optional(conv_type(ty[1]))
795
- when :bool then Type.bool
796
- when :self then Type::Var.new(:self)
797
- when :int then Type::Instance.new(Type::Builtin[:int])
798
- when :str then Type::Instance.new(Type::Builtin[:str])
799
- when :sym then Type::Symbol.new(ty.last, Type::Instance.new(Type::Builtin[:sym]))
800
- when :true then Type::Instance.new(Type::Builtin[:true])
801
- when :false then Type::Instance.new(Type::Builtin[:false])
802
- when :array
803
- _, path, lead_tys, rest_ty = ty
804
- lead_tys = lead_tys.map {|ty| conv_type(ty) }
805
- rest_ty = conv_type(rest_ty)
806
- base_type = Type::Instance.new(path_to_klass(path))
807
- Type::Array.new(Type::Array::Elements.new(lead_tys, rest_ty), base_type)
808
- when :hash
809
- _, path, (k, v) = ty
810
- Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
811
- k_ty = conv_type(k)
812
- v_ty = conv_type(v)
813
- h[k_ty] = v_ty
814
- end
815
- when :hash_record
816
- _, path, key_tys = ty
817
- Type.gen_hash(Type::Instance.new(path_to_klass(path))) do |h|
818
- key_tys.each do |key, ty|
819
- k_ty = Type::Symbol.new(key, Type::Instance.new(Type::Builtin[:sym]))
820
- v_ty = conv_type(ty)
821
- h[k_ty] = v_ty
822
- end
823
- end
824
- when :union
825
- tys = ty[1]
826
- Type::Union.create(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # XXX: Array and Hash support
827
- when :intersection
828
- tys = ty[1]
829
- conv_type(tys.first) # XXX: This is wrong! We need to support intersection type
830
- when :var
831
- Type::Var.new(ty[1])
832
- when :proc
833
- msig, ret_ty = conv_func(ty[1]).first # Currently, RBS Proc does not accept a block, so the size should be always one
834
- Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Instance.new(Type::Builtin[:proc]))
835
- else
836
- pp ty
837
- raise NotImplementedError
838
- end
839
- end
840
-
841
- def path_to_klass(path)
842
- klass = Type::Builtin[:obj]
843
- path.each do |name|
844
- klass, = @scratch.get_constant(klass, name)
845
- if klass == Type.any
846
- raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
847
- end
848
- end
849
- klass
850
- end
851
- end
852
- end