typeprof 0.5.4 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (289) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +7 -5
  3. data/doc/doc.ja.md +3 -4
  4. data/doc/doc.md +3 -4
  5. data/lib/typeprof/analyzer.rb +308 -171
  6. data/lib/typeprof/arguments.rb +14 -6
  7. data/lib/typeprof/block.rb +6 -2
  8. data/lib/typeprof/builtin.rb +230 -67
  9. data/lib/typeprof/cli.rb +33 -34
  10. data/lib/typeprof/config.rb +6 -4
  11. data/lib/typeprof/container-type.rb +159 -104
  12. data/lib/typeprof/export.rb +28 -22
  13. data/lib/typeprof/import.rb +70 -53
  14. data/lib/typeprof/iseq.rb +23 -7
  15. data/lib/typeprof/method.rb +71 -138
  16. data/lib/typeprof/type.rb +73 -15
  17. data/lib/typeprof/version.rb +1 -1
  18. data/smoke/alias.rb +5 -4
  19. data/smoke/alias2.rb +4 -4
  20. data/smoke/any1.rb +2 -1
  21. data/smoke/any2.rb +3 -2
  22. data/smoke/arguments.rb +3 -2
  23. data/smoke/arguments2.rb +11 -10
  24. data/smoke/array-each.rb +2 -1
  25. data/smoke/array-each2.rb +2 -1
  26. data/smoke/array-each3.rb +2 -1
  27. data/smoke/array-ltlt.rb +2 -1
  28. data/smoke/array-ltlt2.rb +2 -1
  29. data/smoke/array-map.rb +2 -1
  30. data/smoke/array-map2.rb +2 -1
  31. data/smoke/array-map3.rb +4 -3
  32. data/smoke/array-mul.rb +3 -2
  33. data/smoke/array-plus1.rb +2 -1
  34. data/smoke/array-plus2.rb +2 -2
  35. data/smoke/array-pop.rb +2 -1
  36. data/smoke/array-range-aref.rb +71 -0
  37. data/smoke/array-replace.rb +2 -1
  38. data/smoke/array-s-aref.rb +2 -1
  39. data/smoke/array1.rb +6 -5
  40. data/smoke/array10.rb +2 -1
  41. data/smoke/array11.rb +2 -1
  42. data/smoke/array12.rb +4 -3
  43. data/smoke/array13.rb +5 -4
  44. data/smoke/array14.rb +2 -1
  45. data/smoke/array15.rb +16 -0
  46. data/smoke/array2.rb +4 -3
  47. data/smoke/array3.rb +4 -4
  48. data/smoke/array4.rb +2 -1
  49. data/smoke/array5.rb +2 -1
  50. data/smoke/array6.rb +3 -2
  51. data/smoke/array7.rb +2 -1
  52. data/smoke/array8.rb +1 -1
  53. data/smoke/array9.rb +2 -1
  54. data/smoke/attr-module.rb +26 -0
  55. data/smoke/attr.rb +5 -5
  56. data/smoke/autoload.rb +14 -0
  57. data/smoke/backtrace.rb +4 -3
  58. data/smoke/block-ambiguous.rb +9 -8
  59. data/smoke/block-args1-rest.rb +12 -11
  60. data/smoke/block-args1.rb +11 -10
  61. data/smoke/block-args2-rest.rb +12 -11
  62. data/smoke/block-args2.rb +11 -10
  63. data/smoke/block-args3-rest.rb +14 -13
  64. data/smoke/block-args3.rb +13 -12
  65. data/smoke/block-blockarg.rb +5 -4
  66. data/smoke/block-kwarg.rb +11 -10
  67. data/smoke/block1.rb +2 -1
  68. data/smoke/block10.rb +2 -1
  69. data/smoke/block11.rb +6 -5
  70. data/smoke/block12.rb +3 -2
  71. data/smoke/block14.rb +3 -2
  72. data/smoke/block2.rb +2 -1
  73. data/smoke/block3.rb +3 -3
  74. data/smoke/block4.rb +3 -2
  75. data/smoke/block5.rb +3 -2
  76. data/smoke/block6.rb +3 -2
  77. data/smoke/block7.rb +2 -1
  78. data/smoke/block8.rb +4 -3
  79. data/smoke/block9.rb +2 -1
  80. data/smoke/blown.rb +2 -1
  81. data/smoke/break1.rb +3 -2
  82. data/smoke/break2.rb +2 -1
  83. data/smoke/break3.rb +13 -0
  84. data/smoke/case.rb +2 -1
  85. data/smoke/case2.rb +2 -1
  86. data/smoke/case3.rb +17 -0
  87. data/smoke/class-hierarchy.rb +5 -5
  88. data/smoke/class-hierarchy2.rb +3 -3
  89. data/smoke/class-new.rb +15 -0
  90. data/smoke/class_instance_var.rb +1 -1
  91. data/smoke/class_method.rb +2 -2
  92. data/smoke/class_method2.rb +2 -2
  93. data/smoke/class_method3.rb +4 -2
  94. data/smoke/constant1.rb +6 -6
  95. data/smoke/constant2.rb +5 -4
  96. data/smoke/constant3.rb +2 -1
  97. data/smoke/constant4.rb +2 -1
  98. data/smoke/context-sensitive1.rb +2 -1
  99. data/smoke/cvar.rb +6 -5
  100. data/smoke/cvar2.rb +2 -2
  101. data/smoke/define_method.rb +16 -0
  102. data/smoke/define_method2.rb +18 -0
  103. data/smoke/define_method3.rb +13 -0
  104. data/smoke/define_method3.rbs +3 -0
  105. data/smoke/define_method4.rb +15 -0
  106. data/smoke/define_method4.rbs +3 -0
  107. data/smoke/define_method5.rb +12 -0
  108. data/smoke/demo.rb +7 -6
  109. data/smoke/demo1.rb +2 -1
  110. data/smoke/demo10.rb +3 -2
  111. data/smoke/demo11.rb +2 -1
  112. data/smoke/demo2.rb +2 -1
  113. data/smoke/demo3.rb +2 -1
  114. data/smoke/demo4.rb +3 -3
  115. data/smoke/demo5.rb +1 -1
  116. data/smoke/demo6.rb +3 -3
  117. data/smoke/demo7.rb +2 -1
  118. data/smoke/demo8.rb +3 -2
  119. data/smoke/demo9.rb +3 -2
  120. data/smoke/dummy-execution1.rb +3 -2
  121. data/smoke/dummy-execution2.rb +2 -2
  122. data/smoke/dummy_element.rb +14 -0
  123. data/smoke/ensure1.rb +3 -2
  124. data/smoke/enumerator.rb +3 -2
  125. data/smoke/expandarray1.rb +2 -1
  126. data/smoke/expandarray2.rb +2 -1
  127. data/smoke/fib.rb +2 -2
  128. data/smoke/flip-flop.rb +28 -0
  129. data/smoke/flow1.rb +2 -1
  130. data/smoke/flow2.rb +2 -1
  131. data/smoke/flow3.rb +2 -1
  132. data/smoke/flow5.rb +2 -1
  133. data/smoke/flow6.rb +2 -1
  134. data/smoke/flow7.rb +2 -1
  135. data/smoke/flow8.rb +2 -1
  136. data/smoke/flow9.rb +12 -0
  137. data/smoke/freeze.rb +2 -1
  138. data/smoke/function.rb +3 -2
  139. data/smoke/gvar.rb +3 -2
  140. data/smoke/gvar2.rb +3 -2
  141. data/smoke/hash-bot.rb +12 -0
  142. data/smoke/hash-fetch.rb +4 -3
  143. data/smoke/hash-merge-bang.rb +2 -1
  144. data/smoke/hash1.rb +3 -2
  145. data/smoke/hash2.rb +2 -1
  146. data/smoke/hash3.rb +2 -1
  147. data/smoke/hash4.rb +2 -1
  148. data/smoke/hash5.rb +1 -1
  149. data/smoke/inheritance.rb +4 -4
  150. data/smoke/inheritance2.rb +2 -2
  151. data/smoke/initialize.rb +6 -5
  152. data/smoke/instance_eval.rb +2 -2
  153. data/smoke/instance_eval2.rb +10 -0
  154. data/smoke/instance_eval3.rb +25 -0
  155. data/smoke/int_times.rb +2 -1
  156. data/smoke/integer.rb +2 -1
  157. data/smoke/ivar.rb +5 -4
  158. data/smoke/ivar2.rb +4 -4
  159. data/smoke/ivar3.rb +2 -2
  160. data/smoke/kernel-class.rb +2 -1
  161. data/smoke/keyword1.rb +2 -1
  162. data/smoke/keyword2.rb +2 -1
  163. data/smoke/keyword3.rb +2 -1
  164. data/smoke/keyword4.rb +2 -1
  165. data/smoke/keyword5.rb +2 -1
  166. data/smoke/kwrest.rb +12 -0
  167. data/smoke/kwrest.rbs +3 -0
  168. data/smoke/kwsplat1.rb +5 -4
  169. data/smoke/kwsplat2.rb +2 -1
  170. data/smoke/lit-complex.rb +10 -0
  171. data/smoke/lit-encoding.rb +10 -0
  172. data/smoke/manual-rbs.rb +4 -3
  173. data/smoke/manual-rbs2.rb +2 -1
  174. data/smoke/manual-rbs3.rb +2 -2
  175. data/smoke/masgn1.rb +2 -1
  176. data/smoke/masgn2.rb +3 -2
  177. data/smoke/masgn3.rb +2 -1
  178. data/smoke/method_in_branch.rb +3 -2
  179. data/smoke/method_missing.rb +28 -0
  180. data/smoke/module1.rb +2 -2
  181. data/smoke/module2.rb +1 -1
  182. data/smoke/module3.rb +2 -2
  183. data/smoke/module4.rb +2 -2
  184. data/smoke/module5.rb +17 -0
  185. data/smoke/module6.rb +40 -0
  186. data/smoke/module_function1.rb +3 -3
  187. data/smoke/module_function2.rb +3 -3
  188. data/smoke/multiple-include.rb +1 -1
  189. data/smoke/multiple-superclass.rb +1 -1
  190. data/smoke/next1.rb +3 -2
  191. data/smoke/next2.rb +2 -1
  192. data/smoke/object-send1.rb +4 -3
  193. data/smoke/object-send2.rb +10 -0
  194. data/smoke/object-send3.rb +18 -0
  195. data/smoke/once.rb +2 -1
  196. data/smoke/optional1.rb +2 -1
  197. data/smoke/optional2.rb +2 -1
  198. data/smoke/optional3.rb +2 -1
  199. data/smoke/parameterizedd-self.rb +3 -2
  200. data/smoke/parameterizedd-self2.rb +15 -0
  201. data/smoke/pathname1.rb +2 -1
  202. data/smoke/pathname2.rb +2 -1
  203. data/smoke/pattern-match1.rb +2 -1
  204. data/smoke/pattern-match2.rb +2 -1
  205. data/smoke/printf.rb +2 -2
  206. data/smoke/proc.rb +3 -2
  207. data/smoke/proc2.rb +2 -1
  208. data/smoke/proc3.rb +2 -1
  209. data/smoke/proc4.rb +2 -1
  210. data/smoke/proc5.rb +19 -0
  211. data/smoke/public.rb +34 -0
  212. data/smoke/range.rb +2 -1
  213. data/smoke/rbs-alias.rb +2 -1
  214. data/smoke/rbs-attr.rb +6 -5
  215. data/smoke/rbs-attr2.rb +11 -0
  216. data/smoke/rbs-attr2.rbs +3 -0
  217. data/smoke/rbs-extend.rb +2 -1
  218. data/smoke/rbs-interface.rb +5 -4
  219. data/smoke/rbs-module.rb +26 -0
  220. data/smoke/rbs-module.rbs +4 -0
  221. data/smoke/rbs-opt-and-rest.rb +10 -0
  222. data/smoke/rbs-opt-and-rest.rbs +3 -0
  223. data/smoke/rbs-proc1.rb +2 -1
  224. data/smoke/rbs-proc2.rb +3 -2
  225. data/smoke/rbs-proc3.rb +2 -1
  226. data/smoke/rbs-record.rb +3 -2
  227. data/smoke/rbs-tyvar.rb +3 -2
  228. data/smoke/rbs-tyvar2.rb +3 -2
  229. data/smoke/rbs-tyvar3.rb +3 -2
  230. data/smoke/rbs-tyvar4.rb +3 -3
  231. data/smoke/rbs-tyvar5.rb +2 -1
  232. data/smoke/rbs-tyvar6.rb +18 -0
  233. data/smoke/rbs-tyvar6.rbs +12 -0
  234. data/smoke/rbs-tyvar7.rb +12 -0
  235. data/smoke/rbs-tyvar7.rbs +7 -0
  236. data/smoke/rbs-vars.rb +7 -8
  237. data/smoke/redo1.rb +3 -2
  238. data/smoke/redo2.rb +3 -2
  239. data/smoke/req-keyword.rb +2 -1
  240. data/smoke/rescue1.rb +3 -2
  241. data/smoke/rescue2.rb +3 -2
  242. data/smoke/rescue3.rb +19 -0
  243. data/smoke/rescue4.rb +17 -0
  244. data/smoke/respond_to.rb +2 -1
  245. data/smoke/rest-farg.rb +2 -1
  246. data/smoke/rest1.rb +3 -2
  247. data/smoke/rest2.rb +2 -1
  248. data/smoke/rest3.rb +7 -6
  249. data/smoke/rest4.rb +3 -2
  250. data/smoke/rest5.rb +2 -1
  251. data/smoke/rest6.rb +2 -1
  252. data/smoke/retry1.rb +3 -2
  253. data/smoke/return.rb +2 -1
  254. data/smoke/singleton_method.rb +1 -1
  255. data/smoke/step.rb +4 -3
  256. data/smoke/string-split.rb +2 -1
  257. data/smoke/struct-keyword_init.rb +20 -0
  258. data/smoke/struct.rb +1 -1
  259. data/smoke/struct2.rb +5 -4
  260. data/smoke/struct3.rb +2 -2
  261. data/smoke/struct4.rb +7 -0
  262. data/smoke/struct5.rb +16 -0
  263. data/smoke/struct6.rb +15 -0
  264. data/smoke/struct7.rb +17 -0
  265. data/smoke/stub-keyword.rb +10 -0
  266. data/smoke/super1.rb +5 -4
  267. data/smoke/super2.rb +1 -1
  268. data/smoke/super3.rb +3 -3
  269. data/smoke/super4.rb +43 -0
  270. data/smoke/super5.rb +36 -0
  271. data/smoke/svar1.rb +2 -1
  272. data/smoke/symbol-proc-attr.rb +22 -0
  273. data/smoke/symbol-proc-attr2.rb +15 -0
  274. data/smoke/symbol-proc-bot.rb +13 -0
  275. data/smoke/symbol-proc.rb +4 -3
  276. data/smoke/tap1.rb +3 -2
  277. data/smoke/toplevel.rb +2 -1
  278. data/smoke/two-map.rb +3 -2
  279. data/smoke/type_var.rb +2 -1
  280. data/smoke/typed_method.rb +2 -1
  281. data/smoke/uninitialize-var.rb +2 -1
  282. data/smoke/union-recv.rb +2 -2
  283. data/smoke/user-demo.rb +3 -3
  284. data/smoke/wrong-extend.rb +2 -2
  285. data/smoke/wrong-include.rb +2 -2
  286. data/smoke/wrong-include2.rb +17 -0
  287. data/typeprof.gemspec +1 -1
  288. metadata +61 -6
  289. data/tools/stackprof-wrapper.rb +0 -10
