typeprof 0.9.2 → 0.10.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 (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