typeprof 0.5.4 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -3,6 +3,7 @@ module TypeProf
3
3
  class ActualArguments
4
4
  def initialize(lead_tys, rest_ty, kw_tys, blk_ty)
5
5
  @lead_tys = lead_tys
6
+ raise unless lead_tys
6
7
  @rest_ty = rest_ty
7
8
  @kw_tys = kw_tys # kw_tys should be {:key1 => Type, :key2 => Type, ...} or {nil => Type}
8
9
  raise if !kw_tys.is_a?(::Hash)
@@ -10,6 +11,10 @@ module TypeProf
10
11
  raise unless blk_ty
11
12
  end
12
13
 
14
+ def for_method_missing(mid)
15
+ ActualArguments.new([mid] + @lead_tys, @rest_ty, @kw_tys, @blk_ty)
16
+ end
17
+
13
18
  attr_reader :lead_tys, :rest_ty, :kw_tys, :blk_ty
14
19
 
15
20
  def globalize(caller_env, visited, depth)
@@ -54,6 +59,7 @@ module TypeProf
54
59
  subst = Type.merge_substitution(subst, subst2)
55
60
  end
56
61
  msig.opt_tys.each do |farg|
62
+ break if aargs.empty?
57
63
  aarg = aargs.shift
58
64
  return nil unless subst2 = Type.match?(aarg, farg)
59
65
  subst = Type.merge_substitution(subst, subst2)
@@ -148,12 +154,14 @@ module TypeProf
148
154
  lead_tys = ty.elems.lead_tys
149
155
  rest_ty = ty.elems.rest_ty
150
156
  when Type::Union
151
- other_elems = nil
152
- ty.elems&.each do |(container_kind, base_type), elems|
153
- if container_kind == Type::Array
154
- rest_ty = rest_ty ? rest_ty.union(elems.squash) : elems.squash
155
- else
156
- other_elems = other_elems ? other_elems.union(elems) : elems
157
+ if ty.elems
158
+ other_elems = {}
159
+ ty.elems.each do |(container_kind, base_type), elems|
160
+ if container_kind == Type::Array
161
+ rest_ty = rest_ty ? rest_ty.union(elems.squash) : elems.squash
162
+ else
163
+ other_elems[[container_kind, base_type]] = elems
164
+ end
157
165
  end
158
166
  end
159
167
  lead_tys = [Type::Union.new(ty.types, other_elems)]
@@ -29,7 +29,10 @@ module TypeProf
29
29
 
30
30
  def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
31
31
  blk_env = scratch.return_envs[@outer_ep]
32
- blk_env = blk_env.replace_recv_ty(replace_recv_ty) if replace_recv_ty
32
+ if replace_recv_ty
33
+ replace_recv_ty = scratch.globalize_type(replace_recv_ty, caller_env, caller_ep)
34
+ blk_env = blk_env.replace_recv_ty(replace_recv_ty)
35
+ end
33
36
  aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
34
37
 
35
38
  scratch.add_block_signature!(self, aargs.to_block_signature)
@@ -119,11 +122,12 @@ module TypeProf
119
122
  def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
120
123
  if aargs.lead_tys.size >= 1
121
124
  recv = aargs.lead_tys[0]
125
+ recv = Type.any if recv == Type.bot
122
126
  aargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
123
127
  elsif aargs.rest_ty
124
128
  recv = aargs.rest_ty.elems.squash_or_any # XXX: need to shift
125
129
  else
126
- raise
130
+ recv = Type.any
127
131
  end
128
132
 
129
133
  scratch.add_block_signature!(self, aargs.to_block_signature)
@@ -33,10 +33,10 @@ module TypeProf
33
33
  h2 = aargs.lead_tys[1]
34
34
  elems = nil
35
35
  h1.each_child do |h1|
36
- if h1.is_a?(Type::LocalHash)
36
+ if h1.is_a?(Type::Local) && h1.kind == Type::Hash
37
37
  h1_elems = scratch.get_container_elem_types(env, ep, h1.id)
38
38
  h2.each_child do |h2|
39
- if h2.is_a?(Type::LocalHash)
39
+ if h2.is_a?(Type::Local) && h2.kind == Type::Hash
40
40
  h2_elems = scratch.get_container_elem_types(env, ep, h2.id)
41
41
  elems0 = h1_elems.union(h2_elems)
42
42
  if elems
@@ -82,14 +82,17 @@ module TypeProf
82
82
  end
83
83
 
