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