typeprof 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -2
  3. data/lib/typeprof/analyzer.rb +82 -59
  4. data/lib/typeprof/block.rb +34 -0
  5. data/lib/typeprof/builtin.rb +169 -64
  6. data/lib/typeprof/cli.rb +2 -0
  7. data/lib/typeprof/config.rb +13 -1
  8. data/lib/typeprof/export.rb +114 -69
  9. data/lib/typeprof/import.rb +50 -28
  10. data/lib/typeprof/iseq.rb +23 -4
  11. data/lib/typeprof/method.rb +29 -7
  12. data/lib/typeprof/type.rb +41 -13
  13. data/lib/typeprof/version.rb +1 -1
  14. data/smoke/alias.rb +4 -4
  15. data/smoke/alias2.rb +3 -1
  16. data/smoke/arguments.rb +2 -2
  17. data/smoke/arguments2.rb +5 -5
  18. data/smoke/array-each.rb +1 -1
  19. data/smoke/array-each3.rb +1 -1
  20. data/smoke/array-map.rb +1 -1
  21. data/smoke/array-map2.rb +1 -1
  22. data/smoke/array-map3.rb +3 -3
  23. data/smoke/array-mul.rb +2 -2
  24. data/smoke/array-plus1.rb +1 -1
  25. data/smoke/array-plus2.rb +1 -0
  26. data/smoke/array-range-aref.rb +11 -11
  27. data/smoke/array-replace.rb +1 -1
  28. data/smoke/array1.rb +5 -5
  29. data/smoke/array10.rb +1 -1
  30. data/smoke/array11.rb +1 -1
  31. data/smoke/array12.rb +1 -1
  32. data/smoke/array14.rb +1 -1
  33. data/smoke/array15.rb +1 -1
  34. data/smoke/array2.rb +2 -2
  35. data/smoke/array3.rb +1 -0
  36. data/smoke/array6.rb +2 -1
  37. data/smoke/array8.rb +1 -1
  38. data/smoke/array9.rb +1 -1
  39. data/smoke/attr-module.rb +1 -0
  40. data/smoke/attr-vis.rb +43 -0
  41. data/smoke/attr-vis.rbs +4 -0
  42. data/smoke/attr.rb +2 -2
  43. data/smoke/block-ambiguous.rb +4 -4
  44. data/smoke/block-args1-rest.rb +6 -5
  45. data/smoke/block-args1.rb +5 -5
  46. data/smoke/block-args2-rest.rb +6 -5
  47. data/smoke/block-args2.rb +5 -5
  48. data/smoke/block-args3-rest.rb +7 -6
  49. data/smoke/block-args3.rb +6 -6
  50. data/smoke/block-blockarg.rb +3 -3
  51. data/smoke/block-kwarg.rb +4 -4
  52. data/smoke/block1.rb +1 -1
  53. data/smoke/block10.rb +1 -1
  54. data/smoke/block11.rb +2 -2
  55. data/smoke/block2.rb +1 -1
  56. data/smoke/block3.rb +1 -1
  57. data/smoke/block5.rb +1 -0
  58. data/smoke/block_given.rb +37 -0
  59. data/smoke/class_method.rb +2 -2
  60. data/smoke/class_method2.rb +2 -2
  61. data/smoke/constant2.rb +3 -2
  62. data/smoke/context-sensitive1.rb +1 -1
  63. data/smoke/cvar.rb +3 -2
  64. data/smoke/define_method.rb +2 -2
  65. data/smoke/define_method3.rb +1 -0
  66. data/smoke/define_method4.rb +1 -1
  67. data/smoke/define_method6.rb +19 -0
  68. data/smoke/demo.rb +6 -6
  69. data/smoke/demo1.rb +1 -1
  70. data/smoke/demo11.rb +1 -1
  71. data/smoke/demo2.rb +1 -1
  72. data/smoke/demo3.rb +1 -1
  73. data/smoke/demo4.rb +3 -3
  74. data/smoke/demo5.rb +1 -1
  75. data/smoke/demo6.rb +2 -1
  76. data/smoke/demo7.rb +1 -1
  77. data/smoke/demo9.rb +1 -0
  78. data/smoke/dummy-execution1.rb +1 -1
  79. data/smoke/dummy-execution2.rb +1 -1
  80. data/smoke/dummy_element.rb +1 -1
  81. data/smoke/ensure1.rb +1 -1
  82. data/smoke/enum_for.rb +15 -0
  83. data/smoke/enum_for2.rb +17 -0
  84. data/smoke/fib.rb +2 -2
  85. data/smoke/flow1.rb +1 -1
  86. data/smoke/flow10.rb +17 -0
  87. data/smoke/flow2.rb +1 -1
  88. data/smoke/flow3.rb +1 -1
  89. data/smoke/flow5.rb +1 -1
  90. data/smoke/flow6.rb +1 -1
  91. data/smoke/flow7.rb +1 -1
  92. data/smoke/flow8.rb +1 -1
  93. data/smoke/flow9.rb +1 -1
  94. data/smoke/function.rb +1 -1
  95. data/smoke/gvar.rb +1 -1
  96. data/smoke/gvar2.rb +1 -1
  97. data/smoke/hash-fetch.rb +3 -3
  98. data/smoke/inheritance.rb +4 -4
  99. data/smoke/initialize.rb +3 -2
  100. data/smoke/instance_eval.rb +1 -1
  101. data/smoke/int_times.rb +1 -1
  102. data/smoke/integer.rb +1 -1
  103. data/smoke/ivar.rb +3 -2
  104. data/smoke/ivar2.rb +2 -2
  105. data/smoke/ivar3.rb +2 -1
  106. data/smoke/ivar4.rb +1 -0
  107. data/smoke/kernel-class.rb +1 -1
  108. data/smoke/keyword4.rb +1 -1
  109. data/smoke/kwrest.rb +1 -0
  110. data/smoke/kwsplat1.rb +2 -2
  111. data/smoke/kwsplat2.rb +1 -1
  112. data/smoke/manual-rbs.rb +1 -0
  113. data/smoke/manual-rbs3.rb +1 -0
  114. data/smoke/method_missing.rb +4 -3
  115. data/smoke/module3.rb +1 -1
  116. data/smoke/module4.rb +1 -0
  117. data/smoke/module5.rb +1 -1
  118. data/smoke/module_function1.rb +3 -2
  119. data/smoke/module_function2.rb +3 -2
  120. data/smoke/multiple-include.rb +1 -0
  121. data/smoke/next1.rb +1 -1
  122. data/smoke/object-send1.rb +3 -3
  123. data/smoke/optional1.rb +1 -1
  124. data/smoke/optional2.rb +1 -1
  125. data/smoke/optional3.rb +1 -1
  126. data/smoke/parameterizedd-self.rb +2 -1
  127. data/smoke/prepend1.rb +33 -0
  128. data/smoke/prepend2.rb +10 -0
  129. data/smoke/prepend2.rbs +9 -0
  130. data/smoke/primitive_method.rb +19 -0
  131. data/smoke/proc4.rb +1 -1
  132. data/smoke/public.rb +4 -0
  133. data/smoke/range.rb +1 -1
  134. data/smoke/rbs-attr.rb +2 -2
  135. data/smoke/rbs-proc2.rb +1 -1
  136. data/smoke/rbs-proc3.rb +1 -1
  137. data/smoke/rbs-tyvar4.rb +3 -2
  138. data/smoke/rbs-tyvar6.rb +3 -3
  139. data/smoke/redo1.rb +1 -1
  140. data/smoke/redo2.rb +1 -1
  141. data/smoke/rescue1.rb +1 -1
  142. data/smoke/rescue2.rb +1 -1
  143. data/smoke/rescue3.rb +1 -0
  144. data/smoke/rescue4.rb +1 -1
  145. data/smoke/respond_to.rb +1 -1
  146. data/smoke/rest1.rb +2 -2
  147. data/smoke/rest2.rb +1 -1
  148. data/smoke/rest3.rb +6 -6
  149. data/smoke/rest4.rb +2 -2
  150. data/smoke/rest5.rb +1 -1
  151. data/smoke/rest6.rb +1 -1
  152. data/smoke/retry1.rb +2 -2
  153. data/smoke/simple.rb +1 -1
  154. data/smoke/step.rb +3 -3
  155. data/smoke/struct-keyword_init.rb +5 -15
  156. data/smoke/struct5.rb +1 -1
  157. data/smoke/struct6.rb +1 -1
  158. data/smoke/super1.rb +4 -4
  159. data/smoke/super3.rb +3 -2
  160. data/smoke/super4.rb +7 -5
  161. data/smoke/super5.rb +6 -4
  162. data/smoke/symbol-proc-attr.rb +1 -1
  163. data/smoke/tap1.rb +2 -2
  164. data/smoke/toplevel.rb +1 -1
  165. data/smoke/type_var.rb +3 -3
  166. data/smoke/user-demo.rb +1 -1
  167. data/smoke/wrong-extend.rb +1 -0
  168. data/smoke/wrong-include.rb +1 -0
  169. data/smoke/wrong-include2.rb +1 -1
  170. metadata +14 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93a881a8e59226faae21acac435131d5961c85ab6c95192ae1261329a87fb6e1
