rbs 3.2.2 → 3.3.0.pre.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/comments.yml +1 -1
- data/.github/workflows/ruby.yml +7 -2
- data/CHANGELOG.md +85 -0
- data/Gemfile.lock +14 -14
- data/README.md +11 -2
- data/Rakefile +10 -7
- data/Steepfile +7 -7
- data/core/basic_object.rbs +7 -7
- data/core/binding.rbs +3 -3
- data/core/builtin.rbs +171 -5
- data/core/constants.rbs +17 -17
- data/core/dir.rbs +3 -3
- data/core/encoding.rbs +434 -628
- data/core/enumerator.rbs +37 -0
- data/core/exception.rbs +11 -11
- data/core/false_class.rbs +5 -11
- data/core/fiber.rbs +3 -3
- data/core/file_test.rbs +28 -26
- data/core/kernel.rbs +900 -21
- data/core/marshal.rbs +24 -14
- data/core/match_data.rbs +8 -8
- data/core/math.rbs +57 -53
- data/core/method.rbs +3 -1
- data/core/module.rbs +38 -36
- data/core/nil_class.rbs +7 -13
- data/core/object.rbs +3 -966
- data/core/process.rbs +3 -3
- data/core/ractor.rbs +2 -2
- data/core/rb_config.rbs +64 -43
- data/core/regexp.rbs +3 -3
- data/core/signal.rbs +10 -4
- data/core/struct.rbs +1 -1
- data/core/thread.rbs +7 -7
- data/core/thread_group.rbs +9 -9
- data/core/true_class.rbs +5 -11
- data/core/unbound_method.rbs +56 -7
- data/core/warning.rbs +33 -0
- data/docs/collection.md +56 -6
- data/docs/data_and_struct.md +57 -0
- data/docs/stdlib.md +61 -2
- data/docs/syntax.md +123 -2
- data/ext/rbs_extension/lexer.c +624 -569
- data/ext/rbs_extension/lexer.h +1 -0
- data/ext/rbs_extension/lexer.re +1 -0
- data/ext/rbs_extension/lexstate.c +1 -0
- data/ext/rbs_extension/parser.c +6 -0
- data/goodcheck.yml +2 -2
- data/lib/rbs/annotate/formatter.rb +13 -3
- data/lib/rbs/annotate/rdoc_source.rb +10 -1
- data/lib/rbs/cli/colored_io.rb +48 -0
- data/lib/rbs/cli/diff.rb +80 -0
- data/lib/rbs/cli.rb +151 -16
- data/lib/rbs/collection/config/lockfile.rb +0 -25
- data/lib/rbs/collection/config/lockfile_generator.rb +0 -6
- data/lib/rbs/collection/installer.rb +1 -1
- data/lib/rbs/collection/sources/git.rb +6 -4
- data/lib/rbs/collection/sources/local.rb +7 -5
- data/lib/rbs/diff.rb +104 -0
- data/lib/rbs/environment.rb +1 -1
- data/lib/rbs/method_type.rb +23 -0
- data/lib/rbs/prototype/rb.rb +2 -9
- data/lib/rbs/prototype/runtime/helpers.rb +59 -0
- data/lib/rbs/prototype/runtime/value_object_generator.rb +236 -0
- data/lib/rbs/prototype/runtime.rb +234 -150
- data/lib/rbs/sorter.rb +144 -117
- data/lib/rbs/test/guaranteed.rb +31 -0
- data/lib/rbs/test/type_check.rb +4 -4
- data/lib/rbs/test.rb +3 -0
- data/lib/rbs/types.rb +184 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +4 -4
- data/lib/rbs.rb +1 -0
- data/rbs.gemspec +1 -0
- data/sig/annotate/formatter.rbs +2 -2
- data/sig/annotate/rdoc_annotater.rbs +1 -1
- data/sig/cli/colored_io.rbs +15 -0
- data/sig/cli/diff.rbs +21 -0
- data/sig/cli.rbs +2 -0
- data/sig/collection/config/lockfile.rbs +0 -6
- data/sig/diff.rbs +23 -0
- data/sig/errors.rbs +1 -5
- data/sig/method_types.rbs +6 -0
- data/sig/prototype/runtime.rbs +108 -0
- data/sig/rdoc/rbs.rbs +4 -0
- data/sig/shims/bundler.rbs +5 -0
- data/sig/sorter.rbs +23 -5
- data/sig/types.rbs +29 -0
- data/stdlib/benchmark/0/benchmark.rbs +1 -1
- data/stdlib/cgi/0/core.rbs +2 -2
- data/stdlib/did_you_mean/0/did_you_mean.rbs +2 -2
- data/stdlib/digest/0/digest.rbs +1 -1
- data/stdlib/fileutils/0/fileutils.rbs +1 -1
- data/stdlib/forwardable/0/forwardable.rbs +4 -4
- data/stdlib/io-console/0/io-console.rbs +1 -1
- data/stdlib/json/0/json.rbs +37 -0
- data/stdlib/logger/0/logger.rbs +2 -2
- data/stdlib/net-http/0/manifest.yaml +1 -1
- data/stdlib/net-http/0/net-http.rbs +16 -63
- data/stdlib/net-protocol/0/manifest.yaml +2 -0
- data/stdlib/net-protocol/0/net-protocol.rbs +56 -0
- data/stdlib/openssl/0/openssl.rbs +1 -1
- data/stdlib/pp/0/manifest.yaml +2 -0
- data/stdlib/pp/0/pp.rbs +301 -0
- data/stdlib/{yaml → psych}/0/dbm.rbs +3 -3
- data/stdlib/psych/0/manifest.yaml +3 -0
- data/stdlib/psych/0/psych.rbs +391 -0
- data/stdlib/{yaml → psych}/0/store.rbs +2 -2
- data/stdlib/rdoc/0/code_object.rbs +55 -0
- data/stdlib/rdoc/0/comment.rbs +60 -0
- data/stdlib/rdoc/0/context.rbs +153 -0
- data/stdlib/rdoc/0/markup.rbs +119 -0
- data/stdlib/rdoc/0/parser.rbs +56 -0
- data/stdlib/rdoc/0/rdoc.rbs +0 -372
- data/stdlib/rdoc/0/ri.rbs +17 -0
- data/stdlib/rdoc/0/store.rbs +48 -0
- data/stdlib/rdoc/0/top_level.rbs +97 -0
- data/stdlib/socket/0/basic_socket.rbs +1 -1
- data/stdlib/socket/0/socket.rbs +1 -1
- data/stdlib/uri/0/common.rbs +1 -1
- data/stdlib/yaml/0/manifest.yaml +1 -2
- data/stdlib/yaml/0/yaml.rbs +1 -199
- metadata +46 -9
- data/sig/shims/pp.rbs +0 -3
- data/sig/shims.rbs +0 -47
@@ -1,26 +1,82 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'runtime/helpers'
|
4
|
+
require_relative 'runtime/value_object_generator'
|
5
|
+
|
3
6
|
module RBS
|
4
7
|
module Prototype
|
5
8
|
class Runtime
|
6
|
-
|
9
|
+
class Todo
|
10
|
+
def initialize(builder:)
|
11
|
+
@builder = builder
|
12
|
+
end
|
13
|
+
|
14
|
+
def skip_mixin?(type_name:, module_name:, mixin_class:)
|
15
|
+
return false unless @builder.env.module_class_entry(type_name.absolute!)
|
16
|
+
return false unless @builder.env.module_class_entry(module_name.absolute!)
|
17
|
+
|
18
|
+
mixin_decls(type_name).any? do |decl|
|
19
|
+
decl.instance_of?(mixin_class) && decl.name == module_name.absolute!
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def skip_singleton_method?(module_name:, method:, accessibility:)
|
24
|
+
return false unless @builder.env.module_class_entry(module_name.absolute!)
|
25
|
+
|
26
|
+
method_definition = @builder.build_singleton(module_name.absolute!).methods[method.name]
|
27
|
+
return false unless method_definition
|
28
|
+
|
29
|
+
method_definition.accessibility == accessibility
|
30
|
+
end
|
31
|
+
|
32
|
+
def skip_instance_method?(module_name:, method:, accessibility:)
|
33
|
+
return false unless @builder.env.module_class_entry(module_name.absolute!)
|
34
|
+
|
35
|
+
method_definition = @builder.build_instance(module_name.absolute!).methods[method.name]
|
36
|
+
return false unless method_definition
|
37
|
+
|
38
|
+
method_definition.accessibility == accessibility
|
39
|
+
end
|
40
|
+
|
41
|
+
def skip_constant?(module_name:, name:)
|
42
|
+
namespace = Namespace.new(path: module_name.split('::').map(&:to_sym), absolute: true)
|
43
|
+
@builder.env.constant_decl?(TypeName.new(namespace: namespace, name: name))
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def mixin_decls(type_name)
|
49
|
+
type_name_absolute = type_name.absolute!
|
50
|
+
(@mixin_decls_cache ||= {}).fetch(type_name_absolute) do
|
51
|
+
@mixin_decls_cache[type_name_absolute] = @builder.env.class_decls[type_name_absolute].decls.flat_map do |d|
|
52
|
+
d.decl.members.select { |m| m.kind_of?(AST::Members::Mixin) }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
private_constant :Todo
|
58
|
+
|
59
|
+
include Prototype::Helpers
|
60
|
+
include Runtime::Helpers
|
7
61
|
|
8
62
|
attr_reader :patterns
|
9
63
|
attr_reader :env
|
10
64
|
attr_reader :merge
|
65
|
+
attr_reader :todo
|
11
66
|
attr_reader :owners_included
|
12
67
|
attr_accessor :outline
|
13
68
|
|
14
|
-
def initialize(patterns:, env:, merge:, owners_included: [])
|
69
|
+
def initialize(patterns:, env:, merge:, todo: false, owners_included: [])
|
15
70
|
@patterns = patterns
|
16
71
|
@decls = nil
|
17
|
-
@modules =
|
72
|
+
@modules = {}
|
18
73
|
@env = env
|
19
74
|
@merge = merge
|
20
75
|
@owners_included = owners_included.map do |name|
|
21
76
|
Object.const_get(name)
|
22
77
|
end
|
23
78
|
@outline = false
|
79
|
+
@todo = todo
|
24
80
|
end
|
25
81
|
|
26
82
|
def target?(const)
|
@@ -36,6 +92,10 @@ module RBS
|
|
36
92
|
end
|
37
93
|
end
|
38
94
|
|
95
|
+
def todo_object
|
96
|
+
@todo_object ||= Todo.new(builder: builder) if todo
|
97
|
+
end
|
98
|
+
|
39
99
|
def builder
|
40
100
|
@builder ||= DefinitionBuilder.new(env: env)
|
41
101
|
end
|
@@ -47,8 +107,11 @@ module RBS
|
|
47
107
|
def decls
|
48
108
|
unless @decls
|
49
109
|
@decls = []
|
50
|
-
@modules = ObjectSpace.each_object(Module)
|
51
|
-
|
110
|
+
@modules = ObjectSpace.each_object(Module)
|
111
|
+
.map { |mod| [const_name(mod), mod] }
|
112
|
+
.select { |name, _| name }
|
113
|
+
.to_h
|
114
|
+
@modules.select { |name, mod| target?(mod) }.sort_by { |name, _| name }.each do |_, mod|
|
52
115
|
case mod
|
53
116
|
when Class
|
54
117
|
generate_class mod
|
@@ -58,48 +121,46 @@ module RBS
|
|
58
121
|
end
|
59
122
|
end
|
60
123
|
|
61
|
-
@decls
|
124
|
+
@decls or raise
|
62
125
|
end
|
63
126
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
else
|
71
|
-
TypeName.new(name: last.to_sym, namespace: Namespace.parse(prefix.join("::")))
|
72
|
-
end
|
73
|
-
else
|
74
|
-
TypeName.new(name: last.to_sym, namespace: Namespace.empty)
|
127
|
+
private def each_mixined_module(type_name, mod)
|
128
|
+
each_mixined_module_one(type_name, mod) do |module_name, module_full_name, is_prepend|
|
129
|
+
yield module_name, module_full_name, is_prepend ? AST::Members::Prepend : AST::Members::Include
|
130
|
+
end
|
131
|
+
each_mixined_module_one(type_name, mod.singleton_class) do |module_name, module_full_name, _|
|
132
|
+
yield module_name, module_full_name, AST::Members::Extend
|
75
133
|
end
|
76
134
|
end
|
77
135
|
|
78
|
-
def
|
79
|
-
supers = Set[]
|
136
|
+
private def each_mixined_module_one(type_name, mod)
|
137
|
+
supers = Set[] #: Set[Module]
|
138
|
+
prepends = mod.ancestors.take_while { |m| !mod.equal?(m) }.to_set
|
80
139
|
|
81
140
|
mod.included_modules.each do |mix|
|
82
141
|
supers.merge(mix.included_modules)
|
83
142
|
end
|
84
143
|
|
85
|
-
if mod.is_a?(Class)
|
86
|
-
mod.superclass
|
87
|
-
|
88
|
-
|
144
|
+
if mod.is_a?(Class)
|
145
|
+
if superclass = mod.superclass
|
146
|
+
superclass.included_modules.each do |mix|
|
147
|
+
supers << mix
|
148
|
+
supers.merge(mix.included_modules)
|
149
|
+
end
|
89
150
|
end
|
90
151
|
end
|
91
152
|
|
92
|
-
mod.included_modules.each do |mix|
|
93
|
-
|
153
|
+
mod.included_modules.uniq.each do |mix|
|
154
|
+
if !supers.include?(mix) || prepends.include?(mix)
|
94
155
|
unless const_name(mix)
|
95
156
|
RBS.logger.warn("Skipping anonymous module #{mix} included in #{mod}")
|
96
157
|
else
|
97
|
-
module_name = module_full_name = to_type_name(const_name(mix), full_name: true)
|
158
|
+
module_name = module_full_name = to_type_name(const_name!(mix), full_name: true)
|
98
159
|
if module_full_name.namespace == type_name.namespace
|
99
160
|
module_name = TypeName.new(name: module_full_name.name, namespace: Namespace.empty)
|
100
161
|
end
|
101
162
|
|
102
|
-
yield module_name, module_full_name, mix
|
163
|
+
yield module_name, module_full_name, prepends.include?(mix)
|
103
164
|
end
|
104
165
|
end
|
105
166
|
end
|
@@ -108,19 +169,19 @@ module RBS
|
|
108
169
|
def method_type(method)
|
109
170
|
untyped = Types::Bases::Any.new(location: nil)
|
110
171
|
|
111
|
-
required_positionals = []
|
112
|
-
optional_positionals = []
|
113
|
-
rest = nil
|
114
|
-
trailing_positionals = []
|
115
|
-
required_keywords = {}
|
116
|
-
optional_keywords = {}
|
117
|
-
rest_keywords = nil
|
172
|
+
required_positionals = [] #: Array[Types::Function::Param]
|
173
|
+
optional_positionals = [] #: Array[Types::Function::Param]
|
174
|
+
rest = nil #: Types::Function::Param?
|
175
|
+
trailing_positionals = [] #: Array[Types::Function::Param]
|
176
|
+
required_keywords = {} #: Hash[Symbol, Types::Function::Param]
|
177
|
+
optional_keywords = {} #: Hash[Symbol, Types::Function::Param]
|
178
|
+
rest_keywords = nil #: Types::Function::Param?
|
118
179
|
|
119
180
|
requireds = required_positionals
|
120
181
|
|
121
|
-
block = nil
|
182
|
+
block = nil #: Types::Block?
|
122
183
|
|
123
|
-
method.parameters.each do |kind, name|
|
184
|
+
method.parameters.each do |(kind, name)|
|
124
185
|
case kind
|
125
186
|
when :req
|
126
187
|
requireds << Types::Function::Param.new(name: name, type: untyped)
|
@@ -132,8 +193,10 @@ module RBS
|
|
132
193
|
name = nil if name == :* # For `def f(...) end` syntax
|
133
194
|
rest = Types::Function::Param.new(name: name, type: untyped)
|
134
195
|
when :keyreq
|
196
|
+
name or raise
|
135
197
|
required_keywords[name] = Types::Function::Param.new(name: nil, type: untyped)
|
136
198
|
when :key
|
199
|
+
name or raise
|
137
200
|
optional_keywords[name] = Types::Function::Param.new(name: nil, type: untyped)
|
138
201
|
when :keyrest
|
139
202
|
rest_keywords = Types::Function::Param.new(name: nil, type: untyped)
|
@@ -175,6 +238,7 @@ module RBS
|
|
175
238
|
def merge_rbs(module_name, members, instance: nil, singleton: nil)
|
176
239
|
if merge
|
177
240
|
if env.class_decls[module_name.absolute!]
|
241
|
+
# @type var kind: AST::Members::MethodDefinition::kind
|
178
242
|
case
|
179
243
|
when instance
|
180
244
|
method = builder.build_instance(module_name.absolute!).methods[instance]
|
@@ -194,6 +258,7 @@ module RBS
|
|
194
258
|
annotations: [],
|
195
259
|
method_type: type.update.tap do |ty|
|
196
260
|
def ty.to_s
|
261
|
+
location or raise
|
197
262
|
location.source
|
198
263
|
end
|
199
264
|
end
|
@@ -224,14 +289,27 @@ module RBS
|
|
224
289
|
when singleton
|
225
290
|
method = mod.singleton_class.instance_method(singleton)
|
226
291
|
method.owner == mod.singleton_class || owners_included.any? {|m| method.owner == m.singleton_class }
|
292
|
+
else
|
293
|
+
raise
|
227
294
|
end
|
228
295
|
end
|
229
296
|
|
230
297
|
def generate_methods(mod, module_name, members)
|
298
|
+
module_name_absolute = to_type_name(const_name!(mod), full_name: true).absolute!
|
231
299
|
mod.singleton_methods.select {|name| target_method?(mod, singleton: name) }.sort.each do |name|
|
232
300
|
method = mod.singleton_class.instance_method(name)
|
301
|
+
next if todo_object&.skip_singleton_method?(module_name: module_name_absolute, method: method, accessibility: :public)
|
233
302
|
|
234
|
-
if
|
303
|
+
if can_alias?(mod.singleton_class, method)
|
304
|
+
members << AST::Members::Alias.new(
|
305
|
+
new_name: method.name,
|
306
|
+
old_name: method.original_name,
|
307
|
+
kind: :singleton,
|
308
|
+
location: nil,
|
309
|
+
comment: nil,
|
310
|
+
annotations: [],
|
311
|
+
)
|
312
|
+
else
|
235
313
|
merge_rbs(module_name, members, singleton: name) do
|
236
314
|
RBS.logger.info "missing #{module_name}.#{name} #{method.source_location}"
|
237
315
|
|
@@ -248,15 +326,6 @@ module RBS
|
|
248
326
|
visibility: nil
|
249
327
|
)
|
250
328
|
end
|
251
|
-
else
|
252
|
-
members << AST::Members::Alias.new(
|
253
|
-
new_name: method.name,
|
254
|
-
old_name: method.original_name,
|
255
|
-
kind: :singleton,
|
256
|
-
location: nil,
|
257
|
-
comment: nil,
|
258
|
-
annotations: [],
|
259
|
-
)
|
260
329
|
end
|
261
330
|
end
|
262
331
|
|
@@ -266,8 +335,18 @@ module RBS
|
|
266
335
|
|
267
336
|
public_instance_methods.sort.each do |name|
|
268
337
|
method = mod.instance_method(name)
|
338
|
+
next if todo_object&.skip_instance_method?(module_name: module_name_absolute, method: method, accessibility: :public)
|
269
339
|
|
270
|
-
if
|
340
|
+
if can_alias?(mod, method)
|
341
|
+
members << AST::Members::Alias.new(
|
342
|
+
new_name: method.name,
|
343
|
+
old_name: method.original_name,
|
344
|
+
kind: :instance,
|
345
|
+
location: nil,
|
346
|
+
comment: nil,
|
347
|
+
annotations: [],
|
348
|
+
)
|
349
|
+
else
|
271
350
|
merge_rbs(module_name, members, instance: name) do
|
272
351
|
RBS.logger.info "missing #{module_name}##{name} #{method.source_location}"
|
273
352
|
|
@@ -284,27 +363,30 @@ module RBS
|
|
284
363
|
visibility: nil
|
285
364
|
)
|
286
365
|
end
|
287
|
-
else
|
288
|
-
members << AST::Members::Alias.new(
|
289
|
-
new_name: method.name,
|
290
|
-
old_name: method.original_name,
|
291
|
-
kind: :instance,
|
292
|
-
location: nil,
|
293
|
-
comment: nil,
|
294
|
-
annotations: [],
|
295
|
-
)
|
296
366
|
end
|
297
367
|
end
|
298
368
|
end
|
299
369
|
|
300
370
|
private_instance_methods = mod.private_instance_methods.select {|name| target_method?(mod, instance: name) }
|
301
371
|
unless private_instance_methods.empty?
|
372
|
+
added = false
|
302
373
|
members << AST::Members::Private.new(location: nil)
|
303
374
|
|
304
375
|
private_instance_methods.sort.each do |name|
|
305
376
|
method = mod.instance_method(name)
|
377
|
+
next if todo_object&.skip_instance_method?(module_name: module_name_absolute, method: method, accessibility: :private)
|
306
378
|
|
307
|
-
|
379
|
+
added = true
|
380
|
+
if can_alias?(mod, method)
|
381
|
+
members << AST::Members::Alias.new(
|
382
|
+
new_name: method.name,
|
383
|
+
old_name: method.original_name,
|
384
|
+
kind: :instance,
|
385
|
+
location: nil,
|
386
|
+
comment: nil,
|
387
|
+
annotations: [],
|
388
|
+
)
|
389
|
+
else
|
308
390
|
merge_rbs(module_name, members, instance: name) do
|
309
391
|
RBS.logger.info "missing #{module_name}##{name} #{method.source_location}"
|
310
392
|
|
@@ -321,22 +403,28 @@ module RBS
|
|
321
403
|
visibility: nil
|
322
404
|
)
|
323
405
|
end
|
324
|
-
else
|
325
|
-
members << AST::Members::Alias.new(
|
326
|
-
new_name: method.name,
|
327
|
-
old_name: method.original_name,
|
328
|
-
kind: :instance,
|
329
|
-
location: nil,
|
330
|
-
comment: nil,
|
331
|
-
annotations: [],
|
332
|
-
)
|
333
406
|
end
|
334
407
|
end
|
408
|
+
|
409
|
+
members.pop unless added
|
410
|
+
end
|
411
|
+
end
|
412
|
+
|
413
|
+
private def can_alias?(mod, method)
|
414
|
+
return false if method.name == method.original_name
|
415
|
+
|
416
|
+
begin
|
417
|
+
mod.instance_method(method.original_name) && true
|
418
|
+
rescue NameError
|
419
|
+
false
|
335
420
|
end
|
336
421
|
end
|
337
422
|
|
338
423
|
def generate_constants(mod, decls)
|
424
|
+
module_name = const_name!(mod)
|
339
425
|
mod.constants(false).sort.each do |name|
|
426
|
+
next if todo_object&.skip_constant?(module_name: module_name, name: name)
|
427
|
+
|
340
428
|
begin
|
341
429
|
value = mod.const_get(name)
|
342
430
|
rescue StandardError, LoadError => e
|
@@ -344,8 +432,10 @@ module RBS
|
|
344
432
|
next
|
345
433
|
end
|
346
434
|
|
347
|
-
next if value.
|
348
|
-
|
435
|
+
next if object_class(value).equal?(Class)
|
436
|
+
next if object_class(value).equal?(Module)
|
437
|
+
|
438
|
+
unless object_class(value).name
|
349
439
|
RBS.logger.warn("Skipping constant #{name} #{value} of #{mod} as an instance of anonymous class")
|
350
440
|
next
|
351
441
|
end
|
@@ -358,8 +448,12 @@ module RBS
|
|
358
448
|
type: Types::Bases::Any.new(location: nil),
|
359
449
|
location: nil
|
360
450
|
)
|
451
|
+
when ARGF
|
452
|
+
Types::ClassInstance.new(name: TypeName("::RBS::Unnamed::ARGFClass"), args: [], location: nil)
|
453
|
+
when ENV
|
454
|
+
Types::ClassInstance.new(name: TypeName("::RBS::Unnamed::ENVClass"), args: [], location: nil)
|
361
455
|
else
|
362
|
-
value_type_name = to_type_name(const_name(value
|
456
|
+
value_type_name = to_type_name(const_name!(object_class(value)), full_name: true).absolute!
|
363
457
|
args = type_args(value_type_name)
|
364
458
|
Types::ClassInstance.new(name: value_type_name, args: args, location: nil)
|
365
459
|
end
|
@@ -374,62 +468,56 @@ module RBS
|
|
374
468
|
end
|
375
469
|
|
376
470
|
def generate_super_class(mod)
|
377
|
-
|
471
|
+
superclass = mod.superclass
|
472
|
+
|
473
|
+
if superclass.nil? || superclass == ::Object
|
378
474
|
nil
|
379
|
-
elsif const_name(
|
380
|
-
RBS.logger.warn("Skipping anonymous superclass #{
|
475
|
+
elsif const_name(superclass).nil?
|
476
|
+
RBS.logger.warn("Skipping anonymous superclass #{superclass} of #{mod}")
|
381
477
|
nil
|
382
478
|
else
|
383
|
-
super_name = to_type_name(const_name(
|
479
|
+
super_name = to_type_name(const_name!(superclass), full_name: true).absolute!
|
384
480
|
super_args = type_args(super_name)
|
385
481
|
AST::Declarations::Class::Super.new(name: super_name, args: super_args, location: nil)
|
386
482
|
end
|
387
483
|
end
|
388
484
|
|
389
485
|
def generate_class(mod)
|
390
|
-
|
486
|
+
type_name_absolute = to_type_name(const_name!(mod), full_name: true).absolute!
|
487
|
+
type_name = to_type_name(const_name!(mod))
|
391
488
|
outer_decls = ensure_outer_module_declarations(mod)
|
392
489
|
|
393
490
|
# Check if a declaration exists for the actual module
|
394
|
-
decl = outer_decls.detect
|
491
|
+
decl = outer_decls.detect do |decl|
|
492
|
+
decl.is_a?(AST::Declarations::Class) && decl.name.name == only_name(mod).to_sym
|
493
|
+
end #: AST::Declarations::Class?
|
494
|
+
|
395
495
|
unless decl
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
496
|
+
if mod < Struct
|
497
|
+
decl = StructGenerator.new(mod).build_decl
|
498
|
+
elsif RUBY_VERSION >= '3.2' && mod < Data
|
499
|
+
decl = DataGenerator.new(mod).build_decl
|
500
|
+
else
|
501
|
+
decl = AST::Declarations::Class.new(
|
502
|
+
name: to_type_name(only_name(mod)),
|
503
|
+
type_params: type_params(mod),
|
504
|
+
super_class: generate_super_class(mod),
|
505
|
+
members: [],
|
506
|
+
annotations: [],
|
507
|
+
location: nil,
|
508
|
+
comment: nil
|
509
|
+
)
|
510
|
+
end
|
405
511
|
|
406
512
|
outer_decls << decl
|
407
513
|
end
|
408
514
|
|
409
|
-
|
410
|
-
args = type_args(module_full_name)
|
411
|
-
decl.members << AST::Members::Include.new(
|
412
|
-
name: module_name,
|
413
|
-
args: args,
|
414
|
-
location: nil,
|
415
|
-
comment: nil,
|
416
|
-
annotations: []
|
417
|
-
)
|
418
|
-
end
|
515
|
+
generate_mixin(mod, decl, type_name, type_name_absolute)
|
419
516
|
|
420
|
-
|
421
|
-
|
422
|
-
decl.members << AST::Members::Extend.new(
|
423
|
-
name: module_name,
|
424
|
-
args: args,
|
425
|
-
location: nil,
|
426
|
-
comment: nil,
|
427
|
-
annotations: []
|
428
|
-
)
|
517
|
+
unless mod < Struct || (RUBY_VERSION >= '3.2' && mod < Data)
|
518
|
+
generate_methods(mod, type_name, decl.members) unless outline
|
429
519
|
end
|
430
520
|
|
431
|
-
generate_methods(mod, type_name, decl.members) unless outline
|
432
|
-
|
433
521
|
generate_constants mod, decl.members
|
434
522
|
end
|
435
523
|
|
@@ -441,11 +529,15 @@ module RBS
|
|
441
529
|
return
|
442
530
|
end
|
443
531
|
|
532
|
+
type_name_absolute = to_type_name(name, full_name: true).absolute!
|
444
533
|
type_name = to_type_name(name)
|
445
534
|
outer_decls = ensure_outer_module_declarations(mod)
|
446
535
|
|
447
536
|
# Check if a declaration exists for the actual class
|
448
|
-
decl = outer_decls.detect
|
537
|
+
decl = outer_decls.detect do |decl|
|
538
|
+
decl.is_a?(AST::Declarations::Module) && decl.name.name == only_name(mod).to_sym
|
539
|
+
end #: AST::Declarations::Module?
|
540
|
+
|
449
541
|
unless decl
|
450
542
|
decl = AST::Declarations::Module.new(
|
451
543
|
name: to_type_name(only_name(mod)),
|
@@ -460,20 +552,19 @@ module RBS
|
|
460
552
|
outer_decls << decl
|
461
553
|
end
|
462
554
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
555
|
+
generate_mixin(mod, decl, type_name, type_name_absolute)
|
556
|
+
|
557
|
+
generate_methods(mod, type_name, decl.members) unless outline
|
558
|
+
|
559
|
+
generate_constants mod, decl.members
|
560
|
+
end
|
561
|
+
|
562
|
+
def generate_mixin(mod, decl, type_name, type_name_absolute)
|
563
|
+
each_mixined_module(type_name, mod) do |module_name, module_full_name, mixin_class|
|
564
|
+
next if todo_object&.skip_mixin?(type_name: type_name_absolute, module_name: module_full_name, mixin_class: mixin_class)
|
473
565
|
|
474
|
-
each_included_module(type_name, mod.singleton_class) do |module_name, module_full_name, _|
|
475
566
|
args = type_args(module_full_name)
|
476
|
-
decl.members <<
|
567
|
+
decl.members << mixin_class.new(
|
477
568
|
name: module_name,
|
478
569
|
args: args,
|
479
570
|
location: nil,
|
@@ -481,26 +572,33 @@ module RBS
|
|
481
572
|
annotations: []
|
482
573
|
)
|
483
574
|
end
|
484
|
-
|
485
|
-
generate_methods(mod, type_name, decl.members) unless outline
|
486
|
-
|
487
|
-
generate_constants mod, decl.members
|
488
575
|
end
|
489
576
|
|
490
577
|
# Generate/find outer module declarations
|
491
578
|
# This is broken down into another method to comply with `DRY`
|
492
579
|
# This generates/finds declarations in nested form & returns the last array of declarations
|
493
580
|
def ensure_outer_module_declarations(mod)
|
494
|
-
|
495
|
-
|
581
|
+
# @type var outer_module_names: Array[String]
|
582
|
+
*outer_module_names, _ = const_name!(mod).split(/::/) #=> parent = [A, B], mod = C
|
583
|
+
# Copy the entries in ivar @decls, not .dup
|
584
|
+
destination = @decls || [] #: Array[AST::Declarations::Class::member]
|
496
585
|
|
497
586
|
outer_module_names&.each_with_index do |outer_module_name, i|
|
498
|
-
current_name = outer_module_names
|
499
|
-
outer_module = @modules
|
500
|
-
outer_decl = destination.detect
|
587
|
+
current_name = outer_module_names.take(i+1).join('::')
|
588
|
+
outer_module = @modules[current_name]
|
589
|
+
outer_decl = destination.detect do |decl|
|
590
|
+
case outer_module
|
591
|
+
when Class
|
592
|
+
decl.is_a?(AST::Declarations::Class) && decl.name.name == outer_module_name.to_sym
|
593
|
+
when Module
|
594
|
+
decl.is_a?(AST::Declarations::Module) && decl.name.name == outer_module_name.to_sym
|
595
|
+
end
|
596
|
+
end #: AST::Declarations::Class | AST::Declarations::Module | nil
|
501
597
|
|
502
598
|
# Insert AST::Declarations if declarations are not added previously
|
503
599
|
unless outer_decl
|
600
|
+
outer_module or raise
|
601
|
+
|
504
602
|
if outer_module.is_a?(Class)
|
505
603
|
outer_decl = AST::Declarations::Class.new(
|
506
604
|
name: to_type_name(outer_module_name),
|
@@ -533,37 +631,21 @@ module RBS
|
|
533
631
|
destination
|
534
632
|
end
|
535
633
|
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
const_name(mod).split(/::/).last # (A::B::C) => C
|
540
|
-
end
|
541
|
-
|
542
|
-
def const_name(const)
|
543
|
-
@module_name_method ||= Module.instance_method(:name)
|
544
|
-
name = @module_name_method.bind(const).call
|
545
|
-
return nil unless name
|
546
|
-
|
547
|
-
begin
|
548
|
-
Object.const_get(name)
|
549
|
-
rescue NameError
|
550
|
-
# Should generate const name if anonymous or internal module (e.g. NameError::message)
|
551
|
-
nil
|
552
|
-
else
|
553
|
-
name
|
554
|
-
end
|
634
|
+
def object_class(value)
|
635
|
+
@object_class ||= Object.instance_method(:class)
|
636
|
+
@object_class.bind_call(value)
|
555
637
|
end
|
556
638
|
|
557
639
|
def type_args(type_name)
|
558
|
-
if class_decl = env.class_decls
|
559
|
-
class_decl.type_params.size.times.map { :
|
640
|
+
if class_decl = env.class_decls.fetch(type_name.absolute!, nil)
|
641
|
+
class_decl.type_params.size.times.map { Types::Bases::Any.new(location: nil) }
|
560
642
|
else
|
561
643
|
[]
|
562
644
|
end
|
563
645
|
end
|
564
646
|
|
565
647
|
def type_params(mod)
|
566
|
-
type_name = to_type_name(const_name(mod), full_name: true)
|
648
|
+
type_name = to_type_name(const_name!(mod), full_name: true)
|
567
649
|
if class_decl = env.class_decls[type_name.absolute!]
|
568
650
|
class_decl.type_params
|
569
651
|
else
|
@@ -580,7 +662,9 @@ module RBS
|
|
580
662
|
return # When the method is defined in eval
|
581
663
|
end
|
582
664
|
|
583
|
-
|
665
|
+
if ast && ast.type == :SCOPE
|
666
|
+
block_from_body(ast)
|
667
|
+
end
|
584
668
|
end
|
585
669
|
end
|
586
670
|
end
|