typeprof 0.9.1 → 0.13.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 (188) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/Gemfile.lock +6 -5
  4. data/doc/demo.md +2 -2
  5. data/doc/todo.md +133 -0
  6. data/lib/typeprof/analyzer.rb +163 -77
  7. data/lib/typeprof/block.rb +39 -4
  8. data/lib/typeprof/builtin.rb +195 -70
  9. data/lib/typeprof/cli.rb +7 -0
  10. data/lib/typeprof/config.rb +30 -14
  11. data/lib/typeprof/container-type.rb +24 -0
  12. data/lib/typeprof/export.rb +134 -74
  13. data/lib/typeprof/import.rb +87 -39
  14. data/lib/typeprof/iseq.rb +23 -4
  15. data/lib/typeprof/method.rb +29 -7
  16. data/lib/typeprof/type.rb +75 -13
  17. data/lib/typeprof/version.rb +1 -1
  18. data/smoke/alias.rb +4 -4
  19. data/smoke/alias2.rb +3 -1
  20. data/smoke/arguments.rb +2 -2
  21. data/smoke/arguments2.rb +5 -5
  22. data/smoke/array-each.rb +1 -1
  23. data/smoke/array-each3.rb +1 -1
  24. data/smoke/array-map.rb +1 -1
  25. data/smoke/array-map2.rb +1 -1
  26. data/smoke/array-map3.rb +3 -3
  27. data/smoke/array-mul.rb +2 -2
  28. data/smoke/array-plus1.rb +1 -1
  29. data/smoke/array-plus2.rb +1 -0
  30. data/smoke/array-range-aref.rb +11 -11
  31. data/smoke/array-replace.rb +1 -1
  32. data/smoke/array1.rb +5 -5
  33. data/smoke/array10.rb +1 -1
  34. data/smoke/array11.rb +1 -1
  35. data/smoke/array12.rb +1 -1
  36. data/smoke/array14.rb +1 -1
  37. data/smoke/array15.rb +1 -1
  38. data/smoke/array2.rb +2 -2
  39. data/smoke/array3.rb +1 -0
  40. data/smoke/array6.rb +2 -1
  41. data/smoke/array8.rb +1 -1
  42. data/smoke/array9.rb +1 -1
  43. data/smoke/attr-module.rb +1 -0
  44. data/smoke/attr-vis.rb +43 -0
  45. data/smoke/attr-vis.rbs +4 -0
  46. data/smoke/attr.rb +2 -2
  47. data/smoke/block-ambiguous.rb +4 -4
  48. data/smoke/block-args1-rest.rb +6 -5
  49. data/smoke/block-args1.rb +5 -5
  50. data/smoke/block-args2-rest.rb +6 -5
  51. data/smoke/block-args2.rb +5 -5
  52. data/smoke/block-args3-rest.rb +7 -6
  53. data/smoke/block-args3.rb +6 -6
  54. data/smoke/block-blockarg.rb +3 -3
  55. data/smoke/block-kwarg.rb +4 -4
  56. data/smoke/block1.rb +1 -1
  57. data/smoke/block10.rb +1 -1
  58. data/smoke/block11.rb +2 -2
  59. data/smoke/block2.rb +1 -1
  60. data/smoke/block3.rb +1 -1
  61. data/smoke/block5.rb +1 -0
  62. data/smoke/block_given.rb +37 -0
  63. data/smoke/class_eval.rb +22 -0
  64. data/smoke/class_method.rb +2 -2
  65. data/smoke/class_method2.rb +2 -2
  66. data/smoke/constant2.rb +3 -2
  67. data/smoke/context-sensitive1.rb +1 -1
  68. data/smoke/cvar.rb +3 -2
  69. data/smoke/define_method.rb +2 -2
  70. data/smoke/define_method3.rb +1 -0
  71. data/smoke/define_method4.rb +1 -1
  72. data/smoke/define_method6.rb +19 -0
  73. data/smoke/define_method7.rb +18 -0
  74. data/smoke/demo.rb +6 -6
  75. data/smoke/demo1.rb +1 -1
  76. data/smoke/demo11.rb +1 -1
  77. data/smoke/demo2.rb +1 -1
  78. data/smoke/demo3.rb +1 -1
  79. data/smoke/demo4.rb +3 -3
  80. data/smoke/demo5.rb +1 -1
  81. data/smoke/demo6.rb +2 -1
  82. data/smoke/demo7.rb +1 -1
  83. data/smoke/demo9.rb +1 -0
  84. data/smoke/dummy-execution1.rb +1 -1
  85. data/smoke/dummy-execution2.rb +1 -1
  86. data/smoke/dummy_element.rb +1 -1
  87. data/smoke/ensure1.rb +1 -1
  88. data/smoke/enum_for.rb +15 -0
  89. data/smoke/enum_for2.rb +17 -0
  90. data/smoke/extended.rb +38 -0
  91. data/smoke/fib.rb +2 -2
  92. data/smoke/flow1.rb +1 -1
  93. data/smoke/flow10.rb +17 -0
  94. data/smoke/flow2.rb +1 -1
  95. data/smoke/flow3.rb +1 -1
  96. data/smoke/flow5.rb +1 -1
  97. data/smoke/flow6.rb +1 -1
  98. data/smoke/flow7.rb +1 -1
  99. data/smoke/flow8.rb +1 -1
  100. data/smoke/flow9.rb +1 -1
  101. data/smoke/function.rb +1 -1
  102. data/smoke/gvar.rb +1 -1
  103. data/smoke/gvar2.rb +1 -1
  104. data/smoke/hash-fetch.rb +3 -3
  105. data/smoke/included.rb +38 -0
  106. data/smoke/inheritance.rb +4 -4
  107. data/smoke/inherited.rb +26 -0
  108. data/smoke/initialize.rb +3 -2
  109. data/smoke/instance_eval.rb +2 -2
  110. data/smoke/instance_eval4.rb +12 -0
  111. data/smoke/int_times.rb +1 -1
  112. data/smoke/integer.rb +1 -1
  113. data/smoke/ivar.rb +3 -2
  114. data/smoke/ivar2.rb +2 -2
  115. data/smoke/ivar3.rb +2 -1
  116. data/smoke/ivar4.rb +1 -0
  117. data/smoke/kernel-class.rb +1 -1
  118. data/smoke/keyword4.rb +1 -1
  119. data/smoke/kwrest.rb +1 -0
  120. data/smoke/kwsplat1.rb +2 -2
  121. data/smoke/kwsplat2.rb +1 -1
  122. data/smoke/manual-rbs.rb +2 -1
  123. data/smoke/manual-rbs3.rb +1 -0
  124. data/smoke/method_in_branch.rb +1 -1
  125. data/smoke/method_missing.rb +4 -3
  126. data/smoke/module3.rb +1 -1
  127. data/smoke/module4.rb +1 -0
  128. data/smoke/module5.rb +1 -1
  129. data/smoke/module_function1.rb +3 -2
  130. data/smoke/module_function2.rb +3 -2
  131. data/smoke/multiple-include.rb +1 -0
  132. data/smoke/next1.rb +1 -1
  133. data/smoke/object-send1.rb +3 -3
  134. data/smoke/optional1.rb +1 -1
  135. data/smoke/optional2.rb +1 -1
  136. data/smoke/optional3.rb +1 -1
  137. data/smoke/parameterizedd-self.rb +2 -1
  138. data/smoke/prepend1.rb +33 -0
  139. data/smoke/prepend2.rb +10 -0
  140. data/smoke/prepend2.rbs +9 -0
  141. data/smoke/primitive_method.rb +19 -0
  142. data/smoke/proc4.rb +1 -1
  143. data/smoke/public.rb +4 -0
  144. data/smoke/range.rb +1 -1
  145. data/smoke/rbs-attr.rb +2 -2
  146. data/smoke/rbs-proc2.rb +1 -1
  147. data/smoke/rbs-proc3.rb +1 -1
  148. data/smoke/rbs-tyvar4.rb +3 -2
  149. data/smoke/rbs-tyvar6.rb +3 -3
  150. data/smoke/redo1.rb +1 -1
  151. data/smoke/redo2.rb +1 -1
  152. data/smoke/rescue1.rb +1 -1
  153. data/smoke/rescue2.rb +1 -1
  154. data/smoke/rescue3.rb +1 -0
  155. data/smoke/rescue4.rb +1 -1
  156. data/smoke/respond_to.rb +1 -1
  157. data/smoke/rest1.rb +2 -2
  158. data/smoke/rest2.rb +1 -1
  159. data/smoke/rest3.rb +6 -6
  160. data/smoke/rest4.rb +2 -2
  161. data/smoke/rest5.rb +1 -1
  162. data/smoke/rest6.rb +1 -1
  163. data/smoke/retry1.rb +2 -2
  164. data/smoke/simple.rb +12 -0
  165. data/smoke/step.rb +3 -3
  166. data/smoke/struct-keyword_init.rb +6 -16
  167. data/smoke/struct.rb +1 -1
  168. data/smoke/struct2.rb +1 -1
  169. data/smoke/struct3.rb +1 -1
  170. data/smoke/struct4.rb +1 -1
  171. data/smoke/struct5.rb +2 -2
  172. data/smoke/struct6.rb +2 -2
  173. data/smoke/struct7.rb +1 -1
  174. data/smoke/super1.rb +4 -4
  175. data/smoke/super3.rb +3 -2
  176. data/smoke/super4.rb +7 -5
  177. data/smoke/super5.rb +6 -4
  178. data/smoke/symbol-proc-attr.rb +1 -1
  179. data/smoke/tap1.rb +2 -2
  180. data/smoke/toplevel.rb +1 -1
  181. data/smoke/type_var.rb +3 -3
  182. data/smoke/user-demo.rb +1 -1
  183. data/smoke/wrong-extend.rb +1 -0
  184. data/smoke/wrong-include.rb +1 -0
  185. data/smoke/wrong-include2.rb +1 -1
  186. data/testbed/goodcheck-Gemfile.lock +1 -1
  187. data/typeprof.gemspec +1 -1
  188. metadata +24 -5
