typeprof 0.5.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -4
- data/doc/doc.ja.md +3 -4
- data/doc/doc.md +3 -4
- data/lib/typeprof/analyzer.rb +248 -166
- data/lib/typeprof/arguments.rb +12 -6
- data/lib/typeprof/builtin.rb +123 -23
- data/lib/typeprof/cli.rb +33 -34
- data/lib/typeprof/config.rb +6 -4
- data/lib/typeprof/container-type.rb +175 -112
- data/lib/typeprof/export.rb +23 -17
- data/lib/typeprof/import.rb +58 -53
- data/lib/typeprof/method.rb +59 -125
- data/lib/typeprof/type.rb +26 -14
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias.rb +1 -0
- data/smoke/any1.rb +1 -0
- data/smoke/any2.rb +1 -0
- data/smoke/arguments.rb +1 -0
- data/smoke/arguments2.rb +1 -0
- data/smoke/array-each.rb +1 -0
- data/smoke/array-each2.rb +1 -0
- data/smoke/array-each3.rb +2 -1
- data/smoke/array-ltlt.rb +1 -0
- data/smoke/array-ltlt2.rb +1 -0
- data/smoke/array-map.rb +1 -0
- data/smoke/array-map2.rb +1 -0
- data/smoke/array-map3.rb +1 -0
- data/smoke/array-mul.rb +1 -0
- data/smoke/array-plus1.rb +1 -0
- data/smoke/array-pop.rb +1 -0
- data/smoke/array-range-aref.rb +71 -0
- data/smoke/array-replace.rb +1 -0
- data/smoke/array-s-aref.rb +1 -0
- data/smoke/array1.rb +1 -0
- data/smoke/array10.rb +1 -0
- data/smoke/array11.rb +2 -1
- data/smoke/array12.rb +1 -0
- data/smoke/array13.rb +1 -0
- data/smoke/array14.rb +1 -0
- data/smoke/array2.rb +1 -0
- data/smoke/array4.rb +1 -0
- data/smoke/array5.rb +1 -0
- data/smoke/array6.rb +3 -2
- data/smoke/array7.rb +1 -0
- data/smoke/array8.rb +1 -1
- data/smoke/array9.rb +1 -0
- data/smoke/autoload.rb +14 -0
- data/smoke/backtrace.rb +1 -0
- data/smoke/block-ambiguous.rb +1 -0
- data/smoke/block-args1-rest.rb +1 -0
- data/smoke/block-args1.rb +1 -0
- data/smoke/block-args2-rest.rb +1 -0
- data/smoke/block-args2.rb +4 -3
- data/smoke/block-args3-rest.rb +1 -0
- data/smoke/block-args3.rb +5 -4
- data/smoke/block-blockarg.rb +2 -1
- data/smoke/block-kwarg.rb +1 -0
- data/smoke/block1.rb +1 -0
- data/smoke/block10.rb +1 -0
- data/smoke/block11.rb +1 -0
- data/smoke/block12.rb +1 -0
- data/smoke/block14.rb +1 -0
- data/smoke/block2.rb +1 -0
- data/smoke/block4.rb +1 -0
- data/smoke/block5.rb +2 -1
- data/smoke/block6.rb +1 -0
- data/smoke/block7.rb +1 -0
- data/smoke/block8.rb +1 -0
- data/smoke/block9.rb +1 -0
- data/smoke/blown.rb +1 -0
- data/smoke/break1.rb +1 -0
- data/smoke/break2.rb +1 -0
- data/smoke/case.rb +1 -0
- data/smoke/case2.rb +1 -0
- data/smoke/class_method3.rb +2 -0
- data/smoke/constant2.rb +2 -2
- data/smoke/constant3.rb +1 -0
- data/smoke/constant4.rb +1 -0
- data/smoke/context-sensitive1.rb +1 -0
- data/smoke/cvar.rb +1 -0
- data/smoke/define_method.rb +16 -0
- data/smoke/define_method2.rb +18 -0
- data/smoke/demo.rb +1 -0
- data/smoke/demo1.rb +1 -0
- data/smoke/demo10.rb +1 -0
- data/smoke/demo11.rb +1 -0
- data/smoke/demo2.rb +1 -0
- data/smoke/demo3.rb +1 -0
- data/smoke/demo5.rb +1 -1
- data/smoke/demo7.rb +1 -0
- data/smoke/demo8.rb +1 -0
- data/smoke/demo9.rb +2 -1
- data/smoke/dummy-execution1.rb +1 -0
- data/smoke/ensure1.rb +1 -0
- data/smoke/enumerator.rb +1 -0
- data/smoke/expandarray1.rb +1 -0
- data/smoke/expandarray2.rb +1 -0
- data/smoke/flow1.rb +1 -0
- data/smoke/flow2.rb +1 -0
- data/smoke/flow3.rb +1 -0
- data/smoke/flow5.rb +1 -0
- data/smoke/flow6.rb +1 -0
- data/smoke/flow7.rb +1 -0
- data/smoke/flow8.rb +1 -0
- data/smoke/freeze.rb +1 -0
- data/smoke/function.rb +1 -0
- data/smoke/gvar.rb +1 -0
- data/smoke/gvar2.rb +1 -0
- data/smoke/hash-fetch.rb +1 -0
- data/smoke/hash-merge-bang.rb +1 -0
- data/smoke/hash1.rb +3 -1
- data/smoke/hash2.rb +1 -0
- data/smoke/hash3.rb +1 -0
- data/smoke/hash4.rb +2 -1
- data/smoke/inheritance2.rb +2 -2
- data/smoke/initialize.rb +1 -0
- data/smoke/int_times.rb +1 -0
- data/smoke/integer.rb +1 -0
- data/smoke/ivar.rb +1 -0
- data/smoke/ivar2.rb +1 -1
- data/smoke/kernel-class.rb +2 -1
- data/smoke/keyword1.rb +1 -0
- data/smoke/keyword2.rb +1 -0
- data/smoke/keyword3.rb +1 -0
- data/smoke/keyword4.rb +1 -0
- data/smoke/keyword5.rb +1 -0
- data/smoke/kwrest.rb +12 -0
- data/smoke/kwrest.rbs +3 -0
- data/smoke/kwsplat1.rb +2 -1
- data/smoke/kwsplat2.rb +1 -0
- data/smoke/manual-rbs.rb +1 -0
- data/smoke/manual-rbs2.rb +1 -0
- data/smoke/masgn1.rb +1 -0
- data/smoke/masgn2.rb +1 -0
- data/smoke/masgn3.rb +1 -0
- data/smoke/method_in_branch.rb +1 -0
- data/smoke/method_missing.rb +28 -0
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/next1.rb +1 -0
- data/smoke/next2.rb +1 -0
- data/smoke/object-send1.rb +1 -0
- data/smoke/once.rb +1 -0
- data/smoke/optional1.rb +1 -0
- data/smoke/optional2.rb +1 -0
- data/smoke/optional3.rb +1 -0
- data/smoke/parameterizedd-self.rb +3 -2
- data/smoke/parameterizedd-self2.rb +15 -0
- data/smoke/pathname1.rb +1 -0
- data/smoke/pathname2.rb +1 -0
- data/smoke/pattern-match1.rb +1 -0
- data/smoke/pattern-match2.rb +1 -0
- data/smoke/proc.rb +1 -0
- data/smoke/proc2.rb +1 -0
- data/smoke/proc3.rb +1 -0
- data/smoke/proc4.rb +1 -0
- data/smoke/range.rb +1 -0
- data/smoke/rbs-alias.rb +1 -0
- data/smoke/rbs-attr.rb +3 -2
- data/smoke/rbs-attr2.rb +11 -0
- data/smoke/rbs-attr2.rbs +3 -0
- data/smoke/rbs-extend.rb +1 -0
- data/smoke/rbs-interface.rb +1 -0
- data/smoke/rbs-proc1.rb +1 -0
- data/smoke/rbs-proc2.rb +1 -0
- data/smoke/rbs-proc3.rb +1 -0
- data/smoke/rbs-record.rb +1 -0
- data/smoke/rbs-tyvar.rb +1 -0
- data/smoke/rbs-tyvar2.rb +1 -0
- data/smoke/rbs-tyvar3.rb +1 -0
- data/smoke/rbs-tyvar5.rb +1 -0
- data/smoke/rbs-tyvar6.rb +18 -0
- data/smoke/rbs-tyvar6.rbs +12 -0
- data/smoke/rbs-tyvar7.rb +12 -0
- data/smoke/rbs-tyvar7.rbs +7 -0
- data/smoke/rbs-vars.rb +1 -2
- data/smoke/redo1.rb +1 -0
- data/smoke/redo2.rb +1 -0
- data/smoke/req-keyword.rb +1 -0
- data/smoke/rescue1.rb +1 -0
- data/smoke/rescue2.rb +1 -0
- data/smoke/respond_to.rb +1 -0
- data/smoke/rest-farg.rb +1 -0
- data/smoke/rest1.rb +1 -0
- data/smoke/rest2.rb +1 -0
- data/smoke/rest3.rb +1 -0
- data/smoke/rest4.rb +1 -0
- data/smoke/rest5.rb +1 -0
- data/smoke/rest6.rb +1 -0
- data/smoke/retry1.rb +1 -0
- data/smoke/return.rb +1 -0
- data/smoke/step.rb +1 -0
- data/smoke/string-split.rb +1 -0
- data/smoke/struct.rb +2 -2
- data/smoke/struct2.rb +1 -0
- data/smoke/super1.rb +1 -0
- data/smoke/super4.rb +43 -0
- data/smoke/super5.rb +36 -0
- data/smoke/svar1.rb +1 -0
- data/smoke/symbol-proc.rb +1 -0
- data/smoke/tap1.rb +1 -0
- data/smoke/toplevel.rb +1 -0
- data/smoke/two-map.rb +1 -0
- data/smoke/type_var.rb +1 -0
- data/smoke/typed_method.rb +1 -0
- data/smoke/uninitialize-var.rb +1 -0
- data/smoke/union-recv.rb +2 -2
- metadata +18 -2
data/lib/typeprof/export.rb
CHANGED
|
@@ -91,9 +91,9 @@ module TypeProf
|
|
|
91
91
|
def conv_class(namespace, class_def, inner_classes)
|
|
92
92
|
@scratch.namespace = namespace
|
|
93
93
|
|
|
94
|
-
if class_def.superclass
|
|
95
|
-
omit =
|
|
96
|
-
superclass = omit ? nil : @scratch.get_class_name(
|
|
94
|
+
if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
|
|
95
|
+
omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
|
|
96
|
+
superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
@scratch.namespace = class_def.name
|
|
@@ -105,12 +105,12 @@ module TypeProf
|
|
|
105
105
|
consts[name] = ty.screen_name(@scratch)
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
included_mods = class_def.modules[false].filter_map do |mod_def, absolute_paths|
|
|
108
|
+
included_mods = class_def.modules[false].filter_map do |mod_def, _type_args, absolute_paths|
|
|
109
109
|
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
|
110
110
|
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
-
extended_mods = class_def.modules[true].filter_map do |mod_def, absolute_paths|
|
|
113
|
+
extended_mods = class_def.modules[true].filter_map do |mod_def, _type_args, absolute_paths|
|
|
114
114
|
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
|
115
115
|
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
|
116
116
|
end
|
|
@@ -135,11 +135,12 @@ module TypeProf
|
|
|
135
135
|
method_name = ctx.mid
|
|
136
136
|
method_name = "self.#{ method_name }" if singleton
|
|
137
137
|
|
|
138
|
-
iseq_methods[method_name] ||= []
|
|
139
|
-
iseq_methods[method_name]
|
|
138
|
+
iseq_methods[method_name] ||= [true, []]
|
|
139
|
+
iseq_methods[method_name][0] &&= mdef.pub_meth
|
|
140
|
+
iseq_methods[method_name][1] << @scratch.show_method_signature(ctx)
|
|
140
141
|
end
|
|
141
142
|
when AttrMethodDef
|
|
142
|
-
next if Config.check_dir_filter(mdef.absolute_path) == :exclude
|
|
143
|
+
next if !mdef.absolute_path || Config.check_dir_filter(mdef.absolute_path) == :exclude
|
|
143
144
|
mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
|
|
144
145
|
method_name = mid
|
|
145
146
|
method_name = "self.#{ mid }" if singleton
|
|
@@ -168,12 +169,14 @@ module TypeProf
|
|
|
168
169
|
next unless var.to_s.start_with?("@")
|
|
169
170
|
var = "self.#{ var }" if singleton
|
|
170
171
|
next if attr_methods[[singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]
|
|
171
|
-
|
|
172
|
+
next if entry.rbs_declared
|
|
173
|
+
[var, ty.screen_name(@scratch)]
|
|
172
174
|
end.compact
|
|
173
175
|
|
|
174
176
|
cvars = cvars.map do |var, entry|
|
|
175
177
|
next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
|
|
176
|
-
|
|
178
|
+
next if entry.rbs_declared
|
|
179
|
+
[var, entry.type.screen_name(@scratch)]
|
|
177
180
|
end.compact
|
|
178
181
|
|
|
179
182
|
if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
|
|
@@ -277,14 +280,12 @@ module TypeProf
|
|
|
277
280
|
output.puts indent + " extend #{ mod }"
|
|
278
281
|
first = false
|
|
279
282
|
end
|
|
280
|
-
class_data.ivars.each do |var, ty
|
|
281
|
-
|
|
282
|
-
output.puts indent + s + "#{ var } : #{ ty }" unless var.start_with?("_")
|
|
283
|
+
class_data.ivars.each do |var, ty|
|
|
284
|
+
output.puts indent + " #{ var } : #{ ty }" unless var.start_with?("_")
|
|
283
285
|
first = false
|
|
284
286
|
end
|
|
285
|
-
class_data.cvars.each do |var, ty
|
|
286
|
-
|
|
287
|
-
output.puts indent + s + "#{ var } : #{ ty }"
|
|
287
|
+
class_data.cvars.each do |var, ty|
|
|
288
|
+
output.puts indent + " #{ var } : #{ ty }"
|
|
288
289
|
first = false
|
|
289
290
|
end
|
|
290
291
|
class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
|
|
@@ -296,8 +297,13 @@ module TypeProf
|
|
|
296
297
|
output.puts indent + "# def #{ method_name } : #{ sigs }"
|
|
297
298
|
first = false
|
|
298
299
|
end
|
|
299
|
-
|
|
300
|
+
prev_pub_meth = true
|
|
301
|
+
class_data.iseq_methods.each do |method_name, (pub_meth, sigs)|
|
|
300
302
|
sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 7) + "| ")
|
|
303
|
+
if prev_pub_meth != pub_meth
|
|
304
|
+
output.puts indent + " #{ pub_meth ? "public" : "private" }"
|
|
305
|
+
prev_pub_meth = pub_meth
|
|
306
|
+
end
|
|
301
307
|
output.puts indent + " def #{ method_name } : #{ sigs }"
|
|
302
308
|
first = false
|
|
303
309
|
end
|
data/lib/typeprof/import.rb
CHANGED
|
@@ -100,14 +100,19 @@ module TypeProf
|
|
|
100
100
|
json = {}
|
|
101
101
|
|
|
102
102
|
each_class_decl do |name, decls|
|
|
103
|
-
super_class_name = get_super_class_name(name, decls)
|
|
104
103
|
klass = conv_type_name(name)
|
|
105
|
-
|
|
104
|
+
super_class_name, super_class_args = get_super_class(name, decls)
|
|
105
|
+
if super_class_name
|
|
106
|
+
name = conv_type_name(super_class_name)
|
|
107
|
+
type_args = super_class_args.map {|type| conv_type(type) }
|
|
108
|
+
superclass = [name, type_args]
|
|
109
|
+
end
|
|
106
110
|
|
|
107
111
|
type_params = nil
|
|
108
112
|
included_modules = []
|
|
109
113
|
extended_modules = []
|
|
110
114
|
methods = {}
|
|
115
|
+
attr_methods = {}
|
|
111
116
|
ivars = {}
|
|
112
117
|
cvars = {}
|
|
113
118
|
rbs_sources = {}
|
|
@@ -143,15 +148,15 @@ module TypeProf
|
|
|
143
148
|
end
|
|
144
149
|
when RBS::AST::Members::AttrReader
|
|
145
150
|
ty = conv_type(member.type)
|
|
146
|
-
|
|
151
|
+
attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
|
|
147
152
|
when RBS::AST::Members::AttrWriter
|
|
148
153
|
ty = conv_type(member.type)
|
|
149
|
-
|
|
154
|
+
attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
|
|
150
155
|
when RBS::AST::Members::AttrAccessor
|
|
151
156
|
ty = conv_type(member.type)
|
|
152
|
-
|
|
153
|
-
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
|
157
|
+
attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
|
|
154
158
|
when RBS::AST::Members::Alias
|
|
159
|
+
# XXX: an alias to attr methods?
|
|
155
160
|
if member.instance?
|
|
156
161
|
method_def = methods[[false, member.old_name]]
|
|
157
162
|
methods[[false, member.new_name]] = method_def if method_def
|
|
@@ -165,7 +170,8 @@ module TypeProf
|
|
|
165
170
|
name = member.name
|
|
166
171
|
if name.kind == :class
|
|
167
172
|
mod = conv_type_name(name)
|
|
168
|
-
|
|
173
|
+
type_args = member.args.map {|type| conv_type(type) }
|
|
174
|
+
included_modules << [mod, type_args]
|
|
169
175
|
else
|
|
170
176
|
# including an interface is not supported yet
|
|
171
177
|
end
|
|
@@ -174,7 +180,8 @@ module TypeProf
|
|
|
174
180
|
name = member.name
|
|
175
181
|
if name.kind == :class
|
|
176
182
|
mod = conv_type_name(name)
|
|
177
|
-
|
|
183
|
+
type_args = member.args.map {|type| conv_type(type) }
|
|
184
|
+
extended_modules << [mod, type_args]
|
|
178
185
|
else
|
|
179
186
|
# extending a module with an interface is not supported yet
|
|
180
187
|
end
|
|
@@ -205,6 +212,7 @@ module TypeProf
|
|
|
205
212
|
included_modules: included_modules,
|
|
206
213
|
extended_modules: extended_modules,
|
|
207
214
|
methods: methods,
|
|
215
|
+
attr_methods: attr_methods,
|
|
208
216
|
ivars: ivars,
|
|
209
217
|
cvars: cvars,
|
|
210
218
|
rbs_sources: rbs_sources,
|
|
@@ -231,7 +239,7 @@ module TypeProf
|
|
|
231
239
|
@all_env.class_decls[name].decls.each do |decl|
|
|
232
240
|
decl = decl.decl
|
|
233
241
|
next if decl.is_a?(RBS::AST::Declarations::Module)
|
|
234
|
-
|
|
242
|
+
each_reference(decl) {|name| queue << [:visit, name] }
|
|
235
243
|
end
|
|
236
244
|
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
|
237
245
|
end
|
|
@@ -246,24 +254,29 @@ module TypeProf
|
|
|
246
254
|
end
|
|
247
255
|
end
|
|
248
256
|
|
|
249
|
-
def
|
|
257
|
+
def each_reference(decl, &blk)
|
|
250
258
|
yield decl.name
|
|
251
|
-
|
|
259
|
+
if decl.super_class
|
|
260
|
+
name = decl.super_class.name
|
|
261
|
+
else
|
|
262
|
+
name = RBS::BuiltinNames::Object.name
|
|
263
|
+
end
|
|
252
264
|
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
|
253
|
-
return if decl.name ==
|
|
254
|
-
@all_env.class_decls[
|
|
255
|
-
|
|
265
|
+
return if decl.name == name
|
|
266
|
+
@all_env.class_decls[name].decls.each do |decl|
|
|
267
|
+
each_reference(decl.decl, &blk)
|
|
256
268
|
end
|
|
257
269
|
end
|
|
258
270
|
|
|
259
|
-
def
|
|
271
|
+
def get_super_class(name, decls)
|
|
260
272
|
return nil if name == RBS::BuiltinNames::BasicObject.name
|
|
261
273
|
|
|
262
274
|
decls.each do |decl|
|
|
263
275
|
decl = decl.decl
|
|
264
276
|
case decl
|
|
265
277
|
when RBS::AST::Declarations::Class
|
|
266
|
-
|
|
278
|
+
super_class = decl.super_class
|
|
279
|
+
return super_class.name, super_class.args if super_class
|
|
267
280
|
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
|
268
281
|
return nil
|
|
269
282
|
else
|
|
@@ -271,7 +284,7 @@ module TypeProf
|
|
|
271
284
|
end
|
|
272
285
|
end
|
|
273
286
|
|
|
274
|
-
return RBS::BuiltinNames::Object.name
|
|
287
|
+
return RBS::BuiltinNames::Object.name, []
|
|
275
288
|
end
|
|
276
289
|
|
|
277
290
|
def conv_method_def(rbs_method_types)
|
|
@@ -290,7 +303,7 @@ module TypeProf
|
|
|
290
303
|
opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
|
291
304
|
req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
|
292
305
|
rest_kw_ty = func.rest_keywords
|
|
293
|
-
|
|
306
|
+
rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
|
|
294
307
|
|
|
295
308
|
ret_ty = conv_type(func.return_type)
|
|
296
309
|
|
|
@@ -307,32 +320,12 @@ module TypeProf
|
|
|
307
320
|
}
|
|
308
321
|
end
|
|
309
322
|
|
|
310
|
-
def
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
req_kw_tys: {},
|
|
317
|
-
opt_kw_tys: {},
|
|
318
|
-
rest_kw_ty: nil,
|
|
319
|
-
blk: nil,
|
|
320
|
-
ret_ty: ty,
|
|
321
|
-
}]
|
|
322
|
-
end
|
|
323
|
-
|
|
324
|
-
def attr_writer_def(ty)
|
|
325
|
-
[{
|
|
326
|
-
type_params: [],
|
|
327
|
-
lead_tys: [ty],
|
|
328
|
-
opt_tys: [],
|
|
329
|
-
rest_ty: nil,
|
|
330
|
-
req_kw_tys: {},
|
|
331
|
-
opt_kw_tys: {},
|
|
332
|
-
rest_kw_ty: nil,
|
|
333
|
-
blk: nil,
|
|
334
|
-
ret_ty: ty,
|
|
335
|
-
}]
|
|
323
|
+
def attr_method_def(kind, name, ty)
|
|
324
|
+
{
|
|
325
|
+
kind: kind,
|
|
326
|
+
ivar: name,
|
|
327
|
+
ty: ty,
|
|
328
|
+
}
|
|
336
329
|
end
|
|
337
330
|
|
|
338
331
|
def conv_block(rbs_block)
|
|
@@ -467,8 +460,8 @@ module TypeProf
|
|
|
467
460
|
def import(explicit = false)
|
|
468
461
|
classes = @json[:classes].map do |classpath, cdef|
|
|
469
462
|
type_params = cdef[:type_params]
|
|
470
|
-
superclass
|
|
471
|
-
members
|
|
463
|
+
superclass, superclass_type_args = cdef[:superclass]
|
|
464
|
+
members = cdef[:members]
|
|
472
465
|
|
|
473
466
|
name = classpath.last
|
|
474
467
|
superclass = path_to_klass(superclass) if superclass
|
|
@@ -492,23 +485,27 @@ module TypeProf
|
|
|
492
485
|
end
|
|
493
486
|
end
|
|
494
487
|
|
|
495
|
-
[klass, members]
|
|
488
|
+
[klass, superclass_type_args, members]
|
|
496
489
|
end
|
|
497
490
|
|
|
498
|
-
classes.each do |klass, members|
|
|
491
|
+
classes.each do |klass, superclass_type_args, members|
|
|
492
|
+
@scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
|
|
499
493
|
included_modules = members[:included_modules]
|
|
500
494
|
extended_modules = members[:extended_modules]
|
|
501
495
|
methods = members[:methods]
|
|
496
|
+
attr_methods = members[:attr_methods]
|
|
502
497
|
ivars = members[:ivars]
|
|
503
498
|
cvars = members[:cvars]
|
|
504
499
|
rbs_sources = members[:rbs_sources]
|
|
505
500
|
|
|
506
|
-
included_modules.each do |mod|
|
|
507
|
-
|
|
501
|
+
included_modules.each do |mod, type_args|
|
|
502
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
|
503
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
|
|
508
504
|
end
|
|
509
505
|
|
|
510
|
-
extended_modules.each do |mod|
|
|
511
|
-
|
|
506
|
+
extended_modules.each do |mod, type_args|
|
|
507
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
|
508
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
|
|
512
509
|
end
|
|
513
510
|
|
|
514
511
|
methods.each do |(singleton, method_name), mdef|
|
|
@@ -517,6 +514,14 @@ module TypeProf
|
|
|
517
514
|
@scratch.add_method(klass, method_name, singleton, mdef)
|
|
518
515
|
end
|
|
519
516
|
|
|
517
|
+
attr_methods.each do |(singleton, method_name), mdef|
|
|
518
|
+
kind = mdef[:kind]
|
|
519
|
+
ivar = mdef[:ivar]
|
|
520
|
+
ty = conv_type(mdef[:ty]).remove_type_vars
|
|
521
|
+
@scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
|
|
522
|
+
@scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
|
|
523
|
+
end
|
|
524
|
+
|
|
520
525
|
ivars.each do |ivar_name, ty|
|
|
521
526
|
ty = conv_type(ty).remove_type_vars
|
|
522
527
|
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
|
@@ -583,7 +588,7 @@ module TypeProf
|
|
|
583
588
|
req, lead_tys, opt_tys, ret_ty = blk
|
|
584
589
|
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
|
585
590
|
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
|
586
|
-
msig = MethodSignature.new(lead_tys, opt_tys, nil,
|
|
591
|
+
msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
|
|
587
592
|
ret_ty = conv_type(ret_ty)
|
|
588
593
|
ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
|
|
589
594
|
ret << Type.nil unless req
|
data/lib/typeprof/method.rb
CHANGED
|
@@ -4,12 +4,16 @@ module TypeProf
|
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
class ISeqMethodDef < MethodDef
|
|
7
|
-
def initialize(iseq, cref)
|
|
7
|
+
def initialize(iseq, cref, outer_ep, pub_meth)
|
|
8
8
|
@iseq = iseq
|
|
9
9
|
raise if iseq.nil?
|
|
10
10
|
@cref = cref
|
|
11
|
+
@outer_ep = outer_ep
|
|
12
|
+
@pub_meth = pub_meth
|
|
11
13
|
end
|
|
12
14
|
|
|
15
|
+
attr_accessor :pub_meth
|
|
16
|
+
|
|
13
17
|
def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
|
14
18
|
recv = recv.base_type while recv.respond_to?(:base_type)
|
|
15
19
|
recv = scratch.globalize_type(recv, caller_env, caller_ep)
|
|
@@ -25,8 +29,8 @@ module TypeProf
|
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
nctx = Context.new(@iseq, @cref, mid)
|
|
28
|
-
callee_ep = ExecutionPoint.new(nctx, 0,
|
|
29
|
-
nenv = Env.new(StaticEnv.new(recv, blk_ty, false), locals, [], Utils::HashWrapper.new({}))
|
|
32
|
+
callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
|
|
33
|
+
nenv = Env.new(StaticEnv.new(recv, blk_ty, false, true), locals, [], Utils::HashWrapper.new({}))
|
|
30
34
|
alloc_site = AllocationSite.new(callee_ep)
|
|
31
35
|
locals.each_with_index do |ty, i|
|
|
32
36
|
alloc_site2 = alloc_site.add_id(i)
|
|
@@ -44,6 +48,14 @@ module TypeProf
|
|
|
44
48
|
end
|
|
45
49
|
|
|
46
50
|
def do_check_send(msig, recv, mid, ep, scratch)
|
|
51
|
+
klass, singleton = recv.method_dispatch_info
|
|
52
|
+
cur_subst = {}
|
|
53
|
+
direct_method = true
|
|
54
|
+
scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
|
|
55
|
+
direct_method &&= direct
|
|
56
|
+
cur_subst = Type.merge_substitution(cur_subst, subst)
|
|
57
|
+
end
|
|
58
|
+
|
|
47
59
|
lead_num = @iseq.fargs_format[:lead_num] || 0
|
|
48
60
|
post_num = @iseq.fargs_format[:post_num] || 0
|
|
49
61
|
rest_start = @iseq.fargs_format[:rest_start]
|
|
@@ -67,7 +79,8 @@ module TypeProf
|
|
|
67
79
|
post_start = @iseq.fargs_format[:post_start]
|
|
68
80
|
rest_start = @iseq.fargs_format[:rest_start]
|
|
69
81
|
kw_start = @iseq.fargs_format[:kwbits]
|
|
70
|
-
|
|
82
|
+
keyword = @iseq.fargs_format[:keyword]
|
|
83
|
+
kw_start -= keyword.size if kw_start
|
|
71
84
|
kw_rest = @iseq.fargs_format[:kwrest]
|
|
72
85
|
block_start = @iseq.fargs_format[:block_start]
|
|
73
86
|
|
|
@@ -77,18 +90,20 @@ module TypeProf
|
|
|
77
90
|
callee_ep = ExecutionPoint.new(ctx, 0, nil)
|
|
78
91
|
|
|
79
92
|
locals = [Type.nil] * @iseq.locals.size
|
|
80
|
-
nenv = Env.new(StaticEnv.new(recv, msig.blk_ty, false), locals, [], Utils::HashWrapper.new({}))
|
|
93
|
+
nenv = Env.new(StaticEnv.new(recv, msig.blk_ty, false, true), locals, [], Utils::HashWrapper.new({}))
|
|
81
94
|
alloc_site = AllocationSite.new(callee_ep)
|
|
82
95
|
idx = 0
|
|
83
96
|
msig.lead_tys.each_with_index do |ty, i|
|
|
84
97
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
|
85
98
|
# nenv is top-level, so it is okay to call Type#localize directly
|
|
99
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
86
100
|
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
87
101
|
nenv = nenv.local_update(i, ty)
|
|
88
102
|
end
|
|
89
103
|
if msig.opt_tys
|
|
90
104
|
msig.opt_tys.each_with_index do |ty, i|
|
|
91
105
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
|
106
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
92
107
|
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
93
108
|
nenv = nenv.local_update(lead_num + i, ty)
|
|
94
109
|
end
|
|
@@ -96,19 +111,27 @@ module TypeProf
|
|
|
96
111
|
if msig.rest_ty
|
|
97
112
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
|
98
113
|
ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
|
|
114
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
99
115
|
nenv, rest_ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
100
116
|
nenv = nenv.local_update(rest_start, rest_ty)
|
|
101
117
|
end
|
|
102
118
|
if msig.post_tys
|
|
103
119
|
msig.post_tys.each_with_index do |ty, i|
|
|
104
120
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
|
121
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
105
122
|
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
106
123
|
nenv = nenv.local_update(post_start + i, ty)
|
|
107
124
|
end
|
|
108
125
|
end
|
|
109
126
|
if msig.kw_tys
|
|
110
|
-
msig.kw_tys.
|
|
127
|
+
msig.kw_tys.each do |_, key, ty|
|
|
128
|
+
i = keyword.index(key)
|
|
129
|
+
unless i
|
|
130
|
+
# warn
|
|
131
|
+
next
|
|
132
|
+
end
|
|
111
133
|
alloc_site2 = alloc_site.add_id(key)
|
|
134
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
112
135
|
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
113
136
|
nenv = nenv.local_update(kw_start + i, ty)
|
|
114
137
|
end
|
|
@@ -116,6 +139,7 @@ module TypeProf
|
|
|
116
139
|
if msig.kw_rest_ty
|
|
117
140
|
ty = msig.kw_rest_ty
|
|
118
141
|
alloc_site2 = alloc_site.add_id(:**)
|
|
142
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
119
143
|
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
|
120
144
|
nenv = nenv.local_update(kw_rest, ty)
|
|
121
145
|
end
|
|
@@ -170,6 +194,15 @@ module TypeProf
|
|
|
170
194
|
|
|
171
195
|
def do_send(recv_orig, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
|
172
196
|
recv = scratch.globalize_type(recv_orig, caller_env, caller_ep)
|
|
197
|
+
|
|
198
|
+
klass, singleton = recv_orig.method_dispatch_info
|
|
199
|
+
cur_subst = {}
|
|
200
|
+
direct_method = true
|
|
201
|
+
scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
|
|
202
|
+
direct_method &&= direct
|
|
203
|
+
cur_subst = Type.merge_substitution(cur_subst, subst)
|
|
204
|
+
end
|
|
205
|
+
|
|
173
206
|
found = false
|
|
174
207
|
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
|
175
208
|
@sig_rets.each do |msig, ret_ty|
|
|
@@ -178,56 +211,15 @@ module TypeProf
|
|
|
178
211
|
# XXX: support self type in msig
|
|
179
212
|
subst = aargs.consistent_with_method_signature?(msig)
|
|
180
213
|
next unless subst
|
|
214
|
+
|
|
215
|
+
if direct_method && recv_orig.is_a?(Type::Local)
|
|
216
|
+
ncaller_env = recv_orig.update_container_elem_type(subst, ncaller_env, caller_ep, scratch)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
subst = Type.merge_substitution(subst, cur_subst)
|
|
181
220
|
# need to check self tyvar?
|
|
182
221
|
subst[Type::Var.new(:self)] = recv
|
|
183
|
-
|
|
184
|
-
when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
|
|
185
|
-
tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
|
|
186
|
-
tyvars.each_with_index do |tyvar, idx|
|
|
187
|
-
ty = subst[tyvar]
|
|
188
|
-
if ty
|
|
189
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
|
190
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
191
|
-
elems.update(idx, ty)
|
|
192
|
-
end
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
|
196
|
-
if subst[tyvar]
|
|
197
|
-
subst[tyvar] = subst[tyvar].union(elem)
|
|
198
|
-
else
|
|
199
|
-
subst[tyvar] = elem
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
|
203
|
-
tyvar_elem = Type::Var.new(:Elem)
|
|
204
|
-
if subst[tyvar_elem]
|
|
205
|
-
ty = subst[tyvar_elem]
|
|
206
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
|
207
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
208
|
-
elems.update(nil, ty)
|
|
209
|
-
end
|
|
210
|
-
end
|
|
211
|
-
subst.merge!({ tyvar_elem => recv.elems.squash })
|
|
212
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
|
213
|
-
tyvar_k = Type::Var.new(:K)
|
|
214
|
-
tyvar_v = Type::Var.new(:V)
|
|
215
|
-
k_ty0, v_ty0 = recv.elems.squash
|
|
216
|
-
if subst[tyvar_k] && subst[tyvar_v]
|
|
217
|
-
k_ty = subst[tyvar_k]
|
|
218
|
-
v_ty = subst[tyvar_v]
|
|
219
|
-
k_ty0 = k_ty0.union(k_ty)
|
|
220
|
-
v_ty0 = v_ty0.union(v_ty)
|
|
221
|
-
alloc_site = AllocationSite.new(caller_ep)
|
|
222
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
|
223
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
|
224
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
225
|
-
elems.update(k_ty, v_ty)
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
# XXX: need to heuristically replace ret type Hash[K, V] with self, instead of conversative type?
|
|
229
|
-
subst.merge!({ tyvar_k => k_ty0, tyvar_v => v_ty0 })
|
|
230
|
-
end
|
|
222
|
+
|
|
231
223
|
found = true
|
|
232
224
|
if aargs.blk_ty.is_a?(Type::Proc)
|
|
233
225
|
#raise NotImplementedError unless aargs.blk_ty.block_body.is_a?(ISeqBlock) # XXX
|
|
@@ -235,91 +227,33 @@ module TypeProf
|
|
|
235
227
|
dummy_ep = ExecutionPoint.new(dummy_ctx, -1, caller_ep)
|
|
236
228
|
s_recv = recv
|
|
237
229
|
s_recv = s_recv.base_type while s_recv.respond_to?(:base_type)
|
|
238
|
-
dummy_env = Env.new(StaticEnv.new(s_recv, msig.blk_ty, false), [], [], Utils::HashWrapper.new({}))
|
|
230
|
+
dummy_env = Env.new(StaticEnv.new(s_recv, msig.blk_ty, false, true), [], [], Utils::HashWrapper.new({}))
|
|
239
231
|
if msig.blk_ty.is_a?(Type::Proc)
|
|
240
232
|
scratch.add_callsite!(dummy_ctx, caller_ep, ncaller_env, &ctn)
|
|
241
|
-
|
|
233
|
+
bsig = msig.blk_ty.block_body.msig
|
|
242
234
|
alloc_site = AllocationSite.new(caller_ep).add_id(self)
|
|
243
|
-
nlead_tys = (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
ty = ty.substitute(subst.merge({ tyvar_elem => recv.elems.squash_or_any }), Config.options[:type_depth_limit])
|
|
247
|
-
else
|
|
248
|
-
ty = ty.substitute(subst, Config.options[:type_depth_limit])
|
|
249
|
-
end
|
|
250
|
-
ty = ty.remove_type_vars
|
|
251
|
-
alloc_site2 = alloc_site.add_id(i)
|
|
252
|
-
dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site2)
|
|
235
|
+
nlead_tys = (bsig.lead_tys + bsig.opt_tys).map.with_index do |ty, i|
|
|
236
|
+
ty = ty.substitute(subst, Config.options[:type_depth_limit]).remove_type_vars
|
|
237
|
+
dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site.add_id(i))
|
|
253
238
|
ty
|
|
254
239
|
end
|
|
255
|
-
0.upto(
|
|
256
|
-
naargs = ActualArguments.new(nlead_tys[0,
|
|
240
|
+
0.upto(bsig.opt_tys.size) do |n|
|
|
241
|
+
naargs = ActualArguments.new(nlead_tys[0, bsig.lead_tys.size + n], nil, {}, Type.nil) # XXX: support block to block?
|
|
257
242
|
scratch.do_invoke_block(aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
|
|
258
243
|
subst2 = Type.match?(blk_ret_ty, msig.blk_ty.block_body.ret_ty)
|
|
259
244
|
if subst2
|
|
260
245
|
subst2 = Type.merge_substitution(subst, subst2)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
tyvars.each_with_index do |tyvar, idx|
|
|
265
|
-
ty = subst2[tyvar]
|
|
266
|
-
if ty
|
|
267
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
|
268
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
269
|
-
elems.update(idx, ty)
|
|
270
|
-
end
|
|
271
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
|
275
|
-
if subst2[tyvar]
|
|
276
|
-
subst2[tyvar] = subst2[tyvar].union(elem)
|
|
277
|
-
else
|
|
278
|
-
subst2[tyvar] = elem
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
|
282
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
|
283
|
-
tyvar_elem = Type::Var.new(:Elem)
|
|
284
|
-
if subst2[tyvar_elem]
|
|
285
|
-
ty = subst2[tyvar_elem]
|
|
286
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
|
287
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
288
|
-
elems.update(nil, ty)
|
|
289
|
-
end
|
|
290
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
|
291
|
-
end
|
|
292
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
|
293
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
|
294
|
-
tyvar_k = Type::Var.new(:K)
|
|
295
|
-
tyvar_v = Type::Var.new(:V)
|
|
296
|
-
k_ty0, v_ty0 = recv.elems.squash
|
|
297
|
-
if subst2[tyvar_k] && subst2[tyvar_v]
|
|
298
|
-
k_ty = subst2[tyvar_k]
|
|
299
|
-
v_ty = subst2[tyvar_v]
|
|
300
|
-
k_ty0 = k_ty0.union(k_ty)
|
|
301
|
-
v_ty0 = v_ty0.union(v_ty)
|
|
302
|
-
alloc_site = AllocationSite.new(caller_ep)
|
|
303
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
|
304
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
|
305
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
|
306
|
-
elems.update(k_ty, v_ty)
|
|
307
|
-
end
|
|
308
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
|
309
|
-
end
|
|
310
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
|
311
|
-
else
|
|
312
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
|
246
|
+
if direct_method && recv_orig.is_a?(Type::Local)
|
|
247
|
+
ncaller_env = recv_orig.update_container_elem_type(subst2, ncaller_env, caller_ep, scratch)
|
|
248
|
+
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
|
313
249
|
end
|
|
250
|
+
ret_ty2 = ret_ty.substitute(subst2, Config.options[:type_depth_limit]).remove_type_vars
|
|
314
251
|
else
|
|
315
|
-
|
|
316
|
-
# XXX: need warning
|
|
317
|
-
ret_ty = Type.any
|
|
252
|
+
ret_ty2 = Type.any
|
|
318
253
|
end
|
|
319
|
-
ret_ty = ret_ty.remove_type_vars
|
|
320
254
|
# XXX: check the return type from the block
|
|
321
255
|
# sig.blk_ty.block_body.ret_ty.eql?(_ret_ty) ???
|
|
322
|
-
scratch.add_return_value!(dummy_ctx,
|
|
256
|
+
scratch.add_return_value!(dummy_ctx, ret_ty2)
|
|
323
257
|
end
|
|
324
258
|
# scratch.add_return_value!(dummy_ctx, ret_ty) ?
|
|
325
259
|
# This makes `def foo; 1.times { return "str" }; end` return Integer|String
|