@@ -72,7 +72,7 @@ module TypeProf
72
72
  gvars.dump.each do |gvar_name, entry|
73
73
  next if entry.type == Type.bot
74
74
  s = entry.rbs_declared ? "#" : ""
75
- output.puts s + "#{ gvar_name } : #{ entry.type.screen_name(scratch) }"
75
+ output.puts s + "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
76
76
  end
77
77
  output.puts
78
78
  end
@@ -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 = @class_defs[class_def.superclass].klass_obj == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
96
- superclass = omit ? nil : @scratch.get_class_name(@class_defs[class_def.superclass].klass_obj)
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] << @scratch.show_method_signature(ctx)
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
- [var, ty.screen_name(@scratch), entry.rbs_declared]
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
- [var, entry.type.screen_name(@scratch), entry.rbs_declared]
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
@@ -266,7 +269,7 @@ module TypeProf
266
269
  output.puts indent + "#{ class_data.kind } #{ name }#{ superclass }"
267
270
  first = true
268
271
  class_data.consts.each do |name, ty|
269
- output.puts indent + " #{ name } : #{ ty }"
272
+ output.puts indent + " #{ name }: #{ ty }"
270
273
  first = false
271
274
  end
272
275
  class_data.included_mods.sort.each do |mod|
@@ -277,28 +280,31 @@ module TypeProf
277
280
  output.puts indent + " extend #{ mod }"