@@ -27,7 +27,7 @@ module TypeProf
27
27
  self
28
28
  end
29
29
 
30
- def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
30
+ def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
31
31
  blk_env = scratch.return_envs[@outer_ep]
32
32
  if replace_recv_ty
33
33
  replace_recv_ty = scratch.globalize_type(replace_recv_ty, caller_env, caller_ep)
@@ -46,7 +46,8 @@ module TypeProf
46
46
  return
47
47
  end
48
48
 
49
- nctx = Context.new(@iseq, @outer_ep.ctx.cref, nil)
49
+ cref = replace_cref || @outer_ep.ctx.cref
50
+ nctx = Context.new(@iseq, cref, nil)
50
51
  callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
51
52
  nenv = Env.new(blk_env.static_env, locals, [], nil)
52
53
  alloc_site = AllocationSite.new(callee_ep)
@@ -87,7 +88,7 @@ module TypeProf
87
88
  TypedBlock.new(msig, ret_ty)
88
89
  end
89
90
 
90
- def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
91
+ def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
91
92
  aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
92
93
  subst = aargs.consistent_with_method_signature?(@msig)
93
94
  unless subst
@@ -119,7 +120,7 @@ module TypeProf
119
120
  self
120
121
  end
121
122
 
122
- def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
123
+ def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
123
124
  if aargs.lead_tys.size >= 1
