typeprof 0.6.0 → 0.9.1

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 +214 -133
  6. data/lib/typeprof/arguments.rb +14 -6
  7. data/lib/typeprof/block.rb +6 -2
  8. data/lib/typeprof/builtin.rb +223 -71
  9. data/lib/typeprof/cli.rb +33 -34
  10. data/lib/typeprof/config.rb +6 -4
  11. data/lib/typeprof/container-type.rb +154 -99
  12. data/lib/typeprof/export.rb +23 -17
  13. data/lib/typeprof/import.rb +49 -42
  14. data/lib/typeprof/iseq.rb +23 -7
  15. data/lib/typeprof/method.rb +63 -147
  16. data/lib/typeprof/type.rb +63 -7
  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/ivar4.rb +20 -0
  161. data/smoke/kernel-class.rb +2 -1
  162. data/smoke/keyword1.rb +2 -1
  163. data/smoke/keyword2.rb +2 -1
  164. data/smoke/keyword3.rb +2 -1
  165. data/smoke/keyword4.rb +2 -1
  166. data/smoke/keyword5.rb +2 -1
  167. data/smoke/kwrest.rb +12 -0
  168. data/smoke/kwrest.rbs +3 -0
  169. data/smoke/kwsplat1.rb +5 -4
  170. data/smoke/kwsplat2.rb +2 -1
  171. data/smoke/lit-complex.rb +10 -0
  172. data/smoke/lit-encoding.rb +10 -0
  173. data/smoke/manual-rbs.rb +4 -3
  174. data/smoke/manual-rbs2.rb +2 -1
  175. data/smoke/manual-rbs3.rb +2 -2
  176. data/smoke/masgn1.rb +2 -1
  177. data/smoke/masgn2.rb +3 -2
  178. data/smoke/masgn3.rb +2 -1
  179. data/smoke/method_in_branch.rb +3 -2
  180. data/smoke/method_missing.rb +28 -0
  181. data/smoke/module1.rb +2 -2
  182. data/smoke/module2.rb +1 -1
  183. data/smoke/module3.rb +2 -2
  184. data/smoke/module4.rb +2 -2
  185. data/smoke/module5.rb +17 -0
  186. data/smoke/module6.rb +40 -0
  187. data/smoke/module_function1.rb +3 -3
  188. data/smoke/module_function2.rb +3 -3
  189. data/smoke/multiple-include.rb +1 -1
  190. data/smoke/multiple-superclass.rb +1 -1
  191. data/smoke/next1.rb +3 -2
  192. data/smoke/next2.rb +2 -1
  193. data/smoke/object-send1.rb +4 -3
  194. data/smoke/object-send2.rb +10 -0
  195. data/smoke/object-send3.rb +18 -0
  196. data/smoke/once.rb +2 -1
  197. data/smoke/optional1.rb +2 -1
  198. data/smoke/optional2.rb +2 -1
  199. data/smoke/optional3.rb +2 -1
  200. data/smoke/parameterizedd-self.rb +3 -2
  201. data/smoke/parameterizedd-self2.rb +1 -1
  202. data/smoke/pathname1.rb +2 -1
  203. data/smoke/pathname2.rb +2 -1
  204. data/smoke/pattern-match1.rb +2 -1
  205. data/smoke/pattern-match2.rb +2 -1
  206. data/smoke/printf.rb +2 -2
  207. data/smoke/proc.rb +3 -2
  208. data/smoke/proc2.rb +2 -1
  209. data/smoke/proc3.rb +2 -1
  210. data/smoke/proc4.rb +2 -1
  211. data/smoke/proc5.rb +19 -0
  212. data/smoke/public.rb +34 -0
  213. data/smoke/range.rb +2 -1
  214. data/smoke/rbs-alias.rb +2 -1
  215. data/smoke/rbs-attr.rb +6 -5
  216. data/smoke/rbs-attr2.rb +11 -0
  217. data/smoke/rbs-attr2.rbs +3 -0
  218. data/smoke/rbs-extend.rb +2 -1
  219. data/smoke/rbs-interface.rb +5 -4
  220. data/smoke/rbs-module.rb +26 -0
  221. data/smoke/rbs-module.rbs +4 -0
  222. data/smoke/rbs-opt-and-rest.rb +10 -0
  223. data/smoke/rbs-opt-and-rest.rbs +3 -0
  224. data/smoke/rbs-proc1.rb +2 -1
  225. data/smoke/rbs-proc2.rb +3 -2
  226. data/smoke/rbs-proc3.rb +2 -1
  227. data/smoke/rbs-record.rb +3 -2
  228. data/smoke/rbs-tyvar.rb +3 -2
  229. data/smoke/rbs-tyvar2.rb +3 -2
  230. data/smoke/rbs-tyvar3.rb +3 -2
  231. data/smoke/rbs-tyvar4.rb +3 -3
  232. data/smoke/rbs-tyvar5.rb +2 -1
  233. data/smoke/rbs-tyvar6.rb +4 -3
  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 +5 -5
  270. data/smoke/super5.rb +4 -4
  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 +56 -5
  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,16 +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
