typeprof 0.21.11 → 0.30.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.
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