4
- data.tar.gz: 8165e47acb1e8d9770922b2ac10487d18ff1b4fd1efa5d4ab8f6f0b11aa15433
3
+ metadata.gz: 8d68099e4f5d60a45f949d6bfc3a47e8b7d3b7ba66a0794f25f5fe61628de1d1
4
+ data.tar.gz: 22792d1acb9b16a4150f1afbaf29d59987bf29772908b23075e6668df81a4309
5
5
  SHA512:
6
- metadata.gz: 43d0bc36fa68827aed7026cc7a52ca37b49d2c042bbaa32bffc9773afad296b81e27b5b4f97b31f24ff4030269f215034568175cae2c4a14bdc4bad8b502172f
7
- data.tar.gz: 898d79a93ceae32f71b1c0fe0b9f2aa6a90477fbee58a582da91fe5e6f4e521062cb99549f8ae709d1f26f854a4b2765cdd455282fcdfa0ab9918c9015647ec9
6
+ metadata.gz: 42faa4e3b5c64fd5976e66067bf13339c530785914caad77bc0a405939bc914e9adf78bfbd0aea57a829cb21aed3c6dfc09f8f57def85b09312facd82d33b5a9
7
+ data.tar.gz: bc6f115fbf1d5292286f04f09d745cfb0c13688a71fdae730d0cfdd903ad8f9f3f9019e532c37b4cf23fe41f39c9a1683f92f28af68716ddf7e625a0efca33f8
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- typeprof (0.9.2)
4
+ typeprof (0.10.0)
5
5
  rbs (>= 0.20.1)
