typeprof 0.9.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/Gemfile.lock +6 -5
  4. data/doc/demo.md +2 -2
  5. data/doc/todo.md +133 -0
  6. data/lib/typeprof/analyzer.rb +163 -77
  7. data/lib/typeprof/block.rb +39 -4
  8. data/lib/typeprof/builtin.rb +195 -70
  9. data/lib/typeprof/cli.rb +7 -0
  10. data/lib/typeprof/config.rb +30 -14
  11. data/lib/typeprof/container-type.rb +24 -0
  12. data/lib/typeprof/export.rb +134 -74
  13. data/lib/typeprof/import.rb +87 -39
  14. data/lib/typeprof/iseq.rb +23 -4
  15. data/lib/typeprof/method.rb +29 -7
  16. data/lib/typeprof/type.rb +75 -13
  17. data/lib/typeprof/version.rb +1 -1
  18. data/smoke/alias.rb +4 -4
  19. data/smoke/alias2.rb +3 -1
  20. data/smoke/arguments.rb +2 -2
  21. data/smoke/arguments2.rb +5 -5
  22. data/smoke/array-each.rb +1 -1
  23. data/smoke/array-each3.rb +1 -1
  24. data/smoke/array-map.rb +1 -1
  25. data/smoke/array-map2.rb +1 -1
  26. data/smoke/array-map3.rb +3 -3
  27. data/smoke/array-mul.rb +2 -2
  28. data/smoke/array-plus1.rb +1 -1
  29. data/smoke/array-plus2.rb +1 -0
  30. data/smoke/array-range-aref.rb +11 -11
  31. data/smoke/array-replace.rb +1 -1
  32. data/smoke/array1.rb +5 -5
  33. data/smoke/array10.rb +1 -1
  34. data/smoke/array11.rb +1 -1
  35. data/smoke/array12.rb +1 -1
  36. data/smoke/array14.rb +1 -1
  37. data/smoke/array15.rb +1 -1
  38. data/smoke/array2.rb +2 -2
  39. data/smoke/array3.rb +1 -0
  40. data/smoke/array6.rb +2 -1
  41. data/smoke/array8.rb +1 -1
  42. data/smoke/array9.rb +1 -1
  43. data/smoke/attr-module.rb +1 -0
  44. data/smoke/attr-vis.rb +43 -0
  45. data/smoke/attr-vis.rbs +4 -0
  46. data/smoke/attr.rb +2 -2
  47. data/smoke/block-ambiguous.rb +4 -4
  48. data/smoke/block-args1-rest.rb +6 -5
  49. data/smoke/block-args1.rb +5 -5
  50. data/smoke/block-args2-rest.rb +6 -5
  51. data/smoke/block-args2.rb +5 -5
  52. data/smoke/block-args3-rest.rb +7 -6
  53. data/smoke/block-args3.rb +6 -6
  54. data/smoke/block-blockarg.rb +3 -3
  55. data/smoke/block-kwarg.rb +4 -4
  56. data/smoke/block1.rb +1 -1
  57. data/smoke/block10.rb +1 -1
  58. data/smoke/block11.rb +2 -2
  59. data/smoke/block2.rb +1 -1
  60. data/smoke/block3.rb +1 -1
  61. data/smoke/block5.rb +1 -0
  62. data/smoke/block_given.rb +37 -0
  63. data/smoke/class_eval.rb +22 -0
  64. data/smoke/class_method.rb +2 -2
  65. data/smoke/class_method2.rb +2 -2
  66. data/smoke/constant2.rb +3 -2
  67. data/smoke/context-sensitive1.rb +1 -1
  68. data/smoke/cvar.rb +3 -2
  69. data/smoke/define_method.rb +2 -2
  70. data/smoke/define_method3.rb +1 -0
  71. data/smoke/define_method4.rb +1 -1
  72. data/smoke/define_method6.rb +19 -0
  73. data/smoke/define_method7.rb +18 -0
  74. data/smoke/demo.rb +6 -6
  75. data/smoke/demo1.rb +1 -1
  76. data/smoke/demo11.rb +1 -1
  77. data/smoke/demo2.rb +1 -1
  78. data/smoke/demo3.rb +1 -1
  79. data/smoke/demo4.rb +3 -3
  80. data/smoke/demo5.rb +1 -1
  81. data/smoke/demo6.rb +2 -1
  82. data/smoke/demo7.rb +1 -1
  83. data/smoke/demo9.rb +1 -0
  84. data/smoke/dummy-execution1.rb +1 -1
  85. data/smoke/dummy-execution2.rb +1 -1
  86. data/smoke/dummy_element.rb +1 -1
  87. data/smoke/ensure1.rb +1 -1
  88. data/smoke/enum_for.rb +15 -0
  89. data/smoke/enum_for2.rb +17 -0
  90. data/smoke/extended.rb +38 -0
  91. data/smoke/fib.rb +2 -2
  92. data/smoke/flow1.rb +1 -1
  93. data/smoke/flow10.rb +17 -0
  94. data/smoke/flow2.rb +1 -1
  95. data/smoke/flow3.rb +1 -1
  96. data/smoke/flow5.rb +1 -1
  97. data/smoke/flow6.rb +1 -1
  98. data/smoke/flow7.rb +1 -1
  99. data/smoke/flow8.rb +1 -1
  100. data/smoke/flow9.rb +1 -1
  101. data/smoke/function.rb +1 -1
  102. data/smoke/gvar.rb +1 -1
  103. data/smoke/gvar2.rb +1 -1
  104. data/smoke/hash-fetch.rb +3 -3
  105. data/smoke/included.rb +38 -0
  106. data/smoke/inheritance.rb +4 -4
  107. data/smoke/inherited.rb +26 -0
  108. data/smoke/initialize.rb +3 -2
  109. data/smoke/instance_eval.rb +2 -2
  110. data/smoke/instance_eval4.rb +12 -0
  111. data/smoke/int_times.rb +1 -1
  112. data/smoke/integer.rb +1 -1
  113. data/smoke/ivar.rb +3 -2
  114. data/smoke/ivar2.rb +2 -2
  115. data/smoke/ivar3.rb +2 -1
  116. data/smoke/ivar4.rb +1 -0
  117. data/smoke/kernel-class.rb +1 -1
  118. data/smoke/keyword4.rb +1 -1
  119. data/smoke/kwrest.rb +1 -0
  120. data/smoke/kwsplat1.rb +2 -2
  121. data/smoke/kwsplat2.rb +1 -1
  122. data/smoke/manual-rbs.rb +2 -1
  123. data/smoke/manual-rbs3.rb +1 -0
  124. data/smoke/method_in_branch.rb +1 -1
  125. data/smoke/method_missing.rb +4 -3
  126. data/smoke/module3.rb +1 -1
  127. data/smoke/module4.rb +1 -0
  128. data/smoke/module5.rb +1 -1
  129. data/smoke/module_function1.rb +3 -2
  130. data/smoke/module_function2.rb +3 -2
  131. data/smoke/multiple-include.rb +1 -0
  132. data/smoke/next1.rb +1 -1
  133. data/smoke/object-send1.rb +3 -3
  134. data/smoke/optional1.rb +1 -1
  135. data/smoke/optional2.rb +1 -1
  136. data/smoke/optional3.rb +1 -1
  137. data/smoke/parameterizedd-self.rb +2 -1
  138. data/smoke/prepend1.rb +33 -0
  139. data/smoke/prepend2.rb +10 -0
  140. data/smoke/prepend2.rbs +9 -0
  141. data/smoke/primitive_method.rb +19 -0
  142. data/smoke/proc4.rb +1 -1
  143. data/smoke/public.rb +4 -0
  144. data/smoke/range.rb +1 -1
  145. data/smoke/rbs-attr.rb +2 -2
  146. data/smoke/rbs-proc2.rb +1 -1
  147. data/smoke/rbs-proc3.rb +1 -1
  148. data/smoke/rbs-tyvar4.rb +3 -2
  149. data/smoke/rbs-tyvar6.rb +3 -3
  150. data/smoke/redo1.rb +1 -1
  151. data/smoke/redo2.rb +1 -1
  152. data/smoke/rescue1.rb +1 -1
  153. data/smoke/rescue2.rb +1 -1
  154. data/smoke/rescue3.rb +1 -0
  155. data/smoke/rescue4.rb +1 -1
  156. data/smoke/respond_to.rb +1 -1
  157. data/smoke/rest1.rb +2 -2
  158. data/smoke/rest2.rb +1 -1
  159. data/smoke/rest3.rb +6 -6
  160. data/smoke/rest4.rb +2 -2
  161. data/smoke/rest5.rb +1 -1
  162. data/smoke/rest6.rb +1 -1
  163. data/smoke/retry1.rb +2 -2
  164. data/smoke/simple.rb +12 -0
  165. data/smoke/step.rb +3 -3
  166. data/smoke/struct-keyword_init.rb +6 -16
  167. data/smoke/struct.rb +1 -1
  168. data/smoke/struct2.rb +1 -1
  169. data/smoke/struct3.rb +1 -1
  170. data/smoke/struct4.rb +1 -1
  171. data/smoke/struct5.rb +2 -2
  172. data/smoke/struct6.rb +2 -2
  173. data/smoke/struct7.rb +1 -1
  174. data/smoke/super1.rb +4 -4
  175. data/smoke/super3.rb +3 -2
  176. data/smoke/super4.rb +7 -5
  177. data/smoke/super5.rb +6 -4
  178. data/smoke/symbol-proc-attr.rb +1 -1
  179. data/smoke/tap1.rb +2 -2
  180. data/smoke/toplevel.rb +1 -1
  181. data/smoke/type_var.rb +3 -3
  182. data/smoke/user-demo.rb +1 -1
  183. data/smoke/wrong-extend.rb +1 -0
  184. data/smoke/wrong-include.rb +1 -0
  185. data/smoke/wrong-include2.rb +1 -1
  186. data/testbed/goodcheck-Gemfile.lock +1 -1
  187. data/typeprof.gemspec +1 -1
  188. metadata +24 -5
