rbs 0.3.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +7 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +39 -0
- data/COPYING +1 -1
- data/Gemfile +16 -2
- data/README.md +87 -48
- data/Rakefile +54 -22
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/bin/test_runner.rb +0 -2
- data/docs/sigs.md +6 -6
- data/docs/stdlib.md +3 -5
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +3 -0
- data/lib/rbs/ast/declarations.rb +115 -14
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +315 -122
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +51 -45
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +802 -604
- data/lib/rbs/environment.rb +352 -210
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +184 -3
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/parser.y +95 -27
- data/lib/rbs/prototype/rb.rb +119 -117
- data/lib/rbs/prototype/rbi.rb +5 -3
- data/lib/rbs/prototype/runtime.rb +34 -7
- data/lib/rbs/substitution.rb +12 -1
- data/lib/rbs/test.rb +82 -3
- data/lib/rbs/test/errors.rb +5 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +35 -19
- data/lib/rbs/test/setup_helper.rb +29 -0
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +116 -0
- data/lib/rbs/test/type_check.rb +43 -7
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +51 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +127 -91
- data/rbs.gemspec +0 -9
- data/schema/annotation.json +14 -0
- data/schema/comment.json +26 -0
- data/schema/decls.json +353 -0
- data/schema/function.json +87 -0
- data/schema/location.json +56 -0
- data/schema/members.json +248 -0
- data/schema/methodType.json +44 -0
- data/schema/types.json +299 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/encoding.rbs +2 -0
- data/stdlib/builtin/enumerable.rbs +4 -4
- data/stdlib/builtin/enumerator.rbs +3 -1
- data/stdlib/builtin/fiber.rbs +5 -1
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/proc.rbs +1 -2
- data/stdlib/builtin/symbol.rbs +1 -1
- data/stdlib/builtin/thread.rbs +2 -2
- data/stdlib/csv/csv.rbs +4 -6
- data/stdlib/fiber/fiber.rbs +117 -0
- data/stdlib/json/json.rbs +1 -1
- data/stdlib/logger/formatter.rbs +23 -0
- data/stdlib/logger/log_device.rbs +39 -0
- data/stdlib/logger/logger.rbs +507 -0
- data/stdlib/logger/period.rbs +7 -0
- data/stdlib/logger/severity.rbs +8 -0
- data/stdlib/mutex_m/mutex_m.rbs +77 -0
- data/stdlib/pathname/pathname.rbs +6 -6
- data/stdlib/prime/integer-extension.rbs +1 -1
- data/stdlib/prime/prime.rbs +44 -44
- data/stdlib/pty/pty.rbs +159 -0
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +28 -116
- data/lib/rbs/test/test_helper.rb +0 -183
@@ -1,188 +1,375 @@
|
|
1
1
|
module RBS
|
2
2
|
class DefinitionBuilder
|
3
3
|
attr_reader :env
|
4
|
+
attr_reader :type_name_resolver
|
5
|
+
|
4
6
|
attr_reader :instance_cache
|
5
7
|
attr_reader :singleton_cache
|
8
|
+
attr_reader :interface_cache
|
9
|
+
|
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_given?
|
40
|
+
yield super_class if super_class
|
41
|
+
self_types&.each(&block)
|
42
|
+
included_modules&.each(&block)
|
43
|
+
prepended_modules&.each(&block)
|
44
|
+
extended_modules&.each(&block)
|
45
|
+
else
|
46
|
+
enum_for :each_ancestor
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.class_instance(type_name:, params:, super_class:)
|
51
|
+
new(
|
52
|
+
type_name: type_name,
|
53
|
+
params: params,
|
54
|
+
super_class: super_class,
|
55
|
+
self_types: nil,
|
56
|
+
included_modules: [],
|
57
|
+
prepended_modules: [],
|
58
|
+
extended_modules: nil
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.singleton(type_name:, super_class:)
|
63
|
+
new(
|
64
|
+
type_name: type_name,
|
65
|
+
params: nil,
|
66
|
+
super_class: super_class,
|
67
|
+
self_types: nil,
|
68
|
+
included_modules: nil,
|
69
|
+
prepended_modules: nil,
|
70
|
+
extended_modules: []
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.module_instance(type_name:, params:)
|
75
|
+
new(
|
76
|
+
type_name: type_name,
|
77
|
+
params: params,
|
78
|
+
self_types: [],
|
79
|
+
included_modules: [],
|
80
|
+
prepended_modules: [],
|
81
|
+
super_class: nil,
|
82
|
+
extended_modules: nil
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
6
86
|
|
7
87
|
def initialize(env:)
|
8
88
|
@env = env
|
89
|
+
@type_name_resolver = TypeNameResolver.from_env(env)
|
90
|
+
|
9
91
|
@instance_cache = {}
|
10
92
|
@singleton_cache = {}
|
93
|
+
@interface_cache = {}
|
94
|
+
|
95
|
+
@one_instance_cache = {}
|
96
|
+
@one_singleton_cache = {}
|
97
|
+
|
98
|
+
@instance_ancestors_cache = {}
|
99
|
+
@singleton_ancestor_cache = {}
|
100
|
+
|
101
|
+
@one_instance_ancestors_cache = {}
|
102
|
+
@one_singleton_ancestors_cache = {}
|
11
103
|
end
|
12
104
|
|
13
|
-
def
|
14
|
-
|
15
|
-
namespace = self_ancestor.name.absolute!.to_namespace
|
105
|
+
def validate_super_class!(type_name, entry)
|
106
|
+
with_super_classes = entry.decls.select {|d| d.decl.super_class }
|
16
107
|
|
17
|
-
|
18
|
-
ancestors: building_ancestors,
|
19
|
-
location: location || decl.location)
|
20
|
-
building_ancestors.push self_ancestor
|
108
|
+
return if with_super_classes.size <= 1
|
21
109
|
|
22
|
-
|
23
|
-
|
24
|
-
args
|
25
|
-
|
26
|
-
|
27
|
-
InvalidTypeApplicationError.check!(
|
28
|
-
type_name: self_ancestor.name,
|
29
|
-
args: args,
|
30
|
-
params: decl.type_params,
|
31
|
-
location: location || decl.location
|
32
|
-
)
|
110
|
+
super_types = with_super_classes.map do |d|
|
111
|
+
super_class = d.decl.super_class
|
112
|
+
Types::ClassInstance.new(name: super_class.name, args: super_class.args, location: nil)
|
113
|
+
end
|
33
114
|
|
34
|
-
|
115
|
+
super_types.uniq!
|
35
116
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
)
|
44
|
-
end || Definition::Ancestor::Instance.new(name: BuiltinNames::Object.name, args: [])
|
117
|
+
return if super_types.size == 1
|
118
|
+
|
119
|
+
raise SuperclassMismatchError.new(name: type_name, super_classes: super_types, entry: entry)
|
120
|
+
end
|
121
|
+
|
122
|
+
def one_instance_ancestors(type_name)
|
123
|
+
as = one_instance_ancestors_cache[type_name] and return as
|
45
124
|
|
46
|
-
|
125
|
+
entry = env.class_decls[type_name] or raise "Unknown name for one_instance_ancestors: #{type_name}"
|
126
|
+
params = entry.type_params.each.map(&:name)
|
127
|
+
|
128
|
+
case entry
|
129
|
+
when Environment::ClassEntry
|
130
|
+
validate_super_class!(type_name, entry)
|
131
|
+
primary = entry.primary
|
132
|
+
super_class = primary.decl.super_class
|
133
|
+
|
134
|
+
if type_name != BuiltinNames::BasicObject.name
|
135
|
+
if super_class
|
136
|
+
super_name = super_class.name
|
137
|
+
super_args = super_class.args
|
138
|
+
else
|
139
|
+
super_name = BuiltinNames::Object.name
|
140
|
+
super_args = []
|
47
141
|
end
|
142
|
+
|
143
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
144
|
+
|
145
|
+
ancestors = OneAncestors.class_instance(
|
146
|
+
type_name: type_name,
|
147
|
+
params: params,
|
148
|
+
super_class: Definition::Ancestor::Instance.new(name: super_name, args: super_args)
|
149
|
+
)
|
150
|
+
else
|
151
|
+
ancestors = OneAncestors.class_instance(
|
152
|
+
type_name: type_name,
|
153
|
+
params: params,
|
154
|
+
super_class: nil
|
155
|
+
)
|
48
156
|
end
|
157
|
+
when Environment::ModuleEntry
|
158
|
+
ancestors = OneAncestors.module_instance(type_name: type_name, params: params)
|
49
159
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
if member.name.class?
|
54
|
-
ancestor = Definition::Ancestor::Instance.new(
|
55
|
-
name: absolute_type_name(member.name, namespace: namespace, location: member.location),
|
56
|
-
args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
|
57
|
-
)
|
58
|
-
build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
|
59
|
-
end
|
60
|
-
end
|
160
|
+
entry.self_types.each do |module_self|
|
161
|
+
NoSelfTypeFoundError.check!(module_self, env: env)
|
162
|
+
ancestors.self_types.push Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
61
163
|
end
|
164
|
+
else
|
165
|
+
raise "Unexpected entry for: #{type_name}"
|
166
|
+
end
|
62
167
|
|
63
|
-
|
168
|
+
mixin_ancestors(entry,
|
169
|
+
included_modules: ancestors.included_modules,
|
170
|
+
prepended_modules: ancestors.prepended_modules,
|
171
|
+
extended_modules: nil)
|
64
172
|
|
65
|
-
|
66
|
-
|
67
|
-
type_name: self_ancestor.name,
|
68
|
-
extension_name: extension.extension_name,
|
69
|
-
extension_params: extension.type_params,
|
70
|
-
class_params: self_ancestor.args.map(&:name),
|
71
|
-
location: extension.location
|
72
|
-
)
|
173
|
+
one_instance_ancestors_cache[type_name] = ancestors
|
174
|
+
end
|
73
175
|
|
74
|
-
|
176
|
+
def one_singleton_ancestors(type_name)
|
177
|
+
as = one_singleton_ancestors_cache[type_name] and return as
|
75
178
|
|
76
|
-
|
77
|
-
case member
|
78
|
-
when AST::Members::Include
|
79
|
-
if member.name.class?
|
80
|
-
ancestor = Definition::Ancestor::Instance.new(
|
81
|
-
name: absolute_type_name(member.name, namespace: namespace, location: member.location),
|
82
|
-
args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
|
83
|
-
)
|
84
|
-
build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
179
|
+
entry = env.class_decls[type_name] or raise "Unknown name for one_singleton_ancestors: #{type_name}"
|
88
180
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
ancestors.unshift(extension_ancestor)
|
181
|
+
case entry
|
182
|
+
when Environment::ClassEntry
|
183
|
+
validate_super_class!(type_name, entry)
|
184
|
+
primary = entry.primary
|
185
|
+
super_class = primary.decl.super_class
|
95
186
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
name: absolute_type_name(member.name, namespace: namespace, location: member.location),
|
102
|
-
args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
|
103
|
-
)
|
104
|
-
build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
|
105
|
-
end
|
106
|
-
end
|
187
|
+
if type_name != BuiltinNames::BasicObject.name
|
188
|
+
if super_class
|
189
|
+
super_name = super_class.name
|
190
|
+
else
|
191
|
+
super_name = BuiltinNames::Object.name
|
107
192
|
end
|
108
|
-
end
|
109
193
|
|
110
|
-
|
111
|
-
case member
|
112
|
-
when AST::Members::Prepend
|
113
|
-
ancestor = Definition::Ancestor::Instance.new(
|
114
|
-
name: absolute_type_name(member.name, namespace: namespace, location: member.location),
|
115
|
-
args: member.args.map {|ty| absolute_type(ty.sub(sub), namespace: namespace) }
|
116
|
-
)
|
117
|
-
build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
|
118
|
-
end
|
119
|
-
end
|
120
|
-
when Definition::Ancestor::Singleton
|
121
|
-
case decl
|
122
|
-
when AST::Declarations::Class
|
123
|
-
if self_ancestor.name == BuiltinNames::BasicObject.name
|
124
|
-
class_ancestor = Definition::Ancestor::Instance.new(
|
125
|
-
name: BuiltinNames::Class.name,
|
126
|
-
args: []
|
127
|
-
)
|
128
|
-
build_ancestors class_ancestor, ancestors: ancestors, building_ancestors: building_ancestors
|
129
|
-
else
|
130
|
-
super_ancestor = decl.super_class&.yield_self do |super_class|
|
131
|
-
Definition::Ancestor::Singleton.new(
|
132
|
-
name: absolute_type_name(super_class.name, namespace: namespace, location: location || decl.location)
|
133
|
-
)
|
134
|
-
end || Definition::Ancestor::Singleton.new(name: BuiltinNames::Object.name)
|
194
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
135
195
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
196
|
+
ancestors = OneAncestors.singleton(
|
197
|
+
type_name: type_name,
|
198
|
+
super_class: Definition::Ancestor::Singleton.new(name: super_name)
|
199
|
+
)
|
200
|
+
else
|
201
|
+
ancestors = OneAncestors.singleton(
|
202
|
+
type_name: type_name,
|
203
|
+
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Class.name, args: [])
|
142
204
|
)
|
143
|
-
build_ancestors module_ancestor, ancestors: ancestors, building_ancestors: building_ancestors
|
144
205
|
end
|
206
|
+
when Environment::ModuleEntry
|
207
|
+
ancestors = OneAncestors.singleton(
|
208
|
+
type_name: type_name,
|
209
|
+
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Module.name, args: [])
|
210
|
+
)
|
211
|
+
|
212
|
+
else
|
213
|
+
raise "Unexpected entry for: #{type_name}"
|
214
|
+
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
|
+
end
|
223
|
+
|
224
|
+
def mixin_ancestors(entry, included_modules:, extended_modules:, prepended_modules:)
|
225
|
+
entry.decls.each do |d|
|
226
|
+
decl = d.decl
|
227
|
+
|
228
|
+
align_params = Substitution.build(
|
229
|
+
decl.type_params.each.map(&:name),
|
230
|
+
Types::Variable.build(entry.type_params.each.map(&:name))
|
231
|
+
)
|
145
232
|
|
146
|
-
decl.
|
233
|
+
decl.each_mixin do |member|
|
147
234
|
case member
|
235
|
+
when AST::Members::Include
|
236
|
+
if included_modules
|
237
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
238
|
+
|
239
|
+
module_name = member.name
|
240
|
+
module_args = member.args.map {|type| type.sub(align_params) }
|
241
|
+
|
242
|
+
included_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
243
|
+
end
|
244
|
+
|
245
|
+
when AST::Members::Prepend
|
246
|
+
if prepended_modules
|
247
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
248
|
+
|
249
|
+
module_name = member.name
|
250
|
+
module_args = member.args.map {|type| type.sub(align_params) }
|
251
|
+
|
252
|
+
prepended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
253
|
+
end
|
254
|
+
|
148
255
|
when AST::Members::Extend
|
149
|
-
if
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
256
|
+
if extended_modules
|
257
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
258
|
+
|
259
|
+
module_name = member.name
|
260
|
+
module_args = member.args
|
261
|
+
|
262
|
+
extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
155
263
|
end
|
156
264
|
end
|
157
265
|
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def instance_ancestors(type_name, building_ancestors: [])
|
270
|
+
as = instance_ancestors_cache[type_name] and return as
|
271
|
+
|
272
|
+
entry = env.class_decls[type_name] or raise "Unknown name for instance_ancestors: #{type_name}"
|
273
|
+
params = entry.type_params.each.map(&:name)
|
274
|
+
args = Types::Variable.build(params)
|
275
|
+
self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
|
276
|
+
|
277
|
+
RecursiveAncestorError.check!(self_ancestor,
|
278
|
+
ancestors: building_ancestors,
|
279
|
+
location: entry.primary.decl.location)
|
280
|
+
building_ancestors.push self_ancestor
|
281
|
+
|
282
|
+
one_ancestors = one_instance_ancestors(type_name)
|
283
|
+
|
284
|
+
ancestors = []
|
285
|
+
|
286
|
+
case entry
|
287
|
+
when Environment::ClassEntry
|
288
|
+
if one_ancestors.super_class
|
289
|
+
super_name = one_ancestors.super_class.name
|
290
|
+
super_args = one_ancestors.super_class.args
|
291
|
+
|
292
|
+
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
293
|
+
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
|
294
|
+
end
|
295
|
+
end
|
158
296
|
|
159
|
-
|
297
|
+
one_ancestors.included_modules.each do |mod|
|
298
|
+
if mod.name.class?
|
299
|
+
name = mod.name
|
300
|
+
args = mod.args
|
301
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
302
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
303
|
+
end
|
304
|
+
end
|
160
305
|
|
161
|
-
|
162
|
-
extension.members.each do |member|
|
163
|
-
case member
|
164
|
-
when AST::Members::Extend
|
165
|
-
if member.name.class?
|
166
|
-
ancestor = Definition::Ancestor::Instance.new(
|
167
|
-
name: absolute_type_name(member.name, namespace: namespace, location: member.location),
|
168
|
-
args: member.args.map {|ty| absolute_type(ty, namespace: namespace) }
|
169
|
-
)
|
170
|
-
build_ancestors ancestor, ancestors: ancestors, building_ancestors: building_ancestors, location: member.location
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
306
|
+
ancestors.unshift(self_ancestor)
|
174
307
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
308
|
+
one_ancestors.prepended_modules.each do |mod|
|
309
|
+
if mod.name.class?
|
310
|
+
name = mod.name
|
311
|
+
args = mod.args
|
312
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
313
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
building_ancestors.pop
|
318
|
+
|
319
|
+
instance_ancestors_cache[type_name] = Definition::InstanceAncestors.new(
|
320
|
+
type_name: type_name,
|
321
|
+
params: params,
|
322
|
+
ancestors: ancestors
|
323
|
+
)
|
324
|
+
end
|
325
|
+
|
326
|
+
def singleton_ancestors(type_name, building_ancestors: [])
|
327
|
+
as = singleton_ancestor_cache[type_name] and return as
|
328
|
+
|
329
|
+
entry = env.class_decls[type_name] or raise "Unknown name for singleton_ancestors: #{type_name}"
|
330
|
+
self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
|
331
|
+
|
332
|
+
RecursiveAncestorError.check!(self_ancestor,
|
333
|
+
ancestors: building_ancestors,
|
334
|
+
location: entry.primary.decl.location)
|
335
|
+
building_ancestors.push self_ancestor
|
336
|
+
|
337
|
+
one_ancestors = one_singleton_ancestors(type_name)
|
338
|
+
|
339
|
+
ancestors = []
|
340
|
+
|
341
|
+
case one_ancestors.super_class
|
342
|
+
when Definition::Ancestor::Instance
|
343
|
+
super_name = one_ancestors.super_class.name
|
344
|
+
super_args = one_ancestors.super_class.args
|
345
|
+
|
346
|
+
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
347
|
+
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
|
348
|
+
|
349
|
+
when Definition::Ancestor::Singleton
|
350
|
+
super_name = one_ancestors.super_class.name
|
351
|
+
|
352
|
+
super_ancestors = singleton_ancestors(super_name, building_ancestors: [])
|
353
|
+
ancestors.unshift(*super_ancestors.ancestors)
|
354
|
+
end
|
355
|
+
|
356
|
+
one_ancestors.extended_modules.each do |mod|
|
357
|
+
if mod.name.class?
|
358
|
+
name = mod.name
|
359
|
+
args = mod.args
|
360
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
361
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
180
362
|
end
|
181
363
|
end
|
182
364
|
|
365
|
+
ancestors.unshift(self_ancestor)
|
366
|
+
|
183
367
|
building_ancestors.pop
|
184
368
|
|
185
|
-
|
369
|
+
singleton_ancestor_cache[type_name] = Definition::SingletonAncestors.new(
|
370
|
+
type_name: type_name,
|
371
|
+
ancestors: ancestors
|
372
|
+
)
|
186
373
|
end
|
187
374
|
|
188
375
|
def each_member_with_accessibility(members, accessibility: :public)
|
@@ -200,334 +387,365 @@ module RBS
|
|
200
387
|
|
201
388
|
def build_instance(type_name)
|
202
389
|
try_cache type_name, cache: instance_cache do
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
390
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
391
|
+
|
392
|
+
case entry
|
393
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
394
|
+
ancestors = instance_ancestors(type_name)
|
395
|
+
self_type = Types::ClassInstance.new(name: type_name,
|
396
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
397
|
+
location: nil)
|
398
|
+
|
399
|
+
definition_pairs = ancestors.ancestors.map do |ancestor|
|
212
400
|
case ancestor
|
213
401
|
when Definition::Ancestor::Instance
|
214
402
|
[ancestor, build_one_instance(ancestor.name)]
|
215
403
|
when Definition::Ancestor::Singleton
|
216
404
|
[ancestor, build_one_singleton(ancestor.name)]
|
217
|
-
|
218
|
-
|
219
|
-
when Definition::Ancestor::ExtensionSingleton
|
220
|
-
[ancestor, build_one_extension_singleton(ancestor.name, extension_name: ancestor.extension_name)]
|
405
|
+
else
|
406
|
+
raise
|
221
407
|
end
|
222
408
|
end
|
223
409
|
|
224
|
-
if
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
410
|
+
if entry.is_a?(Environment::ModuleEntry)
|
411
|
+
entry.self_types.each do |module_self|
|
412
|
+
ancestor = Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
413
|
+
definition_pairs.push(
|
414
|
+
[
|
415
|
+
ancestor,
|
416
|
+
if module_self.name.interface?
|
417
|
+
build_interface(module_self.name)
|
418
|
+
else
|
419
|
+
build_instance(module_self.name)
|
420
|
+
end
|
421
|
+
]
|
422
|
+
)
|
231
423
|
end
|
232
424
|
end
|
233
425
|
|
234
|
-
merge_definitions(definition_pairs,
|
426
|
+
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
427
|
+
|
428
|
+
else
|
429
|
+
raise
|
235
430
|
end
|
236
431
|
end
|
237
432
|
end
|
238
433
|
|
239
434
|
def build_singleton(type_name)
|
240
435
|
try_cache type_name, cache: singleton_cache do
|
241
|
-
|
242
|
-
|
243
|
-
|
436
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
|
437
|
+
|
438
|
+
case entry
|
439
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
440
|
+
ancestors = singleton_ancestors(type_name)
|
441
|
+
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
442
|
+
instance_type = Types::ClassInstance.new(
|
443
|
+
name: type_name,
|
444
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
445
|
+
location: nil
|
446
|
+
)
|
244
447
|
|
245
|
-
|
246
|
-
when AST::Declarations::Class, AST::Declarations::Module
|
247
|
-
ancestors = build_ancestors(self_ancestor)
|
248
|
-
definition_pairs = ancestors.map do |ancestor|
|
448
|
+
definition_pairs = ancestors.ancestors.map do |ancestor|
|
249
449
|
case ancestor
|
250
450
|
when Definition::Ancestor::Instance
|
251
451
|
[ancestor, build_one_instance(ancestor.name)]
|
252
452
|
when Definition::Ancestor::Singleton
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
453
|
+
definition = build_one_singleton(ancestor.name)
|
454
|
+
definition = definition.sub(Substitution.build([], [], instance_type: instance_type))
|
455
|
+
definition = definition.map_method_type do |method_type|
|
456
|
+
s = Substitution.build(
|
457
|
+
method_type.free_variables.to_a,
|
458
|
+
method_type.free_variables.map { Types::Bases::Any.new(location: nil) }
|
459
|
+
)
|
460
|
+
method_type.sub(s)
|
461
|
+
end
|
462
|
+
|
463
|
+
[
|
464
|
+
ancestor,
|
465
|
+
definition
|
466
|
+
]
|
467
|
+
else
|
468
|
+
raise
|
258
469
|
end
|
259
470
|
end
|
260
471
|
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
method_types = initialize_method.method_types.map do |method_type|
|
268
|
-
case method_type
|
269
|
-
when MethodType
|
270
|
-
fvs = method_type.free_variables + class_params
|
271
|
-
unless fvs.empty?
|
272
|
-
param_name_set = Set.new(class_params)
|
273
|
-
bound_variables = method_type.type_params
|
274
|
-
renamed_types = bound_variables.map do |x|
|
275
|
-
if param_name_set.member?(x)
|
276
|
-
Types::Variable.fresh(x)
|
277
|
-
else
|
278
|
-
Types::Variable.new(name: x, location: nil)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
sub = Substitution.build(bound_variables, renamed_types)
|
282
|
-
method_type_params = renamed_types.unshift(*class_params)
|
283
|
-
else
|
284
|
-
sub = Substitution.build([], [])
|
285
|
-
method_type_params = method_type.type_params
|
286
|
-
end
|
472
|
+
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
473
|
+
else
|
474
|
+
raise
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
287
478
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
479
|
+
def method_definition_members(type_name, entry, kind:)
|
480
|
+
interface_methods = {}
|
481
|
+
methods = {}
|
482
|
+
|
483
|
+
entry.decls.each do |d|
|
484
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
485
|
+
case member
|
486
|
+
when AST::Members::MethodDefinition
|
487
|
+
case kind
|
488
|
+
when :singleton
|
489
|
+
next unless member.singleton?
|
490
|
+
when :instance
|
491
|
+
next unless member.instance?
|
492
|
+
end
|
493
|
+
|
494
|
+
methods[member.name] ||= []
|
495
|
+
methods[member.name] << [
|
496
|
+
member.update(types: member.types),
|
497
|
+
accessibility
|
498
|
+
]
|
499
|
+
when AST::Members::Include, AST::Members::Extend
|
500
|
+
if member.name.interface?
|
501
|
+
if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
|
502
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
503
|
+
|
504
|
+
interface_name = member.name
|
505
|
+
interface_args = member.args
|
506
|
+
|
507
|
+
interface_definition = build_interface(interface_name)
|
508
|
+
|
509
|
+
InvalidTypeApplicationError.check!(
|
510
|
+
type_name: interface_name,
|
511
|
+
args: interface_args,
|
512
|
+
params: interface_definition.type_params_decl,
|
513
|
+
location: member.location
|
306
514
|
)
|
515
|
+
|
516
|
+
sub = Substitution.build(interface_definition.type_params, interface_args)
|
517
|
+
|
518
|
+
interface_definition.methods.each do |name, method|
|
519
|
+
interface_methods[name] = [method.sub(sub), member]
|
520
|
+
end
|
307
521
|
end
|
308
522
|
end
|
309
523
|
end
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
result = {}
|
528
|
+
|
529
|
+
interface_methods.each do |name, pair|
|
530
|
+
method_definition, _ = pair
|
531
|
+
result[name] = [:public, method_definition]
|
532
|
+
end
|
533
|
+
|
534
|
+
methods.each do |method_name, array|
|
535
|
+
if result[method_name]
|
536
|
+
unless array.all? {|pair| pair[0].overload? }
|
537
|
+
raise MethodDefinitionConflictWithInterfaceMixinError.new(
|
538
|
+
type_name: type_name,
|
539
|
+
method_name: method_name,
|
540
|
+
kind: :instance,
|
541
|
+
mixin_member: interface_methods[method_name][1],
|
542
|
+
entries: array.map(&:first)
|
543
|
+
)
|
544
|
+
end
|
545
|
+
|
546
|
+
unless array.all? {|pair| pair[1] == :public}
|
547
|
+
raise InconsistentMethodVisibilityError.new(
|
548
|
+
type_name: type_name,
|
549
|
+
method_name: method_name,
|
550
|
+
kind: :instance,
|
551
|
+
member_pairs: array
|
552
|
+
)
|
553
|
+
end
|
554
|
+
|
555
|
+
result[method_name] += array.map(&:first)
|
556
|
+
else
|
557
|
+
case
|
558
|
+
when array.size == 1 && !array[0][0].overload?
|
559
|
+
member, visibility = array[0]
|
560
|
+
result[method_name] = [visibility, nil, member]
|
561
|
+
|
562
|
+
when array.count {|pair| !pair[0].overload? } == 1
|
563
|
+
visibilities = array.group_by {|pair| pair[1] }
|
564
|
+
|
565
|
+
if visibilities.size > 1
|
566
|
+
raise InconsistentMethodVisibilityError.new(
|
567
|
+
type_name: type_name,
|
568
|
+
method_name: method_name,
|
569
|
+
kind: :instance,
|
570
|
+
member_pairs: array
|
571
|
+
)
|
572
|
+
end
|
573
|
+
|
574
|
+
overloads, primary = array.map(&:first).partition(&:overload?)
|
575
|
+
result[method_name] = [array[0][1], nil, *primary, *overloads]
|
310
576
|
|
311
|
-
|
577
|
+
else
|
578
|
+
raise InvalidOverloadMethodError.new(
|
579
|
+
type_name: type_name,
|
580
|
+
method_name: method_name,
|
581
|
+
kind: :instance,
|
582
|
+
members: array.map(&:first)
|
583
|
+
)
|
584
|
+
end
|
312
585
|
end
|
313
586
|
end
|
587
|
+
|
588
|
+
result
|
314
589
|
end
|
315
590
|
|
316
|
-
def build_one_instance(type_name
|
317
|
-
|
318
|
-
|
319
|
-
raise "Unknown extension: #{type_name} (#{extension_name})"
|
320
|
-
else
|
321
|
-
env.find_class(type_name)
|
322
|
-
end
|
323
|
-
|
324
|
-
case decl
|
325
|
-
when AST::Declarations::Interface
|
326
|
-
build_interface type_name, decl
|
327
|
-
else
|
328
|
-
namespace = type_name.to_namespace
|
591
|
+
def build_one_instance(type_name)
|
592
|
+
try_cache(type_name, cache: one_instance_cache) do
|
593
|
+
entry = env.class_decls[type_name]
|
329
594
|
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
location: nil)
|
335
|
-
ancestors = [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
|
336
|
-
when AST::Declarations::Extension
|
337
|
-
self_type = Types::ClassInstance.new(name: type_name, args: Types::Variable.build(decl.type_params), location: nil)
|
338
|
-
ancestors = [Definition::Ancestor::ExtensionInstance.new(name: type_name,
|
339
|
-
extension_name: extension_name,
|
340
|
-
args: self_type.args)]
|
341
|
-
end
|
595
|
+
self_type = Types::ClassInstance.new(name: type_name,
|
596
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
597
|
+
location: nil)
|
598
|
+
ancestors = [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
|
342
599
|
|
343
|
-
Definition.new(
|
344
|
-
|
600
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
601
|
+
method_definition_members(type_name, entry, kind: :instance).each do |method_name, array|
|
602
|
+
visibility, method_def, *members = array
|
345
603
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
:super
|
359
|
-
end
|
604
|
+
m = if method_def
|
605
|
+
Definition::Method.new(
|
606
|
+
super_method: nil,
|
607
|
+
accessibility: visibility,
|
608
|
+
defs: method_def.defs.map {|defn| defn.update(implemented_in: type_name) }
|
609
|
+
)
|
610
|
+
else
|
611
|
+
Definition::Method.new(
|
612
|
+
super_method: nil,
|
613
|
+
accessibility: visibility,
|
614
|
+
defs: []
|
615
|
+
)
|
360
616
|
end
|
361
617
|
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
attrs = if name == :initialize
|
370
|
-
(member.attributes + [:incompatible]).uniq
|
371
|
-
else
|
372
|
-
member.attributes
|
373
|
-
end
|
374
|
-
|
375
|
-
definition.methods[name] = Definition::Method.new(super_method: nil,
|
376
|
-
method_types: method_types,
|
377
|
-
defined_in: decl,
|
378
|
-
implemented_in: decl,
|
379
|
-
accessibility: accessibility,
|
380
|
-
attributes: attrs,
|
381
|
-
annotations: member.annotations,
|
382
|
-
comment: member.comment)
|
383
|
-
end
|
384
|
-
when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
|
385
|
-
name = member.name
|
386
|
-
type = absolute_type(member.type, namespace: namespace)
|
387
|
-
ivar_name = case member.ivar_name
|
388
|
-
when false
|
389
|
-
nil
|
390
|
-
else
|
391
|
-
member.ivar_name || :"@#{member.name}"
|
392
|
-
end
|
393
|
-
|
394
|
-
if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
|
395
|
-
definition.methods[name] = Definition::Method.new(
|
396
|
-
super_method: nil,
|
397
|
-
method_types: [
|
398
|
-
MethodType.new(
|
399
|
-
type_params: [],
|
400
|
-
type: Types::Function.empty(type),
|
401
|
-
block: nil,
|
402
|
-
location: nil
|
403
|
-
)
|
404
|
-
],
|
405
|
-
defined_in: decl,
|
406
|
-
implemented_in: decl,
|
407
|
-
accessibility: accessibility,
|
408
|
-
attributes: [],
|
409
|
-
annotations: member.annotations,
|
410
|
-
comment: member.comment
|
618
|
+
definition.methods[method_name] = members.inject(m) do |original, member|
|
619
|
+
defs = member.types.map do |method_type|
|
620
|
+
Definition::Method::TypeDef.new(
|
621
|
+
type: method_type,
|
622
|
+
member: member,
|
623
|
+
implemented_in: type_name,
|
624
|
+
defined_in: type_name
|
411
625
|
)
|
412
626
|
end
|
413
627
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
628
|
+
Definition::Method.new(
|
629
|
+
super_method: nil,
|
630
|
+
defs: defs + original.defs,
|
631
|
+
accessibility: original.accessibility
|
632
|
+
)
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
entry.decls.each do |d|
|
637
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
638
|
+
case member
|
639
|
+
when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
|
640
|
+
name = member.name
|
641
|
+
type = member.type
|
642
|
+
|
643
|
+
ivar_name = case member.ivar_name
|
644
|
+
when false
|
645
|
+
nil
|
646
|
+
else
|
647
|
+
member.ivar_name || :"@#{member.name}"
|
648
|
+
end
|
649
|
+
|
650
|
+
if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
|
651
|
+
definition.methods[name] = Definition::Method.new(
|
652
|
+
super_method: nil,
|
653
|
+
defs: [
|
654
|
+
Definition::Method::TypeDef.new(
|
655
|
+
type: MethodType.new(
|
656
|
+
type_params: [],
|
657
|
+
type: Types::Function.empty(type),
|
658
|
+
block: nil,
|
659
|
+
location: nil
|
660
|
+
),
|
661
|
+
member: member,
|
662
|
+
defined_in: type_name,
|
663
|
+
implemented_in: type_name
|
664
|
+
)
|
665
|
+
],
|
666
|
+
accessibility: accessibility
|
667
|
+
)
|
668
|
+
end
|
669
|
+
|
670
|
+
if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
|
671
|
+
definition.methods[:"#{name}="] = Definition::Method.new(
|
672
|
+
super_method: nil,
|
673
|
+
defs: [
|
674
|
+
Definition::Method::TypeDef.new(
|
675
|
+
type: MethodType.new(
|
676
|
+
type_params: [],
|
677
|
+
type: Types::Function.empty(type).update(
|
678
|
+
required_positionals: [Types::Function::Param.new(name: name, type: type)]
|
679
|
+
),
|
680
|
+
block: nil,
|
681
|
+
location: nil
|
682
|
+
),
|
683
|
+
member: member,
|
684
|
+
defined_in: type_name,
|
685
|
+
implemented_in: type_name
|
686
|
+
),
|
687
|
+
],
|
688
|
+
accessibility: accessibility
|
689
|
+
)
|
690
|
+
end
|
691
|
+
|
692
|
+
if ivar_name
|
693
|
+
definition.instance_variables[ivar_name] = Definition::Variable.new(
|
694
|
+
parent_variable: nil,
|
695
|
+
type: type,
|
696
|
+
declared_in: type_name
|
697
|
+
)
|
698
|
+
end
|
699
|
+
|
700
|
+
when AST::Members::InstanceVariable
|
701
|
+
definition.instance_variables[member.name] = Definition::Variable.new(
|
702
|
+
parent_variable: nil,
|
703
|
+
type: member.type,
|
704
|
+
declared_in: type_name
|
438
705
|
)
|
439
|
-
end
|
440
706
|
|
441
|
-
|
442
|
-
definition.
|
707
|
+
when AST::Members::ClassVariable
|
708
|
+
definition.class_variables[member.name] = Definition::Variable.new(
|
443
709
|
parent_variable: nil,
|
444
|
-
type: type,
|
445
|
-
declared_in:
|
710
|
+
type: member.type,
|
711
|
+
declared_in: type_name
|
446
712
|
)
|
447
|
-
end
|
448
713
|
|
449
|
-
when AST::Members::Alias
|
450
|
-
if member.instance?
|
451
|
-
alias_members << member
|
452
714
|
end
|
453
|
-
|
454
|
-
|
455
|
-
absolute_name = absolute_type_name(member.name, namespace: namespace, location: member.location)
|
456
|
-
interface_definition = build_one_instance(absolute_name)
|
457
|
-
absolute_args = member.args.map {|ty| absolute_type(ty, namespace: namespace) }
|
458
|
-
|
459
|
-
InvalidTypeApplicationError.check!(
|
460
|
-
type_name: absolute_name,
|
461
|
-
args: absolute_args,
|
462
|
-
params: interface_definition.type_params_decl,
|
463
|
-
location: member.location
|
464
|
-
)
|
715
|
+
end
|
716
|
+
end
|
465
717
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
718
|
+
entry.decls.each do |d|
|
719
|
+
d.decl.members.each do |member|
|
720
|
+
case member
|
721
|
+
when AST::Members::Alias
|
722
|
+
if member.instance?
|
723
|
+
UnknownMethodAliasError.check!(
|
724
|
+
methods: definition.methods,
|
725
|
+
original_name: member.old_name,
|
726
|
+
aliased_name: member.new_name,
|
727
|
+
location: member.location
|
728
|
+
)
|
473
729
|
|
474
730
|
DuplicatedMethodDefinitionError.check!(
|
475
|
-
decl: decl,
|
731
|
+
decl: d.decl,
|
476
732
|
methods: definition.methods,
|
477
|
-
name:
|
733
|
+
name: member.new_name,
|
478
734
|
location: member.location
|
479
735
|
)
|
480
736
|
|
481
|
-
definition.methods[
|
482
|
-
super_method: nil,
|
483
|
-
method_types: method_types,
|
484
|
-
defined_in: method.defined_in,
|
485
|
-
implemented_in: decl,
|
486
|
-
accessibility: method.accessibility,
|
487
|
-
attributes: [],
|
488
|
-
annotations: method.annotations,
|
489
|
-
comment: member.comment
|
490
|
-
)
|
737
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
491
738
|
end
|
492
739
|
end
|
493
|
-
when AST::Members::InstanceVariable
|
494
|
-
definition.instance_variables[member.name] = Definition::Variable.new(
|
495
|
-
type: absolute_type(member.type, namespace: namespace),
|
496
|
-
parent_variable: nil,
|
497
|
-
declared_in: decl
|
498
|
-
)
|
499
|
-
when AST::Members::ClassVariable
|
500
|
-
definition.class_variables[member.name] = Definition::Variable.new(
|
501
|
-
type: absolute_type(member.type, namespace: namespace),
|
502
|
-
parent_variable: nil,
|
503
|
-
declared_in: decl
|
504
|
-
)
|
505
740
|
end
|
506
741
|
end
|
507
742
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
aliased_name: member.new_name,
|
513
|
-
location: member.location
|
514
|
-
)
|
515
|
-
|
516
|
-
DuplicatedMethodDefinitionError.check!(
|
517
|
-
decl: decl,
|
518
|
-
methods: definition.methods,
|
519
|
-
name: member.new_name,
|
520
|
-
location: member.location
|
743
|
+
entry.decls.each do |d|
|
744
|
+
validate_parameter_variance(
|
745
|
+
decl: d.decl,
|
746
|
+
methods: definition.methods
|
521
747
|
)
|
522
|
-
|
523
|
-
# FIXME: may cause a problem if #old_name has super type
|
524
|
-
definition.methods[member.new_name] = definition.methods[member.old_name]
|
525
748
|
end
|
526
|
-
|
527
|
-
validate_parameter_variance(
|
528
|
-
decl: decl,
|
529
|
-
methods: definition.methods
|
530
|
-
)
|
531
749
|
end
|
532
750
|
end
|
533
751
|
end
|
@@ -543,14 +761,8 @@ module RBS
|
|
543
761
|
end
|
544
762
|
|
545
763
|
def validate_parameter_variance(decl:, methods:)
|
546
|
-
type_params =
|
547
|
-
when AST::Declarations::Extension
|
548
|
-
env.find_class(decl.name.absolute!).type_params.rename_to(decl.type_params)
|
549
|
-
else
|
550
|
-
decl.type_params
|
551
|
-
end
|
764
|
+
type_params = decl.type_params
|
552
765
|
|
553
|
-
namespace = decl.name.absolute!.to_namespace
|
554
766
|
calculator = VarianceCalculator.new(builder: self)
|
555
767
|
param_names = type_params.each.map(&:name)
|
556
768
|
|
@@ -558,9 +770,8 @@ module RBS
|
|
558
770
|
|
559
771
|
if decl.is_a?(AST::Declarations::Class)
|
560
772
|
if decl.super_class
|
561
|
-
|
562
|
-
|
563
|
-
result = calculator.in_inherit(name: absolute_super_name, args: absolute_args, variables: param_names)
|
773
|
+
super_class = decl.super_class
|
774
|
+
result = calculator.in_inherit(name: super_class.name, args: super_class.args, variables: param_names)
|
564
775
|
|
565
776
|
validate_params_with type_params, result: result do |param|
|
566
777
|
errors.push InvalidVarianceAnnotationError::InheritanceError.new(
|
@@ -574,9 +785,7 @@ module RBS
|
|
574
785
|
case member
|
575
786
|
when AST::Members::Include
|
576
787
|
if member.name.class?
|
577
|
-
|
578
|
-
absolute_args = member.args.map {|type| absolute_type(type, namespace: namespace) }
|
579
|
-
result = calculator.in_inherit(name: absolute_module_name, args: absolute_args, variables: param_names)
|
788
|
+
result = calculator.in_inherit(name: member.name, args: member.args, variables: param_names)
|
580
789
|
|
581
790
|
validate_params_with type_params, result: result do |param|
|
582
791
|
errors.push InvalidVarianceAnnotationError::MixinError.new(
|
@@ -610,148 +819,151 @@ module RBS
|
|
610
819
|
end
|
611
820
|
end
|
612
821
|
|
613
|
-
def build_one_singleton(type_name
|
614
|
-
|
615
|
-
|
616
|
-
raise "Unknown extension: #{type_name} (#{extension_name})"
|
617
|
-
else
|
618
|
-
env.find_class(type_name)
|
619
|
-
end
|
822
|
+
def build_one_singleton(type_name)
|
823
|
+
try_cache(type_name, cache: one_singleton_cache) do
|
824
|
+
entry = env.class_decls[type_name]
|
620
825
|
|
621
|
-
namespace = type_name.to_namespace
|
622
|
-
|
623
|
-
case decl
|
624
|
-
when AST::Declarations::Module, AST::Declarations::Class
|
625
826
|
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
626
827
|
ancestors = [Definition::Ancestor::Singleton.new(name: type_name)]
|
627
|
-
when AST::Declarations::Extension
|
628
|
-
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
629
|
-
ancestors = [Definition::Ancestor::ExtensionSingleton.new(name: type_name, extension_name: extension_name)]
|
630
|
-
end
|
631
828
|
|
632
|
-
|
633
|
-
|
829
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
830
|
+
method_definition_members(type_name, entry, kind: :singleton).each do |method_name, array|
|
831
|
+
visibility, method_def, *members = array
|
634
832
|
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
833
|
+
m = Definition::Method.new(
|
834
|
+
super_method: nil,
|
835
|
+
defs: method_def&.yield_self do |method_def|
|
836
|
+
method_def.defs.map {|defn| defn.update(implemented_in: type_name) }
|
837
|
+
end || [],
|
838
|
+
accessibility: visibility
|
839
|
+
)
|
840
|
+
definition.methods[method_name] = members.inject(m) do |original, new|
|
841
|
+
defs = new.types.map do |type|
|
842
|
+
Definition::Method::TypeDef.new(
|
843
|
+
type: type,
|
844
|
+
member: new,
|
845
|
+
defined_in: type_name,
|
846
|
+
implemented_in: type_name
|
847
|
+
)
|
644
848
|
end
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
name: name,
|
650
|
-
location: member.location
|
849
|
+
Definition::Method.new(
|
850
|
+
super_method: nil,
|
851
|
+
defs: defs + original.defs,
|
852
|
+
accessibility: original.accessibility
|
651
853
|
)
|
652
|
-
|
653
|
-
definition.methods[name] = Definition::Method.new(super_method: nil,
|
654
|
-
method_types: method_types,
|
655
|
-
defined_in: decl,
|
656
|
-
implemented_in: decl,
|
657
|
-
accessibility: accessibility,
|
658
|
-
attributes: member.attributes,
|
659
|
-
annotations: member.annotations,
|
660
|
-
comment: member.comment)
|
661
854
|
end
|
662
|
-
|
663
|
-
|
664
|
-
|
855
|
+
end
|
856
|
+
|
857
|
+
entry.decls.each do |d|
|
858
|
+
d.decl.members.each do |member|
|
859
|
+
case member
|
860
|
+
when AST::Members::Alias
|
861
|
+
if member.singleton?
|
862
|
+
UnknownMethodAliasError.check!(
|
863
|
+
methods: definition.methods,
|
864
|
+
original_name: member.old_name,
|
865
|
+
aliased_name: member.new_name,
|
866
|
+
location: member.location
|
867
|
+
)
|
868
|
+
|
869
|
+
DuplicatedMethodDefinitionError.check!(
|
870
|
+
decl: d.decl,
|
871
|
+
methods: definition.methods,
|
872
|
+
name: member.new_name,
|
873
|
+
location: member.location
|
874
|
+
)
|
875
|
+
|
876
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
877
|
+
end
|
878
|
+
end
|
665
879
|
end
|
666
|
-
|
667
|
-
if member.name.interface?
|
668
|
-
absolute_name = absolute_type_name(member.name, namespace: namespace, location: member.location)
|
669
|
-
interface_definition = build_one_instance(absolute_name)
|
670
|
-
absolute_args = member.args.map {|ty| absolute_type(ty, namespace: namespace) }
|
671
|
-
|
672
|
-
InvalidTypeApplicationError.check!(
|
673
|
-
type_name: absolute_name,
|
674
|
-
args: absolute_args,
|
675
|
-
params: interface_definition.type_params_decl,
|
676
|
-
location: member.location
|
677
|
-
)
|
880
|
+
end
|
678
881
|
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
882
|
+
unless definition.methods.key?(:new)
|
883
|
+
instance = build_one_instance(type_name)
|
884
|
+
initialize = instance.methods[:initialize]
|
885
|
+
|
886
|
+
if initialize
|
887
|
+
class_params = entry.type_params.each.map(&:name)
|
888
|
+
|
889
|
+
initialize_defs = initialize.defs
|
890
|
+
definition.methods[:new] = Definition::Method.new(
|
891
|
+
super_method: nil,
|
892
|
+
defs: initialize_defs.map do |initialize_def|
|
893
|
+
method_type = initialize_def.type
|
894
|
+
|
895
|
+
class_type_param_vars = Set.new(class_params)
|
896
|
+
method_type_param_vars = Set.new(method_type.type_params)
|
897
|
+
|
898
|
+
if class_type_param_vars.intersect?(method_type_param_vars)
|
899
|
+
renamed_method_params = method_type.type_params.map do |name|
|
900
|
+
if class_type_param_vars.include?(name)
|
901
|
+
Types::Variable.fresh(name).name
|
902
|
+
else
|
903
|
+
name
|
904
|
+
end
|
905
|
+
end
|
906
|
+
method_params = class_params + renamed_method_params
|
907
|
+
|
908
|
+
sub = Substitution.build(method_type.type_params, Types::Variable.build(renamed_method_params))
|
909
|
+
else
|
910
|
+
method_params = class_params + method_type.type_params
|
911
|
+
sub = Substitution.build([], [])
|
684
912
|
end
|
685
|
-
end
|
686
913
|
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
914
|
+
method_type = method_type.map_type {|ty| ty.sub(sub) }
|
915
|
+
method_type = method_type.update(
|
916
|
+
type_params: method_params,
|
917
|
+
type: method_type.type.with_return_type(Types::Bases::Instance.new(location: nil))
|
918
|
+
)
|
919
|
+
|
920
|
+
Definition::Method::TypeDef.new(
|
921
|
+
type: method_type,
|
922
|
+
member: initialize_def.member,
|
923
|
+
defined_in: nil,
|
924
|
+
implemented_in: nil
|
925
|
+
)
|
926
|
+
end,
|
927
|
+
accessibility: :public
|
928
|
+
)
|
929
|
+
end
|
930
|
+
end
|
931
|
+
|
932
|
+
entry.decls.each do |d|
|
933
|
+
each_member_with_accessibility(d.decl.members) do |member, _|
|
934
|
+
case member
|
935
|
+
when AST::Members::ClassInstanceVariable
|
936
|
+
definition.instance_variables[member.name] = Definition::Variable.new(
|
937
|
+
parent_variable: nil,
|
938
|
+
type: member.type,
|
939
|
+
declared_in: type_name
|
692
940
|
)
|
693
941
|
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
accessibility: method.accessibility,
|
700
|
-
attributes: method.attributes,
|
701
|
-
annotations: method.annotations,
|
702
|
-
comment: member.comment
|
942
|
+
when AST::Members::ClassVariable
|
943
|
+
definition.class_variables[member.name] = Definition::Variable.new(
|
944
|
+
parent_variable: nil,
|
945
|
+
type: member.type,
|
946
|
+
declared_in: type_name
|
703
947
|
)
|
704
948
|
end
|
705
949
|
end
|
706
|
-
when AST::Members::ClassInstanceVariable
|
707
|
-
definition.instance_variables[member.name] = Definition::Variable.new(
|
708
|
-
type: absolute_type(member.type, namespace: namespace),
|
709
|
-
parent_variable: nil,
|
710
|
-
declared_in: decl
|
711
|
-
)
|
712
|
-
when AST::Members::ClassVariable
|
713
|
-
definition.class_variables[member.name] = Definition::Variable.new(
|
714
|
-
type: absolute_type(member.type, namespace: namespace),
|
715
|
-
parent_variable: nil,
|
716
|
-
declared_in: decl
|
717
|
-
)
|
718
950
|
end
|
719
951
|
end
|
720
|
-
|
721
|
-
alias_members.each do |member|
|
722
|
-
UnknownMethodAliasError.check!(
|
723
|
-
methods: definition.methods,
|
724
|
-
original_name: member.old_name,
|
725
|
-
aliased_name: member.new_name,
|
726
|
-
location: member.location
|
727
|
-
)
|
728
|
-
|
729
|
-
DuplicatedMethodDefinitionError.check!(
|
730
|
-
decl: decl,
|
731
|
-
methods: definition.methods,
|
732
|
-
name: member.new_name,
|
733
|
-
location: member.location
|
734
|
-
)
|
735
|
-
|
736
|
-
# FIXME: may cause a problem if #old_name has super type
|
737
|
-
definition.methods[member.new_name] = definition.methods[member.old_name]
|
738
|
-
end
|
739
952
|
end
|
740
953
|
end
|
741
954
|
|
742
|
-
def merge_definitions(pairs,
|
743
|
-
Definition.new(
|
955
|
+
def merge_definitions(type_name, pairs, entry:, self_type:, ancestors:)
|
956
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
744
957
|
pairs.reverse_each do |(ancestor, current_definition)|
|
745
958
|
sub = case ancestor
|
746
|
-
when Definition::Ancestor::Instance
|
959
|
+
when Definition::Ancestor::Instance
|
747
960
|
Substitution.build(current_definition.type_params, ancestor.args)
|
748
|
-
when Definition::Ancestor::Singleton
|
961
|
+
when Definition::Ancestor::Singleton
|
749
962
|
Substitution.build([], [])
|
750
963
|
end
|
751
|
-
namespace = current_definition.name.absolute!.to_namespace
|
752
964
|
|
753
965
|
current_definition.methods.each do |name, method|
|
754
|
-
merge_method definition.methods, name, method, sub
|
966
|
+
merge_method definition.methods, name, method, sub
|
755
967
|
end
|
756
968
|
|
757
969
|
current_definition.instance_variables.each do |name, variable|
|
@@ -775,25 +987,13 @@ module RBS
|
|
775
987
|
)
|
776
988
|
end
|
777
989
|
|
778
|
-
def merge_method(methods, name, method, sub
|
990
|
+
def merge_method(methods, name, method, sub)
|
779
991
|
super_method = methods[name]
|
780
992
|
|
781
993
|
methods[name] = Definition::Method.new(
|
782
|
-
method_types: method.method_types.flat_map do |method_type|
|
783
|
-
case method_type
|
784
|
-
when MethodType
|
785
|
-
[absolute_type(method_type.sub(sub), namespace: namespace)]
|
786
|
-
when :super
|
787
|
-
super_method.method_types
|
788
|
-
end
|
789
|
-
end,
|
790
994
|
super_method: super_method,
|
791
|
-
defined_in: method.defined_in,
|
792
|
-
implemented_in: method.implemented_in,
|
793
995
|
accessibility: method.accessibility,
|
794
|
-
|
795
|
-
annotations: method.annotations,
|
796
|
-
comment: method.comment
|
996
|
+
defs: sub.mapping.empty? ? method.defs : method.defs.map {|defn| defn.update(type: defn.type.sub(sub)) }
|
797
997
|
)
|
798
998
|
end
|
799
999
|
|
@@ -816,31 +1016,45 @@ module RBS
|
|
816
1016
|
end
|
817
1017
|
end
|
818
1018
|
|
819
|
-
def build_interface(type_name
|
820
|
-
|
821
|
-
name: type_name
|
822
|
-
|
823
|
-
location: nil
|
824
|
-
)
|
1019
|
+
def build_interface(type_name)
|
1020
|
+
try_cache(type_name, cache: interface_cache) do
|
1021
|
+
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
1022
|
+
declaration = entry.decl
|
825
1023
|
|
826
|
-
|
1024
|
+
self_type = Types::Interface.new(
|
1025
|
+
name: type_name,
|
1026
|
+
args: Types::Variable.build(declaration.type_params.each.map(&:name)),
|
1027
|
+
location: nil
|
1028
|
+
)
|
827
1029
|
|
828
|
-
|
829
|
-
|
1030
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: nil).tap do |definition|
|
1031
|
+
include_members = []
|
1032
|
+
def_members = []
|
1033
|
+
alias_members = []
|
830
1034
|
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
1035
|
+
declaration.members.each do |member|
|
1036
|
+
case member
|
1037
|
+
when AST::Members::Include
|
1038
|
+
include_members << member
|
1039
|
+
when AST::Members::MethodDefinition
|
1040
|
+
def_members << member
|
1041
|
+
when AST::Members::Alias
|
1042
|
+
alias_members << member
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
include_members.each do |member|
|
1047
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
836
1048
|
|
837
|
-
|
838
|
-
|
1049
|
+
mixin = build_interface(member.name)
|
1050
|
+
|
1051
|
+
args = member.args
|
1052
|
+
type_params = mixin.entry.decl.type_params
|
839
1053
|
|
840
1054
|
InvalidTypeApplicationError.check!(
|
841
1055
|
type_name: type_name,
|
842
1056
|
args: args,
|
843
|
-
params: type_params,
|
1057
|
+
params: type_params.each.map(&:name),
|
844
1058
|
location: member.location
|
845
1059
|
)
|
846
1060
|
|
@@ -849,11 +1063,8 @@ module RBS
|
|
849
1063
|
definition.methods[name] = method.sub(sub)
|
850
1064
|
end
|
851
1065
|
end
|
852
|
-
end
|
853
1066
|
|
854
|
-
|
855
|
-
case member
|
856
|
-
when AST::Members::MethodDefinition
|
1067
|
+
def_members.each do |member|
|
857
1068
|
DuplicatedMethodDefinitionError.check!(
|
858
1069
|
decl: declaration,
|
859
1070
|
methods: definition.methods,
|
@@ -863,57 +1074,44 @@ module RBS
|
|
863
1074
|
|
864
1075
|
method = Definition::Method.new(
|
865
1076
|
super_method: nil,
|
866
|
-
|
867
|
-
|
1077
|
+
defs: member.types.map do |method_type|
|
1078
|
+
Definition::Method::TypeDef.new(
|
1079
|
+
type: method_type,
|
1080
|
+
member: member,
|
1081
|
+
defined_in: type_name,
|
1082
|
+
implemented_in: nil
|
1083
|
+
)
|
868
1084
|
end,
|
869
|
-
|
870
|
-
implemented_in: nil,
|
871
|
-
accessibility: :public,
|
872
|
-
attributes: member.attributes,
|
873
|
-
annotations: member.annotations,
|
874
|
-
comment: member.comment
|
1085
|
+
accessibility: :public
|
875
1086
|
)
|
876
1087
|
definition.methods[member.name] = method
|
877
|
-
when AST::Members::Alias
|
878
|
-
alias_members << member
|
879
1088
|
end
|
880
|
-
end
|
881
1089
|
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
1090
|
+
alias_members.each do |member|
|
1091
|
+
UnknownMethodAliasError.check!(
|
1092
|
+
methods: definition.methods,
|
1093
|
+
original_name: member.old_name,
|
1094
|
+
aliased_name: member.new_name,
|
1095
|
+
location: member.location
|
1096
|
+
)
|
889
1097
|
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
1098
|
+
DuplicatedMethodDefinitionError.check!(
|
1099
|
+
decl: declaration,
|
1100
|
+
methods: definition.methods,
|
1101
|
+
name: member.new_name,
|
1102
|
+
location: member.location
|
1103
|
+
)
|
896
1104
|
|
897
|
-
|
898
|
-
|
1105
|
+
# FIXME: may cause a problem if #old_name has super type
|
1106
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
1107
|
+
end
|
899
1108
|
end
|
900
1109
|
end
|
901
1110
|
end
|
902
1111
|
|
903
|
-
def absolute_type(type, namespace:)
|
904
|
-
env.absolute_type(type, namespace: namespace) do |type|
|
905
|
-
NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
|
906
|
-
end
|
907
|
-
end
|
908
|
-
|
909
|
-
def absolute_type_name(type_name, namespace:, location:)
|
910
|
-
env.absolute_type_name(type_name, namespace: namespace) do |type_name|
|
911
|
-
NoTypeFoundError.check!(type_name.absolute!, env: env, location: location)
|
912
|
-
end
|
913
|
-
end
|
914
|
-
|
915
1112
|
def expand_alias(type_name)
|
916
|
-
|
1113
|
+
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
|
1114
|
+
entry.decl.type
|
917
1115
|
end
|
918
1116
|
end
|
919
1117
|
end
|