278
281
  first = false
279
282
  end
280
- class_data.ivars.each do |var, ty, rbs_declared|
281
- s = rbs_declared ? "# " : " "
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, rbs_declared|
286
- s = rbs_declared ? "# " : " "
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)|
291
- output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" } : #{ ty }"
292
+ output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }"
292
293
  first = false
293
294
  end
294
295
  class_data.explicit_methods.each do |method_name, sigs|
295
296
  sigs = sigs.sort.join("\n" + indent + "#" + " " * (method_name.size + 6) + "| ")
296
- output.puts indent + "# def #{ method_name } : #{ sigs }"
297
+ output.puts indent + "# def #{ method_name }: #{ sigs }"
297
298
  first = false
298
299
  end
299
- class_data.iseq_methods.each do |method_name, sigs|
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) + "| ")
301
- output.puts indent + " def #{ method_name } : #{ sigs }"
303
+ if prev_pub_meth != pub_meth
304
+ output.puts indent + " #{ pub_meth ? "public" : "private" }"
305
+ prev_pub_meth = pub_meth
306
+ end
307
+ output.puts indent + " def #{ method_name }: #{ sigs }"
302
308
  first = false
303
309
  end
304
310
  show_class_hierarchy(depth + 1, class_data.inner_classes, output, first)