84
84
  def object_is_a?(recv, mid, aargs, ep, env, scratch, &ctn)
85
- raise unless aargs.lead_tys.size != 0
86
- if recv.is_a?(Type::Instance)
87
- if recv.klass == aargs.lead_tys[0] # XXX: inheritance
88
- true_val = Type::Instance.new(Type::Builtin[:true])
89
- ctn[true_val, ep, env]
85
+ if aargs.lead_tys.size == 1
86
+ if recv.is_a?(Type::Instance)
87
+ if recv.klass == aargs.lead_tys[0] # XXX: inheritance
88
+ true_val = Type::Instance.new(Type::Builtin[:true])
89
+ ctn[true_val, ep, env]
90
+ else
91
+ false_val = Type::Instance.new(Type::Builtin[:false])
92
+ ctn[false_val, ep, env]
93
+ end
90
94
  else
91
- false_val = Type::Instance.new(Type::Builtin[:false])
92
- ctn[false_val, ep, env]
95
+ ctn[Type.bool, ep, env]
93
96
  end
94
97
  else
95
98
  ctn[Type.bool, ep, env]
@@ -97,15 +100,19 @@ module TypeProf
97
100
  end
98
101
 
99
102
  def object_respond_to?(recv, mid, aargs, ep, env, scratch, &ctn)
100
- raise unless aargs.lead_tys.size != 0
101
- sym = get_sym("respond_to?", aargs.lead_tys[0], ep, scratch)
102
- if sym
103
- if recv.get_method(sym, scratch)
104
- true_val = Type::Instance.new(Type::Builtin[:true])
105
- ctn[true_val, ep, env]
103
+ if aargs.lead_tys.size == 1
104
+ sym = get_sym("respond_to?", aargs.lead_tys[0], ep, scratch)
105
+ if sym
106
+ klass, singleton = recv.method_dispatch_info
107
+ if scratch.get_method(klass, singleton, sym)
108
+ true_val = Type::Instance.new(Type::Builtin[:true])
109
+ ctn[true_val, ep, env]
110
+ else
111
+ false_val = Type::Instance.new(Type::Builtin[:false])
112
+ ctn[false_val, ep, env]
113
+ end
106
114
  else
107
- false_val = Type::Instance.new(Type::Builtin[:false])
108
- ctn[false_val, ep, env]
115
+ ctn[Type.bool, ep, env]
109
116
  end
110
117
  else
111
118
  ctn[Type.bool, ep, env]
@@ -123,10 +130,12 @@ module TypeProf
123
130
  def object_send(recv, mid, aargs, ep, env, scratch, &ctn)
124
131
  if aargs.lead_tys.size >= 1
125
132
  mid_ty, = aargs.lead_tys
126
- else
133
+ elsif aargs.rest_ty
127
134
  mid_ty = aargs.rest_ty
135
+ else
136
+ return ctn[Type.any, ep, env]
128
137
  end
129
- aargs = ActualArguments.new(aargs.lead_tys[1..-1], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
138
+ aargs = ActualArguments.new(aargs.lead_tys[1..] || [], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
130
139
  found = false
131
140
  mid_ty.each_child do |mid|
132
141
  if mid.is_a?(Type::Symbol)
@@ -142,31 +151,55 @@ module TypeProf
142
151
 
143
152
  def object_instance_eval(recv, mid, aargs, ep, env, scratch, &ctn)
144
153
  if aargs.lead_tys.size >= 1
145
- scratch.warn(ep, "instance_eval with arguments are ignored")
146
- ctn[type.any, ep, env]
154
+ scratch.warn(ep, "instance_eval with arguments is ignored")
155
+ ctn[Type.any, ep, env]
147
156
  return
148
157
  end
149
158
  naargs = ActualArguments.new([recv], nil, {}, Type.nil)
150
- scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: recv) do |_ret_ty, ep|
151
- ctn[recv, ep, scratch.return_envs[ep]]
159
+ nrecv = recv
160
+ nrecv = nrecv.base_type if nrecv.is_a?(Type::ContainerType)
161
+ scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv) do |_ret_ty, ep|
162
+ ctn[recv, ep, env]
152
163
  end
153
164
  end
154
165
 
155
166
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
167
+ if aargs.lead_tys.size != 1
168
+ scratch.warn(ep, "Module#include without an argument is ignored")
169
+ ctn[Type.any, ep, env]
170
+ return
171
+ end
172
+
173
+ unless recv.is_a?(Type::Class)
174
+ # XXX: warn?
175
+ return ctn[Type.any, ep, env]
176
+ end
177
+
156
178
  arg = aargs.lead_tys[0]