6
6
 
7
7
  GEM
@@ -24,6 +24,7 @@ GEM
24
24
 
25
25
  PLATFORMS
26
26
  ruby
27
+ x86_64-linux
27
28
 
28
29
  DEPENDENCIES
29
30
  coverage-helpers
@@ -35,4 +36,4 @@ DEPENDENCIES
35
36
  typeprof!
36
37
 
37
38
  BUNDLED WITH
38
- 2.2.0.rc.1
39
+ 2.2.1
@@ -117,30 +117,6 @@ module TypeProf
117
117
  end
118
118
  end
119
119
 
120
- class TopStaticEnv
121
- include Utils::StructuralEquality
122
-
123
- def recv_ty
124
- Type.bot
125
- end
126
-
127
- def blk_ty
128
- Type.nil
129
- end
130
-
131
- def mod_func
132
- false
133
- end
134
-
135
- def pub_meth
136
- true
137
- end
138
-
139
- def merge(other)
140
- raise unless other.is_a?(TopStaticEnv)
141
- end
142
- end
143
-
144
120
  class Env
145
121
  include Utils::StructuralEquality
146
122
 
@@ -246,6 +222,11 @@ module TypeProf
246
222
  Env.new(senv, @locals, @stack, @type_params)
247
223
  end
248
224
 
225
+ def replace_blk_ty(ty)
226
+ senv = StaticEnv.new(@static_env.recv_ty, ty, @static_env.mod_func, @static_env.pub_meth)
227
+ Env.new(senv, @locals, @stack, @type_params)
228
+ end
229
+
249
230
  def inspect
250
231
  "Env[#{ @static_env.inspect }, locals:#{ @locals.inspect }, stack:#{ @stack.inspect }, type_params:#{ (@type_params&.internal_hash).inspect }]"
251
232
  end
@@ -319,7 +300,10 @@ module TypeProf
319
300
  def initialize(kind, name, absolute_path)
320
301
  raise unless name.is_a?(Array)
321
302
  @kind = kind
322
- @modules = { true => [], false => [] }
303
+ @modules = {
304
+ :before => { true => [], false => [] }, # before = include/extend
305
+ :after => { true => [], false => [] }, # after = prepend
306
+ }
323
307
  @name = name
324
308
  @consts = {}
325
309
  @methods = {}
@@ -332,13 +316,13 @@ module TypeProf
332
316
  attr_reader :kind, :modules, :consts, :methods, :ivars, :cvars, :absolute_path
333
317
  attr_accessor :name, :klass_obj
334
318
 
335
- def include_module(mod, type_args, singleton, absolute_path)
336
- mod_, module_type_args, absolute_paths = @modules[singleton].find {|m,| m == mod }
319
+ def mix_module(kind, mod, type_args, singleton, absolute_path)
320
+ mod_, module_type_args, absolute_paths = @modules[kind][singleton].find {|m,| m == mod }
337
321
  if mod_
338
- raise "inconsistent include/extend type args in RBS?" if module_type_args != type_args && type_args != [] && type_args != nil
322
+ raise "inconsistent #{ kind == :after ? "include/extend" : "prepend" } type args in RBS?" if module_type_args != type_args && type_args != [] && type_args != nil
339
323
  else
340
324
  absolute_paths = Utils::MutableSet.new
341
- @modules[singleton].unshift([mod, type_args, absolute_paths])
325
+ @modules[kind][singleton].unshift([mod, type_args, absolute_paths])
342
326
  end
343
327
  absolute_paths << absolute_path
344
328
  end
@@ -355,10 +339,8 @@ module TypeProf
355
339
  @consts[name] = [ty, absolute_path]
356
340
  end
357
341
 
