rbs 0.18.1 → 1.0.0.pre2
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/CHANGELOG.md +31 -0
- data/Rakefile +12 -0
- data/Steepfile +2 -1
- data/bin/annotate-with-rdoc +0 -4
- data/core/builtin.rbs +4 -0
- data/core/file.rbs +3 -4
- data/core/hash.rbs +1 -3
- data/core/io.rbs +165 -7
- data/core/kernel.rbs +1 -1
- data/core/module.rbs +41 -0
- data/core/time.rbs +0 -12
- data/docs/syntax.md +0 -17
- data/goodcheck.yml +22 -2
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -49
- data/lib/rbs/ast/members.rb +10 -4
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +573 -984
- data/lib/rbs/definition_builder/ancestor_builder.rb +525 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +6 -8
- data/lib/rbs/environment_loader.rb +8 -4
- data/lib/rbs/errors.rb +88 -121
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +1082 -1014
- data/lib/rbs/parser.y +108 -76
- data/lib/rbs/prototype/rb.rb +18 -3
- data/lib/rbs/prototype/rbi.rb +6 -6
- data/lib/rbs/prototype/runtime.rb +71 -35
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +26 -8
- data/lib/rbs/types.rb +68 -7
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +13 -4
- data/schema/members.json +5 -1
- data/sig/ancestor_builder.rbs +98 -0
- data/sig/declarations.rbs +4 -16
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +15 -67
- data/sig/errors.rbs +159 -0
- data/sig/members.rbs +4 -1
- data/sig/method_builder.rbs +71 -0
- data/sig/method_types.rbs +3 -16
- data/sig/substitution.rbs +3 -0
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +17 -15
- data/sig/validator.rbs +12 -0
- data/stdlib/csv/0/csv.rbs +3 -0
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/pathname/0/pathname.rbs +1 -1
- data/stdlib/prime/0/prime.rbs +6 -0
- data/stdlib/securerandom/0/securerandom.rbs +2 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/tsort/0/tsort.rbs +8 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +13 -14
- metadata +16 -5
data/goodcheck.yml
CHANGED
@@ -3,7 +3,7 @@ rules:
|
|
3
3
|
pattern: 💪👽🚨
|
4
4
|
message: Do you forget to delete `arglists` section?
|
5
5
|
glob:
|
6
|
-
- "stdlib/**/*.rbs"
|
6
|
+
- "{core,stdlib}/**/*.rbs"
|
7
7
|
fail:
|
8
8
|
- |
|
9
9
|
# arglists 💪👽🚨 << Delete this section
|
@@ -22,12 +22,32 @@ rules:
|
|
22
22
|
justification:
|
23
23
|
- Documents (comments) may contain that pattern.
|
24
24
|
glob:
|
25
|
-
- "stdlib/**/*.rbs"
|
25
|
+
- "{core,stdlib}/**/*.rbs"
|
26
26
|
fail:
|
27
27
|
- "def `send`: (String | Symbol arg0, *untyped arg1) -> untyped"
|
28
28
|
pass:
|
29
29
|
- "def `send`: (String | Symbol, *untyped) -> untyped"
|
30
30
|
|
31
|
+
- id: rbs.prefer_boolish
|
32
|
+
pattern:
|
33
|
+
- regexp: '\([^(]*\bbool\b[^\n]*\)'
|
34
|
+
- token: "-> bool }"
|
35
|
+
message: |
|
36
|
+
Prefer `boolish` over `bool` for method arguments and block return values
|
37
|
+
|
38
|
+
See the doc below:
|
39
|
+
https://github.com/ruby/rbs/blob/78d04a2db0f1c4925d2b13c2939868edf9465d6c/docs/syntax.md#bool-or-boolish
|
40
|
+
glob:
|
41
|
+
- "**/*.rbs"
|
42
|
+
justification:
|
43
|
+
- When you strictly want `true | false`.
|
44
|
+
pass:
|
45
|
+
- "(arg: boolish)"
|
46
|
+
- "{ () -> boolish }"
|
47
|
+
fail:
|
48
|
+
- "(arg: bool)"
|
49
|
+
- "{ () -> bool }"
|
50
|
+
|
31
51
|
- id: deprecate_stdlib_test
|
32
52
|
pattern:
|
33
53
|
token: < StdlibTest
|
data/lib/rbs.rb
CHANGED
@@ -23,6 +23,8 @@ require "rbs/environment_loader"
|
|
23
23
|
require "rbs/builtin_names"
|
24
24
|
require "rbs/definition"
|
25
25
|
require "rbs/definition_builder"
|
26
|
+
require "rbs/definition_builder/ancestor_builder"
|
27
|
+
require "rbs/definition_builder/method_builder"
|
26
28
|
require "rbs/variance_calculator"
|
27
29
|
require "rbs/substitution"
|
28
30
|
require "rbs/constant"
|
data/lib/rbs/ast/declarations.rb
CHANGED
@@ -136,10 +136,12 @@ module RBS
|
|
136
136
|
class Super
|
137
137
|
attr_reader :name
|
138
138
|
attr_reader :args
|
139
|
+
attr_reader :location
|
139
140
|
|
140
|
-
def initialize(name:, args:)
|
141
|
+
def initialize(name:, args:, location:)
|
141
142
|
@name = name
|
142
143
|
@args = args
|
144
|
+
@location = location
|
143
145
|
end
|
144
146
|
|
145
147
|
def ==(other)
|
@@ -155,7 +157,8 @@ module RBS
|
|
155
157
|
def to_json(*a)
|
156
158
|
{
|
157
159
|
name: name,
|
158
|
-
args: args
|
160
|
+
args: args,
|
161
|
+
location: location
|
159
162
|
}.to_json(*a)
|
160
163
|
end
|
161
164
|
end
|
@@ -297,53 +300,6 @@ module RBS
|
|
297
300
|
end
|
298
301
|
end
|
299
302
|
|
300
|
-
class Extension < Base
|
301
|
-
attr_reader :name
|
302
|
-
attr_reader :type_params
|
303
|
-
attr_reader :extension_name
|
304
|
-
attr_reader :members
|
305
|
-
attr_reader :annotations
|
306
|
-
attr_reader :location
|
307
|
-
attr_reader :comment
|
308
|
-
|
309
|
-
def initialize(name:, type_params:, extension_name:, members:, annotations:, location:, comment:)
|
310
|
-
@name = name
|
311
|
-
@type_params = type_params
|
312
|
-
@extension_name = extension_name
|
313
|
-
@members = members
|
314
|
-
@annotations = annotations
|
315
|
-
@location = location
|
316
|
-
@comment = comment
|
317
|
-
end
|
318
|
-
|
319
|
-
def ==(other)
|
320
|
-
other.is_a?(Extension) &&
|
321
|
-
other.name == name &&
|
322
|
-
other.type_params == type_params &&
|
323
|
-
other.extension_name == extension_name &&
|
324
|
-
other.members == members
|
325
|
-
end
|
326
|
-
|
327
|
-
alias eql? ==
|
328
|
-
|
329
|
-
def hash
|
330
|
-
self.class.hash ^ name.hash ^ type_params.hash ^ extension_name.hash ^ members.hash
|
331
|
-
end
|
332
|
-
|
333
|
-
def to_json(*a)
|
334
|
-
{
|
335
|
-
declaration: :extension,
|
336
|
-
name: name,
|
337
|
-
type_params: type_params,
|
338
|
-
extension_name: extension_name,
|
339
|
-
members: members,
|
340
|
-
annotations: annotations,
|
341
|
-
location: location,
|
342
|
-
comment: comment
|
343
|
-
}.to_json(*a)
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
303
|
class Interface < Base
|
348
304
|
attr_reader :name
|
349
305
|
attr_reader :type_params
|
@@ -352,6 +308,8 @@ module RBS
|
|
352
308
|
attr_reader :location
|
353
309
|
attr_reader :comment
|
354
310
|
|
311
|
+
include MixinHelper
|
312
|
+
|
355
313
|
def initialize(name:, type_params:, members:, annotations:, location:, comment:)
|
356
314
|
@name = name
|
357
315
|
@type_params = type_params
|
data/lib/rbs/ast/members.rb
CHANGED
@@ -20,7 +20,7 @@ module RBS
|
|
20
20
|
@annotations = annotations
|
21
21
|
@location = location
|
22
22
|
@comment = comment
|
23
|
-
@overload = overload
|
23
|
+
@overload = overload ? true : false
|
24
24
|
end
|
25
25
|
|
26
26
|
def ==(other)
|
@@ -216,31 +216,34 @@ module RBS
|
|
216
216
|
module Attribute
|
217
217
|
attr_reader :name
|
218
218
|
attr_reader :type
|
219
|
+
attr_reader :kind
|
219
220
|
attr_reader :ivar_name
|
220
221
|
attr_reader :annotations
|
221
222
|
attr_reader :location
|
222
223
|
attr_reader :comment
|
223
224
|
|
224
|
-
def initialize(name:, type:, ivar_name:, annotations:, location:, comment:)
|
225
|
+
def initialize(name:, type:, ivar_name:, kind:, annotations:, location:, comment:)
|
225
226
|
@name = name
|
226
227
|
@type = type
|
227
228
|
@ivar_name = ivar_name
|
228
229
|
@annotations = annotations
|
229
230
|
@location = location
|
230
231
|
@comment = comment
|
232
|
+
@kind = kind
|
231
233
|
end
|
232
234
|
|
233
235
|
def ==(other)
|
234
236
|
other.is_a?(self.class) &&
|
235
237
|
other.name == name &&
|
236
238
|
other.type == type &&
|
237
|
-
other.ivar_name == ivar_name
|
239
|
+
other.ivar_name == ivar_name &&
|
240
|
+
other.kind == kind
|
238
241
|
end
|
239
242
|
|
240
243
|
alias eql? ==
|
241
244
|
|
242
245
|
def hash
|
243
|
-
self.class.hash ^ name.hash ^ type.hash ^ ivar_name.hash
|
246
|
+
self.class.hash ^ name.hash ^ type.hash ^ ivar_name.hash ^ kind.hash
|
244
247
|
end
|
245
248
|
end
|
246
249
|
|
@@ -253,6 +256,7 @@ module RBS
|
|
253
256
|
name: name,
|
254
257
|
type: type,
|
255
258
|
ivar_name: ivar_name,
|
259
|
+
kind: kind,
|
256
260
|
annotations: annotations,
|
257
261
|
location: location,
|
258
262
|
comment: comment
|
@@ -269,6 +273,7 @@ module RBS
|
|
269
273
|
name: name,
|
270
274
|
type: type,
|
271
275
|
ivar_name: ivar_name,
|
276
|
+
kind: kind,
|
272
277
|
annotations: annotations,
|
273
278
|
location: location,
|
274
279
|
comment: comment
|
@@ -285,6 +290,7 @@ module RBS
|
|
285
290
|
name: name,
|
286
291
|
type: type,
|
287
292
|
ivar_name: ivar_name,
|
293
|
+
kind: kind,
|
288
294
|
annotations: annotations,
|
289
295
|
location: location,
|
290
296
|
comment: comment
|
data/lib/rbs/cli.rb
CHANGED
@@ -25,7 +25,7 @@ module RBS
|
|
25
25
|
end
|
26
26
|
|
27
27
|
loader = EnvironmentLoader.new(core_root: core_root, repository: repository)
|
28
|
-
|
28
|
+
|
29
29
|
dirs.each do |dir|
|
30
30
|
loader.add(path: Pathname(dir))
|
31
31
|
end
|
@@ -43,21 +43,21 @@ module RBS
|
|
43
43
|
opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
|
44
44
|
libs << lib
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
opts.on("-I DIR", "Load RBS files from the directory") do |dir|
|
48
48
|
dirs << dir
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
opts.on("--no-stdlib", "Skip loading standard library signatures") do
|
52
52
|
self.core_root = nil
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
opts.on("--repo DIR", "Add RBS repository") do |dir|
|
56
56
|
repos << dir
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
opts
|
60
|
-
end
|
60
|
+
end
|
61
61
|
end
|
62
62
|
|
63
63
|
attr_reader :stdout
|
@@ -242,7 +242,7 @@ EOU
|
|
242
242
|
|
243
243
|
env = Environment.from_loader(loader).resolve_type_names
|
244
244
|
|
245
|
-
builder = DefinitionBuilder.new(env: env)
|
245
|
+
builder = DefinitionBuilder::AncestorBuilder.new(env: env)
|
246
246
|
type_name = TypeName(args[0]).absolute!
|
247
247
|
|
248
248
|
if env.class_decls.key?(type_name)
|
@@ -626,7 +626,7 @@ EOU
|
|
626
626
|
|
627
627
|
opts = OptionParser.new
|
628
628
|
opts.banner = <<EOU
|
629
|
-
Usage: rbs prototype #{format} [
|
629
|
+
Usage: rbs prototype #{format} [files...]
|
630
630
|
#{availability}
|
631
631
|
Generate RBS prototype from source code.
|
632
632
|
It parses specified Ruby code and and generates RBS prototypes.
|
@@ -735,7 +735,7 @@ Examples:
|
|
735
735
|
syntax_error = false
|
736
736
|
args.each do |path|
|
737
737
|
path = Pathname(path)
|
738
|
-
loader.each_file(path, skip_hidden: false, immediate: true) do |file_path|
|
738
|
+
loader.each_file(path, skip_hidden: false, immediate: true) do |file_path|
|
739
739
|
Parser.parse_signature(file_path.read)
|
740
740
|
rescue RBS::Parser::SyntaxError => ex
|
741
741
|
loc = ex.error_value.location
|
@@ -757,7 +757,7 @@ Examples:
|
|
757
757
|
opts.push(*options.repos.map {|dir| "--repo #{Shellwords.escape(dir)}"})
|
758
758
|
opts.push(*options.dirs.map {|dir| "-I #{Shellwords.escape(dir)}"})
|
759
759
|
opts.push(*options.libs.map {|lib| "-r#{Shellwords.escape(lib)}"})
|
760
|
-
|
760
|
+
|
761
761
|
opts.empty? ? nil : opts.join(" ")
|
762
762
|
end
|
763
763
|
|
data/lib/rbs/definition.rb
CHANGED
@@ -34,6 +34,20 @@ module RBS
|
|
34
34
|
@implemented_in = implemented_in
|
35
35
|
end
|
36
36
|
|
37
|
+
def ==(other)
|
38
|
+
other.is_a?(TypeDef) &&
|
39
|
+
other.type == type &&
|
40
|
+
other.member == member &&
|
41
|
+
other.defined_in == defined_in &&
|
42
|
+
other.implemented_in == implemented_in
|
43
|
+
end
|
44
|
+
|
45
|
+
alias eql? ==
|
46
|
+
|
47
|
+
def hash
|
48
|
+
self.class.hash ^ type.hash ^ member.hash ^ defined_in.hash ^ implemented_in.hash
|
49
|
+
end
|
50
|
+
|
37
51
|
def comment
|
38
52
|
member.comment
|
39
53
|
end
|
@@ -70,6 +84,21 @@ module RBS
|
|
70
84
|
@alias_of = alias_of
|
71
85
|
end
|
72
86
|
|
87
|
+
def ==(other)
|
88
|
+
other.is_a?(Method) &&
|
89
|
+
other.super_method == super_method &&
|
90
|
+
other.defs == defs &&
|
91
|
+
other.accessibility == accessibility &&
|
92
|
+
other.annotations == annotations &&
|
93
|
+
other.alias_of == alias_of
|
94
|
+
end
|
95
|
+
|
96
|
+
alias eql? ==
|
97
|
+
|
98
|
+
def hash
|
99
|
+
self.class.hash ^ super_method.hash ^ defs.hash ^ accessibility.hash ^ annotations.hash ^ alias_of.hash
|
100
|
+
end
|
101
|
+
|
73
102
|
def defined_in
|
74
103
|
@defined_in ||= begin
|
75
104
|
last_def = defs.last or raise
|
@@ -137,8 +166,43 @@ module RBS
|
|
137
166
|
end
|
138
167
|
|
139
168
|
module Ancestor
|
140
|
-
Instance
|
141
|
-
|
169
|
+
class Instance
|
170
|
+
attr_reader :name, :args, :source
|
171
|
+
|
172
|
+
def initialize(name:, args:, source:)
|
173
|
+
@name = name
|
174
|
+
@args = args
|
175
|
+
@source = source
|
176
|
+
end
|
177
|
+
|
178
|
+
def ==(other)
|
179
|
+
other.is_a?(Instance) && other.name == name && other.args == args
|
180
|
+
end
|
181
|
+
|
182
|
+
alias eql? ==
|
183
|
+
|
184
|
+
def hash
|
185
|
+
self.class.hash ^ name.hash ^ args.hash
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class Singleton
|
190
|
+
attr_reader :name
|
191
|
+
|
192
|
+
def initialize(name:)
|
193
|
+
@name = name
|
194
|
+
end
|
195
|
+
|
196
|
+
def ==(other)
|
197
|
+
other.is_a?(Singleton) && other.name == name
|
198
|
+
end
|
199
|
+
|
200
|
+
alias eql? ==
|
201
|
+
|
202
|
+
def hash
|
203
|
+
self.class.hash ^ name.hash
|
204
|
+
end
|
205
|
+
end
|
142
206
|
end
|
143
207
|
|
144
208
|
class InstanceAncestors
|
@@ -170,7 +234,8 @@ module RBS
|
|
170
234
|
else
|
171
235
|
Ancestor::Instance.new(
|
172
236
|
name: ancestor.name,
|
173
|
-
args: ancestor.args.map {|type| type.sub(subst) }
|
237
|
+
args: ancestor.args.map {|type| type.sub(subst) },
|
238
|
+
source: ancestor.source
|
174
239
|
)
|
175
240
|
end
|
176
241
|
when Ancestor::Singleton
|
@@ -233,6 +298,8 @@ module RBS
|
|
233
298
|
case en = entry
|
234
299
|
when Environment::SingleEntry
|
235
300
|
en.decl.is_a?(AST::Declarations::Interface)
|
301
|
+
else
|
302
|
+
false
|
236
303
|
end
|
237
304
|
end
|
238
305
|
|
@@ -2,443 +2,342 @@ module RBS
|
|
2
2
|
class DefinitionBuilder
|
3
3
|
attr_reader :env
|
4
4
|
attr_reader :type_name_resolver
|
5
|
+
attr_reader :ancestor_builder
|
6
|
+
attr_reader :method_builder
|
5
7
|
|
6
8
|
attr_reader :instance_cache
|
7
9
|
attr_reader :singleton_cache
|
10
|
+
attr_reader :singleton0_cache
|
8
11
|
attr_reader :interface_cache
|
9
12
|
|
10
|
-
attr_reader :one_instance_cache
|
11
|
-
attr_reader :one_singleton_cache
|
12
|
-
|
13
|
-
attr_reader :instance_ancestors_cache
|
14
|
-
attr_reader :singleton_ancestor_cache
|
15
|
-
|
16
|
-
attr_reader :one_instance_ancestors_cache
|
17
|
-
attr_reader :one_singleton_ancestors_cache
|
18
|
-
|
19
|
-
class OneAncestors
|
20
|
-
attr_reader :type_name
|
21
|
-
attr_reader :params
|
22
|
-
attr_reader :super_class
|
23
|
-
attr_reader :self_types
|
24
|
-
attr_reader :included_modules
|
25
|
-
attr_reader :prepended_modules
|
26
|
-
attr_reader :extended_modules
|
27
|
-
|
28
|
-
def initialize(type_name:, params:, super_class:, self_types:, included_modules:, prepended_modules:, extended_modules:)
|
29
|
-
@type_name = type_name
|
30
|
-
@params = params
|
31
|
-
@super_class = super_class
|
32
|
-
@self_types = self_types
|
33
|
-
@included_modules = included_modules
|
34
|
-
@prepended_modules = prepended_modules
|
35
|
-
@extended_modules = extended_modules
|
36
|
-
end
|
37
|
-
|
38
|
-
def each_ancestor(&block)
|
39
|
-
if block
|
40
|
-
if s = super_class
|
41
|
-
yield s
|
42
|
-
end
|
43
|
-
|
44
|
-
self_types&.each(&block)
|
45
|
-
included_modules&.each(&block)
|
46
|
-
prepended_modules&.each(&block)
|
47
|
-
extended_modules&.each(&block)
|
48
|
-
else
|
49
|
-
enum_for :each_ancestor
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.class_instance(type_name:, params:, super_class:)
|
54
|
-
new(
|
55
|
-
type_name: type_name,
|
56
|
-
params: params,
|
57
|
-
super_class: super_class,
|
58
|
-
self_types: nil,
|
59
|
-
included_modules: [],
|
60
|
-
prepended_modules: [],
|
61
|
-
extended_modules: nil
|
62
|
-
)
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.singleton(type_name:, super_class:)
|
66
|
-
new(
|
67
|
-
type_name: type_name,
|
68
|
-
params: nil,
|
69
|
-
super_class: super_class,
|
70
|
-
self_types: nil,
|
71
|
-
included_modules: nil,
|
72
|
-
prepended_modules: nil,
|
73
|
-
extended_modules: []
|
74
|
-
)
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.module_instance(type_name:, params:)
|
78
|
-
new(
|
79
|
-
type_name: type_name,
|
80
|
-
params: params,
|
81
|
-
self_types: [],
|
82
|
-
included_modules: [],
|
83
|
-
prepended_modules: [],
|
84
|
-
super_class: nil,
|
85
|
-
extended_modules: nil
|
86
|
-
)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
13
|
def initialize(env:)
|
91
14
|
@env = env
|
92
15
|
@type_name_resolver = TypeNameResolver.from_env(env)
|
16
|
+
@ancestor_builder = AncestorBuilder.new(env: env)
|
17
|
+
@method_builder = MethodBuilder.new(env: env)
|
93
18
|
|
94
19
|
@instance_cache = {}
|
95
20
|
@singleton_cache = {}
|
21
|
+
@singleton0_cache = {}
|
96
22
|
@interface_cache = {}
|
97
|
-
|
98
|
-
@one_instance_cache = {}
|
99
|
-
@one_singleton_cache = {}
|
100
|
-
|
101
|
-
@instance_ancestors_cache = {}
|
102
|
-
@singleton_ancestor_cache = {}
|
103
|
-
|
104
|
-
@one_instance_ancestors_cache = {}
|
105
|
-
@one_singleton_ancestors_cache = {}
|
106
23
|
end
|
107
24
|
|
108
|
-
def
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
super_types = with_super_classes.map do |d|
|
114
|
-
super_class = d.decl.super_class or raise
|
115
|
-
Types::ClassInstance.new(name: super_class.name, args: super_class.args, location: nil)
|
116
|
-
end
|
117
|
-
|
118
|
-
super_types.uniq!
|
119
|
-
|
120
|
-
return if super_types.size == 1
|
121
|
-
|
122
|
-
raise SuperclassMismatchError.new(name: type_name, super_classes: super_types, entry: entry)
|
123
|
-
end
|
124
|
-
|
125
|
-
def one_instance_ancestors(type_name)
|
126
|
-
as = one_instance_ancestors_cache[type_name] and return as
|
127
|
-
|
128
|
-
entry = env.class_decls[type_name] or raise "Unknown name for one_instance_ancestors: #{type_name}"
|
129
|
-
params = entry.type_params.each.map(&:name)
|
130
|
-
|
131
|
-
case entry
|
132
|
-
when Environment::ClassEntry
|
133
|
-
validate_super_class!(type_name, entry)
|
134
|
-
primary = entry.primary
|
135
|
-
super_class = primary.decl.super_class
|
136
|
-
|
137
|
-
if type_name != BuiltinNames::BasicObject.name
|
138
|
-
if super_class
|
139
|
-
super_name = super_class.name
|
140
|
-
super_args = super_class.args
|
141
|
-
else
|
142
|
-
super_name = BuiltinNames::Object.name
|
143
|
-
super_args = []
|
144
|
-
end
|
145
|
-
|
146
|
-
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
147
|
-
|
148
|
-
ancestors = OneAncestors.class_instance(
|
149
|
-
type_name: type_name,
|
150
|
-
params: params,
|
151
|
-
super_class: Definition::Ancestor::Instance.new(name: super_name, args: super_args)
|
152
|
-
)
|
153
|
-
else
|
154
|
-
ancestors = OneAncestors.class_instance(
|
155
|
-
type_name: type_name,
|
156
|
-
params: params,
|
157
|
-
super_class: nil
|
158
|
-
)
|
159
|
-
end
|
160
|
-
when Environment::ModuleEntry
|
161
|
-
ancestors = OneAncestors.module_instance(type_name: type_name, params: params)
|
162
|
-
|
163
|
-
entry.self_types.each do |module_self|
|
164
|
-
NoSelfTypeFoundError.check!(module_self, env: env)
|
165
|
-
|
166
|
-
self_types = ancestors.self_types or raise
|
167
|
-
self_types.push Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
25
|
+
def ensure_namespace!(namespace, location:)
|
26
|
+
namespace.ascend do |ns|
|
27
|
+
unless ns.empty?
|
28
|
+
NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
|
168
29
|
end
|
169
30
|
end
|
170
|
-
|
171
|
-
mixin_ancestors(entry,
|
172
|
-
included_modules: ancestors.included_modules,
|
173
|
-
prepended_modules: ancestors.prepended_modules,
|
174
|
-
extended_modules: nil)
|
175
|
-
|
176
|
-
one_instance_ancestors_cache[type_name] = ancestors
|
177
31
|
end
|
178
32
|
|
179
|
-
def
|
180
|
-
|
33
|
+
def build_interface(type_name)
|
34
|
+
try_cache(type_name, cache: interface_cache) do
|
35
|
+
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
36
|
+
declaration = entry.decl
|
37
|
+
ensure_namespace!(type_name.namespace, location: declaration.location)
|
181
38
|
|
182
|
-
|
39
|
+
self_type = Types::Interface.new(
|
40
|
+
name: type_name,
|
41
|
+
args: Types::Variable.build(declaration.type_params.each.map(&:name)),
|
42
|
+
location: nil
|
43
|
+
)
|
183
44
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
45
|
+
ancestors = ancestor_builder.interface_ancestors(type_name)
|
46
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
47
|
+
included_interfaces = ancestor_builder.one_interface_ancestors(type_name).included_interfaces or raise
|
48
|
+
included_interfaces.each do |mod|
|
49
|
+
defn = build_interface(mod.name)
|
50
|
+
subst = Substitution.build(defn.type_params, mod.args)
|
189
51
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
else
|
194
|
-
super_name = BuiltinNames::Object.name
|
52
|
+
defn.methods.each do |name, method|
|
53
|
+
definition.methods[name] = method.sub(subst)
|
54
|
+
end
|
195
55
|
end
|
196
56
|
|
197
|
-
|
57
|
+
methods = method_builder.build_interface(type_name)
|
58
|
+
one_ancestors = ancestor_builder.one_interface_ancestors(type_name)
|
59
|
+
|
60
|
+
validate_type_params(definition, methods: methods, ancestors: one_ancestors)
|
61
|
+
|
62
|
+
methods.each do |defn|
|
63
|
+
method = case original = defn.original
|
64
|
+
when AST::Members::MethodDefinition
|
65
|
+
defs = original.types.map do |method_type|
|
66
|
+
Definition::Method::TypeDef.new(
|
67
|
+
type: method_type,
|
68
|
+
member: original,
|
69
|
+
defined_in: type_name,
|
70
|
+
implemented_in: nil
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
Definition::Method.new(
|
75
|
+
super_method: nil,
|
76
|
+
defs: defs,
|
77
|
+
accessibility: :public,
|
78
|
+
alias_of: nil
|
79
|
+
)
|
80
|
+
when AST::Members::Alias
|
81
|
+
unless definition.methods.key?(original.old_name)
|
82
|
+
raise UnknownMethodAliasError.new(
|
83
|
+
original_name: original.old_name,
|
84
|
+
aliased_name: original.new_name,
|
85
|
+
location: original.location
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
original_method = definition.methods[original.old_name]
|
90
|
+
Definition::Method.new(
|
91
|
+
super_method: nil,
|
92
|
+
defs: original_method.defs.map do |defn|
|
93
|
+
defn.update(implemented_in: nil, defined_in: type_name)
|
94
|
+
end,
|
95
|
+
accessibility: :public,
|
96
|
+
alias_of: original_method
|
97
|
+
)
|
98
|
+
when nil
|
99
|
+
unless definition.methods.key?(defn.name)
|
100
|
+
raise InvalidOverloadMethodError.new(
|
101
|
+
type_name: type_name,
|
102
|
+
method_name: defn.name,
|
103
|
+
kind: :instance,
|
104
|
+
members: defn.overloads
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
definition.methods[defn.name]
|
109
|
+
|
110
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
111
|
+
raise
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
defn.overloads.each do |overload|
|
116
|
+
overload_defs = overload.types.map do |method_type|
|
117
|
+
Definition::Method::TypeDef.new(
|
118
|
+
type: method_type,
|
119
|
+
member: overload,
|
120
|
+
defined_in: type_name,
|
121
|
+
implemented_in: nil
|
122
|
+
)
|
123
|
+
end
|
198
124
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
ancestors = OneAncestors.singleton(
|
205
|
-
type_name: type_name,
|
206
|
-
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Class.name, args: [])
|
207
|
-
)
|
125
|
+
method.defs.unshift(*overload_defs)
|
126
|
+
end
|
127
|
+
|
128
|
+
definition.methods[defn.name] = method
|
129
|
+
end
|
208
130
|
end
|
209
|
-
when Environment::ModuleEntry
|
210
|
-
ancestors = OneAncestors.singleton(
|
211
|
-
type_name: type_name,
|
212
|
-
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Module.name, args: [])
|
213
|
-
)
|
214
131
|
end
|
215
|
-
|
216
|
-
mixin_ancestors(entry,
|
217
|
-
included_modules: nil,
|
218
|
-
prepended_modules: nil,
|
219
|
-
extended_modules: ancestors.extended_modules)
|
220
|
-
|
221
|
-
one_singleton_ancestors_cache[type_name] = ancestors
|
222
132
|
end
|
223
133
|
|
224
|
-
def
|
225
|
-
|
226
|
-
|
134
|
+
def build_instance(type_name)
|
135
|
+
try_cache(type_name, cache: instance_cache) do
|
136
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
137
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
227
138
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
139
|
+
case entry
|
140
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
141
|
+
ancestors = ancestor_builder.instance_ancestors(type_name)
|
142
|
+
self_type = Types::ClassInstance.new(name: type_name,
|
143
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
144
|
+
location: nil)
|
232
145
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
if included_modules
|
237
|
-
NoMixinFoundError.check!(member.name, env: env, member: member)
|
146
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
147
|
+
one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
|
148
|
+
methods = method_builder.build_instance(type_name)
|
238
149
|
|
239
|
-
|
240
|
-
module_args = member.args.map {|type| type.sub(align_params) }
|
150
|
+
validate_type_params definition, methods: methods, ancestors: one_ancestors
|
241
151
|
|
242
|
-
|
152
|
+
if super_class = one_ancestors.super_class
|
153
|
+
case super_class
|
154
|
+
when Definition::Ancestor::Instance
|
155
|
+
build_instance(super_class.name).yield_self do |defn|
|
156
|
+
merge_definition(src: defn,
|
157
|
+
dest: definition,
|
158
|
+
subst: Substitution.build(defn.type_params, super_class.args),
|
159
|
+
keep_super: true)
|
160
|
+
end
|
161
|
+
else
|
162
|
+
raise
|
163
|
+
end
|
243
164
|
end
|
244
165
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
166
|
+
if self_types = one_ancestors.self_types
|
167
|
+
self_types.each do |ans|
|
168
|
+
defn = if ans.name.interface?
|
169
|
+
build_interface(ans.name)
|
170
|
+
else
|
171
|
+
build_instance(ans.name)
|
172
|
+
end
|
173
|
+
|
174
|
+
# Successor interface method overwrites.
|
175
|
+
merge_definition(src: defn,
|
176
|
+
dest: definition,
|
177
|
+
subst: Substitution.build(defn.type_params, ans.args),
|
178
|
+
keep_super: true)
|
179
|
+
end
|
253
180
|
end
|
254
181
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
module_args = member.args
|
261
|
-
|
262
|
-
extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
182
|
+
one_ancestors.each_included_module do |mod|
|
183
|
+
defn = build_instance(mod.name)
|
184
|
+
merge_definition(src: defn,
|
185
|
+
dest: definition,
|
186
|
+
subst: Substitution.build(defn.type_params, mod.args))
|
263
187
|
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
188
|
|
269
|
-
|
270
|
-
as = instance_ancestors_cache[type_name] and return as
|
189
|
+
interface_methods = {}
|
271
190
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
|
191
|
+
one_ancestors.each_included_interface do |mod|
|
192
|
+
defn = build_interface(mod.name)
|
193
|
+
subst = Substitution.build(defn.type_params, mod.args)
|
276
194
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
building_ancestors.push self_ancestor
|
195
|
+
defn.methods.each do |name, method|
|
196
|
+
if interface_methods.key?(name)
|
197
|
+
include_member = mod.source
|
281
198
|
|
282
|
-
|
199
|
+
raise unless include_member.is_a?(AST::Members::Include)
|
283
200
|
|
284
|
-
|
201
|
+
raise DuplicatedInterfaceMethodDefinitionError.new(
|
202
|
+
type: self_type,
|
203
|
+
method_name: name,
|
204
|
+
member: include_member
|
205
|
+
)
|
206
|
+
end
|
285
207
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
# @type var super_class: Definition::Ancestor::Instance
|
290
|
-
super_name = super_class.name
|
291
|
-
super_args = super_class.args
|
208
|
+
merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
|
209
|
+
end
|
210
|
+
end
|
292
211
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
212
|
+
define_methods(definition,
|
213
|
+
interface_methods: interface_methods,
|
214
|
+
methods: methods,
|
215
|
+
super_interface_method: entry.is_a?(Environment::ModuleEntry))
|
216
|
+
|
217
|
+
entry.decls.each do |d|
|
218
|
+
d.decl.members.each do |member|
|
219
|
+
case member
|
220
|
+
when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
|
221
|
+
if member.kind == :instance
|
222
|
+
ivar_name = case member.ivar_name
|
223
|
+
when false
|
224
|
+
nil
|
225
|
+
else
|
226
|
+
member.ivar_name || :"@#{member.name}"
|
227
|
+
end
|
228
|
+
|
229
|
+
if ivar_name
|
230
|
+
insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
|
231
|
+
end
|
232
|
+
end
|
297
233
|
|
298
|
-
|
299
|
-
|
300
|
-
if mod.name.class?
|
301
|
-
name = mod.name
|
302
|
-
arg_types = mod.args
|
303
|
-
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
304
|
-
ancestors.unshift(*mod_ancestors.apply(arg_types, location: entry.primary.decl.location))
|
305
|
-
end
|
306
|
-
end
|
307
|
-
end
|
234
|
+
when AST::Members::InstanceVariable
|
235
|
+
insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
|
308
236
|
|
309
|
-
|
237
|
+
when AST::Members::ClassVariable
|
238
|
+
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
310
242
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
ancestors.unshift(*mod_ancestors.apply(arg_types, location: entry.primary.decl.location))
|
243
|
+
one_ancestors.each_prepended_module do |mod|
|
244
|
+
defn = build_instance(mod.name)
|
245
|
+
merge_definition(src: defn,
|
246
|
+
dest: definition,
|
247
|
+
subst: Substitution.build(defn.type_params, mod.args))
|
248
|
+
end
|
318
249
|
end
|
319
250
|
end
|
320
251
|
end
|
321
|
-
|
322
|
-
building_ancestors.pop
|
323
|
-
|
324
|
-
instance_ancestors_cache[type_name] = Definition::InstanceAncestors.new(
|
325
|
-
type_name: type_name,
|
326
|
-
params: params,
|
327
|
-
ancestors: ancestors
|
328
|
-
)
|
329
252
|
end
|
330
253
|
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
RecursiveAncestorError.check!(self_ancestor,
|
338
|
-
ancestors: building_ancestors,
|
339
|
-
location: entry.primary.decl.location)
|
340
|
-
building_ancestors.push self_ancestor
|
341
|
-
|
342
|
-
one_ancestors = one_singleton_ancestors(type_name)
|
343
|
-
|
344
|
-
ancestors = []
|
345
|
-
|
346
|
-
case super_class = one_ancestors.super_class
|
347
|
-
when Definition::Ancestor::Instance
|
348
|
-
super_name = super_class.name
|
349
|
-
super_args = super_class.args
|
350
|
-
|
351
|
-
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
352
|
-
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
|
353
|
-
|
354
|
-
when Definition::Ancestor::Singleton
|
355
|
-
super_name = super_class.name
|
356
|
-
|
357
|
-
super_ancestors = singleton_ancestors(super_name, building_ancestors: [])
|
358
|
-
ancestors.unshift(*super_ancestors.ancestors)
|
359
|
-
end
|
360
|
-
|
361
|
-
extended_modules = one_ancestors.extended_modules or raise
|
362
|
-
extended_modules.each do |mod|
|
363
|
-
if mod.name.class?
|
364
|
-
name = mod.name
|
365
|
-
args = mod.args
|
366
|
-
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
367
|
-
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
368
|
-
end
|
369
|
-
end
|
254
|
+
# Builds a definition for singleton without .new method.
|
255
|
+
#
|
256
|
+
def build_singleton0(type_name)
|
257
|
+
try_cache type_name, cache: singleton0_cache do
|
258
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton0: #{type_name}"
|
259
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
370
260
|
|
371
|
-
|
261
|
+
case entry
|
262
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
263
|
+
ancestors = ancestor_builder.singleton_ancestors(type_name)
|
264
|
+
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
372
265
|
|
373
|
-
|
266
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
267
|
+
one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
|
268
|
+
|
269
|
+
if super_class = one_ancestors.super_class
|
270
|
+
case super_class
|
271
|
+
when Definition::Ancestor::Instance
|
272
|
+
defn = build_instance(super_class.name)
|
273
|
+
merge_definition(src: defn,
|
274
|
+
dest: definition,
|
275
|
+
subst: Substitution.build(defn.type_params, super_class.args),
|
276
|
+
keep_super: true)
|
277
|
+
when Definition::Ancestor::Singleton
|
278
|
+
defn = build_singleton0(super_class.name)
|
279
|
+
merge_definition(src: defn, dest: definition, subst: Substitution.new, keep_super: true)
|
280
|
+
end
|
281
|
+
end
|
374
282
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
283
|
+
one_ancestors.each_extended_module do |mod|
|
284
|
+
mod_defn = build_instance(mod.name)
|
285
|
+
merge_definition(src: mod_defn,
|
286
|
+
dest: definition,
|
287
|
+
subst: Substitution.build(mod_defn.type_params, mod.args))
|
288
|
+
end
|
380
289
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
accessibility = :public
|
386
|
-
when AST::Members::Private
|
387
|
-
accessibility = :private
|
388
|
-
else
|
389
|
-
yield member, accessibility
|
390
|
-
end
|
391
|
-
end
|
392
|
-
end
|
290
|
+
interface_methods = {}
|
291
|
+
one_ancestors.each_extended_interface do |mod|
|
292
|
+
mod_defn = build_interface(mod.name)
|
293
|
+
subst = Substitution.build(mod_defn.type_params, mod.args)
|
393
294
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
295
|
+
mod_defn.methods.each do |name, method|
|
296
|
+
if interface_methods.key?(name)
|
297
|
+
src_member = mod.source
|
401
298
|
|
402
|
-
|
403
|
-
try_cache type_name, cache: instance_cache do
|
404
|
-
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
405
|
-
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
299
|
+
raise unless src_member.is_a?(AST::Members::Extend)
|
406
300
|
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
301
|
+
raise DuplicatedInterfaceMethodDefinitionError.new(
|
302
|
+
type: self_type,
|
303
|
+
method_name: name,
|
304
|
+
member: src_member
|
305
|
+
)
|
306
|
+
end
|
413
307
|
|
414
|
-
|
415
|
-
|
416
|
-
case ancestor
|
417
|
-
when Definition::Ancestor::Instance
|
418
|
-
[ancestor, build_one_instance(ancestor.name)]
|
419
|
-
when Definition::Ancestor::Singleton
|
420
|
-
[ancestor, build_one_singleton(ancestor.name)]
|
308
|
+
merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
|
309
|
+
end
|
421
310
|
end
|
422
|
-
end
|
423
311
|
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
if
|
432
|
-
|
433
|
-
|
434
|
-
|
312
|
+
methods = method_builder.build_singleton(type_name)
|
313
|
+
define_methods(definition, interface_methods: interface_methods, methods: methods, super_interface_method: false)
|
314
|
+
|
315
|
+
entry.decls.each do |d|
|
316
|
+
d.decl.members.each do |member|
|
317
|
+
case member
|
318
|
+
when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
|
319
|
+
if member.kind == :singleton
|
320
|
+
ivar_name = case member.ivar_name
|
321
|
+
when false
|
322
|
+
nil
|
323
|
+
else
|
324
|
+
member.ivar_name || :"@#{member.name}"
|
325
|
+
end
|
326
|
+
|
327
|
+
if ivar_name
|
328
|
+
insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
|
329
|
+
end
|
435
330
|
end
|
436
|
-
|
437
|
-
|
331
|
+
|
332
|
+
when AST::Members::ClassInstanceVariable
|
333
|
+
insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
|
334
|
+
|
335
|
+
when AST::Members::ClassVariable
|
336
|
+
insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
|
337
|
+
end
|
338
|
+
end
|
438
339
|
end
|
439
340
|
end
|
440
|
-
|
441
|
-
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
442
341
|
end
|
443
342
|
end
|
444
343
|
end
|
@@ -450,333 +349,84 @@ module RBS
|
|
450
349
|
|
451
350
|
case entry
|
452
351
|
when Environment::ClassEntry, Environment::ModuleEntry
|
453
|
-
ancestors = singleton_ancestors(type_name)
|
352
|
+
ancestors = ancestor_builder.singleton_ancestors(type_name)
|
454
353
|
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
455
354
|
instance_type = Types::ClassInstance.new(
|
456
355
|
name: type_name,
|
457
|
-
args:
|
356
|
+
args: entry.type_params.each.map { Types::Bases::Any.new(location: nil) },
|
458
357
|
location: nil
|
459
358
|
)
|
460
359
|
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
when Definition::Ancestor::Instance
|
465
|
-
[ancestor, build_one_instance(ancestor.name)]
|
466
|
-
when Definition::Ancestor::Singleton
|
467
|
-
definition = build_one_singleton(ancestor.name)
|
468
|
-
definition = definition.sub(Substitution.build([], [], instance_type: instance_type))
|
469
|
-
definition = definition.map_method_type do |method_type|
|
470
|
-
s = Substitution.build(
|
471
|
-
method_type.free_variables.to_a,
|
472
|
-
method_type.free_variables.map { Types::Bases::Any.new(location: nil) }
|
473
|
-
)
|
474
|
-
method_type.sub(s)
|
475
|
-
end
|
476
|
-
|
477
|
-
[
|
478
|
-
ancestor,
|
479
|
-
definition
|
480
|
-
]
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
485
|
-
end
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
def method_definition_members(type_name, entry, kind:)
|
490
|
-
# @type var interface_methods: Hash[Symbol, [Definition::Method, AST::Members::t]]
|
491
|
-
interface_methods = {}
|
492
|
-
# @type var methods: Hash[Symbol, Array[[AST::Members::MethodDefinition, Definition::accessibility]]]
|
493
|
-
methods = {}
|
494
|
-
|
495
|
-
entry.decls.each do |d|
|
496
|
-
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
497
|
-
case member
|
498
|
-
when AST::Members::MethodDefinition
|
499
|
-
case kind
|
500
|
-
when :singleton
|
501
|
-
next unless member.singleton?
|
502
|
-
when :instance
|
503
|
-
next unless member.instance?
|
504
|
-
end
|
505
|
-
|
506
|
-
methods[member.name] ||= []
|
507
|
-
methods[member.name] << [
|
508
|
-
member.update(types: member.types),
|
509
|
-
accessibility
|
510
|
-
]
|
511
|
-
when AST::Members::Include, AST::Members::Extend
|
512
|
-
if member.name.interface?
|
513
|
-
if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
|
514
|
-
NoMixinFoundError.check!(member.name, env: env, member: member)
|
515
|
-
|
516
|
-
interface_name = member.name
|
517
|
-
interface_args = member.args
|
518
|
-
|
519
|
-
interface_definition = build_interface(interface_name)
|
520
|
-
|
521
|
-
InvalidTypeApplicationError.check!(
|
522
|
-
type_name: interface_name,
|
523
|
-
args: interface_args,
|
524
|
-
params: interface_definition.type_params_decl,
|
525
|
-
location: member.location
|
526
|
-
)
|
527
|
-
|
528
|
-
sub = Substitution.build(interface_definition.type_params, interface_args)
|
529
|
-
|
530
|
-
interface_definition.methods.each do |name, method|
|
531
|
-
interface_methods[name] = [method.sub(sub), member]
|
532
|
-
end
|
533
|
-
end
|
534
|
-
end
|
535
|
-
end
|
536
|
-
end
|
537
|
-
end
|
538
|
-
|
539
|
-
# @type var result: Hash[Symbol, member_detail]
|
540
|
-
result = {}
|
541
|
-
|
542
|
-
interface_methods.each do |name, pair|
|
543
|
-
method_definition, _ = pair
|
544
|
-
# @type var detail: member_detail
|
545
|
-
detail = [:public, method_definition, nil, []]
|
546
|
-
result[name] = detail
|
547
|
-
end
|
548
|
-
|
549
|
-
methods.each do |method_name, array|
|
550
|
-
if result[method_name]
|
551
|
-
unless array.all? {|pair| pair[0].overload? }
|
552
|
-
raise MethodDefinitionConflictWithInterfaceMixinError.new(
|
553
|
-
type_name: type_name,
|
554
|
-
method_name: method_name,
|
555
|
-
kind: :instance,
|
556
|
-
mixin_member: interface_methods[method_name][1],
|
557
|
-
entries: array.map(&:first)
|
558
|
-
)
|
559
|
-
end
|
560
|
-
|
561
|
-
unless array.all? {|pair| pair[1] == :public}
|
562
|
-
raise InconsistentMethodVisibilityError.new(
|
563
|
-
type_name: type_name,
|
564
|
-
method_name: method_name,
|
565
|
-
kind: :instance,
|
566
|
-
member_pairs: array
|
567
|
-
)
|
568
|
-
end
|
569
|
-
|
570
|
-
result[method_name][3].push(*array.map(&:first))
|
571
|
-
else
|
572
|
-
case
|
573
|
-
when array.size == 1 && !array[0][0].overload?
|
574
|
-
member, visibility = array[0]
|
575
|
-
result[method_name] = [visibility, nil, member, []]
|
576
|
-
|
577
|
-
else
|
578
|
-
visibilities = array.group_by {|pair| pair[1] }
|
579
|
-
|
580
|
-
if visibilities.size > 1
|
581
|
-
raise InconsistentMethodVisibilityError.new(
|
582
|
-
type_name: type_name,
|
583
|
-
method_name: method_name,
|
584
|
-
kind: :instance,
|
585
|
-
member_pairs: array
|
586
|
-
)
|
587
|
-
end
|
588
|
-
|
589
|
-
overloads, primary = array.map(&:first).partition(&:overload?)
|
590
|
-
result[method_name] = [array[0][1], nil, primary[0], overloads]
|
591
|
-
end
|
592
|
-
end
|
593
|
-
end
|
360
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
361
|
+
def0 = build_singleton0(type_name)
|
362
|
+
subst = Substitution.build([], [], instance_type: instance_type)
|
594
363
|
|
595
|
-
|
596
|
-
end
|
597
|
-
|
598
|
-
def build_one_instance(type_name)
|
599
|
-
try_cache(type_name, cache: one_instance_cache) do
|
600
|
-
entry = env.class_decls[type_name]
|
601
|
-
|
602
|
-
param_names = entry.type_params.each.map(&:name)
|
603
|
-
self_type = Types::ClassInstance.new(name: type_name,
|
604
|
-
args: Types::Variable.build(param_names),
|
605
|
-
location: nil)
|
606
|
-
ancestors = Definition::InstanceAncestors.new(
|
607
|
-
type_name: type_name,
|
608
|
-
params: param_names,
|
609
|
-
ancestors: [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
|
610
|
-
)
|
364
|
+
merge_definition(src: def0, dest: definition, subst: subst, keep_super: true)
|
611
365
|
|
612
|
-
|
613
|
-
|
614
|
-
|
366
|
+
if entry.is_a?(Environment::ClassEntry)
|
367
|
+
new_method = definition.methods[:new]
|
368
|
+
if new_method.defs.all? {|d| d.defined_in == BuiltinNames::Class.name }
|
369
|
+
# The method is _untyped new_.
|
615
370
|
|
616
|
-
|
617
|
-
|
618
|
-
else
|
619
|
-
overload_members
|
620
|
-
end
|
371
|
+
instance = build_instance(type_name)
|
372
|
+
initialize = instance.methods[:initialize]
|
621
373
|
|
622
|
-
|
623
|
-
|
624
|
-
super_method: nil,
|
625
|
-
accessibility: visibility,
|
626
|
-
defs: method_def.defs.map {|defn| defn.update(implemented_in: type_name) },
|
627
|
-
alias_of: nil
|
628
|
-
)
|
629
|
-
else
|
630
|
-
Definition::Method.new(
|
631
|
-
super_method: nil,
|
632
|
-
accessibility: visibility,
|
633
|
-
defs: [],
|
634
|
-
alias_of: nil
|
635
|
-
)
|
636
|
-
end
|
374
|
+
if initialize
|
375
|
+
class_params = entry.type_params.each.map(&:name)
|
637
376
|
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
defined_in: type_name
|
645
|
-
)
|
646
|
-
end
|
377
|
+
# Inject a virtual _typed new_.
|
378
|
+
initialize_defs = initialize.defs
|
379
|
+
definition.methods[:new] = Definition::Method.new(
|
380
|
+
super_method: new_method,
|
381
|
+
defs: initialize_defs.map do |initialize_def|
|
382
|
+
method_type = initialize_def.type
|
647
383
|
|
648
|
-
|
649
|
-
|
650
|
-
defs: defs + original.defs,
|
651
|
-
accessibility: original.accessibility,
|
652
|
-
alias_of: nil
|
653
|
-
)
|
654
|
-
end
|
655
|
-
end
|
384
|
+
class_type_param_vars = Set.new(class_params)
|
385
|
+
method_type_param_vars = Set.new(method_type.type_params)
|
656
386
|
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
387
|
+
if class_type_param_vars.intersect?(method_type_param_vars)
|
388
|
+
renamed_method_params = method_type.type_params.map do |name|
|
389
|
+
if class_type_param_vars.include?(name)
|
390
|
+
Types::Variable.fresh(name).name
|
391
|
+
else
|
392
|
+
name
|
393
|
+
end
|
394
|
+
end
|
395
|
+
method_params = class_params + renamed_method_params
|
663
396
|
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
end
|
397
|
+
sub = Substitution.build(method_type.type_params, Types::Variable.build(renamed_method_params))
|
398
|
+
else
|
399
|
+
method_params = class_params + method_type.type_params
|
400
|
+
sub = Substitution.build([], [])
|
401
|
+
end
|
670
402
|
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
),
|
682
|
-
member: member,
|
683
|
-
defined_in: type_name,
|
684
|
-
implemented_in: type_name
|
403
|
+
method_type = method_type.map_type {|ty| ty.sub(sub) }
|
404
|
+
method_type = method_type.update(
|
405
|
+
type_params: method_params,
|
406
|
+
type: method_type.type.with_return_type(
|
407
|
+
Types::ClassInstance.new(
|
408
|
+
name: type_name,
|
409
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
410
|
+
location: nil
|
411
|
+
)
|
412
|
+
)
|
685
413
|
)
|
686
|
-
],
|
687
|
-
accessibility: accessibility,
|
688
|
-
alias_of: nil
|
689
|
-
)
|
690
|
-
end
|
691
414
|
|
692
|
-
if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
|
693
|
-
definition.methods[:"#{name}="] = Definition::Method.new(
|
694
|
-
super_method: nil,
|
695
|
-
defs: [
|
696
415
|
Definition::Method::TypeDef.new(
|
697
|
-
type:
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
member: member,
|
706
|
-
defined_in: type_name,
|
707
|
-
implemented_in: type_name
|
708
|
-
),
|
709
|
-
],
|
710
|
-
accessibility: accessibility,
|
416
|
+
type: method_type,
|
417
|
+
member: initialize_def.member,
|
418
|
+
defined_in: initialize_def.defined_in,
|
419
|
+
implemented_in: initialize_def.implemented_in
|
420
|
+
)
|
421
|
+
end,
|
422
|
+
accessibility: :public,
|
423
|
+
annotations: [],
|
711
424
|
alias_of: nil
|
712
425
|
)
|
713
426
|
end
|
714
|
-
|
715
|
-
if ivar_name
|
716
|
-
definition.instance_variables[ivar_name] = Definition::Variable.new(
|
717
|
-
parent_variable: nil,
|
718
|
-
type: type,
|
719
|
-
declared_in: type_name
|
720
|
-
)
|
721
|
-
end
|
722
|
-
|
723
|
-
when AST::Members::InstanceVariable
|
724
|
-
definition.instance_variables[member.name] = Definition::Variable.new(
|
725
|
-
parent_variable: nil,
|
726
|
-
type: member.type,
|
727
|
-
declared_in: type_name
|
728
|
-
)
|
729
|
-
|
730
|
-
when AST::Members::ClassVariable
|
731
|
-
definition.class_variables[member.name] = Definition::Variable.new(
|
732
|
-
parent_variable: nil,
|
733
|
-
type: member.type,
|
734
|
-
declared_in: type_name
|
735
|
-
)
|
736
|
-
|
737
427
|
end
|
738
428
|
end
|
739
429
|
end
|
740
|
-
|
741
|
-
entry.decls.each do |d|
|
742
|
-
d.decl.members.each do |member|
|
743
|
-
case member
|
744
|
-
when AST::Members::Alias
|
745
|
-
if member.instance?
|
746
|
-
UnknownMethodAliasError.check!(
|
747
|
-
methods: definition.methods,
|
748
|
-
original_name: member.old_name,
|
749
|
-
aliased_name: member.new_name,
|
750
|
-
location: member.location
|
751
|
-
)
|
752
|
-
|
753
|
-
DuplicatedMethodDefinitionError.check!(
|
754
|
-
decl: d.decl,
|
755
|
-
methods: definition.methods,
|
756
|
-
name: member.new_name,
|
757
|
-
location: member.location
|
758
|
-
)
|
759
|
-
|
760
|
-
original_method = definition.methods[member.old_name]
|
761
|
-
|
762
|
-
definition.methods[member.new_name] = Definition::Method.new(
|
763
|
-
super_method: original_method.super_method,
|
764
|
-
defs: original_method.defs,
|
765
|
-
accessibility: original_method.accessibility,
|
766
|
-
alias_of: original_method,
|
767
|
-
annotations: original_method.annotations
|
768
|
-
)
|
769
|
-
end
|
770
|
-
end
|
771
|
-
end
|
772
|
-
end
|
773
|
-
|
774
|
-
entry.decls.each do |d|
|
775
|
-
validate_parameter_variance(
|
776
|
-
decl: d.decl,
|
777
|
-
methods: definition.methods
|
778
|
-
)
|
779
|
-
end
|
780
430
|
end
|
781
431
|
end
|
782
432
|
end
|
@@ -791,277 +441,313 @@ module RBS
|
|
791
441
|
end
|
792
442
|
end
|
793
443
|
|
794
|
-
def
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
case decl
|
803
|
-
when AST::Declarations::Class
|
804
|
-
if super_class = decl.super_class
|
805
|
-
result = calculator.in_inherit(name: super_class.name, args: super_class.args, variables: param_names)
|
806
|
-
|
807
|
-
validate_params_with type_params, result: result do |param|
|
808
|
-
errors.push InvalidVarianceAnnotationError::InheritanceError.new(
|
809
|
-
param: param
|
810
|
-
)
|
811
|
-
end
|
444
|
+
def source_location(source, decl)
|
445
|
+
case source
|
446
|
+
when nil
|
447
|
+
decl.location
|
448
|
+
when :super
|
449
|
+
case decl
|
450
|
+
when AST::Declarations::Class
|
451
|
+
decl.super_class&.location
|
812
452
|
end
|
453
|
+
else
|
454
|
+
source.location
|
813
455
|
end
|
456
|
+
end
|
814
457
|
|
815
|
-
|
458
|
+
def validate_type_params(definition, ancestors:, methods:)
|
459
|
+
type_params = definition.type_params_decl
|
816
460
|
|
817
|
-
|
818
|
-
|
819
|
-
when AST::Members::Include
|
820
|
-
if member.name.class?
|
821
|
-
result = calculator.in_inherit(name: member.name, args: member.args, variables: param_names)
|
461
|
+
calculator = VarianceCalculator.new(builder: self)
|
462
|
+
param_names = type_params.each.map(&:name)
|
822
463
|
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
464
|
+
ancestors.each_ancestor do |ancestor|
|
465
|
+
case ancestor
|
466
|
+
when Definition::Ancestor::Instance
|
467
|
+
result = calculator.in_inherit(name: ancestor.name, args: ancestor.args, variables: param_names)
|
468
|
+
validate_params_with(type_params, result: result) do |param|
|
469
|
+
decl = case entry = definition.entry
|
470
|
+
when Environment::ModuleEntry, Environment::ClassEntry
|
471
|
+
entry.primary.decl
|
472
|
+
when Environment::SingleEntry
|
473
|
+
entry.decl
|
474
|
+
end
|
475
|
+
|
476
|
+
raise InvalidVarianceAnnotationError.new(
|
477
|
+
type_name: definition.type_name,
|
478
|
+
param: param,
|
479
|
+
location: source_location(ancestor.source, decl)
|
480
|
+
)
|
829
481
|
end
|
830
482
|
end
|
831
483
|
end
|
832
484
|
|
833
|
-
methods.each do |
|
834
|
-
|
835
|
-
|
485
|
+
methods.each do |defn|
|
486
|
+
next if defn.name == :initialize
|
487
|
+
|
488
|
+
method_types = case original = defn.original
|
489
|
+
when AST::Members::MethodDefinition
|
490
|
+
original.types
|
491
|
+
when AST::Members::AttrWriter, AST::Members::AttrReader, AST::Members::AttrAccessor
|
492
|
+
if defn.name.to_s.end_with?("=")
|
493
|
+
[
|
494
|
+
MethodType.new(
|
495
|
+
type_params: [],
|
496
|
+
type: Types::Function.empty(original.type).update(
|
497
|
+
required_positionals: [
|
498
|
+
Types::Function::Param.new(type: original.type, name: original.name)
|
499
|
+
]
|
500
|
+
),
|
501
|
+
block: nil,
|
502
|
+
location: original.location
|
503
|
+
)
|
504
|
+
]
|
505
|
+
else
|
506
|
+
[
|
507
|
+
MethodType.new(
|
508
|
+
type_params: [],
|
509
|
+
type: Types::Function.empty(original.type),
|
510
|
+
block: nil,
|
511
|
+
location: original.location
|
512
|
+
)
|
513
|
+
]
|
514
|
+
end
|
515
|
+
when AST::Members::Alias
|
516
|
+
nil
|
517
|
+
when nil
|
518
|
+
nil
|
519
|
+
end
|
520
|
+
|
521
|
+
if method_types
|
522
|
+
method_types.each do |method_type|
|
836
523
|
result = calculator.in_method_type(method_type: method_type, variables: param_names)
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
param: param
|
524
|
+
validate_params_with(type_params, result: result) do |param|
|
525
|
+
raise InvalidVarianceAnnotationError.new(
|
526
|
+
type_name: definition.type_name,
|
527
|
+
param: param,
|
528
|
+
location: method_type.location
|
843
529
|
)
|
844
530
|
end
|
845
531
|
end
|
846
532
|
end
|
847
533
|
end
|
534
|
+
end
|
848
535
|
|
849
|
-
|
850
|
-
|
851
|
-
|
536
|
+
def insert_variable(type_name, variables, name:, type:)
|
537
|
+
variables[name] = Definition::Variable.new(
|
538
|
+
parent_variable: variables[name],
|
539
|
+
type: type,
|
540
|
+
declared_in: type_name
|
541
|
+
)
|
852
542
|
end
|
853
543
|
|
854
|
-
def
|
855
|
-
|
856
|
-
|
544
|
+
def define_methods(definition, interface_methods:, methods:, super_interface_method:)
|
545
|
+
methods.each do |method_def|
|
546
|
+
method_name = method_def.name
|
547
|
+
original = method_def.original
|
857
548
|
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
ancestors: [Definition::Ancestor::Singleton.new(name: type_name)]
|
862
|
-
)
|
549
|
+
if original.is_a?(AST::Members::Alias)
|
550
|
+
existing_method = interface_methods[method_name] || definition.methods[method_name]
|
551
|
+
original_method = interface_methods[original.old_name] || definition.methods[original.old_name]
|
863
552
|
|
864
|
-
|
865
|
-
|
866
|
-
|
553
|
+
unless original_method
|
554
|
+
raise UnknownMethodAliasError.new(
|
555
|
+
original_name: original.old_name,
|
556
|
+
aliased_name: original.new_name,
|
557
|
+
location: original.location
|
558
|
+
)
|
559
|
+
end
|
867
560
|
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
end
|
561
|
+
method = Definition::Method.new(
|
562
|
+
super_method: existing_method,
|
563
|
+
defs: original_method.defs.map do |defn|
|
564
|
+
defn.update(defined_in: definition.type_name, implemented_in: definition.type_name)
|
565
|
+
end,
|
566
|
+
accessibility: method_def.accessibility,
|
567
|
+
alias_of: original_method
|
568
|
+
)
|
569
|
+
else
|
570
|
+
if interface_methods.key?(method_name)
|
571
|
+
interface_method = interface_methods[method_name]
|
873
572
|
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
accessibility: visibility,
|
880
|
-
alias_of: nil
|
881
|
-
)
|
882
|
-
definition.methods[method_name] = members.inject(m) do |original, new|
|
883
|
-
defs = new.types.map do |type|
|
884
|
-
Definition::Method::TypeDef.new(
|
885
|
-
type: type,
|
886
|
-
member: new,
|
887
|
-
defined_in: type_name,
|
888
|
-
implemented_in: type_name
|
889
|
-
)
|
890
|
-
end
|
891
|
-
Definition::Method.new(
|
892
|
-
super_method: nil,
|
893
|
-
defs: defs + original.defs,
|
894
|
-
accessibility: original.accessibility,
|
895
|
-
alias_of: nil
|
573
|
+
if original = method_def.original
|
574
|
+
raise DuplicatedMethodDefinitionError.new(
|
575
|
+
type: definition.self_type,
|
576
|
+
method_name: method_name,
|
577
|
+
members: [original]
|
896
578
|
)
|
897
579
|
end
|
898
|
-
end
|
899
580
|
|
900
|
-
|
901
|
-
|
902
|
-
case member
|
903
|
-
when AST::Members::Alias
|
904
|
-
if member.singleton?
|
905
|
-
UnknownMethodAliasError.check!(
|
906
|
-
methods: definition.methods,
|
907
|
-
original_name: member.old_name,
|
908
|
-
aliased_name: member.new_name,
|
909
|
-
location: member.location
|
910
|
-
)
|
581
|
+
definition.methods[method_name] = interface_method
|
582
|
+
end
|
911
583
|
|
912
|
-
|
913
|
-
decl: d.decl,
|
914
|
-
methods: definition.methods,
|
915
|
-
name: member.new_name,
|
916
|
-
location: member.location
|
917
|
-
)
|
584
|
+
existing_method = definition.methods[method_name]
|
918
585
|
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
end
|
586
|
+
case original
|
587
|
+
when AST::Members::MethodDefinition
|
588
|
+
defs = original.types.map do |method_type|
|
589
|
+
Definition::Method::TypeDef.new(
|
590
|
+
type: method_type,
|
591
|
+
member: original,
|
592
|
+
defined_in: definition.type_name,
|
593
|
+
implemented_in: definition.type_name
|
594
|
+
)
|
929
595
|
end
|
930
|
-
end
|
931
596
|
|
932
|
-
|
933
|
-
|
934
|
-
|
597
|
+
# @type var accessibility: RBS::Definition::accessibility
|
598
|
+
accessibility = if method_name == :initialize
|
599
|
+
:private
|
600
|
+
else
|
601
|
+
method_def.accessibility
|
602
|
+
end
|
935
603
|
|
936
|
-
|
937
|
-
|
604
|
+
method = Definition::Method.new(
|
605
|
+
super_method: existing_method,
|
606
|
+
defs: defs,
|
607
|
+
accessibility: accessibility,
|
608
|
+
alias_of: nil
|
609
|
+
)
|
938
610
|
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
611
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
612
|
+
method_type = if method_name.to_s.end_with?("=")
|
613
|
+
# setter
|
614
|
+
MethodType.new(
|
615
|
+
type_params: [],
|
616
|
+
type: Types::Function.empty(original.type).update(
|
617
|
+
required_positionals: [
|
618
|
+
Types::Function::Param.new(type: original.type, name: original.name)
|
619
|
+
]
|
620
|
+
),
|
621
|
+
block: nil,
|
622
|
+
location: nil
|
623
|
+
)
|
624
|
+
else
|
625
|
+
# getter
|
626
|
+
MethodType.new(
|
627
|
+
type_params: [],
|
628
|
+
type: Types::Function.empty(original.type),
|
629
|
+
block: nil,
|
630
|
+
location: nil
|
631
|
+
)
|
632
|
+
end
|
633
|
+
defs = [
|
634
|
+
Definition::Method::TypeDef.new(
|
635
|
+
type: method_type,
|
636
|
+
member: original,
|
637
|
+
defined_in: definition.type_name,
|
638
|
+
implemented_in: definition.type_name
|
639
|
+
)
|
640
|
+
]
|
944
641
|
|
945
|
-
|
946
|
-
|
642
|
+
method = Definition::Method.new(
|
643
|
+
super_method: existing_method,
|
644
|
+
defs: defs,
|
645
|
+
accessibility: method_def.accessibility,
|
646
|
+
alias_of: nil
|
647
|
+
)
|
947
648
|
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
649
|
+
when nil
|
650
|
+
unless definition.methods.key?(method_name)
|
651
|
+
raise InvalidOverloadMethodError.new(
|
652
|
+
type_name: definition.type_name,
|
653
|
+
method_name: method_name,
|
654
|
+
kind: :instance,
|
655
|
+
members: method_def.overloads
|
656
|
+
)
|
657
|
+
end
|
957
658
|
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
659
|
+
if !super_interface_method && existing_method.defs.any? {|defn| defn.defined_in.interface? }
|
660
|
+
super_method = existing_method.super_method
|
661
|
+
else
|
662
|
+
super_method = existing_method
|
663
|
+
end
|
963
664
|
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
665
|
+
method = Definition::Method.new(
|
666
|
+
super_method: super_method,
|
667
|
+
defs: existing_method.defs.map do |defn|
|
668
|
+
defn.update(implemented_in: definition.type_name)
|
669
|
+
end,
|
670
|
+
accessibility: existing_method.accessibility,
|
671
|
+
alias_of: existing_method.alias_of
|
672
|
+
)
|
673
|
+
end
|
674
|
+
end
|
969
675
|
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
annotations: [AST::Annotation.new(location: nil, string: "rbs:test:target")],
|
979
|
-
alias_of: nil
|
980
|
-
)
|
981
|
-
end
|
676
|
+
method_def.overloads.each do |overload|
|
677
|
+
type_defs = overload.types.map do |method_type|
|
678
|
+
Definition::Method::TypeDef.new(
|
679
|
+
type: method_type,
|
680
|
+
member: overload,
|
681
|
+
defined_in: definition.type_name,
|
682
|
+
implemented_in: definition.type_name
|
683
|
+
)
|
982
684
|
end
|
983
685
|
|
984
|
-
|
985
|
-
|
986
|
-
case member
|
987
|
-
when AST::Members::ClassInstanceVariable
|
988
|
-
definition.instance_variables[member.name] = Definition::Variable.new(
|
989
|
-
parent_variable: nil,
|
990
|
-
type: member.type,
|
991
|
-
declared_in: type_name
|
992
|
-
)
|
686
|
+
method.defs.unshift(*type_defs)
|
687
|
+
end
|
993
688
|
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
end
|
1001
|
-
end
|
1002
|
-
end
|
689
|
+
definition.methods[method_name] = method
|
690
|
+
end
|
691
|
+
|
692
|
+
interface_methods.each do |name, method|
|
693
|
+
unless methods.methods.key?(name)
|
694
|
+
merge_method(definition.type_name, definition.methods, name, method, Substitution.new)
|
1003
695
|
end
|
1004
696
|
end
|
1005
697
|
end
|
1006
698
|
|
1007
|
-
def
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
when Definition::Ancestor::Instance
|
1012
|
-
Substitution.build(current_definition.type_params, ancestor.args)
|
1013
|
-
when Definition::Ancestor::Singleton
|
1014
|
-
Substitution.build([], [])
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
# @type var kind: method_kind
|
1018
|
-
kind = case ancestor
|
1019
|
-
when Definition::Ancestor::Instance
|
1020
|
-
:instance
|
1021
|
-
when Definition::Ancestor::Singleton
|
1022
|
-
:singleton
|
1023
|
-
end
|
1024
|
-
|
1025
|
-
current_definition.methods.each do |name, method|
|
1026
|
-
merge_method type_name, definition.methods, name, method, sub, kind: kind
|
1027
|
-
end
|
699
|
+
def merge_definition(src:, dest:, subst:, implemented_in: :keep, keep_super: false)
|
700
|
+
src.methods.each do |name, method|
|
701
|
+
merge_method(dest.type_name, dest.methods, name, method, subst, implemented_in: implemented_in, keep_super: keep_super)
|
702
|
+
end
|
1028
703
|
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
704
|
+
src.instance_variables.each do |name, variable|
|
705
|
+
merge_variable(dest.instance_variables, name, variable, subst, keep_super: keep_super)
|
706
|
+
end
|
1032
707
|
|
1033
|
-
|
1034
|
-
|
1035
|
-
end
|
1036
|
-
end
|
708
|
+
src.class_variables.each do |name, variable|
|
709
|
+
merge_variable(dest.class_variables, name, variable, subst, keep_super: keep_super)
|
1037
710
|
end
|
1038
711
|
end
|
1039
712
|
|
1040
|
-
def merge_variable(variables, name, variable)
|
713
|
+
def merge_variable(variables, name, variable, sub, keep_super: false)
|
1041
714
|
super_variable = variables[name]
|
1042
715
|
|
1043
716
|
variables[name] = Definition::Variable.new(
|
1044
|
-
parent_variable: super_variable,
|
1045
|
-
type: variable.type,
|
717
|
+
parent_variable: keep_super ? variable.parent_variable : super_variable,
|
718
|
+
type: sub.empty? ? variable.type : variable.type.sub(sub),
|
1046
719
|
declared_in: variable.declared_in
|
1047
720
|
)
|
1048
721
|
end
|
1049
722
|
|
1050
|
-
def merge_method(type_name, methods, name, method, sub,
|
1051
|
-
|
723
|
+
def merge_method(type_name, methods, name, method, sub, implemented_in: :keep, keep_super: false)
|
724
|
+
defs = method.defs.yield_self do |defs|
|
725
|
+
if sub.empty? && implemented_in == :keep
|
726
|
+
defs
|
727
|
+
else
|
728
|
+
defs.map do |defn|
|
729
|
+
defn.update(
|
730
|
+
type: sub.empty? ? defn.type : defn.type.sub(sub),
|
731
|
+
implemented_in: case implemented_in
|
732
|
+
when :keep
|
733
|
+
defn.implemented_in
|
734
|
+
when nil
|
735
|
+
nil
|
736
|
+
else
|
737
|
+
implemented_in
|
738
|
+
end
|
739
|
+
)
|
740
|
+
end
|
741
|
+
end
|
742
|
+
end
|
1052
743
|
|
1053
|
-
|
1054
|
-
raise InvalidOverloadMethodError.new(type_name: type_name, method_name: name, kind: kind, members: method.members) unless super_method
|
1055
|
-
method.defs + super_method.defs
|
1056
|
-
else
|
1057
|
-
method.defs
|
1058
|
-
end
|
744
|
+
super_method = methods[name]
|
1059
745
|
|
1060
746
|
methods[name] = Definition::Method.new(
|
1061
|
-
super_method: super_method,
|
747
|
+
super_method: keep_super ? method.super_method : super_method,
|
1062
748
|
accessibility: method.accessibility,
|
1063
|
-
defs:
|
1064
|
-
alias_of:
|
749
|
+
defs: defs,
|
750
|
+
alias_of: method.alias_of
|
1065
751
|
)
|
1066
752
|
end
|
1067
753
|
|
@@ -1086,103 +772,6 @@ module RBS
|
|
1086
772
|
end
|
1087
773
|
end
|
1088
774
|
|
1089
|
-
def build_interface(type_name)
|
1090
|
-
try_cache(type_name, cache: interface_cache) do
|
1091
|
-
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
1092
|
-
declaration = entry.decl
|
1093
|
-
ensure_namespace!(type_name.namespace, location: declaration.location)
|
1094
|
-
|
1095
|
-
self_type = Types::Interface.new(
|
1096
|
-
name: type_name,
|
1097
|
-
args: Types::Variable.build(declaration.type_params.each.map(&:name)),
|
1098
|
-
location: nil
|
1099
|
-
)
|
1100
|
-
|
1101
|
-
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: nil).tap do |definition|
|
1102
|
-
include_members = []
|
1103
|
-
def_members = []
|
1104
|
-
alias_members = []
|
1105
|
-
|
1106
|
-
declaration.members.each do |member|
|
1107
|
-
case member
|
1108
|
-
when AST::Members::Include
|
1109
|
-
include_members << member
|
1110
|
-
when AST::Members::MethodDefinition
|
1111
|
-
def_members << member
|
1112
|
-
when AST::Members::Alias
|
1113
|
-
alias_members << member
|
1114
|
-
end
|
1115
|
-
end
|
1116
|
-
|
1117
|
-
include_members.each do |member|
|
1118
|
-
NoMixinFoundError.check!(member.name, env: env, member: member)
|
1119
|
-
|
1120
|
-
mixin = build_interface(member.name)
|
1121
|
-
|
1122
|
-
args = member.args
|
1123
|
-
# @type var interface_entry: Environment::SingleEntry[TypeName, AST::Declarations::Interface]
|
1124
|
-
interface_entry = _ = mixin.entry
|
1125
|
-
type_params = interface_entry.decl.type_params
|
1126
|
-
|
1127
|
-
InvalidTypeApplicationError.check!(
|
1128
|
-
type_name: type_name,
|
1129
|
-
args: args,
|
1130
|
-
params: type_params.each.map(&:name),
|
1131
|
-
location: member.location
|
1132
|
-
)
|
1133
|
-
|
1134
|
-
sub = Substitution.build(type_params.each.map(&:name), args)
|
1135
|
-
mixin.methods.each do |name, method|
|
1136
|
-
definition.methods[name] = method.sub(sub)
|
1137
|
-
end
|
1138
|
-
end
|
1139
|
-
|
1140
|
-
def_members.each do |member|
|
1141
|
-
DuplicatedMethodDefinitionError.check!(
|
1142
|
-
decl: declaration,
|
1143
|
-
methods: definition.methods,
|
1144
|
-
name: member.name,
|
1145
|
-
location: member.location
|
1146
|
-
)
|
1147
|
-
|
1148
|
-
method = Definition::Method.new(
|
1149
|
-
super_method: nil,
|
1150
|
-
defs: member.types.map do |method_type|
|
1151
|
-
Definition::Method::TypeDef.new(
|
1152
|
-
type: method_type,
|
1153
|
-
member: member,
|
1154
|
-
defined_in: type_name,
|
1155
|
-
implemented_in: nil
|
1156
|
-
)
|
1157
|
-
end,
|
1158
|
-
accessibility: :public,
|
1159
|
-
alias_of: nil
|
1160
|
-
)
|
1161
|
-
definition.methods[member.name] = method
|
1162
|
-
end
|
1163
|
-
|
1164
|
-
alias_members.each do |member|
|
1165
|
-
UnknownMethodAliasError.check!(
|
1166
|
-
methods: definition.methods,
|
1167
|
-
original_name: member.old_name,
|
1168
|
-
aliased_name: member.new_name,
|
1169
|
-
location: member.location
|
1170
|
-
)
|
1171
|
-
|
1172
|
-
DuplicatedMethodDefinitionError.check!(
|
1173
|
-
decl: declaration,
|
1174
|
-
methods: definition.methods,
|
1175
|
-
name: member.new_name,
|
1176
|
-
location: member.location
|
1177
|
-
)
|
1178
|
-
|
1179
|
-
# FIXME: may cause a problem if #old_name has super type
|
1180
|
-
definition.methods[member.new_name] = definition.methods[member.old_name]
|
1181
|
-
end
|
1182
|
-
end
|
1183
|
-
end
|
1184
|
-
end
|
1185
|
-
|
1186
775
|
def expand_alias(type_name)
|
1187
776
|
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
|
1188
777
|
ensure_namespace!(type_name.namespace, location: entry.decl.location)
|