124
125
  recv = aargs.lead_tys[0]
125
126
  recv = Type.any if recv == Type.bot
@@ -137,4 +138,38 @@ module TypeProf
137
138
  end
138
139
  end
139
140
  end
141
+
142
+ class CustomBlock < Block
143
+ def initialize(caller_ep, mid, &blk)
144
+ @caller_ep = caller_ep
145
+ @mid = mid
146
+ @blk = blk
147
+ end
148
+
149
+ def inspect
150
+ "#<CustomBlock>"
151
+ end
152
+
153
+ def consistent?(other)
154
+ true # XXX
155
+ end
156
+
157
+ def substitute(_subst, _depth)
158
+ self
159
+ end
160
+
161
+ def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
162
+ aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
163
+
164
+ dummy_ctx = TypedContext.new(@caller_ep, @mid)
165
+
166
+ scratch.add_block_signature!(self, aargs.to_block_signature)
167
+ scratch.add_block_to_ctx!(self, dummy_ctx)
168
+
169
+ @blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty, replace_cref: replace_cref) do |ret_ty, ep, env|
170
+ scratch.add_return_value!(dummy_ctx, ret_ty)
171
+ ctn[ret_ty, ep, env]
172
+ end
173
+ end
174
+ end
140
175
  end
@@ -19,7 +19,7 @@ module TypeProf
19
19
  klass, new_mid, old_mid = aargs.lead_tys