157
179
  arg.each_child do |arg|
158
180
  if arg.is_a?(Type::Class)
159
- scratch.include_module(recv, arg, false, ep.ctx.iseq.absolute_path)
181
+ scratch.include_module(recv, arg, nil, false, ep)
160
182
  end
161
183
  end
162
184
  ctn[recv, ep, env]
163
185
  end
164
186
 
165
187
  def module_extend(recv, mid, aargs, ep, env, scratch, &ctn)
188
+ if aargs.lead_tys.size != 1
189
+ scratch.warn(ep, "Module#extend without an argument is ignored")
190
+ ctn[Type.any, ep, env]
191
+ return
192
+ end
193
+
194
+ unless recv.is_a?(Type::Class)
195
+ # XXX: warn?
196
+ return ctn[Type.any, ep, env]
197
+ end
198
+
166
199
  arg = aargs.lead_tys[0]
167
200
  arg.each_child do |arg|
168
201
  if arg.is_a?(Type::Class)
169
- scratch.include_module(recv, arg, true, ep.ctx.iseq.absolute_path)
202
+ scratch.include_module(recv, arg, nil, true, ep)
170
203
  end
171
204
  end
172
205
  ctn[recv, ep, env]
@@ -178,7 +211,7 @@ module TypeProf
178
211
  else
179
212
  aargs.lead_tys.each do |aarg|
180
213
  sym = get_sym("module_function", aarg, ep, scratch) or next
181
- meths = Type::Instance.new(recv).get_method(sym, scratch)
214
+ meths = scratch.get_method(recv, false, sym)
182
215
  meths.each do |mdef|
183
216
  scratch.add_method(recv, sym, true, mdef)
184
217
  end
@@ -187,6 +220,75 @@ module TypeProf
187
220
  end
188
221
  end
189
222
 
223
+ def module_public(recv, mid, aargs, ep, env, scratch, &ctn)
224
+ if aargs.lead_tys.empty?
225
+ ctn[recv, ep, env.method_public_set(true)]
226
+ else
227
+ if recv.is_a?(Type::Class)
228
+ aargs.lead_tys.each do |aarg|
229
+ sym = get_sym("public", aarg, ep, scratch) or next
230
+ meths = scratch.get_method(recv, false, sym)
231
+ next unless meths
232
+ meths.each do |mdef|
233
+ mdef.pub_meth = true if mdef.respond_to?(:pub_meth=)
234
+ end
235
+ end
236
+ else
237
+ # XXX: warn?
238
+ end
239
+ ctn[recv, ep, env]
240
+ end
241
+ end
242
+
243
+ def module_private(recv, mid, aargs, ep, env, scratch, &ctn)
244
+ if aargs.lead_tys.empty?
245
+ ctn[recv, ep, env.method_public_set(false)]
246
+ else
247
+ if recv.is_a?(Type::Class)
248
+ aargs.lead_tys.each do |aarg|
249
+ sym = get_sym("private", aarg, ep, scratch) or next
250
+ meths = scratch.get_method(recv, false, sym)
251
+ next unless meths
252
+ meths.each do |mdef|
253
+ mdef.pub_meth = false if mdef.respond_to?(:pub_meth=)
254
+ end
255
+ end
256
+ else
257
+ # XXX: warn?
258
+ end
259
+ ctn[recv, ep, env]
260
+ end
261
+ end
262
+
263
+ def module_define_method(recv, mid, aargs, ep, env, scratch, &ctn)
264
+ if aargs.lead_tys.size != 1
265
+ scratch.warn(ep, "Module#define with #{ aargs.lead_tys.size } argument is ignored")
266
+ ctn[Type.any, ep, env]
267
+ return
268
+ end
269
+
270
+ mid, = aargs.lead_tys
271
+ if mid.is_a?(Type::Symbol)
272
+ mid = mid.sym
273
+ aargs.blk_ty.each_child do |blk_ty|
274
+ if blk_ty.is_a?(Type::Proc)
275
+ blk = blk_ty.block_body
276
+ case blk
277
+ when ISeqBlock
278
+ scratch.do_define_iseq_method(ep, env, mid, blk.iseq, blk.outer_ep)
279
+ else
280
+ # XXX: what to do?
281
+ end
282
+ else
283
+ # XXX: what to do?
284
+ end
285
+ end
286
+ else
287
+ # XXX: what to do?
288
+ end
289
+ ctn[Type.any, ep, env]
290
+ end
291
+
190
292
  def module_attr_accessor(recv, mid, aargs, ep, env, scratch, &ctn)