@@ -3,6 +3,10 @@ require "rbs"
3
3
  module TypeProf
4
4
  class RBSReader
5
5
  def initialize
6
+ @repo = RBS::Repository.new
7
+ Config.gem_repo_dirs.each do |dir|
8
+ @repo.add(Pathname(dir))
9
+ end
6
10
  @env, @builtin_env_json = RBSReader.get_builtin_env
7
11
  end
8
12
 
@@ -11,7 +15,7 @@ module TypeProf
11
15
  unless @builtin_env
12
16
  @builtin_env = RBS::Environment.new
13
17
 
14
- loader = RBS::EnvironmentLoader.new
18
+ loader = RBS::EnvironmentLoader.new(repository: @repo)
15
19
  new_decls = loader.load(env: @builtin_env).map {|decl,| decl }
16
20
  @builtin_env_json = load_rbs(@builtin_env, new_decls)
17
21
  end
@@ -24,22 +28,30 @@ module TypeProf
24
28
  end
25
29
 
26
30
  def load_library(lib)
27
- loader = RBS::EnvironmentLoader.new(core_root: nil)
31
+ loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
28
32
  loader.add(library: lib)
29
33
 
30
34
  case lib
35
+ when 'bigdecimal-math'
36
+ loader.add(library: 'bigdecimal')
31
37
  when "yaml"