20
20
  new_sym = get_sym("alias", new_mid, ep, scratch) or return
21
21
  old_sym = get_sym("alias", old_mid, ep, scratch) or return
22
- scratch.alias_method(klass, ep.ctx.cref.singleton, new_sym, old_sym)
22
+ scratch.alias_method(klass, ep.ctx.cref.singleton, new_sym, old_sym, ep)
23
23
  ctn[Type.nil, ep, env]
24
24
  end
25
25
 
@@ -158,11 +158,86 @@ module TypeProf
158
158
  naargs = ActualArguments.new([recv], nil, {}, Type.nil)
159
159
  nrecv = recv
160
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|
161
+ scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv) do |ret_ty, ep|
162
+ ctn[ret_ty, ep, env]
163
+ end
164
+ end
165
+
166
+ def object_module_eval(recv, mid, aargs, ep, env, scratch, &ctn)
167
+ if aargs.lead_tys.size >= 1
168
+ scratch.warn(ep, "class_eval with arguments is ignored")
169
+ ctn[Type.any, ep, env]
170
+ return
171
+ end
172
+ naargs = ActualArguments.new([recv], nil, {}, Type.nil)
173
+ nrecv = recv
174
+ nrecv = nrecv.base_type if nrecv.is_a?(Type::ContainerType)
175
+ ncref = ep.ctx.cref.extend(nrecv, true)
176
+ scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv, replace_cref: ncref) do |_ret_ty, ep|
162
177
  ctn[recv, ep, env]
163
178
  end
164
179
  end
165
180
 
181
+ def object_enum_for(recv, mid, aargs, ep, env, scratch, &ctn)
182
+ if aargs.lead_tys.size >= 1
183
+ mid_ty, = aargs.lead_tys
184
+ naargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
185
+ elsif aargs.rest_ty
186
+ mid_ty = aargs.rest_ty
187
+ naargs = aargs
188
+ else
189
+ mid_ty = Type::Symbol.new(:each, Type::Instance.new(Type::Builtin[:sym]))
190
+ naargs = aargs
191
+ end
192
+
193
+ elem_ty = Type.bot
194
+ enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &blk_ctn|
195
+ if aargs.lead_tys.size >= 1
196
+ elem_ty = elem_ty.union(aargs.lead_tys[0])
197
+ else
198
+ elem_ty = elem_ty.union(Type.any)
199
+ end
200
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
201
+ blk_ctn[Type.any, caller_ep, caller_env]
202
+ end
203
+ enum_for_blk_ty = Type::Proc.new(enum_for_blk, Type::Instance.new(Type::Builtin[:proc]))
204
+
205
+ naargs = ActualArguments.new(naargs.lead_tys, naargs.rest_ty, naargs.kw_tys, enum_for_blk_ty)
206
+ mid_ty.each_child do |mid|
207
+ if mid.is_a?(Type::Symbol)
208
+ mid = mid.sym
209
+ scratch.do_send(recv, mid, naargs, ep, env) do |_ret_ty, _ep|
210
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ def object_privitive_method(recv, mid, aargs, ep, env, scratch, &ctn)
217
+ ctn[Type::Symbol.new(ep.ctx.mid, Type::Instance.new(Type::Builtin[:sym])), ep, env]
218
+ end
219
+
220
+ def object_block_given?(recv, mid, aargs, ep, env, scratch, &ctn)
221
+ procs = Type.bot
222
+ no_proc = false
223
+ env.static_env.blk_ty.each_child do |blk_ty|
224
+ case blk_ty
225
+ when Type::Proc
226
+ procs = procs.union(blk_ty)
227
+ when Type.nil
228
+ no_proc = true
229
+ else
230
+ ctn[Type.bool, ep, env]
231
+ end
232
+ end
233
+ if procs != Type.bot
234
+ ctn[Type::Instance.new(Type::Builtin[:true]), ep, env.replace_blk_ty(procs)]
235
+ end
236
+ if no_proc
237
+ ctn[Type::Instance.new(Type::Builtin[:false]), ep, env.replace_blk_ty(Type.nil)]
238
+ end
239
+ end
240
+
166
241
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
167
242
  if aargs.lead_tys.size != 1
