typeprof 0.9.2 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (189) 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 +201 -104
  7. data/lib/typeprof/block.rb +39 -4
  8. data/lib/typeprof/builtin.rb +217 -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 +116 -41
  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/break4.rb +17 -0
  64. data/smoke/class_eval.rb +22 -0
  65. data/smoke/class_method.rb +2 -2
  66. data/smoke/class_method2.rb +2 -2
  67. data/smoke/constant2.rb +3 -2
  68. data/smoke/context-sensitive1.rb +1 -1
  69. data/smoke/cvar.rb +3 -2
  70. data/smoke/define_method.rb +2 -2
  71. data/smoke/define_method3.rb +1 -0
  72. data/smoke/define_method4.rb +1 -1
  73. data/smoke/define_method6.rb +19 -0
  74. data/smoke/define_method7.rb +18 -0
  75. data/smoke/demo.rb +6 -6
  76. data/smoke/demo1.rb +1 -1
  77. data/smoke/demo11.rb +1 -1
  78. data/smoke/demo2.rb +1 -1
  79. data/smoke/demo3.rb +1 -1
  80. data/smoke/demo4.rb +3 -3
  81. data/smoke/demo5.rb +1 -1
  82. data/smoke/demo6.rb +2 -1
  83. data/smoke/demo7.rb +1 -1
  84. data/smoke/demo9.rb +1 -0
  85. data/smoke/dummy-execution1.rb +1 -1
  86. data/smoke/dummy-execution2.rb +1 -1
  87. data/smoke/dummy_element.rb +1 -1
  88. data/smoke/ensure1.rb +1 -1
  89. data/smoke/enum_for.rb +15 -0
  90. data/smoke/enum_for2.rb +17 -0
  91. data/smoke/extended.rb +38 -0
  92. data/smoke/fib.rb +2 -2
  93. data/smoke/flow1.rb +1 -1
  94. data/smoke/flow10.rb +17 -0
  95. data/smoke/flow11.rb +17 -0
  96. data/smoke/flow2.rb +1 -1
  97. data/smoke/flow3.rb +1 -1
  98. data/smoke/flow5.rb +1 -1
  99. data/smoke/flow6.rb +1 -1
  100. data/smoke/flow7.rb +1 -1
  101. data/smoke/flow8.rb +1 -1
  102. data/smoke/flow9.rb +1 -1
  103. data/smoke/function.rb +1 -1
  104. data/smoke/gvar.rb +1 -1
  105. data/smoke/gvar2.rb +1 -1
  106. data/smoke/hash-fetch.rb +3 -3
  107. data/smoke/included.rb +38 -0
  108. data/smoke/inheritance.rb +4 -4
  109. data/smoke/inherited.rb +26 -0
  110. data/smoke/initialize.rb +3 -2
  111. data/smoke/instance_eval.rb +2 -2
  112. data/smoke/instance_eval4.rb +12 -0
  113. data/smoke/int_times.rb +1 -1
  114. data/smoke/integer.rb +1 -1
  115. data/smoke/ivar.rb +3 -2
  116. data/smoke/ivar2.rb +2 -2
  117. data/smoke/ivar3.rb +2 -1
  118. data/smoke/ivar4.rb +1 -0
  119. data/smoke/kernel-class.rb +1 -1
  120. data/smoke/keyword4.rb +1 -1
  121. data/smoke/kwrest.rb +1 -0
  122. data/smoke/kwsplat1.rb +2 -2
  123. data/smoke/kwsplat2.rb +1 -1
  124. data/smoke/manual-rbs.rb +1 -0
  125. data/smoke/manual-rbs3.rb +1 -0
  126. data/smoke/method_missing.rb +4 -3
  127. data/smoke/module3.rb +1 -1
  128. data/smoke/module4.rb +1 -0
  129. data/smoke/module5.rb +1 -1
  130. data/smoke/module_function1.rb +3 -2
  131. data/smoke/module_function2.rb +3 -2
  132. data/smoke/multiple-include.rb +1 -0
  133. data/smoke/next1.rb +1 -1
  134. data/smoke/object-send1.rb +3 -3
  135. data/smoke/optional1.rb +1 -1
  136. data/smoke/optional2.rb +1 -1
  137. data/smoke/optional3.rb +1 -1
  138. data/smoke/parameterizedd-self.rb +2 -1
  139. data/smoke/prepend1.rb +33 -0
  140. data/smoke/prepend2.rb +10 -0
  141. data/smoke/prepend2.rbs +9 -0
  142. data/smoke/primitive_method.rb +19 -0
  143. data/smoke/proc4.rb +1 -1
  144. data/smoke/public.rb +4 -0
  145. data/smoke/range.rb +1 -1
  146. data/smoke/rbs-attr.rb +2 -2
  147. data/smoke/rbs-proc2.rb +1 -1
  148. data/smoke/rbs-proc3.rb +1 -1
  149. data/smoke/rbs-tyvar4.rb +3 -2
  150. data/smoke/rbs-tyvar6.rb +3 -3
  151. data/smoke/redo1.rb +1 -1
  152. data/smoke/redo2.rb +1 -1
  153. data/smoke/rescue1.rb +1 -1
  154. data/smoke/rescue2.rb +1 -1
  155. data/smoke/rescue3.rb +1 -0
  156. data/smoke/rescue4.rb +1 -1
  157. data/smoke/respond_to.rb +1 -1
  158. data/smoke/rest1.rb +2 -2
  159. data/smoke/rest2.rb +1 -1
  160. data/smoke/rest3.rb +6 -6
  161. data/smoke/rest4.rb +2 -2
  162. data/smoke/rest5.rb +1 -1
  163. data/smoke/rest6.rb +1 -1
  164. data/smoke/retry1.rb +2 -2
  165. data/smoke/simple.rb +1 -1
  166. data/smoke/step.rb +3 -3
  167. data/smoke/struct-keyword_init.rb +6 -16
  168. data/smoke/struct.rb +1 -1
  169. data/smoke/struct2.rb +1 -1
  170. data/smoke/struct3.rb +1 -1
  171. data/smoke/struct4.rb +1 -1
  172. data/smoke/struct5.rb +2 -2
  173. data/smoke/struct6.rb +2 -2
  174. data/smoke/struct7.rb +1 -1
  175. data/smoke/super1.rb +4 -4
  176. data/smoke/super3.rb +3 -2
  177. data/smoke/super4.rb +7 -5
  178. data/smoke/super5.rb +6 -4
  179. data/smoke/symbol-proc-attr.rb +1 -1
  180. data/smoke/tap1.rb +2 -2
  181. data/smoke/toplevel.rb +1 -1
  182. data/smoke/type_var.rb +3 -3
  183. data/smoke/user-demo.rb +1 -1
  184. data/smoke/wrong-extend.rb +1 -0
  185. data/smoke/wrong-include.rb +1 -0
  186. data/smoke/wrong-include2.rb +1 -1
  187. data/testbed/goodcheck-Gemfile.lock +1 -1
  188. data/typeprof.gemspec +1 -1
  189. metadata +25 -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,107 @@ 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 module_eqq(recv, mid, aargs, ep, env, scratch, &ctn)