358
- def adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
359
- mthds = @methods[[singleton, mid]]
360
- yield subst, direct if mthds&.include?(mthd)
361
- @modules[singleton].each do |mod_def, type_args,|
342
+ def adjust_substitution_for_module(mods, mid, mthd, subst, &blk)
343
+ mods.each do |mod_def, type_args,|
362
344
  if mod_def.klass_obj.type_params && type_args
363
345
  subst2 = {}
364
346
  mod_def.klass_obj.type_params.zip(type_args) do |(tyvar, *), tyarg|
@@ -370,13 +352,28 @@ module TypeProf
370
352
  end
371
353
  end
372
354
 
355
+ def adjust_substitution(singleton, mid, mthd, subst, direct, &blk)
356
+ adjust_substitution_for_module(@modules[:before][singleton], mid, mthd, subst, &blk)
357
+
358
+ mthds = @methods[[singleton, mid]]
359
+ yield subst, direct if mthds&.include?(mthd)
360
+
361
+ adjust_substitution_for_module(@modules[:after][singleton], mid, mthd, subst, &blk)
362
+ end
363
+
373
364
  def search_method(singleton, mid, visited, &blk)
374
365
  # Currently, circular inclusion of modules is allowed
375
366
  return if visited[self]
376
367
  visited[self] = true
368
+
369
+ @modules[:before][singleton].each do |mod_def,|
370
+ mod_def.search_method(false, mid, visited, &blk)
371
+ end
372
+
377
373
  mthds = @methods[[singleton, mid]]
378
374
  yield mthds, @klass_obj, singleton if mthds
379
- @modules[singleton].each do |mod_def,|
375
+
376
+ @modules[:after][singleton].each do |mod_def,|
380
377
  mod_def.search_method(false, mid, visited, &blk)
381
378
  end
382
379
  end
@@ -405,17 +402,17 @@ module TypeProf
405
402
  end
406
403
  end
407
404
 
408
- def include_module(including_mod, included_mod, type_args, singleton, caller_ep)
409
- return if included_mod == Type.any
405
+ def mix_module(kind, mixing_mod, mixed_mod, type_args, singleton, caller_ep)
406
+ return if mixed_mod == Type.any
410
407
 
411
- including_mod = @class_defs[including_mod.idx]
412
- included_mod.each_child do |included_mod|
413
- if included_mod.is_a?(Type::Class)
414
- included_mod = @class_defs[included_mod.idx]
415
- if included_mod && included_mod.kind == :module
416
- including_mod.include_module(included_mod, type_args, singleton, caller_ep ? caller_ep.ctx.iseq.absolute_path : nil)
408
+ mixing_mod = @class_defs[mixing_mod.idx]
409
+ mixed_mod.each_child do |mixed_mod|
410
+ if mixed_mod.is_a?(Type::Class)
411
+ mixed_mod = @class_defs[mixed_mod.idx]
412
+ if mixed_mod && mixed_mod.kind == :module
413
+ mixing_mod.mix_module(kind, mixed_mod, type_args, singleton, caller_ep ? caller_ep.ctx.iseq.absolute_path : nil)
417
414
  else
418
- warn(caller_ep, "including something that is not a module")
415
+ warn(caller_ep, "attempted to #{ kind == :after ? "include/extend" : "prepend" } non-module; ignored")
419
416
  end
420
417
  end
421
418
  end
@@ -602,12 +599,12 @@ module TypeProf
602
599
  mdef
603
600
  end
604
601
 
605
- def add_attr_method(klass, absolute_path, mid, ivar, kind)
602
+ def add_attr_method(klass, mid, ivar, kind, pub_meth, ep)
606
603
  if kind == :reader || kind == :accessor
607
- add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader, absolute_path))
604
+ add_method(klass, mid, false, AttrMethodDef.new(ivar, :reader, pub_meth, ep))
608
605
  end
609
606
  if kind == :writer || kind == :accessor
610
- add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer, absolute_path))
607
+ add_method(klass, :"#{ mid }=", false, AttrMethodDef.new(ivar, :writer, pub_meth, ep))
611
608
  end
612
609
  end
613
610
 
@@ -619,22 +616,22 @@ module TypeProf
619
616
  add_method(klass, mid, true, ISeqMethodDef.new(iseq, cref, outer_ep, pub_meth))
620
617
  end
621
618
 
622
- def set_custom_method(klass, mid, impl)
623
- set_method(klass, mid, false, CustomMethodDef.new(impl))
619
+ def set_custom_method(klass, mid, impl, pub_meth = true)
620
+ set_method(klass, mid, false, CustomMethodDef.new(impl, pub_meth))
624
621
  end
625
622
 
626
- def set_singleton_custom_method(klass, mid, impl)
627
- set_method(klass, mid, true, CustomMethodDef.new(impl))
623
+ def set_singleton_custom_method(klass, mid, impl, pub_meth = true)
624
+ set_method(klass, mid, true, CustomMethodDef.new(impl, pub_meth))
628
625
  end
629
626
 