168
243
  scratch.warn(ep, "Module#include without an argument is ignored")
@@ -175,10 +250,13 @@ module TypeProf
175
250
  return ctn[Type.any, ep, env]
176
251
  end
177
252
 
253
+ # support multiple arguments: include M1, M2
178
254
  arg = aargs.lead_tys[0]
179
255
  arg.each_child do |arg|
180
256
  if arg.is_a?(Type::Class)
181
- scratch.include_module(recv, arg, nil, false, ep)
257
+ aargs = ActualArguments.new([recv], nil, {}, Type.nil)
258
+ scratch.do_send(arg, :included, aargs, ep, env) {|_ret_ty, _ep| }
259
+ scratch.mix_module(:after, recv, arg, nil, ep.ctx.cref.singleton, ep)
182
260
  end
183
261
  end
184
262
  ctn[recv, ep, env]
@@ -199,7 +277,31 @@ module TypeProf
199
277
  arg = aargs.lead_tys[0]
200
278
  arg.each_child do |arg|
201
279
  if arg.is_a?(Type::Class)
202
- scratch.include_module(recv, arg, nil, true, ep)
280
+ aargs = ActualArguments.new([recv], nil, {}, Type.nil)
281
+ scratch.do_send(arg, :extended, aargs, ep, env) {|_ret_ty, _ep| }
282
+ # if ep.ctx.cref.singleton is true, the meta-meta level is ignored. Should we warn?
283
+ scratch.mix_module(:after, recv, arg, nil, true, ep)
284
+ end
285
+ end
286
+ ctn[recv, ep, env]
287
+ end
288
+
289
+ def module_prepend(recv, mid, aargs, ep, env, scratch, &ctn)
290
+ if aargs.lead_tys.size != 1
291
+ scratch.warn(ep, "Module#prepend without an argument is ignored")
292
+ ctn[Type.any, ep, env]
293
+ return
294
+ end
295
+
296
+ unless recv.is_a?(Type::Class)
297
+ # XXX: warn?
298
+ return ctn[Type.any, ep, env]
299
+ end
300
+
301
+ arg = aargs.lead_tys[0]
302
+ arg.each_child do |arg|
303
+ if arg.is_a?(Type::Class)
304
+ scratch.mix_module(:before, recv, arg, nil, ep.ctx.cref.singleton, ep)
203
305
  end
204
306
  end
205
307
  ctn[recv, ep, env]
@@ -268,23 +370,25 @@ module TypeProf
268
370
  end
269
371
 
270
372
  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)