167
+ if aargs.lead_tys.size == 1
168
+ aargs.lead_tys[0].each_child do |aarg|
169
+ aarg = aarg.base_type if aarg.is_a?(Type::Symbol) # XXX
170
+ if aarg.is_a?(Type::Instance)
171
+ if aarg.klass == recv # XXX: inheritance
172
+ true_val = Type::Instance.new(Type::Builtin[:true])
173
+ ctn[true_val, ep, env]
174
+ else
175
+ false_val = Type::Instance.new(Type::Builtin[:false])
176
+ ctn[false_val, ep, env]
177
+ end
178
+ else
179
+ ctn[Type.bool, ep, env]
180
+ end
181
+ end
182
+ else
183
+ ctn[Type.bool, ep, env]
184
+ end
185
+ end
186
+
187
+ def object_module_eval(recv, mid, aargs, ep, env, scratch, &ctn)
188
+ if aargs.lead_tys.size >= 1
189
+ scratch.warn(ep, "class_eval with arguments is ignored")
190
+ ctn[Type.any, ep, env]
191
+ return
192
+ end
193
+ naargs = ActualArguments.new([recv], nil, {}, Type.nil)
194
+ nrecv = recv
195
+ nrecv = nrecv.base_type if nrecv.is_a?(Type::ContainerType)
196
+ ncref = ep.ctx.cref.extend(nrecv, true)
197
+ scratch.do_invoke_block(aargs.blk_ty, naargs, ep, env, replace_recv_ty: nrecv, replace_cref: ncref) do |_ret_ty, ep|
162
198
  ctn[recv, ep, env]