630
- def alias_method(klass, singleton, new, old)
627
+ def alias_method(klass, singleton, alias_mid, orig_mid, ep)
631
628
  if klass == Type.any
632
629
  self
633
630
  else
634
- mdefs = get_method(klass, singleton, old)
631
+ mdefs = get_method(klass, singleton, orig_mid)
635
632
  if mdefs
636
633
  mdefs.each do |mdef|
637
- @class_defs[klass.idx].add_method(new, singleton, mdef)
634
+ @class_defs[klass.idx].add_method(alias_mid, singleton, AliasMethodDef.new(orig_mid, mdef, ep))
638
635
  end
639
636
  end
640
637
  end
@@ -723,7 +720,7 @@ module TypeProf
723
720
  if ep
724
721
  if entry.rbs_declared
725
722
  unless Type.match?(ty, entry.type)
726
- scratch.warn(ep, "inconsistent assignment to RBS-declared global variable")
723
+ scratch.warn(ep, "inconsistent assignment to RBS-declared variable")
727
724
  return
728
725
  end
729
726
  end
@@ -1076,7 +1073,7 @@ module TypeProf
1076
1073
  lead_tys = env.locals[0, lead_num].map {|ty| globalize_type(ty, env, ep) }
1077
1074
  opt_tys = opt.size > 1 ? env.locals[lead_num, opt.size - 1].map {|ty| globalize_type(ty, env, ep) } : []
1078
1075
  if rest_start # XXX:squash
1079
- ty = globalize_type(env.locals[lead_num + opt.size - 1], env, ep)
1076
+ ty = globalize_type(env.locals[rest_start], env, ep)
1080
1077
  rest_ty = Type.bot
1081
1078
  ty.each_child_global do |ty|
1082
1079
  if ty.is_a?(Type::Array)
@@ -1111,6 +1108,7 @@ module TypeProf
1111
1108
  end
1112
1109
  end
1113
1110
  kw_rest_ty = globalize_type(env.locals[kw_rest], env, ep) if kw_rest
1111
+ kw_rest_ty = nil if kw_rest_ty == Type.nil
1114
1112
  if block_start
1115
1113
  blk_ty = globalize_type(env.locals[block_start], env, ep)
1116
1114
  elsif iseq.type == :method
@@ -1290,7 +1288,7 @@ module TypeProf
1290
1288
  end
1291
1289
  end
1292
1290
  return
1293
- when :send_branch
1291
+ when :getlocal_send_branch
1294
1292
  getlocal_operands, send_operands, branch_operands = operands
1295
1293
  env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
1296
1294
  recvs = Type.any if recvs == Type.bot
@@ -1318,6 +1316,31 @@ module TypeProf
1318
1316
  end
1319
1317
  end
1320
1318
  return
1319
+ when :send_branch
1320
+ send_operands, branch_operands = operands
1321
+ env, recvs, mid, aargs = setup_actual_arguments(:method, send_operands, ep, env)
1322
+ recvs = Type.any if recvs == Type.bot
1323
+ recvs.each_child do |recv|
1324
+ do_send(recv, mid, aargs, ep, env) do |ret_ty, ep, env|
1325
+ env, ret_ty, = localize_type(ret_ty, env, ep)
1326
+
1327
+ branchtype, target, = branch_operands
1328
+ # branchtype: :if or :unless or :nil
1329
+ ep_then = ep.next
1330
+ ep_else = ep.jump(target)
1331
+
1332
+ case ret_ty
1333
+ when Type::Instance.new(Type::Builtin[:true])
1334
+ merge_env(branchtype == :if ? ep_else : ep_then, env)
1335
+ when Type::Instance.new(Type::Builtin[:false])
1336
+ merge_env(branchtype == :if ? ep_then : ep_else, env)
1337
+ else
1338
+ merge_env(ep_then, env)
1339
+ merge_env(ep_else, env)
1340
+ end
1341
+ end
1342
+ end
1343
+ return
1321
1344
  when :invokeblock
1322
1345
  env, recvs, mid, aargs = setup_actual_arguments(:block, operands, ep, env)
1323
1346
  blk = env.static_env.blk_ty
@@ -2130,7 +2153,7 @@ module TypeProf
2130
2153
 
2131
2154
  bsig ||= BlockSignature.new([], [], nil, Type.nil)
2132
2155
 
2133
- bsig = bsig.screen_name(self)#, block: true)
2156
+ bsig = bsig.screen_name(nil, self)
2134
2157
  ret_ty = ret_ty.screen_name(self)
2135
2158
  ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
2136
2159
 
@@ -2157,7 +2180,7 @@ module TypeProf
2157
2180
  end
2158
2181
  end
2159
2182
 
2160
- farg_tys = farg_tys ? farg_tys.screen_name(self) : "(unknown)"
2183
+ farg_tys = farg_tys ? farg_tys.screen_name(nil, self) : "(unknown)"
2161
2184
  ret_ty = ret_ty.screen_name(self)