191
293
  aargs.lead_tys.each do |aarg|
192
294
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
@@ -222,21 +324,16 @@ module TypeProf
222
324
  end
223
325
 
224
326
  def array_aref(recv, mid, aargs, ep, env, scratch, &ctn)
225
- return ctn[Type.any, ep, env] unless recv.is_a?(Type::LocalArray)
327
+ return ctn[Type.any, ep, env] unless recv.is_a?(Type::Local) && recv.kind == Type::Array
226
328
 
227
329
  case aargs.lead_tys.size
228
330
  when 1
229
331
  idx = aargs.lead_tys.first
230
332
  if idx.is_a?(Type::Literal)
231
333
  idx = idx.lit
232
- if idx.is_a?(Range)
233
- ty = scratch.get_array_elem_type(env, ep, recv.id)
234
- base_ty = Type::Instance.new(Type::Builtin[:ary])
235
- ret_ty = Type::Array.new(Type::Array::Elements.new([], ty), base_ty)
236
- ctn[ret_ty, ep, env]
237
- return
238
- end
239
- idx = nil if !idx.is_a?(Integer)
334
+ idx = nil if !idx.is_a?(Integer) && !idx.is_a?(Range)
335
+ elsif idx == Type::Instance.new(Type::Builtin[:range])
336
+ idx = (nil..nil)
240
337
  else
241
338
  idx = nil
242
339
  end
@@ -253,17 +350,22 @@ module TypeProf
253
350
  end
254
351
 
255
352
  def array_aset(recv, mid, aargs, ep, env, scratch, &ctn)
256
- return ctn[Type.any, ep, env] unless recv.is_a?(Type::LocalArray)
353
+ return ctn[Type.any, ep, env] unless recv.is_a?(Type::Local) && recv.kind == Type::Array
257
354
 
258
355
  if aargs.lead_tys.size != 2
356
+ # XXX: Support `ary[idx, len] = val`
259
357
  #raise NotImplementedError # XXX
260
- ctn[Type.any, ep, env]
358
+ return ctn[Type.any, ep, env]
261
359
  end
262
360
 
263
361
  idx = aargs.lead_tys.first
264
362
  if idx.is_a?(Type::Literal)
265
363
  idx = idx.lit
266
- raise NotImplementedError if !idx.is_a?(Integer)
364
+ if !idx.is_a?(Integer)
365
+ # XXX: Support `ary[idx..end] = val`
366
+ #raise NotImplementedError # XXX
367
+ return ctn[Type.any, ep, env]
368
+ end
267
369
  else
268
370
  idx = nil
269
371
  end
@@ -278,7 +380,7 @@ module TypeProf
278
380
  end
279
381
 
280
382
  def array_pop(recv, mid, aargs, ep, env, scratch, &ctn)
281
- return ctn[Type.any, ep, env] unless recv.is_a?(Type::LocalArray)
383
+ return ctn[Type.any, ep, env] unless recv.is_a?(Type::Local) && recv.kind == Type::Array
282
384
 
283
385
  if aargs.lead_tys.size != 0
284
386
  ctn[Type.any, ep, env]
@@ -290,7 +392,7 @@ module TypeProf
290
392
  end
291
393
 
292
394
  def hash_aref(recv, mid, aargs, ep, env, scratch, &ctn)
293
- return ctn[Type.any, ep, env] unless recv.is_a?(Type::LocalHash)
395
+ return ctn[Type.any, ep, env] unless recv.is_a?(Type::Local) && recv.kind == Type::Hash
294
396
 
295
397
  if aargs.lead_tys.size != 1
296
398
  ctn[Type.any, ep, env]
@@ -298,8 +400,9 @@ module TypeProf
298
400
  end
299
401
  idx = aargs.lead_tys.first
300
402
  recv.each_child do |recv|
301
- if recv.is_a?(Type::LocalHash)
403
+ if recv.is_a?(Type::Local) && recv.kind == Type::Hash
302
404
  ty = scratch.get_hash_elem_type(env, ep, recv.id, idx)
405
+ ty = Type.nil if ty == Type.bot
303
406
  else
304
407
  ty = Type.any
305
408
  end
@@ -308,15 +411,19 @@ module TypeProf
308
411
  end
309
412
 