163
199
  end
164
200
  end
165
201
 
202
+ def object_enum_for(recv, mid, aargs, ep, env, scratch, &ctn)
203
+ if aargs.lead_tys.size >= 1
204
+ mid_ty, = aargs.lead_tys
205
+ naargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
206
+ elsif aargs.rest_ty
207
+ mid_ty = aargs.rest_ty
208
+ naargs = aargs
209
+ else
210
+ mid_ty = Type::Symbol.new(:each, Type::Instance.new(Type::Builtin[:sym]))
211
+ naargs = aargs
212
+ end
213
+
214
+ elem_ty = Type.bot
215
+ enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &blk_ctn|
216
+ if aargs.lead_tys.size >= 1
217
+ elem_ty = elem_ty.union(aargs.lead_tys[0])
218
+ else
219
+ elem_ty = elem_ty.union(Type.any)
220
+ end
221
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
222
+ blk_ctn[Type.any, caller_ep, caller_env]
223
+ end
224
+ enum_for_blk_ty = Type::Proc.new(enum_for_blk, Type::Instance.new(Type::Builtin[:proc]))
225
+
226
+ naargs = ActualArguments.new(naargs.lead_tys, naargs.rest_ty, naargs.kw_tys, enum_for_blk_ty)
227
+ mid_ty.each_child do |mid|
228
+ if mid.is_a?(Type::Symbol)
229
+ mid = mid.sym
230
+ scratch.do_send(recv, mid, naargs, ep, env) do |_ret_ty, _ep|
231
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ def object_privitive_method(recv, mid, aargs, ep, env, scratch, &ctn)
238
+ ctn[Type::Symbol.new(ep.ctx.mid, Type::Instance.new(Type::Builtin[:sym])), ep, env]
239
+ end
240
+
241
+ def object_block_given?(recv, mid, aargs, ep, env, scratch, &ctn)
242
+ procs = Type.bot
243
+ no_proc = false
244
+ env.static_env.blk_ty.each_child do |blk_ty|
245
+ case blk_ty
246
+ when Type::Proc
247
+ procs = procs.union(blk_ty)
248
+ when Type.nil
249
+ no_proc = true
250
+ else
251
+ ctn[Type.bool, ep, env]
252
+ end
253
+ end
254
+ if procs != Type.bot
255
+ ctn[Type::Instance.new(Type::Builtin[:true]), ep, env.replace_blk_ty(procs)]
256
+ end
257
+ if no_proc
258
+ ctn[Type::Instance.new(Type::Builtin[:false]), ep, env.replace_blk_ty(Type.nil)]
259
+ end
260
+ end
261
+
166
262
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
167
263
  if aargs.lead_tys.size != 1
168
264
  scratch.warn(ep, "Module#include without an argument is ignored")
@@ -175,10 +271,13 @@ module TypeProf
175
271
  return ctn[Type.any, ep, env]
176
272
  end
177
273
 
274
+ # support multiple arguments: include M1, M2
178
275
  arg = aargs.lead_tys[0]
179
276
  arg.each_child do |arg|
180
277
  if arg.is_a?(Type::Class)
181
- scratch.include_module(recv, arg, nil, false, ep)
278
+ aargs = ActualArguments.new([recv], nil, {}, Type.nil)
279
+ scratch.do_send(arg, :included, aargs, ep, env) {|_ret_ty, _ep| }
280
+ scratch.mix_module(:after, recv, arg, nil, ep.ctx.cref.singleton, ep)
182
281
  end
183
282
  end
184
283
  ctn[recv, ep, env]
@@ -199,7 +298,31 @@ module TypeProf
199
298
  arg = aargs.lead_tys[0]
200
299
  arg.each_child do |arg|
201
300
  if arg.is_a?(Type::Class)