@@ -26,6 +26,13 @@ module TypeProf
26
26
  def load_library(lib)
27
27
  loader = RBS::EnvironmentLoader.new(core_root: nil)
28
28
  loader.add(library: lib)
29
+
30
+ case lib
31
+ when "yaml"
32
+ loader.add(library: "pstore")
33
+ loader.add(library: "dbm")
34
+ end
35
+
29
36
  new_decls = loader.load(env: @env).map {|decl,| decl }
30
37
  RBSReader.load_rbs(@env, new_decls)
31
38
  end
@@ -100,14 +107,19 @@ module TypeProf
100
107
  json = {}
101
108
 
102
109
  each_class_decl do |name, decls|
103
- super_class_name = get_super_class_name(name, decls)
104
110
  klass = conv_type_name(name)
105
- superclass = super_class_name ? conv_type_name(super_class_name) : nil
111
+ super_class_name, super_class_args = get_super_class(name, decls)
112
+ if super_class_name
113
+ name = conv_type_name(super_class_name)
114
+ type_args = super_class_args.map {|type| conv_type(type) }
115
+ superclass = [name, type_args]
116
+ end
106
117
 
107
118
  type_params = nil
108
119
  included_modules = []
109
120
  extended_modules = []
110
121
  methods = {}
122
+ attr_methods = {}
111
123
  ivars = {}
