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