202
- scratch.include_module(recv, arg, nil, true, ep)
301
+ aargs = ActualArguments.new([recv], nil, {}, Type.nil)
302
+ scratch.do_send(arg, :extended, aargs, ep, env) {|_ret_ty, _ep| }
303
+ # if ep.ctx.cref.singleton is true, the meta-meta level is ignored. Should we warn?
304
+ scratch.mix_module(:after, recv, arg, nil, true, ep)
305
+ end
306
+ end
307
+ ctn[recv, ep, env]
308
+ end
309
+
310
+ def module_prepend(recv, mid, aargs, ep, env, scratch, &ctn)
311
+ if aargs.lead_tys.size != 1
312
+ scratch.warn(ep, "Module#prepend without an argument is ignored")
313
+ ctn[Type.any, ep, env]
314
+ return
315
+ end
316
+
317
+ unless recv.is_a?(Type::Class)
318
+ # XXX: warn?
319
+ return ctn[Type.any, ep, env]
320
+ end
321
+
322
+ arg = aargs.lead_tys[0]
323
+ arg.each_child do |arg|
324
+ if arg.is_a?(Type::Class)
325
+ scratch.mix_module(:before, recv, arg, nil, ep.ctx.cref.singleton, ep)
203
326
  end
204
327
  end
205
328
  ctn[recv, ep, env]
@@ -268,23 +391,25 @@ module TypeProf
268
391
  end
269
392
 
270
393
  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)
394
+ mid.each_child do |mid|
395
+ if mid.is_a?(Type::Symbol)
396
+ mid = mid.sym
397
+ aargs.blk_ty.each_child do |blk_ty|
398
+ if blk_ty.is_a?(Type::Proc)
399
+ blk = blk_ty.block_body
400
+ case blk
401
+ when ISeqBlock
402
+ scratch.do_define_iseq_method(ep, env, mid, blk.iseq, blk.outer_ep)
403
+ else
404
+ # XXX: what to do?
405
+ end
279
406
  else
280
407
  # XXX: what to do?
281
408
  end
282
- else
283
- # XXX: what to do?
284
409
  end
410
+ else
411
+ # XXX: what to do?
285
412
  end
286
- else
287
- # XXX: what to do?
288
413
  end
289
414
  ctn[Type.any, ep, env]
290
415
  end
@@ -293,7 +418,7 @@ module TypeProf
293
418
  aargs.lead_tys.each do |aarg|
294
419
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
295
420
  cref = ep.ctx.cref
296
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :accessor)
421
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :accessor, env.static_env.pub_meth, ep)
297
422
  end
298
423
  ctn[Type.nil, ep, env]
299
424
  end
@@ -302,7 +427,7 @@ module TypeProf
302
427
  aargs.lead_tys.each do |aarg|
303
428
  sym = get_sym("attr_reader", aarg, ep, scratch) or next
304
429
  cref = ep.ctx.cref
305
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :reader)
430
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :reader, env.static_env.pub_meth, ep)
306
431
  end
307
432
  ctn[Type.nil, ep, env]
308
433
  end
@@ -311,7 +436,7 @@ module TypeProf
311
436
  aargs.lead_tys.each do |aarg|
312
437
  sym = get_sym("attr_writer", aarg, ep, scratch) or next
313
438
  cref = ep.ctx.cref
314
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :writer)
439
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :writer, env.static_env.pub_meth, ep)
315
440
  end
316
441
  ctn[Type.nil, ep, env]
317
442
  end
@@ -444,43 +569,55 @@ module TypeProf
444
569
  ctn[Type.any, ep, env]
445
570
  return
446
571
  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)
572
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_keyword_init, ep) do |keyword_init, ep|
573
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |member_ary_ty, ep|
574
+ next if member_ary_ty == Type.nil
575
+ if keyword_init == Type::Instance.new(Type::Builtin[:true])
576
+ # TODO: support kw_rest_ty
577
+ aargs.kw_tys.each do |key, val_ty|
578
+ found = false
579
+ member_ary_ty.elems.lead_tys.each do |sym|
580
+ if sym.sym == key
581
+ found = true
582
+ scratch.set_instance_variable(recv, sym.sym, val_ty, ep, env)
583
+ end
584
+ end
585
+ unless found
586
+ # TODO: what to do when not found?
587
+ end
588
+ end
589
+ else
590
+ member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
591
+ ty ||= Type.nil
592
+ scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
593
+ end
594
+ end
452
595
  end
453
596
  end
454
597
  ctn[recv, ep, env]
