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