32
38
  loader.add(library: "pstore")
33
39
  loader.add(library: "dbm")
40
+ when "logger"
41
+ loader.add(library: "monitor")
42
+ when "csv"
43
+ loader.add(library: "forwardable")
44
+ when "prime"
45
+ loader.add(library: "singleton")
34
46
  end
35
47
 
36
48
  new_decls = loader.load(env: @env).map {|decl,| decl }
37
49
  RBSReader.load_rbs(@env, new_decls)
38
50
  end
39
51
 
40
- def load_path(path)
41
- loader = RBS::EnvironmentLoader.new(core_root: nil)
42
- loader.add(path: path)
52
+ def load_paths(paths)
53
+ loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
54
+ paths.each {|path| loader.add(path: path) }
43
55
  new_decls = loader.load(env: @env).map {|decl,| decl }
44
56
  RBSReader.load_rbs(@env, new_decls)
45
57
  end
@@ -69,6 +81,7 @@ module TypeProf
69
81
  class RBS2JSON
70
82
  def initialize(all_env, cur_env)
71
83
  @all_env, @cur_env = all_env, cur_env
84
+ @alias_resolution_stack = {}
72
85
  end
73
86
 
74
87
  def dump_json
@@ -116,13 +129,13 @@ module TypeProf
116
129
  end