455
598
  end
456
599
 
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]
600
+ def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
601
+ keyword_init = false
602
+ if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
603
+ if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
604
+ keyword_init = true
465
605
  end
466
606
  end
467
- end
468
-
469
- def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
470
- # TODO: keyword_init
471
607
 
472
608
  fields = aargs.lead_tys.map {|ty| get_sym("Struct.new", ty, ep, scratch) }.compact
473
609
  struct_klass = scratch.new_struct(ep)
474
610
 
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))
611
+ scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:object_s_new))
612
+ scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:object_s_new))
477
613
  fields.each do |field|
478
- scratch.add_attr_method(struct_klass, ep.ctx.iseq.absolute_path, field, field, :accessor)
614
+ scratch.add_attr_method(struct_klass, field, field, :accessor, true, ep)
479
615
  end
480
616
  fields = fields.map {|field| Type::Symbol.new(field, Type::Instance.new(Type::Builtin[:sym])) }
481
617
  base_ty = Type::Instance.new(Type::Builtin[:ary])
482
618
  fields = Type::Array.new(Type::Array::Elements.new(fields), base_ty)
483
619
  scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_members, fields, ep)
620
+ scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_keyword_init, Type::Instance.new(Type::Builtin[:true]), ep) if keyword_init
484
621
  #set_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
485
622
 
486
623
  ctn[struct_klass, ep, env]
@@ -654,25 +791,26 @@ module TypeProf
654
791
 
655
792
  Import.import_builtin(scratch)
656
793
 
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)
794
+ Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
795
+ Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
796
+ Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
797
+ Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
798
+ Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
799
+ Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
800
+ Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
801
+ Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
802
+ Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
803
+ Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
804
+ Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
805
+ Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
806
+ Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
807
+ Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
808
+ Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
809
+ Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
810
+ Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
811
+ Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
812
+ Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
813
+ Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
676
814
 
677
815
  klass_vmcore = Type::Builtin[:vmcore]
678
816
  klass_ary = Type::Builtin[:ary]
@@ -687,23 +825,32 @@ module TypeProf
687
825
  scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
688
826
  scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
689
827
  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))
828
+ scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p), false)
691
829
  scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
692
830
  scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
693
831
  scratch.set_custom_method(klass_obj, :class, Builtin.method(:object_class))
694
832
  scratch.set_custom_method(klass_obj, :send, Builtin.method(:object_send))
695
833
  scratch.set_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
696
- scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda))
834
+ scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda), false)
835
+ scratch.set_custom_method(klass_obj, :__method__, Builtin.method(:object_privitive_method), false)
836
+ scratch.set_custom_method(klass_obj, :block_given?, Builtin.method(:object_block_given?), false)
837
+
838
+ scratch.set_custom_method(klass_obj, :enum_for, Builtin.method(:object_enum_for))
839
+ scratch.set_custom_method(klass_obj, :to_enum, Builtin.method(:object_enum_for))
697
840
 
698
841
  scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
699
842
  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))
843
+ scratch.set_custom_method(klass_module, :prepend, Builtin.method(:module_prepend))
844
+ scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function), false)
845
+ scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public), false)
846
+ scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private), false)
703
847
  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))
848
+ scratch.set_custom_method(klass_module, :attr_accessor, Builtin.method(:module_attr_accessor))
849
+ scratch.set_custom_method(klass_module, :attr_reader, Builtin.method(:module_attr_reader))
850
+ scratch.set_custom_method(klass_module, :attr_writer, Builtin.method(:module_attr_writer))
851
+ scratch.set_custom_method(klass_module, :class_eval, Builtin.method(:object_module_eval))
852
+ scratch.set_custom_method(klass_module, :module_eval, Builtin.method(:object_module_eval))
853
+ scratch.set_custom_method(klass_module, :===, Builtin.method(:module_eqq))
707
854
 
708
855
  scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
709
856
  scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
@@ -718,10 +865,10 @@ module TypeProf
718
865
  scratch.set_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
719
866
  scratch.set_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
720
867
 
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))
868
+ scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require), false)
869
+ scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative), false)
870
+ scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array), false)
871
+ scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload), false)
725
872
  scratch.set_custom_method(klass_module, :autoload, Builtin.method(:module_autoload))
726
873
 
727
874
  # remove BasicObject#method_missing