- klass, singleton = recv.method_dispatch_info
104
- if scratch.get_method(klass, singleton, sym)
105
- true_val = Type::Instance.new(Type::Builtin[:true])
106
- 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
107
114
  else
108
- false_val = Type::Instance.new(Type::Builtin[:false])
109
- ctn[false_val, ep, env]
115
+ ctn[Type.bool, ep, env]
110
116
  end
111
117
  else
112
118
  ctn[Type.bool, ep, env]
@@ -124,10 +130,12 @@ module TypeProf
124
130
  def object_send(recv, mid, aargs, ep, env, scratch, &ctn)
125
131
  if aargs.lead_tys.size >= 1
126
132
  mid_ty, = aargs.lead_tys
127
- else
133
+ elsif aargs.rest_ty
128
134
  mid_ty = aargs.rest_ty
135
+ else
136
+ return ctn[Type.any, ep, env]
129
137
  end
130
- 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)
131
139
  found = false
132
140
  mid_ty.each_child do |mid|
133
141
  if mid.is_a?(Type::Symbol)
@@ -143,26 +151,34 @@ module TypeProf
143
151
 
144
152
  def object_instance_eval(recv, mid, aargs, ep, env, scratch, &ctn)
145
153
  if aargs.lead_tys.size >= 1
146
- scratch.warn(ep, "instance_eval with arguments are ignored")
154
+ scratch.warn(ep, "instance_eval with arguments is ignored")
147
155
  ctn[Type.any, ep, env]
148
156
  return
149
157
  end
150
158
  naargs = ActualArguments.new([recv], nil, {}, Type.nil)
151
- scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: recv) do |_ret_ty, ep|
152
- 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]
153
163
  end
154
164
  end
155
165
 
156
166
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
157
167
  if aargs.lead_tys.size != 1
158
- scratch.warn(ep, "Module#include without an argument are ignored")
168
+ scratch.warn(ep, "Module#include without an argument is ignored")
159
169
  ctn[Type.any, ep, env]
160
170
  return
161
171
  end
172
+
173
+ unless recv.is_a?(Type::Class)
174
+ # XXX: warn?
175
+ return ctn[Type.any, ep, env]
176
+ end
177
+
162
178
  arg = aargs.lead_tys[0]
163
179
  arg.each_child do |arg|
164
180
  if arg.is_a?(Type::Class)
165
- scratch.include_module(recv, arg, nil, false, ep.ctx.iseq.absolute_path)
181
+ scratch.include_module(recv, arg, nil, false, ep)
166
182
  end
167
183
  end
168
184
  ctn[recv, ep, env]
@@ -170,14 +186,20 @@ module TypeProf
170
186
 
171
187
  def module_extend(recv, mid, aargs, ep, env, scratch, &ctn)
172
188
  if aargs.lead_tys.size != 1
173
- scratch.warn(ep, "Module#extend without an argument are ignored")
189
+ scratch.warn(ep, "Module#extend without an argument is ignored")
174
190
  ctn[Type.any, ep, env]
175
191
  return
176
192
  end
193
+
194
+ unless recv.is_a?(Type::Class)
195
+ # XXX: warn?
196
+ return ctn[Type.any, ep, env]
197
+ end
198
+
177
199
  arg = aargs.lead_tys[0]
178
200
  arg.each_child do |arg|
179
201
  if arg.is_a?(Type::Class)
180
- scratch.include_module(recv, arg, nil, true, ep.ctx.iseq.absolute_path)
202
+ scratch.include_module(recv, arg, nil, true, ep)
181
203
  end
182
204
  end
183
205
  ctn[recv, ep, env]
@@ -198,6 +220,75 @@ module TypeProf
198
220
  end
199
221
  end
200
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
+
201
292
  def module_attr_accessor(recv, mid, aargs, ep, env, scratch, &ctn)
202
293
  aargs.lead_tys.each do |aarg|
203
294
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
@@ -233,21 +324,16 @@ module TypeProf
233
324
  end
234
325
 
235
326
  def array_aref(recv, mid, aargs, ep, env, scratch, &ctn)
236
- 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
237
328
 
238
329
  case aargs.lead_tys.size