112
124
  cvars = {}
113
125
  rbs_sources = {}
@@ -143,15 +155,15 @@ module TypeProf
143
155
  end
144
156
  when RBS::AST::Members::AttrReader
145
157
  ty = conv_type(member.type)
146
- methods[[false, member.name]] = attr_reader_def(ty)
158
+ attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
147
159
  when RBS::AST::Members::AttrWriter
148
160
  ty = conv_type(member.type)
149
- methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
161
+ attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
150
162
  when RBS::AST::Members::AttrAccessor
151
163
  ty = conv_type(member.type)
152
- methods[[false, member.name]] = attr_reader_def(ty)
153
- methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
164
+ attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
154
165
  when RBS::AST::Members::Alias
166
+ # XXX: an alias to attr methods?
155
167
  if member.instance?
156
168
  method_def = methods[[false, member.old_name]]
157
169
  methods[[false, member.new_name]] = method_def if method_def
@@ -165,7 +177,8 @@ module TypeProf
165
177
  name = member.name
166
178
  if name.kind == :class
167
179
  mod = conv_type_name(name)
168
- included_modules << mod
180
+ type_args = member.args.map {|type| conv_type(type) }
181
+ included_modules << [mod, type_args]
169
182
  else
170
183
  # including an interface is not supported yet
171
184
  end
@@ -174,7 +187,8 @@ module TypeProf
174
187
  name = member.name
175
188
  if name.kind == :class
176
189
  mod = conv_type_name(name)
177
- extended_modules << mod
190
+ type_args = member.args.map {|type| conv_type(type) }
191
+ extended_modules << [mod, type_args]
178
192
  else
179
193
  # extending a module with an interface is not supported yet
180
194
  end
@@ -205,6 +219,7 @@ module TypeProf
205
219
  included_modules: included_modules,
206
220
  extended_modules: extended_modules,
207
221
  methods: methods,
222
+ attr_methods: attr_methods,
208
223
  ivars: ivars,
209
224
  cvars: cvars,
210
225
  rbs_sources: rbs_sources,
@@ -231,7 +246,7 @@ module TypeProf
231
246
  @all_env.class_decls[name].decls.each do |decl|
232
247
  decl = decl.decl
233
248
  next if decl.is_a?(RBS::AST::Declarations::Module)
234
- each_ancestor(decl) {|name| queue << [:visit, name] }
249
+ each_reference(decl) {|name| queue << [:visit, name] }
235
250
  end
236
251
  queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
237
252
  end
@@ -246,24 +261,32 @@ module TypeProf
246
261
  end
247
262
  end
