rbs 0.4.0 → 0.9.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 +35 -0
- data/Gemfile +14 -0
- data/README.md +86 -47
- data/Rakefile +53 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/docs/stdlib.md +0 -2
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +3 -0
- data/lib/rbs/ast/comment.rb +6 -0
- data/lib/rbs/ast/declarations.rb +106 -13
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +317 -121
- 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 +814 -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/location.rb +15 -0
- data/lib/rbs/parser.y +100 -34
- data/lib/rbs/prototype/rb.rb +101 -113
- data/lib/rbs/prototype/rbi.rb +5 -3
- data/lib/rbs/prototype/runtime.rb +11 -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 +55 -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 -10
- data/schema/decls.json +36 -10
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +3 -3
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/proc.rbs +1 -2
- 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 +7 -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 +19 -130
- 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
|
-
|
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
|
124
|
+
|
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)
|
45
127
|
|
46
|
-
|
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
|
+
)
|
145
211
|
|
146
|
-
|
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
|
+
)
|
232
|
+
|
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))
|
180
314
|
end
|
181
315
|
end
|
182
316
|
|
183
317
|
building_ancestors.pop
|
184
318
|
|
185
|
-
|
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))
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
ancestors.unshift(self_ancestor)
|
366
|
+
|
367
|
+
building_ancestors.pop
|
368
|
+
|
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)
|
@@ -198,336 +385,377 @@ module RBS
|
|
198
385
|
end
|
199
386
|
end
|
200
387
|
|
388
|
+
def ensure_namespace!(namespace, location:)
|
389
|
+
namespace.ascend do |ns|
|
390
|
+
unless ns.empty?
|
391
|
+
NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
201
396
|
def build_instance(type_name)
|
202
397
|
try_cache type_name, cache: instance_cache do
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
398
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
399
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
400
|
+
|
401
|
+
case entry
|
402
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
403
|
+
ancestors = instance_ancestors(type_name)
|
404
|
+
self_type = Types::ClassInstance.new(name: type_name,
|
405
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
406
|
+
location: nil)
|
407
|
+
|
408
|
+
definition_pairs = ancestors.ancestors.map do |ancestor|
|
212
409
|
case ancestor
|
213
410
|
when Definition::Ancestor::Instance
|
214
411
|
[ancestor, build_one_instance(ancestor.name)]
|
215
412
|
when Definition::Ancestor::Singleton
|
216
413
|
[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)]
|
414
|
+
else
|
415
|
+
raise
|
221
416
|
end
|
222
417
|
end
|
223
418
|
|
224
|
-
if
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
419
|
+
if entry.is_a?(Environment::ModuleEntry)
|
420
|
+
entry.self_types.each do |module_self|
|
421
|
+
ancestor = Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
422
|
+
definition_pairs.push(
|
423
|
+
[
|
424
|
+
ancestor,
|
425
|
+
if module_self.name.interface?
|
426
|
+
build_interface(module_self.name)
|
427
|
+
else
|
428
|
+
build_instance(module_self.name)
|
429
|
+
end
|
430
|
+
]
|
431
|
+
)
|
231
432
|
end
|
232
433
|
end
|
233
434
|
|
234
|
-
merge_definitions(definition_pairs,
|
435
|
+
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
436
|
+
|
437
|
+
else
|
438
|
+
raise
|
235
439
|
end
|
236
440
|
end
|
237
441
|
end
|
238
442
|
|
239
443
|
def build_singleton(type_name)
|
240
444
|
try_cache type_name, cache: singleton_cache do
|
241
|
-
|
242
|
-
|
243
|
-
|
445
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
|
446
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
447
|
+
|
448
|
+
case entry
|
449
|
+
when Environment::ClassEntry, Environment::ModuleEntry
|
450
|
+
ancestors = singleton_ancestors(type_name)
|
451
|
+
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
452
|
+
instance_type = Types::ClassInstance.new(
|
453
|
+
name: type_name,
|
454
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
455
|
+
location: nil
|
456
|
+
)
|
244
457
|
|
245
|
-
|
246
|
-
when AST::Declarations::Class, AST::Declarations::Module
|
247
|
-
ancestors = build_ancestors(self_ancestor)
|
248
|
-
definition_pairs = ancestors.map do |ancestor|
|
458
|
+
definition_pairs = ancestors.ancestors.map do |ancestor|
|
249
459
|
case ancestor
|
250
460
|
when Definition::Ancestor::Instance
|
251
461
|
[ancestor, build_one_instance(ancestor.name)]
|
252
462
|
when Definition::Ancestor::Singleton
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
463
|
+
definition = build_one_singleton(ancestor.name)
|
464
|
+
definition = definition.sub(Substitution.build([], [], instance_type: instance_type))
|
465
|
+
definition = definition.map_method_type do |method_type|
|
466
|
+
s = Substitution.build(
|
467
|
+
method_type.free_variables.to_a,
|
468
|
+
method_type.free_variables.map { Types::Bases::Any.new(location: nil) }
|
469
|
+
)
|
470
|
+
method_type.sub(s)
|
471
|
+
end
|
472
|
+
|
473
|
+
[
|
474
|
+
ancestor,
|
475
|
+
definition
|
476
|
+
]
|
477
|
+
else
|
478
|
+
raise
|
258
479
|
end
|
259
480
|
end
|
260
481
|
|
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
|
482
|
+
merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
|
483
|
+
else
|
484
|
+
raise
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
287
488
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
489
|
+
def method_definition_members(type_name, entry, kind:)
|
490
|
+
interface_methods = {}
|
491
|
+
methods = {}
|
492
|
+
|
493
|
+
entry.decls.each do |d|
|
494
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
495
|
+
case member
|
496
|
+
when AST::Members::MethodDefinition
|
497
|
+
case kind
|
498
|
+
when :singleton
|
499
|
+
next unless member.singleton?
|
500
|
+
when :instance
|
501
|
+
next unless member.instance?
|
502
|
+
end
|
503
|
+
|
504
|
+
methods[member.name] ||= []
|
505
|
+
methods[member.name] << [
|
506
|
+
member.update(types: member.types),
|
507
|
+
accessibility
|
508
|
+
]
|
509
|
+
when AST::Members::Include, AST::Members::Extend
|
510
|
+
if member.name.interface?
|
511
|
+
if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
|
512
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
513
|
+
|
514
|
+
interface_name = member.name
|
515
|
+
interface_args = member.args
|
516
|
+
|
517
|
+
interface_definition = build_interface(interface_name)
|
518
|
+
|
519
|
+
InvalidTypeApplicationError.check!(
|
520
|
+
type_name: interface_name,
|
521
|
+
args: interface_args,
|
522
|
+
params: interface_definition.type_params_decl,
|
523
|
+
location: member.location
|
306
524
|
)
|
525
|
+
|
526
|
+
sub = Substitution.build(interface_definition.type_params, interface_args)
|
527
|
+
|
528
|
+
interface_definition.methods.each do |name, method|
|
529
|
+
interface_methods[name] = [method.sub(sub), member]
|
530
|
+
end
|
307
531
|
end
|
308
532
|
end
|
309
533
|
end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
result = {}
|
538
|
+
|
539
|
+
interface_methods.each do |name, pair|
|
540
|
+
method_definition, _ = pair
|
541
|
+
result[name] = [:public, method_definition]
|
542
|
+
end
|
543
|
+
|
544
|
+
methods.each do |method_name, array|
|
545
|
+
if result[method_name]
|
546
|
+
unless array.all? {|pair| pair[0].overload? }
|
547
|
+
raise MethodDefinitionConflictWithInterfaceMixinError.new(
|
548
|
+
type_name: type_name,
|
549
|
+
method_name: method_name,
|
550
|
+
kind: :instance,
|
551
|
+
mixin_member: interface_methods[method_name][1],
|
552
|
+
entries: array.map(&:first)
|
553
|
+
)
|
554
|
+
end
|
555
|
+
|
556
|
+
unless array.all? {|pair| pair[1] == :public}
|
557
|
+
raise InconsistentMethodVisibilityError.new(
|
558
|
+
type_name: type_name,
|
559
|
+
method_name: method_name,
|
560
|
+
kind: :instance,
|
561
|
+
member_pairs: array
|
562
|
+
)
|
563
|
+
end
|
564
|
+
|
565
|
+
result[method_name] += array.map(&:first)
|
566
|
+
else
|
567
|
+
case
|
568
|
+
when array.size == 1 && !array[0][0].overload?
|
569
|
+
member, visibility = array[0]
|
570
|
+
result[method_name] = [visibility, nil, member]
|
571
|
+
|
572
|
+
when array.count {|pair| !pair[0].overload? } == 1
|
573
|
+
visibilities = array.group_by {|pair| pair[1] }
|
574
|
+
|
575
|
+
if visibilities.size > 1
|
576
|
+
raise InconsistentMethodVisibilityError.new(
|
577
|
+
type_name: type_name,
|
578
|
+
method_name: method_name,
|
579
|
+
kind: :instance,
|
580
|
+
member_pairs: array
|
581
|
+
)
|
582
|
+
end
|
310
583
|
|
311
|
-
|
584
|
+
overloads, primary = array.map(&:first).partition(&:overload?)
|
585
|
+
result[method_name] = [array[0][1], nil, *primary, *overloads]
|
586
|
+
|
587
|
+
else
|
588
|
+
raise InvalidOverloadMethodError.new(
|
589
|
+
type_name: type_name,
|
590
|
+
method_name: method_name,
|
591
|
+
kind: :instance,
|
592
|
+
members: array.map(&:first)
|
593
|
+
)
|
594
|
+
end
|
312
595
|
end
|
313
596
|
end
|
597
|
+
|
598
|
+
result
|
314
599
|
end
|
315
600
|
|
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
|
601
|
+
def build_one_instance(type_name)
|
602
|
+
try_cache(type_name, cache: one_instance_cache) do
|
603
|
+
entry = env.class_decls[type_name]
|
329
604
|
|
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
|
605
|
+
self_type = Types::ClassInstance.new(name: type_name,
|
606
|
+
args: Types::Variable.build(entry.type_params.each.map(&:name)),
|
607
|
+
location: nil)
|
608
|
+
ancestors = [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
|
342
609
|
|
343
|
-
Definition.new(
|
344
|
-
|
610
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
611
|
+
method_definition_members(type_name, entry, kind: :instance).each do |method_name, array|
|
612
|
+
visibility, method_def, *members = array
|
345
613
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
:super
|
359
|
-
end
|
614
|
+
m = if method_def
|
615
|
+
Definition::Method.new(
|
616
|
+
super_method: nil,
|
617
|
+
accessibility: visibility,
|
618
|
+
defs: method_def.defs.map {|defn| defn.update(implemented_in: type_name) }
|
619
|
+
)
|
620
|
+
else
|
621
|
+
Definition::Method.new(
|
622
|
+
super_method: nil,
|
623
|
+
accessibility: visibility,
|
624
|
+
defs: []
|
625
|
+
)
|
360
626
|
end
|
361
627
|
|
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
|
628
|
+
definition.methods[method_name] = members.inject(m) do |original, member|
|
629
|
+
defs = member.types.map do |method_type|
|
630
|
+
Definition::Method::TypeDef.new(
|
631
|
+
type: method_type,
|
632
|
+
member: member,
|
633
|
+
implemented_in: type_name,
|
634
|
+
defined_in: type_name
|
411
635
|
)
|
412
636
|
end
|
413
637
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
638
|
+
Definition::Method.new(
|
639
|
+
super_method: nil,
|
640
|
+
defs: defs + original.defs,
|
641
|
+
accessibility: original.accessibility
|
642
|
+
)
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
entry.decls.each do |d|
|
647
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
648
|
+
case member
|
649
|
+
when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
|
650
|
+
name = member.name
|
651
|
+
type = member.type
|
652
|
+
|
653
|
+
ivar_name = case member.ivar_name
|
654
|
+
when false
|
655
|
+
nil
|
656
|
+
else
|
657
|
+
member.ivar_name || :"@#{member.name}"
|
658
|
+
end
|
659
|
+
|
660
|
+
if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
|
661
|
+
definition.methods[name] = Definition::Method.new(
|
662
|
+
super_method: nil,
|
663
|
+
defs: [
|
664
|
+
Definition::Method::TypeDef.new(
|
665
|
+
type: MethodType.new(
|
666
|
+
type_params: [],
|
667
|
+
type: Types::Function.empty(type),
|
668
|
+
block: nil,
|
669
|
+
location: nil
|
670
|
+
),
|
671
|
+
member: member,
|
672
|
+
defined_in: type_name,
|
673
|
+
implemented_in: type_name
|
674
|
+
)
|
675
|
+
],
|
676
|
+
accessibility: accessibility
|
677
|
+
)
|
678
|
+
end
|
679
|
+
|
680
|
+
if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
|
681
|
+
definition.methods[:"#{name}="] = Definition::Method.new(
|
682
|
+
super_method: nil,
|
683
|
+
defs: [
|
684
|
+
Definition::Method::TypeDef.new(
|
685
|
+
type: MethodType.new(
|
686
|
+
type_params: [],
|
687
|
+
type: Types::Function.empty(type).update(
|
688
|
+
required_positionals: [Types::Function::Param.new(name: name, type: type)]
|
689
|
+
),
|
690
|
+
block: nil,
|
691
|
+
location: nil
|
692
|
+
),
|
693
|
+
member: member,
|
694
|
+
defined_in: type_name,
|
695
|
+
implemented_in: type_name
|
696
|
+
),
|
697
|
+
],
|
698
|
+
accessibility: accessibility
|
699
|
+
)
|
700
|
+
end
|
701
|
+
|
702
|
+
if ivar_name
|
703
|
+
definition.instance_variables[ivar_name] = Definition::Variable.new(
|
704
|
+
parent_variable: nil,
|
705
|
+
type: type,
|
706
|
+
declared_in: type_name
|
707
|
+
)
|
708
|
+
end
|
709
|
+
|
710
|
+
when AST::Members::InstanceVariable
|
711
|
+
definition.instance_variables[member.name] = Definition::Variable.new(
|
712
|
+
parent_variable: nil,
|
713
|
+
type: member.type,
|
714
|
+
declared_in: type_name
|
438
715
|
)
|
439
|
-
end
|
440
716
|
|
441
|
-
|
442
|
-
definition.
|
717
|
+
when AST::Members::ClassVariable
|
718
|
+
definition.class_variables[member.name] = Definition::Variable.new(
|
443
719
|
parent_variable: nil,
|
444
|
-
type: type,
|
445
|
-
declared_in:
|
720
|
+
type: member.type,
|
721
|
+
declared_in: type_name
|
446
722
|
)
|
447
|
-
end
|
448
723
|
|
449
|
-
when AST::Members::Alias
|
450
|
-
if member.instance?
|
451
|
-
alias_members << member
|
452
724
|
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
|
-
)
|
725
|
+
end
|
726
|
+
end
|
465
727
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
728
|
+
entry.decls.each do |d|
|
729
|
+
d.decl.members.each do |member|
|
730
|
+
case member
|
731
|
+
when AST::Members::Alias
|
732
|
+
if member.instance?
|
733
|
+
UnknownMethodAliasError.check!(
|
734
|
+
methods: definition.methods,
|
735
|
+
original_name: member.old_name,
|
736
|
+
aliased_name: member.new_name,
|
737
|
+
location: member.location
|
738
|
+
)
|
473
739
|
|
474
740
|
DuplicatedMethodDefinitionError.check!(
|
475
|
-
decl: decl,
|
741
|
+
decl: d.decl,
|
476
742
|
methods: definition.methods,
|
477
|
-
name:
|
743
|
+
name: member.new_name,
|
478
744
|
location: member.location
|
479
745
|
)
|
480
746
|
|
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
|
-
)
|
747
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
491
748
|
end
|
492
749
|
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
750
|
end
|
506
751
|
end
|
507
752
|
|
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
|
753
|
+
entry.decls.each do |d|
|
754
|
+
validate_parameter_variance(
|
755
|
+
decl: d.decl,
|
756
|
+
methods: definition.methods
|
521
757
|
)
|
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
758
|
end
|
526
|
-
|
527
|
-
validate_parameter_variance(
|
528
|
-
decl: decl,
|
529
|
-
methods: definition.methods
|
530
|
-
)
|
531
759
|
end
|
532
760
|
end
|
533
761
|
end
|
@@ -543,14 +771,8 @@ module RBS
|
|
543
771
|
end
|
544
772
|
|
545
773
|
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
|
774
|
+
type_params = decl.type_params
|
552
775
|
|
553
|
-
namespace = decl.name.absolute!.to_namespace
|
554
776
|
calculator = VarianceCalculator.new(builder: self)
|
555
777
|
param_names = type_params.each.map(&:name)
|
556
778
|
|
@@ -558,9 +780,8 @@ module RBS
|
|
558
780
|
|
559
781
|
if decl.is_a?(AST::Declarations::Class)
|
560
782
|
if decl.super_class
|
561
|
-
|
562
|
-
|
563
|
-
result = calculator.in_inherit(name: absolute_super_name, args: absolute_args, variables: param_names)
|
783
|
+
super_class = decl.super_class
|
784
|
+
result = calculator.in_inherit(name: super_class.name, args: super_class.args, variables: param_names)
|
564
785
|
|
565
786
|
validate_params_with type_params, result: result do |param|
|
566
787
|
errors.push InvalidVarianceAnnotationError::InheritanceError.new(
|
@@ -574,9 +795,7 @@ module RBS
|
|
574
795
|
case member
|
575
796
|
when AST::Members::Include
|
576
797
|
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)
|
798
|
+
result = calculator.in_inherit(name: member.name, args: member.args, variables: param_names)
|
580
799
|
|
581
800
|
validate_params_with type_params, result: result do |param|
|
582
801
|
errors.push InvalidVarianceAnnotationError::MixinError.new(
|
@@ -610,148 +829,151 @@ module RBS
|
|
610
829
|
end
|
611
830
|
end
|
612
831
|
|
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
|
832
|
+
def build_one_singleton(type_name)
|
833
|
+
try_cache(type_name, cache: one_singleton_cache) do
|
834
|
+
entry = env.class_decls[type_name]
|
622
835
|
|
623
|
-
case decl
|
624
|
-
when AST::Declarations::Module, AST::Declarations::Class
|
625
836
|
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
|
626
837
|
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
838
|
|
632
|
-
|
633
|
-
|
839
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
840
|
+
method_definition_members(type_name, entry, kind: :singleton).each do |method_name, array|
|
841
|
+
visibility, method_def, *members = array
|
634
842
|
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
843
|
+
m = Definition::Method.new(
|
844
|
+
super_method: nil,
|
845
|
+
defs: method_def&.yield_self do |method_def|
|
846
|
+
method_def.defs.map {|defn| defn.update(implemented_in: type_name) }
|
847
|
+
end || [],
|
848
|
+
accessibility: visibility
|
849
|
+
)
|
850
|
+
definition.methods[method_name] = members.inject(m) do |original, new|
|
851
|
+
defs = new.types.map do |type|
|
852
|
+
Definition::Method::TypeDef.new(
|
853
|
+
type: type,
|
854
|
+
member: new,
|
855
|
+
defined_in: type_name,
|
856
|
+
implemented_in: type_name
|
857
|
+
)
|
644
858
|
end
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
name: name,
|
650
|
-
location: member.location
|
859
|
+
Definition::Method.new(
|
860
|
+
super_method: nil,
|
861
|
+
defs: defs + original.defs,
|
862
|
+
accessibility: original.accessibility
|
651
863
|
)
|
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
864
|
end
|
662
|
-
|
663
|
-
|
664
|
-
|
865
|
+
end
|
866
|
+
|
867
|
+
entry.decls.each do |d|
|
868
|
+
d.decl.members.each do |member|
|
869
|
+
case member
|
870
|
+
when AST::Members::Alias
|
871
|
+
if member.singleton?
|
872
|
+
UnknownMethodAliasError.check!(
|
873
|
+
methods: definition.methods,
|
874
|
+
original_name: member.old_name,
|
875
|
+
aliased_name: member.new_name,
|
876
|
+
location: member.location
|
877
|
+
)
|
878
|
+
|
879
|
+
DuplicatedMethodDefinitionError.check!(
|
880
|
+
decl: d.decl,
|
881
|
+
methods: definition.methods,
|
882
|
+
name: member.new_name,
|
883
|
+
location: member.location
|
884
|
+
)
|
885
|
+
|
886
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
887
|
+
end
|
888
|
+
end
|
665
889
|
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
|
-
)
|
890
|
+
end
|
678
891
|
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
892
|
+
unless definition.methods.key?(:new)
|
893
|
+
instance = build_one_instance(type_name)
|
894
|
+
initialize = instance.methods[:initialize]
|
895
|
+
|
896
|
+
if initialize
|
897
|
+
class_params = entry.type_params.each.map(&:name)
|
898
|
+
|
899
|
+
initialize_defs = initialize.defs
|
900
|
+
definition.methods[:new] = Definition::Method.new(
|
901
|
+
super_method: nil,
|
902
|
+
defs: initialize_defs.map do |initialize_def|
|
903
|
+
method_type = initialize_def.type
|
904
|
+
|
905
|
+
class_type_param_vars = Set.new(class_params)
|
906
|
+
method_type_param_vars = Set.new(method_type.type_params)
|
907
|
+
|
908
|
+
if class_type_param_vars.intersect?(method_type_param_vars)
|
909
|
+
renamed_method_params = method_type.type_params.map do |name|
|
910
|
+
if class_type_param_vars.include?(name)
|
911
|
+
Types::Variable.fresh(name).name
|
912
|
+
else
|
913
|
+
name
|
914
|
+
end
|
915
|
+
end
|
916
|
+
method_params = class_params + renamed_method_params
|
917
|
+
|
918
|
+
sub = Substitution.build(method_type.type_params, Types::Variable.build(renamed_method_params))
|
919
|
+
else
|
920
|
+
method_params = class_params + method_type.type_params
|
921
|
+
sub = Substitution.build([], [])
|
684
922
|
end
|
685
|
-
end
|
686
923
|
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
924
|
+
method_type = method_type.map_type {|ty| ty.sub(sub) }
|
925
|
+
method_type = method_type.update(
|
926
|
+
type_params: method_params,
|
927
|
+
type: method_type.type.with_return_type(Types::Bases::Instance.new(location: nil))
|
928
|
+
)
|
929
|
+
|
930
|
+
Definition::Method::TypeDef.new(
|
931
|
+
type: method_type,
|
932
|
+
member: initialize_def.member,
|
933
|
+
defined_in: nil,
|
934
|
+
implemented_in: nil
|
935
|
+
)
|
936
|
+
end,
|
937
|
+
accessibility: :public
|
938
|
+
)
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
942
|
+
entry.decls.each do |d|
|
943
|
+
each_member_with_accessibility(d.decl.members) do |member, _|
|
944
|
+
case member
|
945
|
+
when AST::Members::ClassInstanceVariable
|
946
|
+
definition.instance_variables[member.name] = Definition::Variable.new(
|
947
|
+
parent_variable: nil,
|
948
|
+
type: member.type,
|
949
|
+
declared_in: type_name
|
692
950
|
)
|
693
951
|
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
accessibility: method.accessibility,
|
700
|
-
attributes: method.attributes,
|
701
|
-
annotations: method.annotations,
|
702
|
-
comment: member.comment
|
952
|
+
when AST::Members::ClassVariable
|
953
|
+
definition.class_variables[member.name] = Definition::Variable.new(
|
954
|
+
parent_variable: nil,
|
955
|
+
type: member.type,
|
956
|
+
declared_in: type_name
|
703
957
|
)
|
704
958
|
end
|
705
959
|
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
960
|
end
|
719
961
|
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
962
|
end
|
740
963
|
end
|
741
964
|
|
742
|
-
def merge_definitions(pairs,
|
743
|
-
Definition.new(
|
965
|
+
def merge_definitions(type_name, pairs, entry:, self_type:, ancestors:)
|
966
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
|
744
967
|
pairs.reverse_each do |(ancestor, current_definition)|
|
745
968
|
sub = case ancestor
|
746
|
-
when Definition::Ancestor::Instance
|
969
|
+
when Definition::Ancestor::Instance
|
747
970
|
Substitution.build(current_definition.type_params, ancestor.args)
|
748
|
-
when Definition::Ancestor::Singleton
|
971
|
+
when Definition::Ancestor::Singleton
|
749
972
|
Substitution.build([], [])
|
750
973
|
end
|
751
|
-
namespace = current_definition.name.absolute!.to_namespace
|
752
974
|
|
753
975
|
current_definition.methods.each do |name, method|
|
754
|
-
merge_method definition.methods, name, method, sub
|
976
|
+
merge_method definition.methods, name, method, sub
|
755
977
|
end
|
756
978
|
|
757
979
|
current_definition.instance_variables.each do |name, variable|
|
@@ -775,25 +997,13 @@ module RBS
|
|
775
997
|
)
|
776
998
|
end
|
777
999
|
|
778
|
-
def merge_method(methods, name, method, sub
|
1000
|
+
def merge_method(methods, name, method, sub)
|
779
1001
|
super_method = methods[name]
|
780
1002
|
|
781
1003
|
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
1004
|
super_method: super_method,
|
791
|
-
defined_in: method.defined_in,
|
792
|
-
implemented_in: method.implemented_in,
|
793
1005
|
accessibility: method.accessibility,
|
794
|
-
|
795
|
-
annotations: method.annotations,
|
796
|
-
comment: method.comment
|
1006
|
+
defs: sub.mapping.empty? ? method.defs : method.defs.map {|defn| defn.update(type: defn.type.sub(sub)) }
|
797
1007
|
)
|
798
1008
|
end
|
799
1009
|
|
@@ -816,31 +1026,46 @@ module RBS
|
|
816
1026
|
end
|
817
1027
|
end
|
818
1028
|
|
819
|
-
def build_interface(type_name
|
820
|
-
|
821
|
-
name: type_name
|
822
|
-
|
823
|
-
location:
|
824
|
-
)
|
1029
|
+
def build_interface(type_name)
|
1030
|
+
try_cache(type_name, cache: interface_cache) do
|
1031
|
+
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
1032
|
+
declaration = entry.decl
|
1033
|
+
ensure_namespace!(type_name.namespace, location: declaration.location)
|
825
1034
|
|
826
|
-
|
1035
|
+
self_type = Types::Interface.new(
|
1036
|
+
name: type_name,
|
1037
|
+
args: Types::Variable.build(declaration.type_params.each.map(&:name)),
|
1038
|
+
location: nil
|
1039
|
+
)
|
827
1040
|
|
828
|
-
|
829
|
-
|
1041
|
+
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: nil).tap do |definition|
|
1042
|
+
include_members = []
|
1043
|
+
def_members = []
|
1044
|
+
alias_members = []
|
830
1045
|
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
1046
|
+
declaration.members.each do |member|
|
1047
|
+
case member
|
1048
|
+
when AST::Members::Include
|
1049
|
+
include_members << member
|
1050
|
+
when AST::Members::MethodDefinition
|
1051
|
+
def_members << member
|
1052
|
+
when AST::Members::Alias
|
1053
|
+
alias_members << member
|
1054
|
+
end
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
include_members.each do |member|
|
1058
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
836
1059
|
|
837
|
-
|
838
|
-
|
1060
|
+
mixin = build_interface(member.name)
|
1061
|
+
|
1062
|
+
args = member.args
|
1063
|
+
type_params = mixin.entry.decl.type_params
|
839
1064
|
|
840
1065
|
InvalidTypeApplicationError.check!(
|
841
1066
|
type_name: type_name,
|
842
1067
|
args: args,
|
843
|
-
params: type_params,
|
1068
|
+
params: type_params.each.map(&:name),
|
844
1069
|
location: member.location
|
845
1070
|
)
|
846
1071
|
|
@@ -849,11 +1074,8 @@ module RBS
|
|
849
1074
|
definition.methods[name] = method.sub(sub)
|
850
1075
|
end
|
851
1076
|
end
|
852
|
-
end
|
853
1077
|
|
854
|
-
|
855
|
-
case member
|
856
|
-
when AST::Members::MethodDefinition
|
1078
|
+
def_members.each do |member|
|
857
1079
|
DuplicatedMethodDefinitionError.check!(
|
858
1080
|
decl: declaration,
|
859
1081
|
methods: definition.methods,
|
@@ -863,57 +1085,45 @@ module RBS
|
|
863
1085
|
|
864
1086
|
method = Definition::Method.new(
|
865
1087
|
super_method: nil,
|
866
|
-
|
867
|
-
|
1088
|
+
defs: member.types.map do |method_type|
|
1089
|
+
Definition::Method::TypeDef.new(
|
1090
|
+
type: method_type,
|
1091
|
+
member: member,
|
1092
|
+
defined_in: type_name,
|
1093
|
+
implemented_in: nil
|
1094
|
+
)
|
868
1095
|
end,
|
869
|
-
|
870
|
-
implemented_in: nil,
|
871
|
-
accessibility: :public,
|
872
|
-
attributes: member.attributes,
|
873
|
-
annotations: member.annotations,
|
874
|
-
comment: member.comment
|
1096
|
+
accessibility: :public
|
875
1097
|
)
|
876
1098
|
definition.methods[member.name] = method
|
877
|
-
when AST::Members::Alias
|
878
|
-
alias_members << member
|
879
1099
|
end
|
880
|
-
end
|
881
1100
|
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
1101
|
+
alias_members.each do |member|
|
1102
|
+
UnknownMethodAliasError.check!(
|
1103
|
+
methods: definition.methods,
|
1104
|
+
original_name: member.old_name,
|
1105
|
+
aliased_name: member.new_name,
|
1106
|
+
location: member.location
|
1107
|
+
)
|
889
1108
|
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
1109
|
+
DuplicatedMethodDefinitionError.check!(
|
1110
|
+
decl: declaration,
|
1111
|
+
methods: definition.methods,
|
1112
|
+
name: member.new_name,
|
1113
|
+
location: member.location
|
1114
|
+
)
|
896
1115
|
|
897
|
-
|
898
|
-
|
1116
|
+
# FIXME: may cause a problem if #old_name has super type
|
1117
|
+
definition.methods[member.new_name] = definition.methods[member.old_name]
|
1118
|
+
end
|
899
1119
|
end
|
900
1120
|
end
|
901
1121
|
end
|
902
1122
|
|
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
1123
|
def expand_alias(type_name)
|
916
|
-
|
1124
|
+
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
|
1125
|
+
ensure_namespace!(type_name.namespace, location: entry.decl.location)
|
1126
|
+
entry.decl.type
|
917
1127
|
end
|
918
1128
|
end
|
919
1129
|
end
|