239
330
  when 1
240
331
  idx = aargs.lead_tys.first
241
332
  if idx.is_a?(Type::Literal)
242
333
  idx = idx.lit
243
- if idx.is_a?(Range)
244
- ty = scratch.get_array_elem_type(env, ep, recv.id)
245
- base_ty = Type::Instance.new(Type::Builtin[:ary])
246
- ret_ty = Type::Array.new(Type::Array::Elements.new([], ty), base_ty)
247
- ctn[ret_ty, ep, env]
248
- return
249
- end
250
- 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)
251
337
  else
252
338
  idx = nil
253
339
  end
@@ -264,17 +350,22 @@ module TypeProf
264
350
  end
265
351
 
266
352
  def array_aset(recv, mid, aargs, ep, env, scratch, &ctn)
267
- 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
268
354
 
269
355
  if aargs.lead_tys.size != 2
356
+ # XXX: Support `ary[idx, len] = val`
270
357
  #raise NotImplementedError # XXX
271
- ctn[Type.any, ep, env]
358
+ return ctn[Type.any, ep, env]
272
359
  end
273
360
 
274
361
  idx = aargs.lead_tys.first
275
362
  if idx.is_a?(Type::Literal)
276
363
  idx = idx.lit
277
- 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
278
369
  else
279
370
  idx = nil
280
371
  end
@@ -289,7 +380,7 @@ module TypeProf
289
380
  end
290
381
 
291
382
  def array_pop(recv, mid, aargs, ep, env, scratch, &ctn)
292
- 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
293
384
 
294
385
  if aargs.lead_tys.size != 0
295
386
  ctn[Type.any, ep, env]
@@ -301,7 +392,7 @@ module TypeProf
301
392
  end
302
393
 
303
394
  def hash_aref(recv, mid, aargs, ep, env, scratch, &ctn)
304
- 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
305
396
 
306
397
  if aargs.lead_tys.size != 1
307
398
  ctn[Type.any, ep, env]
@@ -309,8 +400,9 @@ module TypeProf
309
400
  end
310
401
  idx = aargs.lead_tys.first
311
402
  recv.each_child do |recv|
312
- if recv.is_a?(Type::LocalHash)
403
+ if recv.is_a?(Type::Local) && recv.kind == Type::Hash
313
404
  ty = scratch.get_hash_elem_type(env, ep, recv.id, idx)
405
+ ty = Type.nil if ty == Type.bot
314
406
  else
315
407
  ty = Type.any
316
408
  end
@@ -319,15 +411,19 @@ module TypeProf
319
411
  end
320
412
 
321
413
  def hash_aset(recv, mid, aargs, ep, env, scratch, &ctn)
322
- 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
323
415
 
324
- 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
325
421
 
326
422
  idx = aargs.lead_tys.first
327
423
  idx = scratch.globalize_type(idx, env, ep)
328
424
  ty = aargs.lead_tys.last
329
425
 
330
- unless recv.is_a?(Type::LocalHash)
426
+ unless recv.is_a?(Type::Local) && recv.kind == Type::Hash
331
427
  # to ignore: class OptionMap < Hash
332
428
  return ctn[ty, ep, env]
333
429
  end
@@ -340,18 +436,7 @@ module TypeProf
340
436
  end
341
437
 
342
438
  def struct_initialize(recv, mid, aargs, ep, env, scratch, &ctn)
343
- recv = Type::Instance.new(recv)
344
- scratch.add_ivar_read!(recv, :_members, ep) do |member_ary_ty, ep|
345
- member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
346
- ty ||= Type.nil
347
- scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
348
- end
349
- end
350
- ctn[recv, ep, env]
351
- end
352
-
353
- def struct_i_new(recv, mid, aargs, ep, env, scratch, &ctn)
354
- struct_klass = recv
439
+ struct_klass = recv.klass
355
440
  while struct_klass.superclass != Type::Builtin[:struct]
356
441
  struct_klass = struct_klass.superclass
357
442
  end
@@ -359,15 +444,24 @@ module TypeProf
359
444
  ctn[Type.any, ep, env]
360
445
  return
361
446
  end
362
- if struct_klass != recv
363
- scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |ty, ep|
364
- 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.nil
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)
365
452
  end
366
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
+
367
460
  meths = scratch.get_method(recv, false, :initialize)
461
+ recv = Type::Instance.new(recv)
368
462
  meths.flat_map do |meth|
369
463
  meth.do_send(recv, :initialize, aargs, ep, env, scratch) do |ret_ty, ep, env|
370
- ctn[Type::Instance.new(recv), ep, env]
464
+ ctn[recv, ep, env]
371
465
  end