248
263
 
249
- def each_ancestor(decl, &blk)
264
+ def each_reference(decl, &blk)
250
265
  yield decl.name
251
- super_class = decl.super_class || RBS::BuiltinNames::Object
266
+ if decl.super_class
267
+ name = decl.super_class.name
268
+ else
269
+ name = RBS::BuiltinNames::Object.name
270
+ end
252
271
  return if decl.name == RBS::BuiltinNames::BasicObject.name
253
- return if decl.name == super_class.name
254
- @all_env.class_decls[super_class.name].decls.each do |decl|
255
- each_ancestor(decl.decl, &blk)
272
+ return if decl.name == name
273
+ decls = @all_env.class_decls[name]
274
+ if decls
275
+ decls.decls.each do |decl|
276
+ each_reference(decl.decl, &blk)
277
+ end
256
278
  end
257
279
  end
258
280
 
259
- def get_super_class_name(name, decls)
281
+ def get_super_class(name, decls)
260
282
  return nil if name == RBS::BuiltinNames::BasicObject.name
261
283
 
262
284
  decls.each do |decl|
263
285
  decl = decl.decl
264
286
  case decl
265
287
  when RBS::AST::Declarations::Class
266
- return decl.super_class.name if decl.super_class
288
+ super_class = decl.super_class
289
+ return super_class.name, super_class.args if super_class
267
290
  when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
268
291
  return nil
269
292
  else
@@ -271,7 +294,7 @@ module TypeProf
271
294
  end
272
295
  end
273
296
 
274
- return RBS::BuiltinNames::Object.name
297
+ return RBS::BuiltinNames::Object.name, []
275
298
  end
276
299
 
277
300
  def conv_method_def(rbs_method_types)
@@ -290,7 +313,7 @@ module TypeProf
290
313
  opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
291
314
  req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
292
315
  rest_kw_ty = func.rest_keywords
293
- raise NotImplementedError if rest_kw_ty # XXX
316
+ rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
294
317
 
295
318
  ret_ty = conv_type(func.return_type)
296
319
 
@@ -307,32 +330,12 @@ module TypeProf
307
330
  }
308
331
  end
309
332
 
310
- def attr_reader_def(ty)
311
- [{
312
- type_params: [],
313
- lead_tys: [],
314
- opt_tys: [],
315
- rest_ty: nil,
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
- }]
333
+ def attr_method_def(kind, name, ty)
334
+ {
335
+ kind: kind,
336
+ ivar: name,
337
+ ty: ty,
338
+ }
336
339
  end
337
340
 
338
341
  def conv_block(rbs_block)
@@ -445,6 +448,8 @@ module TypeProf
445
448
  json = scratch.rbs_reader.load_library(feature)
446
449
  rescue RBS::EnvironmentLoader::UnknownLibraryError
447
450
  return nil
451
+ rescue RBS::DuplicatedDeclarationError
452
+ return true
448
453
  end
449
454
  # need cache?
450
455
  Import.new(scratch, json).import
@@ -467,8 +472,8 @@ module TypeProf
467
472
  def import(explicit = false)
468
473
  classes = @json[:classes].map do |classpath, cdef|
469
474
  type_params = cdef[:type_params]
470
- superclass = cdef[:superclass]
471
- members = cdef[:members]
475
+ superclass, superclass_type_args = cdef[:superclass]
476
+ members = cdef[:members]
472
477
 
473
478
  name = classpath.last
474
479
  superclass = path_to_klass(superclass) if superclass
@@ -492,23 +497,27 @@ module TypeProf
492
497
  end
493
498
  end
494
499
 
495
- [klass, members]
500
+ [klass, superclass_type_args, members]
496
501
  end
497
502
 
498
- classes.each do |klass, members|
503
+ classes.each do |klass, superclass_type_args, members|
504
+ @scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
499
505
  included_modules = members[:included_modules]
500
506
  extended_modules = members[:extended_modules]
501
507
  methods = members[:methods]
508
+ attr_methods = members[:attr_methods]
502
509
  ivars = members[:ivars]
503
510
  cvars = members[:cvars]
504
511
  rbs_sources = members[:rbs_sources]
505
512
 
506
- included_modules.each do |mod|
507
- @scratch.include_module(klass, path_to_klass(mod), false, nil)
513
+ included_modules.each do |mod, type_args|
514
+ type_args = type_args&.map {|ty| conv_type(ty) }
515
+ @scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
508
516
  end
509
517
 
