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
@@ -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])