310
413
  def hash_aset(recv, mid, aargs, ep, env, scratch, &ctn)
311
- return ctn[Type.any, ep, env] unless recv.is_a?(Type::LocalHash)
414
+ return ctn[Type.any, ep, env] unless recv.is_a?(Type::Local) && recv.kind == Type::Hash
312
415
 
313
- raise NotImplementedError if aargs.lead_tys.size != 2
416
+ if aargs.lead_tys.size != 2
417
+ # XXX: error?
418
+ ctn[Type.any, ep, env]
419
+ return
420
+ end
314
421
 
315
422
  idx = aargs.lead_tys.first
316
423
  idx = scratch.globalize_type(idx, env, ep)
317
424
  ty = aargs.lead_tys.last
318
425
 
319
- unless recv.is_a?(Type::LocalHash)
426
+ unless recv.is_a?(Type::Local) && recv.kind == Type::Hash
320
427
  # to ignore: class OptionMap < Hash
321
428
  return ctn[ty, ep, env]
322
429
  end
@@ -329,18 +436,7 @@ module TypeProf
329
436
  end
330
437
 
331
438
  def struct_initialize(recv, mid, aargs, ep, env, scratch, &ctn)
332
- recv = Type::Instance.new(recv)
333
- scratch.add_ivar_read!(recv, :_members, ep) do |member_ary_ty, ep|
334
- member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
335
- ty ||= Type.nil
336
- scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
337
- end
338
- end
339
- ctn[recv, ep, env]
340
- end
341
-
342
- def struct_i_new(recv, mid, aargs, ep, env, scratch, &ctn)
343
- struct_klass = recv
439
+ struct_klass = recv.klass
344
440
  while struct_klass.superclass != Type::Builtin[:struct]
345
441
  struct_klass = struct_klass.superclass
346
442
  end
@@ -348,15 +444,24 @@ module TypeProf
348
444
  ctn[Type.any, ep, env]
349
445
  return
350
446
  end
351
- if struct_klass != recv
352
- scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |ty, ep|
353
- scratch.add_ivar_write!(Type::Instance.new(recv), :_members, ty, ep)
447
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |member_ary_ty, ep|
448
+ next if member_ary_ty == Type.bot
449
+ member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
450
+ ty ||= Type.nil
451
+ scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
354
452
  end
355
453
  end
454
+ ctn[recv, ep, env]
455
+ end
456
+
457
+ def struct_i_new(recv, mid, aargs, ep, env, scratch, &ctn)
458
+ # TODO: keyword_init
459
+
356
460
  meths = scratch.get_method(recv, false, :initialize)
461
+ recv = Type::Instance.new(recv)
357
462
  meths.flat_map do |meth|
358
463
  meth.do_send(recv, :initialize, aargs, ep, env, scratch) do |ret_ty, ep, env|
359
- ctn[Type::Instance.new(recv), ep, env]
464
+ ctn[recv, ep, env]
360
465
  end
361
466
  end
362
467
  end
@@ -424,11 +529,20 @@ module TypeProf
424
529
  end
425
530
 
426
531
  def kernel_require(recv, mid, aargs, ep, env, scratch, &ctn)
427
- raise NotImplementedError if aargs.lead_tys.size != 1
532
+ if aargs.lead_tys.size != 1
533
+ # XXX: handle correctly
534
+ ctn[Type.any, ep, env]
535
+ return
536
+ end
537
+
428
538
  feature = aargs.lead_tys.first
429
539
  if feature.is_a?(Type::Literal)
430
540
  feature = feature.lit
431
541
 
542
+ unless feature.is_a?(String)
543
+ return ctn[Type.any, ep, env]
544
+ end
545
+
432
546
  action, arg = Builtin.file_require(feature, scratch)
433
547
  case action
434
548
  when :do
@@ -438,22 +552,31 @@ module TypeProf
438
552
  ctn[result, ep, env]
439
553
  when :error
440
554
  scratch.warn(ep, arg)
441
- result = Type::Instance.new(Type.bool)
555
+ result = Type.bool
442
556
  ctn[result, ep, env]
443
557
  end
444
558
  else
445
559
  scratch.warn(ep, "require target cannot be identified statically")
446
- result = Type::Instance.new(Type.bool)
560
+ result = Type.bool
447
561
  ctn[result, ep, env]
448
562
  end
449
563
  end
450
564
 
451
565
  def kernel_require_relative(recv, mid, aargs, ep, env, scratch, &ctn)