117
130
 
118
131
  type_params = nil
119
- included_modules = []
120
- extended_modules = []
132
+ modules = { include: [], extend: [], prepend: [] }
121
133
  methods = {}
122
134
  attr_methods = {}
123
135
  ivars = {}
124
136
  cvars = {}
125
137
  rbs_sources = {}
138
+ visibility = true
126
139
 
127
140
  decls.each do |decl|
128
141
  decl = decl.decl
@@ -143,7 +156,7 @@ module TypeProf
143
156
  end
144
157
  end
145
158
 
146
- method_def = conv_method_def(method_types)
159
+ method_def = conv_method_def(method_types, visibility)
147
160
  rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
148
161
  if member.instance?
149
162
  methods[[false, name]] = method_def
@@ -155,13 +168,13 @@ module TypeProf
155
168
  end
156
169
  when RBS::AST::Members::AttrReader
157
170
  ty = conv_type(member.type)
158
- attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
171
+ attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty, visibility)
159
172
  when RBS::AST::Members::AttrWriter
160
173
  ty = conv_type(member.type)
161
- attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
174
+ attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty, visibility)
162
175
  when RBS::AST::Members::AttrAccessor
163
176
  ty = conv_type(member.type)
164
- attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
177
+ attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty, visibility)
165
178
  when RBS::AST::Members::Alias
166
179
  # XXX: an alias to attr methods?
167
180
  if member.instance?
@@ -176,11 +189,15 @@ module TypeProf
176
189
  when RBS::AST::Members::Include
177
190
  name = member.name
178
191
  if name.kind == :class
192
+ # including a module
179
193
  mod = conv_type_name(name)
180
194
  type_args = member.args.map {|type| conv_type(type) }
181
- included_modules << [mod, type_args]
195
+ modules[:include] << [mod, type_args]
182
196
  else
183
- # including an interface is not supported yet
197
+ # including an interface
198
+ mod = conv_type_name(name)
199
+ type_args = member.args.map {|type| conv_type(type) }
200
+ modules[:include] << [mod, type_args]
184
201
  end
185
202
 
186
203
  when RBS::AST::Members::Extend
@@ -188,7 +205,17 @@ module TypeProf
188
205
  if name.kind == :class
189
206
  mod = conv_type_name(name)
190
207
  type_args = member.args.map {|type| conv_type(type) }
191
- extended_modules << [mod, type_args]
208
+ modules[:extend] << [mod, type_args]
209
+ else
210
+ # extending a module with an interface is not supported yet
211
+ end
212
+
213
+ when RBS::AST::Members::Prepend
214
+ name = member.name
215
+ if name.kind == :class
216
+ mod = conv_type_name(name)
217
+ type_args = member.args.map {|type| conv_type(type) }
218
+ modules[:prepend] << [mod, type_args]
192
219
  else
193
220
  # extending a module with an interface is not supported yet
194
221
  end
@@ -198,7 +225,10 @@ module TypeProf
198
225
  when RBS::AST::Members::ClassVariable
199
226
  cvars[member.name] = conv_type(member.type)
200
227
 
201
- when RBS::AST::Members::Public, RBS::AST::Members::Private # XXX
228
+ when RBS::AST::Members::Public
229
+ visibility = true
230
+ when RBS::AST::Members::Private
231
+ visibility = false
202
232
 
203
233
  # The following declarations are ignoreable because they are handled in other level
204
234
  when RBS::AST::Declarations::Constant
@@ -216,8 +246,7 @@ module TypeProf
216
246
  type_params: type_params,
217
247
  superclass: superclass,
218
248
  members: {
219
- included_modules: included_modules,
220
- extended_modules: extended_modules,
249
+ modules: modules,
221
250
  methods: methods,
222
251
  attr_methods: attr_methods,
223
252
  ivars: ivars,
@@ -297,10 +326,14 @@ module TypeProf
297
326
  return RBS::BuiltinNames::Object.name, []
298
327
  end
299
328
 
300
- def conv_method_def(rbs_method_types)
301
- rbs_method_types.map do |method_type|
329
+ def conv_method_def(rbs_method_types, visibility)
330
+ sig_rets = rbs_method_types.map do |method_type|
302
331
  conv_func(method_type.type_params, method_type.type, method_type.block)
303
332
  end
333
+ {
334
+ sig_rets: sig_rets,
335
+ visibility: visibility,
336
+ }
304
337
  end
305
338
 
306
339
  def conv_func(type_params, func, block)
@@ -330,11 +363,12 @@ module TypeProf
330
363
  }