373
+ mid.each_child do |mid|
374
+ if mid.is_a?(Type::Symbol)
375
+ mid = mid.sym
376
+ aargs.blk_ty.each_child do |blk_ty|
377
+ if blk_ty.is_a?(Type::Proc)
378
+ blk = blk_ty.block_body
379
+ case blk
380
+ when ISeqBlock
381
+ scratch.do_define_iseq_method(ep, env, mid, blk.iseq, blk.outer_ep)
382
+ else
383
+ # XXX: what to do?
384
+ end
279
385
  else
280
386
  # XXX: what to do?
281
387
  end
282
- else
283
- # XXX: what to do?
284
388
  end
389
+ else
390
+ # XXX: what to do?
285
391
  end
286
- else
287
- # XXX: what to do?
288
392
  end
289
393
  ctn[Type.any, ep, env]
290
394
  end
@@ -293,7 +397,7 @@ module TypeProf
293
397
  aargs.lead_tys.each do |aarg|
294
398
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
295
399
  cref = ep.ctx.cref
296
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :accessor)
400
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :accessor, env.static_env.pub_meth, ep)
297
401
  end
298
402
  ctn[Type.nil, ep, env]
299
403
  end
@@ -302,7 +406,7 @@ module TypeProf
302
406
  aargs.lead_tys.each do |aarg|
303
407
  sym = get_sym("attr_reader", aarg, ep, scratch) or next
304
408
  cref = ep.ctx.cref
305
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :reader)
409
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :reader, env.static_env.pub_meth, ep)
306
410
  end
307
411
  ctn[Type.nil, ep, env]
308
412
  end
@@ -311,7 +415,7 @@ module TypeProf
311
415
  aargs.lead_tys.each do |aarg|
312
416
  sym = get_sym("attr_writer", aarg, ep, scratch) or next
313
417
  cref = ep.ctx.cref
314
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :writer)
418
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :writer, env.static_env.pub_meth, ep)
315
419
  end
316
420
  ctn[Type.nil, ep, env]
317
421
  end
@@ -444,43 +548,55 @@ module TypeProf
444
548
  ctn[Type.any, ep, env]
445
549
  return
446
550
  end
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)
551
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_keyword_init, ep) do |keyword_init, ep|
552
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |member_ary_ty, ep|
553
+ next if member_ary_ty == Type.nil
554
+ if keyword_init == Type::Instance.new(Type::Builtin[:true])
555
+ # TODO: support kw_rest_ty
556
+ aargs.kw_tys.each do |key, val_ty|
557
+ found = false
558
+ member_ary_ty.elems.lead_tys.each do |sym|
559
+ if sym.sym == key
560
+ found = true
561
+ scratch.set_instance_variable(recv, sym.sym, val_ty, ep, env)
562
+ end
563
+ end
564
+ unless found
565
+ # TODO: what to do when not found?
566
+ end
567
+ end
568
+ else
569
+ member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
570
+ ty ||= Type.nil
571
+ scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
572
+ end
573
+ end
452
574
  end
453
575
  end
454
576
  ctn[recv, ep, env]
455
577
  end
456
578
 
457
- def struct_i_new(recv, mid, aargs, ep, env, scratch, &ctn)
458
- # TODO: keyword_init
459
-
460
- meths = scratch.get_method(recv, false, :initialize)
461
- recv = Type::Instance.new(recv)
462
- meths.flat_map do |meth|
463
- meth.do_send(recv, :initialize, aargs, ep, env, scratch) do |ret_ty, ep, env|
464
- ctn[recv, ep, env]
579
+ def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
580
+ keyword_init = false
581
+ if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
582
+ if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
583
+ keyword_init = true
465
584
  end
466
585
  end
467
- end
468
-
469
- def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
470
- # TODO: keyword_init
471
586
 
472
587
  fields = aargs.lead_tys.map {|ty| get_sym("Struct.new", ty, ep, scratch) }.compact
473
588
  struct_klass = scratch.new_struct(ep)
474
589
 
475
- scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:struct_i_new))
476
- scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:struct_i_new))
590
+ scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:object_s_new))
591
+ scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:object_s_new))
477
592
  fields.each do |field|