510
- extended_modules.each do |mod|
511
- @scratch.include_module(klass, path_to_klass(mod), true, nil)
518
+ extended_modules.each do |mod, type_args|
519
+ type_args = type_args&.map {|ty| conv_type(ty) }
520
+ @scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
512
521
  end
513
522
 
514
523
  methods.each do |(singleton, method_name), mdef|
@@ -517,6 +526,14 @@ module TypeProf
517
526
  @scratch.add_method(klass, method_name, singleton, mdef)
518
527
  end
519
528
 
529
+ attr_methods.each do |(singleton, method_name), mdef|
530
+ kind = mdef[:kind]
531
+ ivar = mdef[:ivar]
532
+ ty = conv_type(mdef[:ty]).remove_type_vars
533
+ @scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
534
+ @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
535
+ end
536
+
520
537
  ivars.each do |ivar_name, ty|
521
538
  ty = conv_type(ty).remove_type_vars
522
539
  @scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
@@ -583,7 +600,7 @@ module TypeProf
583
600
  req, lead_tys, opt_tys, ret_ty = blk
584
601
  lead_tys = lead_tys.map {|ty| conv_type(ty) }
585
602
  opt_tys = opt_tys.map {|ty| conv_type(ty) }
586
- msig = MethodSignature.new(lead_tys, opt_tys, nil, nil, nil, nil, nil)
603
+ msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
587
604
  ret_ty = conv_type(ret_ty)
588
605
  ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
589
606
  ret << Type.nil unless req
@@ -49,10 +49,18 @@ module TypeProf
49
49
  insns[i, 0] = [[:_iseq_body_start]]
50
50
  end
51
51
 
52
+ # rescue/ensure clauses need to have a dedicated return addresses
53
+ # because they requires to be virtually called.
54
+ # So, this preprocess adds "nop" to make a new insn for their return addresses
55
+ special_labels = {}
56
+ catch_table.map do |type, iseq, first, last, cont, stack_depth|
57
+ special_labels[cont] = true if type == :rescue || type == :ensure
58
+ end
59
+
52
60
  @insns = []
53
61
  @linenos = []
54
62
 
55
- labels = setup_iseq(insns)
63
+ labels = setup_iseq(insns, special_labels)
56
64
 
57
65
  # checkmatch->branch
58
66
  # send->branch
@@ -60,7 +68,8 @@ module TypeProf
60
68
  @catch_table = []
61
69
  catch_table.map do |type, iseq, first, last, cont, stack_depth|
62
70
  iseq = iseq ? ISeq.new(iseq) : nil
63
- entry = [type, iseq, labels[cont], stack_depth]
71
+ target = labels[special_labels[cont] ? :"#{ cont }_special" : cont]
72
+ entry = [type, iseq, target, stack_depth]
64
73
  labels[first].upto(labels[last]) do |i|
65
74
  @catch_table[i] ||= []
66
75
  @catch_table[i] << entry
@@ -76,19 +85,26 @@ module TypeProf
76
85
  @id <=> other.id
77
86
  end
78
87
 
79
- def setup_iseq(insns)
88
+ def setup_iseq(insns, special_labels)
80
89
  i = 0
81
90
  labels = {}
91
+ ninsns = []
82
92
  insns.each do |e|
83
93
  if e.is_a?(Symbol) && e.to_s.start_with?("label")
94
+ if special_labels[e]
95
+ labels[:"#{ e }_special"] = i
96
+ ninsns << [:nop]
97
+ i += 1
98
+ end
84
99
  labels[e] = i
85
- elsif e.is_a?(Array)
86
- i += 1
100
+ else
101
+ i += 1 if e.is_a?(Array)
102
+ ninsns << e
87
103
  end
88
104
  end
89
105
 
90
106
  lineno = 0
91
- insns.each do |e|
107
+ ninsns.each do |e|
92
108
  case e
93
109
  when Integer # lineno
94
110
  lineno = e
@@ -209,7 +225,7 @@ module TypeProf
209
225
  end
210
226
  end
211
227
  send_branch_list.each do |i, j|
212
- next if (i + 1 .. j).any? {|i| branch_targets[i] }
228
+ next if (i + 1 .. j + 1).any? {|i| branch_targets[i] }
213
229
  _insn, getlocal_operands = @insns[i]
214
230
  _insn, send_operands = @insns[j]
215
231
  _insn, branch_operands = @insns[j + 1]
@@ -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, nil)
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,63 +79,75 @@ 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
- kw_start -= @iseq.fargs_format[:keyword].size if kw_start
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
 
74
87
  # XXX: need to check .rbs msig and .rb fargs