331
364
  end
332
365
 
333
- def attr_method_def(kind, name, ty)
366
+ def attr_method_def(kind, name, ty, visibility)
334
367
  {
335
368
  kind: kind,
336
369
  ivar: name,
337
370
  ty: ty,
371
+ visibility: visibility,
338
372
  }
339
373
  end
340
374
 
@@ -407,8 +441,17 @@ module TypeProf
407
441
  raise NotImplementedError
408
442
  end
409
443
  when RBS::Types::Alias
410
- alias_decl = @all_env.alias_decls[ty.name]
411
- alias_decl ? conv_type(alias_decl.decl.type) : [:any]
444
+ if @alias_resolution_stack[ty.name]
445
+ [:any]
446
+ else
447
+ begin
448
+ @alias_resolution_stack[ty.name] = true
449
+ alias_decl = @all_env.alias_decls[ty.name]
450
+ alias_decl ? conv_type(alias_decl.decl.type) : [:any]
451
+ ensure
452
+ @alias_resolution_stack.delete(ty.name)
453
+ end
454
+ end
412
455
  when RBS::Types::Union
413
456
  [:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
414
457
  when RBS::Types::Optional
@@ -455,9 +498,9 @@ module TypeProf
455
498
  Import.new(scratch, json).import
456
499
  end
457
500
 
458
- def self.import_rbs_file(scratch, rbs_path)
459
- rbs_path = Pathname(rbs_path) unless rbs_path.is_a?(Pathname)
460
- Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
501
+ def self.import_rbs_files(scratch, rbs_paths)
502
+ rbs_paths = rbs_paths.map {|rbs_path| Pathname(rbs_path) }
503
+ Import.new(scratch, scratch.rbs_reader.load_paths(rbs_paths)).import(true)
461
504
  end
462
505
 
463
506
  def self.import_rbs_code(scratch, rbs_name, rbs_code)
@@ -502,22 +545,25 @@ module TypeProf
502
545
 
503
546
  classes.each do |klass, superclass_type_args, members|
504
547
  @scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
505
- included_modules = members[:included_modules]
506
- extended_modules = members[:extended_modules]
548
+ modules = members[:modules]
507
549
  methods = members[:methods]
508
550
  attr_methods = members[:attr_methods]
509
551
  ivars = members[:ivars]
510
552
  cvars = members[:cvars]
511
553
  rbs_sources = members[:rbs_sources]
512
554
 
513
- included_modules.each do |mod, type_args|
514
- type_args = type_args&.map {|ty| conv_type(ty) }
515
- @scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
516
- end
517
-
518
- extended_modules.each do |mod, type_args|
519
- type_args = type_args&.map {|ty| conv_type(ty) }
520
- @scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
555
+ modules.each do |kind, mods|
556
+ mods.each do |mod, type_args|
557
+ type_args = type_args&.map {|ty| conv_type(ty) }
558
+ case kind
559
+ when :include
560
+ @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, false, nil)
561
+ when :extend
562
+ @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, true, nil)
563
+ when :prepend
564
+ @scratch.mix_module(:before, klass, path_to_klass(mod), type_args, false, nil)
565
+ end
566
+ end
521
567
  end
522
568
 
523
569
  methods.each do |(singleton, method_name), mdef|
@@ -530,7 +576,7 @@ module TypeProf
530
576
  kind = mdef[:kind]
531
577
  ivar = mdef[:ivar]
532
578
  ty = conv_type(mdef[:ty]).remove_type_vars
533
- @scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
579
+ @scratch.add_attr_method(klass, ivar, :"@#{ ivar }", kind, mdef[:visibility], nil)
534
580
  @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
535
581
  end
536
582
 
@@ -560,11 +606,11 @@ module TypeProf
560
606
  end
561
607
 
562
608
  def conv_method_def(method_name, mdef, rbs_source)
563
- sig_rets = mdef.flat_map do |sig_ret|
609
+ sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
564
610
  conv_func(sig_ret)