452
- raise NotImplementedError if aargs.lead_tys.size != 1
566
+ if aargs.lead_tys.size != 1
567
+ # XXX: handle correctly
568
+ ctn[Type.any, ep, env]
569
+ return
570
+ end
571
+
453
572
  feature = aargs.lead_tys.first
454
573
  if feature.is_a?(Type::Literal)
455
574
  feature = feature.lit
456
575
 
576
+ unless feature.is_a?(String)
577
+ return ctn[Type.any, ep, env]
578
+ end
579
+
457
580
  if scratch.loaded_features[feature]
458
581
  result = Type::Instance.new(Type::Builtin[:false])
459
582
  return ctn[result, ep, env]
@@ -473,6 +596,36 @@ module TypeProf
473
596
  ctn[result, ep, env]
474
597
  end
475
598
 
599
+ def kernel_autoload(recv, mid, aargs, ep, env, scratch, &ctn)
600
+ if aargs.lead_tys.size != 2
601
+ # XXX: handle correctly
602
+ ctn[Type.any, ep, env]
603
+ return
604
+ end
605
+
606
+ feature = aargs.lead_tys[1]
607
+ if feature.is_a?(Type::Literal)
608
+ feature = feature.lit
609
+
610
+ action, arg = Builtin.file_require(feature, scratch)
611
+ case action
612
+ when :do
613
+ Builtin.file_load(arg, ep, env, scratch, &ctn)
614
+ when :done
615
+ when :error
616
+ scratch.warn(ep, arg)
617
+ end
618
+ ctn[Type.nil, ep, env]
619
+ else
620
+ scratch.warn(ep, "autoload target cannot be identified statically")
621
+ ctn[Type.nil, ep, env]
622
+ end
623
+ end
624
+
625
+ def module_autoload(recv, mid, aargs, ep, env, scratch, &ctn)
626
+ kernel_autoload(recv, mid, aargs, ep, env, scratch, &ctn)
627
+ end
628
+
476
629
  def kernel_Array(recv, mid, aargs, ep, env, scratch, &ctn)
477
630
  raise NotImplementedError if aargs.lead_tys.size != 1
478
631
  ty = aargs.lead_tys.first
@@ -505,6 +658,7 @@ module TypeProf
505
658
  Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
506
659
  Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
507
660
  Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
661
+ Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
508
662
  Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
509
663
  Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
510
664
  Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
@@ -518,6 +672,7 @@ module TypeProf
518
672
  Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
519
673
  Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
520
674
  Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
675
+ Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
521
676
 
522
677
  klass_vmcore = Type::Builtin[:vmcore]
523
678
  klass_ary = Type::Builtin[:ary]
@@ -532,9 +687,6 @@ module TypeProf
532
687
  scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
533
688
  scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
534
689
  scratch.set_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
535
- scratch.set_singleton_custom_method(klass_obj, :"attr_accessor", Builtin.method(:module_attr_accessor))
536
- scratch.set_singleton_custom_method(klass_obj, :"attr_reader", Builtin.method(:module_attr_reader))
537
- scratch.set_singleton_custom_method(klass_obj, :"attr_writer", Builtin.method(:module_attr_writer))
538
690
  scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
539
691
  scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
540
692
  scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
@@ -546,6 +698,12 @@ module TypeProf
546
698
  scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
547
699
  scratch.set_custom_method(klass_module, :extend, Builtin.method(:module_extend))
548
700
  scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function))
701
+ scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public))
702
+ scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private))
703
+ scratch.set_custom_method(klass_module, :define_method, Builtin.method(:module_define_method))
704
+ scratch.set_custom_method(klass_module, :"attr_accessor", Builtin.method(:module_attr_accessor))
705
+ scratch.set_custom_method(klass_module, :"attr_reader", Builtin.method(:module_attr_reader))
706
+ scratch.set_custom_method(klass_module, :"attr_writer", Builtin.method(:module_attr_writer))
549
707
 
550
708
  scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
551
709
  scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
@@ -563,6 +721,11 @@ module TypeProf
563
721
  scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
564
722
  scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
565
723
  scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array))
724
+ scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload))
725
+ scratch.set_custom_method(klass_module, :autoload, Builtin.method(:module_autoload))
726
+
727
+ # remove BasicObject#method_missing
728
+ scratch.set_method(klass_basic_obj, :method_missing, false, nil)
566
729
 
567
730
  # ENV: Hash[String, String]
568
731
  str_ty = Type::Instance.new(Type::Builtin[:str])