2162
2185
  ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
2163
2186
 
@@ -2169,7 +2192,7 @@ module TypeProf
2169
2192
  farg_tys = @method_signatures[ctx]
2170
2193
  ret_ty = @return_values[ctx] || Type.bot
2171
2194
 
2172
- farg_tys = farg_tys.screen_name(self)
2195
+ farg_tys = farg_tys.screen_name(ctx.iseq, self)
2173
2196
  ret_ty = ret_ty.screen_name(self)
2174
2197
  ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
2175
2198
  "#{ (farg_tys.empty? ? "" : "#{ farg_tys } ") }-> #{ ret_ty }"
@@ -137,4 +137,38 @@ module TypeProf
137
137
  end
138
138
  end
139
139
  end
140
+
141
+ class CustomBlock < Block
142
+ def initialize(caller_ep, mid, &blk)
143
+ @caller_ep = caller_ep
144
+ @mid = mid
145
+ @blk = blk
146
+ end
147
+
148
+ def inspect
149
+ "#<CustomBlock>"
150
+ end
151
+
152
+ def consistent?(other)
153
+ true # XXX
154
+ end
155
+
156
+ def substitute(_subst, _depth)
157
+ self
158
+ end
159
+
160
+ def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &ctn)
161
+ aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
162
+
163
+ dummy_ctx = TypedContext.new(@caller_ep, @mid)
164
+
165
+ scratch.add_block_signature!(self, aargs.to_block_signature)
166
+ scratch.add_block_to_ctx!(self, dummy_ctx)
167
+
168
+ @blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty) do |ret_ty, ep, env|
169
+ scratch.add_return_value!(dummy_ctx, ret_ty)
170
+ ctn[ret_ty, ep, env]
171
+ end
172
+ end
173
+ end
140
174
  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
 
@@ -163,6 +163,66 @@ module TypeProf
163
163
  end
164
164
  end
165
165
 
166
+ def object_enum_for(recv, mid, aargs, ep, env, scratch, &ctn)
167
+ if aargs.lead_tys.size >= 1
168
+ mid_ty, = aargs.lead_tys
169
+ naargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
170
+ elsif aargs.rest_ty
171
+ mid_ty = aargs.rest_ty
172
+ naargs = aargs
173
+ else
174
+ mid_ty = Type::Symbol.new(:each, Type::Instance.new(Type::Builtin[:sym]))
175
+ naargs = aargs
176
+ end
177
+
178
+ elem_ty = Type.bot
179
+ enum_for_blk = CustomBlock.new(ep, mid) do |aargs, caller_ep, caller_env, scratch, replace_recv_ty:, &blk_ctn|
180
+ if aargs.lead_tys.size >= 1
181
+ elem_ty = elem_ty.union(aargs.lead_tys[0])
182
+ else
183
+ elem_ty = elem_ty.union(Type.any)
184
+ end
185
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
186
+ blk_ctn[Type.any, caller_ep, caller_env]
187
+ end
188
+ enum_for_blk_ty = Type::Proc.new(enum_for_blk, Type::Instance.new(Type::Builtin[:proc]))
189
+
190
+ naargs = ActualArguments.new(naargs.lead_tys, naargs.rest_ty, naargs.kw_tys, enum_for_blk_ty)
191
+ mid_ty.each_child do |mid|
192
+ if mid.is_a?(Type::Symbol)
193
+ mid = mid.sym
194
+ scratch.do_send(recv, mid, naargs, ep, env) do |_ret_ty, _ep|
195
+ ctn[Type::Cell.new(Type::Cell::Elements.new([elem_ty, Type.any]), Type::Instance.new(Type::Builtin[:enumerator])), ep, env]
196
+ end
197
+ end
198
+ end
199
+ end
200
+
201
+ def object_privitive_method(recv, mid, aargs, ep, env, scratch, &ctn)
202
+ ctn[Type::Symbol.new(ep.ctx.mid, Type::Instance.new(Type::Builtin[:sym])), ep, env]
203
+ end
204
+
205
+ def object_block_given?(recv, mid, aargs, ep, env, scratch, &ctn)
206
+ procs = Type.bot
207
+ no_proc = false
208
+ env.static_env.blk_ty.each_child do |blk_ty|
209
+ case blk_ty
210
+ when Type::Proc
211
+ procs = procs.union(blk_ty)
212
+ when Type.nil
213
+ no_proc = true
214
+ else
215
+ ctn[Type.bool, ep, env]
216
+ end
217
+ end
218
+ if procs != Type.bot
219
+ ctn[Type::Instance.new(Type::Builtin[:true]), ep, env.replace_blk_ty(procs)]
220
+ end
221
+ if no_proc
222
+ ctn[Type::Instance.new(Type::Builtin[:false]), ep, env.replace_blk_ty(Type.nil)]
223
+ end
224
+ end
225
+
166
226
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
167
227
  if aargs.lead_tys.size != 1