565
611
  end
566
612
 
567
- TypedMethodDef.new(sig_rets, rbs_source)
613
+ TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
568
614
  end
569
615
 
570
616
  def conv_func(sig_ret)
@@ -664,7 +710,9 @@ module TypeProf
664
710
  klass = Type::Builtin[:obj]
665
711
  path.each do |name|
666
712
  klass = @scratch.get_constant(klass, name)
667
- raise path.inspect if klass == Type.any
713
+ if klass == Type.any
714
+ raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
715
+ end
668
716
  end
669
717
  klass
670
718
  end
data/lib/typeprof/iseq.rb CHANGED
@@ -207,7 +207,7 @@ module TypeProf
207
207
  end
208
208
 
209
209
  # find a pattern: getlocal, ..., send (is_a?, respond_to?), branch
210
- send_branch_list = []
210
+ getlocal_send_branch_list = []
211
211
  (@insns.size - 1).times do |i|
212
212
  insn, operands = @insns[i]
213
213
  if insn == :getlocal && operands[1] == 0
@@ -216,7 +216,7 @@ module TypeProf
216
216
  while @insns[j]
217
217
  sp = check_send_branch(sp, j)
218
218
  if sp == :match
219
- send_branch_list << [i, j]
219
+ getlocal_send_branch_list << [i, j]
220
220
  break
221
221
  end
222
222
  break if !sp
@@ -224,13 +224,32 @@ module TypeProf
224
224
  end
225
225
  end
226
226
  end
227
- send_branch_list.each do |i, j|
227
+ getlocal_send_branch_list.each do |i, j|
228
228
  next if (i + 1 .. j + 1).any? {|i| branch_targets[i] }
229
229
  _insn, getlocal_operands = @insns[i]
230
230
  _insn, send_operands = @insns[j]
231
231
  _insn, branch_operands = @insns[j + 1]
232
232
  @insns[j] = [:nop]
233
- @insns[j + 1] = [:send_branch, [getlocal_operands, send_operands, branch_operands]]
233
+ @insns[j + 1] = [:getlocal_send_branch, [getlocal_operands, send_operands, branch_operands]]
234
+ end
235
+
236
+ # find a pattern: send (block_given?), branch
237
+ send_branch_list = []
238
+ (@insns.size - 1).times do |i|
239
+ insn, _operands = @insns[i]
240
+ if insn == :send
241
+ insn, _operands = @insns[i + 1]
242
+ if insn == :branch
243
+ send_branch_list << i
244
+ end
245
+ end
246
+ end
247
+ send_branch_list.each do |i|
248
+ next if branch_targets[i + 1]
249
+ _insn, send_operands = @insns[i]
250
+ _insn, branch_operands = @insns[i + 1]
251
+ @insns[i] = [:nop]
252
+ @insns[i + 1] = [:send_branch, [send_operands, branch_operands]]
234
253
  end
235
254
 
236
255
  # find a pattern: getlocal, dup, branch
@@ -1,5 +1,7 @@
1
1
  module TypeProf
2
2
  class MethodDef
3
+ attr_accessor :pub_meth
4
+
3
5
  include Utils::StructuralEquality
4
6
  end
5
7
 
@@ -12,8 +14,6 @@ module TypeProf
12
14
  @pub_meth = pub_meth
13
15
  end
14
16
 
15
- attr_accessor :pub_meth
16
-
17
17
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
18
18
  recv = recv.base_type while recv.respond_to?(:base_type)
19
19
  recv = scratch.globalize_type(recv, caller_env, caller_ep)
@@ -153,14 +153,34 @@ module TypeProf
153
153
  end
154
154
  end
155
155
 
156
+ class AliasMethodDef < MethodDef
157
+ def initialize(orig_mid, mdef, def_ep)
158
+ @orig_mid = orig_mid
159
+ @mdef = mdef
160
+ @pub_meth = mdef.pub_meth
161
+ @def_ep = def_ep
162
+ end
163
+
164
+ attr_reader :orig_mid, :mdef, :def_ep
165
+
166
+ def do_send(recv, _mid, aargs, caller_ep, caller_env, scratch, &ctn)
167
+ @mdef.do_send(recv, @orig_mid, aargs, caller_ep, caller_env, scratch, &ctn)
168
+ end
169
+
170
+ def do_check_send(msig, recv, mid, ep, scratch)
171
+ @mdef.do_check_send(msig, recv, mid, ep, scratch)
172
+ end
173
+ end
174
+
156
175
  class AttrMethodDef < MethodDef