75
88
 
76
89
  ctx = Context.new(@iseq, @cref, mid)
77
- callee_ep = ExecutionPoint.new(ctx, 0, nil)
90
+ callee_ep = ExecutionPoint.new(ctx, 0, @outer_ep)
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
- # nenv is top-level, so it is okay to call Type#localize directly
86
- nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
98
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
99
+ nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
87
100
  nenv = nenv.local_update(i, ty)
88
101
  end
89
102
  if msig.opt_tys
90
103
  msig.opt_tys.each_with_index do |ty, i|
91
104
  alloc_site2 = alloc_site.add_id(idx += 1)
92
- nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
105
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
106
+ nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
93
107
  nenv = nenv.local_update(lead_num + i, ty)
94
108
  end
95
109
  end
96
110
  if msig.rest_ty
97
111
  alloc_site2 = alloc_site.add_id(idx += 1)
98
112
  ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
99
- nenv, rest_ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
113
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
114
+ nenv, rest_ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
100
115
  nenv = nenv.local_update(rest_start, rest_ty)
101
116
  end
102
117
  if msig.post_tys
103
118
  msig.post_tys.each_with_index do |ty, i|
104
119
  alloc_site2 = alloc_site.add_id(idx += 1)
105
- nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
120
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
121
+ nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
106
122
  nenv = nenv.local_update(post_start + i, ty)
107
123
  end
108
124
  end
109
- if msig.kw_tys
110
- msig.kw_tys.each_with_index do |(_, key, ty), i|
125
+ if msig.kw_tys && keyword # TODO: support the case where RBS writes kw_tys and RB method accepts **kwrest
126
+ msig.kw_tys.each do |_, key, ty|
127
+ i = keyword.index {|callee_key,| callee_key == key }
128
+ unless i
129
+ # warn
130
+ next
131
+ end
111
132
  alloc_site2 = alloc_site.add_id(key)
112
- nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
133
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
134
+ nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
113
135
  nenv = nenv.local_update(kw_start + i, ty)
114
136
  end
115
137
  end
116
138
  if msig.kw_rest_ty
117
139
  ty = msig.kw_rest_ty
118
140
  alloc_site2 = alloc_site.add_id(:**)
119
- nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
141
+ ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
142
+ nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
120
143
  nenv = nenv.local_update(kw_rest, ty)
121
144
  end
122
145
  nenv = nenv.local_update(block_start, msig.blk_ty) if block_start
123
146
 
124
147
  opt.each do |start_pc|
125
- scratch.merge_env(ExecutionPoint.new(ctx, start_pc, nil), nenv)
148
+ scratch.merge_env(callee_ep.jump(start_pc), nenv)
126
149
  end
150
+ scratch.add_executed_iseq(@iseq)
127
151
 
128
152
  ctx
129
153
  end
@@ -142,8 +166,8 @@ module TypeProf
142
166
  case @kind
143
167
  when :reader
144
168
  if aargs.lead_tys.size == 0
145
- scratch.get_instance_variable(recv, @ivar, caller_ep, caller_env) do |ty, nenv|
146
- ctn[ty, caller_ep, nenv]
169
+ scratch.add_ivar_read!(recv, @ivar, caller_ep) do |ty, _ep|
170
+ ctn[ty, caller_ep, caller_env]
147
171
  end
148
172
  else
149
173
  ctn[Type.any, caller_ep, caller_env]
@@ -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
- case
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
- nfargs = msig.blk_ty.block_body.msig
233
+ bsig = msig.blk_ty.block_body.msig
242
234
  alloc_site = AllocationSite.new(caller_ep).add_id(self)
243
- nlead_tys = (nfargs.lead_tys + nfargs.opt_tys).map.with_index do |ty, i|
244
- if recv.is_a?(Type::Array)
245
- tyvar_elem = Type::Var.new(:Elem)
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(nfargs.opt_tys.size) do |n|
256
- naargs = ActualArguments.new(nlead_tys[0, nfargs.lead_tys.size + n], nil, {}, Type.nil) # XXX: support block to block?
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
- case
262
- when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
263
- tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
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
- # raise "???"
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, ret_ty)
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
@@ -357,7 +291,6 @@ module TypeProf
357
291
  end
358
292
 
359
293
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
360
- scratch.merge_return_env(caller_ep) {|env| env ? env.merge(caller_env) : caller_env } # for Kernel#lambda
361
294
  @impl[recv, mid, aargs, caller_ep, caller_env, scratch, &ctn]
362
295
  end
363
296
  end