478
- scratch.add_attr_method(struct_klass, ep.ctx.iseq.absolute_path, field, field, :accessor)
593
+ scratch.add_attr_method(struct_klass, field, field, :accessor, true, ep)
479
594
  end
480
595
  fields = fields.map {|field| Type::Symbol.new(field, Type::Instance.new(Type::Builtin[:sym])) }
481
596
  base_ty = Type::Instance.new(Type::Builtin[:ary])
482
597
  fields = Type::Array.new(Type::Array::Elements.new(fields), base_ty)
483
598
  scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_members, fields, ep)
599
+ scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_keyword_init, Type::Instance.new(Type::Builtin[:true]), ep) if keyword_init
484
600
  #set_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
485
601
 
486
602
  ctn[struct_klass, ep, env]
@@ -654,25 +770,26 @@ module TypeProf
654
770
 
655
771
  Import.import_builtin(scratch)
656
772
 
657
- Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
658
- Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
659
- Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
660
- Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
661
- Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
662
- Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
663
- Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
664
- Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
665
- Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
666
- Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
667
- Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
668
- Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
669
- Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
670
- Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
671
- Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
672
- Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
673
- Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
674
- Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
675
- Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
773
+ Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
774
+ Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
775
+ Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
776
+ Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
777
+ Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
778
+ Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
779
+ Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
780
+ Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
781
+ Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
782
+ Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
783
+ Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
784
+ Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
785
+ Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
786
+ Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
787
+ Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
788
+ Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
789
+ Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
790
+ Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
791
+ Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
792
+ Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
676
793
 
677
794
  klass_vmcore = Type::Builtin[:vmcore]
678
795
  klass_ary = Type::Builtin[:ary]
@@ -687,23 +804,31 @@ module TypeProf
687
804
  scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
688
805
  scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
689
806
  scratch.set_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
690
- scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
807
+ scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p), false)
691
808
  scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
692
809
  scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
693
810
  scratch.set_custom_method(klass_obj, :class, Builtin.method(:object_class))
694
811
  scratch.set_custom_method(klass_obj, :send, Builtin.method(:object_send))
695
812
  scratch.set_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
696
- scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda))
813
+ scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda), false)
814
+ scratch.set_custom_method(klass_obj, :__method__, Builtin.method(:object_privitive_method), false)
815
+ scratch.set_custom_method(klass_obj, :block_given?, Builtin.method(:object_block_given?), false)
816
+
817
+ scratch.set_custom_method(klass_obj, :enum_for, Builtin.method(:object_enum_for))
818
+ scratch.set_custom_method(klass_obj, :to_enum, Builtin.method(:object_enum_for))
697
819
 
698
820
  scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
699
821
  scratch.set_custom_method(klass_module, :extend, Builtin.method(:module_extend))
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))
822
+ scratch.set_custom_method(klass_module, :prepend, Builtin.method(:module_prepend))
823
+ scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function), false)
824
+ scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public), false)
825
+ scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private), false)
703
826
  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))
827
+ scratch.set_custom_method(klass_module, :attr_accessor, Builtin.method(:module_attr_accessor))
828
+ scratch.set_custom_method(klass_module, :attr_reader, Builtin.method(:module_attr_reader))
829
+ scratch.set_custom_method(klass_module, :attr_writer, Builtin.method(:module_attr_writer))
830
+ scratch.set_custom_method(klass_module, :class_eval, Builtin.method(:object_module_eval))
831
+ scratch.set_custom_method(klass_module, :module_eval, Builtin.method(:object_module_eval))
707
832
 
708
833
  scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
709
834
  scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
@@ -718,10 +843,10 @@ module TypeProf
718
843
  scratch.set_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
719
844
  scratch.set_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
720
845
 
721
- scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
722
- scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
723
- scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array))
724
- scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload))
846
+ scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require), false)
847
+ scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative), false)
848
+ scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array), false)
849
+ scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload), false)
725
850
  scratch.set_custom_method(klass_module, :autoload, Builtin.method(:module_autoload))
726
851
 
727
852
  # remove BasicObject#method_missing