157
- def initialize(ivar, kind, absolute_path)
176
+ def initialize(ivar, kind, pub_meth, def_ep)
158
177
  @ivar = ivar
159
178
  @kind = kind # :reader | :writer
160
- @absolute_path = absolute_path
179
+ @pub_meth = pub_meth
180
+ @def_ep = def_ep
161
181
  end
162
182
 
163
- attr_reader :ivar, :kind, :absolute_path
183
+ attr_reader :ivar, :kind, :def_ep
164
184
 
165
185
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
166
186
  case @kind
@@ -185,9 +205,10 @@ module TypeProf
185
205
  end
186
206
 
187
207
  class TypedMethodDef < MethodDef
188
- def initialize(sig_rets, rbs_source) # sig_rets: Array<[MethodSignature, (return)Type]>
208
+ def initialize(sig_rets, rbs_source, pub_meth) # sig_rets: Array<[MethodSignature, (return)Type]>
189
209
  @sig_rets = sig_rets
190
210
  @rbs_source = rbs_source
211
+ @pub_meth = pub_meth
191
212
  end
192
213
 
193
214
  attr_reader :rbs_source
@@ -286,8 +307,9 @@ module TypeProf
286
307
  end
287
308
 
288
309
  class CustomMethodDef < MethodDef
289
- def initialize(impl)
310
+ def initialize(impl, pub_meth)
290
311
  @impl = impl
312
+ @pub_meth = pub_meth
291
313
  end
292
314
 
293
315
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
data/lib/typeprof/type.rb CHANGED
@@ -162,6 +162,10 @@ module TypeProf
162
162
  substitute(DummySubstitution, Config.options[:type_depth_limit])
163
163
  end
164
164
 
165
+ def include_untyped?(_scratch)
166
+ false
167
+ end
168
+
165
169
  class Any < Type
166
170
  def initialize
167
171
  end
@@ -185,6 +189,10 @@ module TypeProf
185
189
  def substitute(_subst, _depth)
186
190
  self
187
191
  end
192
+
193
+ def include_untyped?(_scratch)
194
+ true
195
+ end
188
196
  end
189
197
 
190
198
  class Void < Any
@@ -379,6 +387,17 @@ module TypeProf
379
387
  end
380
388
  ty
381
389
  end
390
+
391
+ def include_untyped?(scratch)
392
+ @types.each do |ty|
393
+ return true if ty.include_untyped?(scratch)
394
+ end
395
+ @elems&.each do |(container_kind, base_type), elems|
396
+ return true if base_type.include_untyped?(scratch)
397
+ return true if elems.include_untyped?(scratch)
398
+ end
399
+ false
400
+ end
382
401
  end
383
402
 
384
403
  def self.any
@@ -583,6 +602,10 @@ module TypeProf
583
602
  def screen_name(scratch)
584
603
  scratch.show_proc_signature([self])
585
604
  end
605
+
606
+ def include_untyped?(scratch)
607
+ false # XXX: need to check the block signatures recursively
608
+ end
586
609
  end
587
610
 
588
611
  class Symbol < Type
@@ -781,31 +804,56 @@ module TypeProf
781
804
  class Signature
782
805
  include Utils::StructuralEquality
783
806
 
784
- def screen_name(scratch)
785
- str = @lead_tys.map {|ty| ty.screen_name(scratch) }
807
+ def screen_name(iseq, scratch)
808
+ fargs = @lead_tys.map {|ty| ty.screen_name(scratch) }
809
+ farg_names = []
810
+ farg_names += iseq.locals[0, @lead_tys.size] if iseq
786
811
  if @opt_tys
787
- str += @opt_tys.map {|ty| "?" + ty.screen_name(scratch) }
812
+ fargs += @opt_tys.map {|ty| "?" + ty.screen_name(scratch) }
813
+ farg_names += iseq.locals[@lead_tys.size, @opt_tys.size] if iseq
788
814
  end
789
815
  if @rest_ty