372
466
  end
373
467
  end
@@ -435,11 +529,20 @@ module TypeProf
435
529
  end
436
530
 
437
531
  def kernel_require(recv, mid, aargs, ep, env, scratch, &ctn)
438
- 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
+
439
538
  feature = aargs.lead_tys.first
440
539
  if feature.is_a?(Type::Literal)
441
540
  feature = feature.lit
442
541
 
542
+ unless feature.is_a?(String)
543
+ return ctn[Type.any, ep, env]
544
+ end
545
+
443
546
  action, arg = Builtin.file_require(feature, scratch)
444
547
  case action
445
548
  when :do
@@ -449,22 +552,31 @@ module TypeProf
449
552
  ctn[result, ep, env]
450
553
  when :error
451
554
  scratch.warn(ep, arg)
452
- result = Type::Instance.new(Type.bool)
555
+ result = Type.bool
453
556
  ctn[result, ep, env]
454
557
  end
455
558
  else
456
559
  scratch.warn(ep, "require target cannot be identified statically")
457
- result = Type::Instance.new(Type.bool)
560
+ result = Type.bool
458
561
  ctn[result, ep, env]
459
562
  end
460
563
  end
461
564
 
462
565
  def kernel_require_relative(recv, mid, aargs, ep, env, scratch, &ctn)
463
- 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
+
464
572
  feature = aargs.lead_tys.first
465
573
  if feature.is_a?(Type::Literal)
466
574
  feature = feature.lit
467
575
 
576
+ unless feature.is_a?(String)
577
+ return ctn[Type.any, ep, env]
578
+ end
579
+
468
580
  if scratch.loaded_features[feature]
469
581
  result = Type::Instance.new(Type::Builtin[:false])
470
582
  return ctn[result, ep, env]
@@ -484,6 +596,36 @@ module TypeProf
484
596
  ctn[result, ep, env]
485
597
  end
486
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
+
487
629
  def kernel_Array(recv, mid, aargs, ep, env, scratch, &ctn)
488
630
  raise NotImplementedError if aargs.lead_tys.size != 1
489
631
  ty = aargs.lead_tys.first
@@ -502,8 +644,8 @@ module TypeProf
502
644
  end
503
645
 
504
646
  def self.setup_initial_global_env(scratch)
505
- klass_basic_obj = scratch.new_class(nil, :BasicObject, [], :__root__, nil, nil) # cbase, name, superclass
506
- klass_obj = scratch.new_class(nil, :Object, [], klass_basic_obj, [], nil)
647
+ klass_basic_obj = scratch.new_class(nil, :BasicObject, [], :__root__, nil) # cbase, name, superclass
648
+ klass_obj = scratch.new_class(nil, :Object, [], klass_basic_obj, nil)
507
649
  scratch.add_constant(klass_obj, :Object, klass_obj, nil)
508
650
  scratch.add_constant(klass_obj, :BasicObject, klass_basic_obj, nil)
509
651
 
@@ -512,10 +654,11 @@ module TypeProf
512
654
 
513
655
  Import.import_builtin(scratch)
514
656
 
515
- Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, [], nil)
657
+ Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
516
658
  Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
517
659
  Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
518
660
  Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
661
+ Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
519
662
  Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
520
663
  Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
521
664
  Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
@@ -529,6 +672,7 @@ module TypeProf
529
672
  Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
530
673
  Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
531
674
  Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
675
+ Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
532
676
 
533
677
  klass_vmcore = Type::Builtin[:vmcore]
534
678
  klass_ary = Type::Builtin[:ary]
@@ -543,9 +687,6 @@ module TypeProf
543
687
  scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
544
688
  scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
545
689
  scratch.set_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
546
- scratch.set_singleton_custom_method(klass_obj, :"attr_accessor", Builtin.method(:module_attr_accessor))
547
- scratch.set_singleton_custom_method(klass_obj, :"attr_reader", Builtin.method(:module_attr_reader))
548
- scratch.set_singleton_custom_method(klass_obj, :"attr_writer", Builtin.method(:module_attr_writer))
549
690
  scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
550
691
  scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
551
692
  scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
@@ -557,6 +698,12 @@ module TypeProf
557
698
  scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
558
699
  scratch.set_custom_method(klass_module, :extend, Builtin.method(:module_extend))
559
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))
560
707
 
561
708
  scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
562
709
  scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
@@ -574,6 +721,11 @@ module TypeProf
574
721
  scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
575
722
  scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
576
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)
577
729
 
578
730
  # ENV: Hash[String, String]
579
731
  str_ty = Type::Instance.new(Type::Builtin[:str])