168
228
  scratch.warn(ep, "Module#include without an argument is ignored")
@@ -178,7 +238,7 @@ module TypeProf
178
238
  arg = aargs.lead_tys[0]
179
239
  arg.each_child do |arg|
180
240
  if arg.is_a?(Type::Class)
181
- scratch.include_module(recv, arg, nil, false, ep)
241
+ scratch.mix_module(:after, recv, arg, nil, ep.ctx.cref.singleton, ep)
182
242
  end
183
243
  end
184
244
  ctn[recv, ep, env]
@@ -199,7 +259,29 @@ module TypeProf
199
259
  arg = aargs.lead_tys[0]
200
260
  arg.each_child do |arg|
201
261
  if arg.is_a?(Type::Class)
202
- scratch.include_module(recv, arg, nil, true, ep)
262
+ # if ep.ctx.cref.singleton is true, the meta-meta level is ignored. Should we warn?
263
+ scratch.mix_module(:after, recv, arg, nil, true, ep)
264
+ end
265
+ end
266
+ ctn[recv, ep, env]
267
+ end
268
+
269
+ def module_prepend(recv, mid, aargs, ep, env, scratch, &ctn)
270
+ if aargs.lead_tys.size != 1
271
+ scratch.warn(ep, "Module#prepend without an argument is ignored")
272
+ ctn[Type.any, ep, env]
273
+ return
274
+ end
275
+
276
+ unless recv.is_a?(Type::Class)
277
+ # XXX: warn?
278
+ return ctn[Type.any, ep, env]
279
+ end
280
+
281
+ arg = aargs.lead_tys[0]
282
+ arg.each_child do |arg|
283
+ if arg.is_a?(Type::Class)
284
+ scratch.mix_module(:before, recv, arg, nil, ep.ctx.cref.singleton, ep)
203
285
  end
204
286
  end
205
287
  ctn[recv, ep, env]
@@ -268,23 +350,25 @@ module TypeProf
268
350
  end
269
351
 
270
352
  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)
353
+ mid.each_child do |mid|
354
+ if mid.is_a?(Type::Symbol)
355
+ mid = mid.sym
356
+ aargs.blk_ty.each_child do |blk_ty|
357
+ if blk_ty.is_a?(Type::Proc)
358
+ blk = blk_ty.block_body
359
+ case blk
360
+ when ISeqBlock
361
+ scratch.do_define_iseq_method(ep, env, mid, blk.iseq, blk.outer_ep)
362
+ else
363
+ # XXX: what to do?
364
+ end
279
365
  else
280
366
  # XXX: what to do?
281
367
  end
282
- else
283
- # XXX: what to do?
284
368
  end
369
+ else
370
+ # XXX: what to do?
285
371
  end
286
- else
287
- # XXX: what to do?
288
372
  end
289
373
  ctn[Type.any, ep, env]
290
374
  end
@@ -293,7 +377,7 @@ module TypeProf
293
377
  aargs.lead_tys.each do |aarg|
294
378
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
295
379
  cref = ep.ctx.cref
296
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :accessor)
380
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :accessor, env.static_env.pub_meth, ep)
297
381
  end
298
382
  ctn[Type.nil, ep, env]
299
383
  end
@@ -302,7 +386,7 @@ module TypeProf
302
386
  aargs.lead_tys.each do |aarg|
303
387
  sym = get_sym("attr_reader", aarg, ep, scratch) or next
304
388
  cref = ep.ctx.cref
305
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :reader)
389
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :reader, env.static_env.pub_meth, ep)
306
390
  end
307
391
  ctn[Type.nil, ep, env]
308
392
  end
@@ -311,7 +395,7 @@ module TypeProf
311
395
  aargs.lead_tys.each do |aarg|
312
396
  sym = get_sym("attr_writer", aarg, ep, scratch) or next
313
397
  cref = ep.ctx.cref
314
- scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :writer)
398
+ scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :writer, env.static_env.pub_meth, ep)
315
399
  end
316
400
  ctn[Type.nil, ep, env]
317
401
  end
@@ -444,43 +528,57 @@ module TypeProf
444
528
  ctn[Type.any, ep, env]
445
529
  return
446
530
  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)
531
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_keyword_init, ep) do |keyword_init, ep|
532
+ scratch.add_ivar_read!(Type::Instance.new(struct_klass), :_members, ep) do |member_ary_ty, ep|
533
+ next if member_ary_ty == Type.nil
534
+ if keyword_init == Type::Instance.new(Type::Builtin[:true])
535
+ # TODO: support kw_rest_ty
536
+ aargs.kw_tys.each do |key, val_ty|
537
+ found = false
538
+ member_ary_ty.elems.lead_tys.each do |sym|
539
+ if sym.sym == key
540
+ found = true
541
+ scratch.set_instance_variable(recv, sym.sym, val_ty, ep, env)
542
+ end
543
+ end
544
+ unless found
545
+ # TODO: what to do when not found?
546
+ end
547
+ end
548
+ else
549
+ member_ary_ty.elems.lead_tys.zip(aargs.lead_tys) do |sym, ty|
550
+ ty ||= Type.nil
551
+ scratch.set_instance_variable(recv, sym.sym, ty, ep, env)
552
+ end
553
+ end
452
554
  end