790
- str << ("*" + @rest_ty.screen_name(scratch))
816
+ fargs << ("*" + @rest_ty.screen_name(scratch))
817
+ if iseq
818
+ rest_index = iseq.fargs_format[:rest_start]
819
+ farg_names << (rest_index ? iseq.locals[rest_index] : nil)
820
+ end
791
821
  end
792
822
  if @post_tys
793
- str += @post_tys.map {|ty| ty.screen_name(scratch) }
823
+ fargs += @post_tys.map {|ty| ty.screen_name(scratch) }
824
+ if iseq
825
+ post_start = iseq.fargs_format[:post_start]
826
+ farg_names += (post_start ? iseq.locals[post_start, @post_tys.size] : [nil] * @post_tys.size)
827
+ end
794
828
  end
795
829
  if @kw_tys
796
830
  @kw_tys.each do |req, sym, ty|
797
831
  opt = req ? "" : "?"
798
- str << "#{ opt }#{ sym }: #{ ty.screen_name(scratch) }"
832
+ fargs << "#{ opt }#{ sym }: #{ ty.screen_name(scratch) }"
799
833
  end
800
834
  end
801
835
  if @kw_rest_ty
802
- str << ("**" + @kw_rest_ty.screen_name(scratch))
836
+ all_val_ty = Type.bot
837
+ @kw_rest_ty.each_child_global do |ty|
838
+ if ty == Type.any
839
+ val_ty = ty
840
+ else
841
+ # ty is a Type::Hash
842
+ _key_ty, val_ty = ty.elems.squash
843
+ end
844
+ all_val_ty = all_val_ty.union(val_ty)
845
+ end
846
+ fargs << ("**" + all_val_ty.screen_name(scratch))
847
+ end
848
+ if Config.options[:show_parameter_names]
849
+ farg_names = farg_names.map {|name| name == :type ? :type_ : name } # XXX: workaround of RBS parser bug
850
+ fargs = fargs.zip(farg_names).map {|farg, name| name ? "#{ farg } #{ name }" : farg }
803
851
  end
804
- str = str.empty? ? "" : "(#{ str.join(", ") })"
852
+ fargs = fargs.empty? ? "" : "(#{ fargs.join(", ") })"
805
853
 
806
854
  # Dirty Hack: Stop the iteration at most once!
807
855
  # I'll remove this hack if RBS removes the limitation of nesting blocks
808
- return str if caller_locations.any? {|frame| frame.label == "show_block_signature" }
856
+ return fargs if caller_locations.any? {|frame| frame.label == "show_block_signature" }
809
857
 
810
858
  optional = false
811
859
  blks = []
@@ -818,12 +866,12 @@ module TypeProf
818
866
  end
819
867
  end
820
868
  if blks != []
821
- str << " " if str != ""
822
- str << "?" if optional
823
- str << scratch.show_block_signature(blks)
869
+ fargs << " " if fargs != ""
870
+ fargs << "?" if optional
871
+ fargs << scratch.show_block_signature(blks)
824
872
  end
825
873
 
826
- str
874
+ fargs
827
875
  end
828
876
  end
829
877
 
@@ -838,9 +886,23 @@ module TypeProf
838
886
  @kw_tys = kw_tys
839
887
  kw_tys.each {|a| raise if a.size != 3 } if kw_tys
840
888
  @kw_rest_ty = kw_rest_ty
889
+ kw_rest_ty&.each_child_global do |ty|
890
+ raise ty.inspect if ty != Type.any && !ty.is_a?(Type::Hash)
891
+ end
841
892
  @blk_ty = blk_ty
842
893
  end
843
894
 
895
+ def include_untyped?(scratch)
896
+ return true if @lead_tys.any? {|ty| ty.include_untyped?(scratch) }
897
+ return true if @opt_tys.any? {|ty| ty.include_untyped?(scratch) }
898
+ return true if @rest_ty&.include_untyped?(scratch)
899
+ return true if @post_tys.any? {|ty| ty.include_untyped?(scratch) }
900
+ return true if @kw_tys&.any? {|_, _, ty| ty.include_untyped?(scratch) }
901
+ return true if @kw_rest_ty&.include_untyped?(scratch)
902
+ return true if @blk_ty&.include_untyped?(scratch)
903
+ false
904
+ end
905
+
844
906
  attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty
845
907
 
846
908
  def substitute(subst, depth)