453
555
  end
454
556
  ctn[recv, ep, env]
455
557
  end
456
558
 
457
- def struct_i_new(recv, mid, aargs, ep, env, scratch, &ctn)
559
+ def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
458
560
  # TODO: keyword_init
459
561
 
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]
562
+ keyword_init = false
563
+ if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
564
+ if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
565
+ keyword_init = true
465
566
  end
466
567
  end
467
- end
468
-
469
- def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
470
- # TODO: keyword_init
471
568
 
472
569
  fields = aargs.lead_tys.map {|ty| get_sym("Struct.new", ty, ep, scratch) }.compact
473
570
  struct_klass = scratch.new_struct(ep)
474
571
 
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))
572
+ scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:object_s_new))
573
+ scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:object_s_new))
477
574
  fields.each do |field|
478
- scratch.add_attr_method(struct_klass, ep.ctx.iseq.absolute_path, field, field, :accessor)
575
+ scratch.add_attr_method(struct_klass, field, field, :accessor, true, ep)
479
576
  end
480
577
  fields = fields.map {|field| Type::Symbol.new(field, Type::Instance.new(Type::Builtin[:sym])) }
481
578
  base_ty = Type::Instance.new(Type::Builtin[:ary])
482
579
  fields = Type::Array.new(Type::Array::Elements.new(fields), base_ty)
483
580
  scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_members, fields, ep)
581
+ scratch.add_ivar_write!(Type::Instance.new(struct_klass), :_keyword_init, Type::Instance.new(Type::Builtin[:true]), ep) if keyword_init
484
582
  #set_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
485
583
 
486
584
  ctn[struct_klass, ep, env]
@@ -654,25 +752,26 @@ module TypeProf
654
752
 
655
753
  Import.import_builtin(scratch)
656
754
 
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)
755
+ Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
756
+ Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
757
+ Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
758
+ Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
759
+ Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
760
+ Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
761
+ Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
762
+ Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
763
+ Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
764
+ Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
765
+ Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
766
+ Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
767
+ Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
768
+ Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
769
+ Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
770
+ Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
771
+ Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
772
+ Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
773
+ Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
774
+ Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
676
775
 
677
776
  klass_vmcore = Type::Builtin[:vmcore]
678
777
  klass_ary = Type::Builtin[:ary]
@@ -687,19 +786,25 @@ module TypeProf
687
786
  scratch.set_custom_method(klass_vmcore, :"core#raise", Builtin.method(:vmcore_raise))
688
787
  scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
689
788
  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))
789
+ scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p), false)
691
790
  scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
692
791
  scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
693
792
  scratch.set_custom_method(klass_obj, :class, Builtin.method(:object_class))
694
793
  scratch.set_custom_method(klass_obj, :send, Builtin.method(:object_send))
695
794
  scratch.set_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
696
- scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda))
795
+ scratch.set_custom_method(klass_obj, :proc, Builtin.method(:lambda), false)
796
+ scratch.set_custom_method(klass_obj, :__method__, Builtin.method(:object_privitive_method), false)
797
+ scratch.set_custom_method(klass_obj, :block_given?, Builtin.method(:object_block_given?), false)
798
+
799
+ scratch.set_custom_method(klass_obj, :enum_for, Builtin.method(:object_enum_for))
800
+ scratch.set_custom_method(klass_obj, :to_enum, Builtin.method(:object_enum_for))
697
801
 
698
802
  scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
699
803
  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))
804
+ scratch.set_custom_method(klass_module, :prepend, Builtin.method(:module_prepend))
805
+ scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function), false)
806
+ scratch.set_custom_method(klass_module, :public, Builtin.method(:module_public), false)
807
+ scratch.set_custom_method(klass_module, :private, Builtin.method(:module_private), false)
703
808
  scratch.set_custom_method(klass_module, :define_method, Builtin.method(:module_define_method))
704
809
  scratch.set_custom_method(klass_module, :"attr_accessor", Builtin.method(:module_attr_accessor))
705
810
  scratch.set_custom_method(klass_module, :"attr_reader", Builtin.method(:module_attr_reader))
@@ -718,10 +823,10 @@ module TypeProf
718
823
  scratch.set_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
719
824
  scratch.set_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
720
825
 
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))
826
+ scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require), false)
827
+ scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative), false)
828
+ scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array), false)
829
+ scratch.set_custom_method(klass_obj, :autoload, Builtin.method(:kernel_autoload), false)
725
830
  scratch.set_custom_method(klass_module, :autoload, Builtin.method(:module_autoload))
726
831
 
727
832
  # remove BasicObject#method_missing