typeprof 0.7.0 → 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 (296) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +8 -5
  3. data/lib/typeprof/analyzer.rb +211 -98
  4. data/lib/typeprof/arguments.rb +2 -0
  5. data/lib/typeprof/block.rb +40 -2
  6. data/lib/typeprof/builtin.rb +301 -99
  7. data/lib/typeprof/cli.rb +2 -0
  8. data/lib/typeprof/config.rb +14 -2
  9. data/lib/typeprof/container-type.rb +5 -4
  10. data/lib/typeprof/export.rb +116 -65
  11. data/lib/typeprof/import.rb +68 -41
  12. data/lib/typeprof/iseq.rb +46 -11
  13. data/lib/typeprof/method.rb +47 -23
  14. data/lib/typeprof/type.rb +96 -18
  15. data/lib/typeprof/version.rb +1 -1
  16. data/smoke/alias.rb +5 -4
  17. data/smoke/alias2.rb +6 -4
  18. data/smoke/any1.rb +2 -1
  19. data/smoke/any2.rb +3 -2
  20. data/smoke/arguments.rb +3 -2
  21. data/smoke/arguments2.rb +11 -10
  22. data/smoke/array-each.rb +2 -1
  23. data/smoke/array-each2.rb +2 -1
  24. data/smoke/array-each3.rb +2 -1
  25. data/smoke/array-ltlt.rb +2 -1
  26. data/smoke/array-ltlt2.rb +2 -1
  27. data/smoke/array-map.rb +2 -1
  28. data/smoke/array-map2.rb +2 -1
  29. data/smoke/array-map3.rb +4 -3
  30. data/smoke/array-mul.rb +3 -2
  31. data/smoke/array-plus1.rb +2 -1
  32. data/smoke/array-plus2.rb +3 -2
  33. data/smoke/array-pop.rb +2 -1
  34. data/smoke/array-range-aref.rb +12 -11
  35. data/smoke/array-replace.rb +2 -1
  36. data/smoke/array-s-aref.rb +2 -1
  37. data/smoke/array1.rb +6 -5
  38. data/smoke/array10.rb +2 -1
  39. data/smoke/array11.rb +2 -1
  40. data/smoke/array12.rb +4 -3
  41. data/smoke/array13.rb +5 -4
  42. data/smoke/array14.rb +2 -1
  43. data/smoke/array15.rb +16 -0
  44. data/smoke/array2.rb +4 -3
  45. data/smoke/array3.rb +5 -4
  46. data/smoke/array4.rb +2 -1
  47. data/smoke/array5.rb +2 -1
  48. data/smoke/array6.rb +4 -2
  49. data/smoke/array7.rb +2 -1
  50. data/smoke/array8.rb +1 -1
  51. data/smoke/array9.rb +2 -1
  52. data/smoke/attr-module.rb +27 -0
  53. data/smoke/attr-vis.rb +43 -0
  54. data/smoke/attr-vis.rbs +4 -0
  55. data/smoke/attr.rb +5 -5
  56. data/smoke/autoload.rb +2 -1
  57. data/smoke/backtrace.rb +4 -3
  58. data/smoke/block-ambiguous.rb +9 -8
  59. data/smoke/block-args1-rest.rb +13 -11
  60. data/smoke/block-args1.rb +11 -10
  61. data/smoke/block-args2-rest.rb +13 -11
  62. data/smoke/block-args2.rb +11 -10
  63. data/smoke/block-args3-rest.rb +15 -13
  64. data/smoke/block-args3.rb +13 -12
  65. data/smoke/block-blockarg.rb +5 -4
  66. data/smoke/block-kwarg.rb +11 -10
  67. data/smoke/block1.rb +2 -1
  68. data/smoke/block10.rb +2 -1
  69. data/smoke/block11.rb +6 -5
  70. data/smoke/block12.rb +3 -2
  71. data/smoke/block14.rb +3 -2
  72. data/smoke/block2.rb +2 -1
  73. data/smoke/block3.rb +3 -3
  74. data/smoke/block4.rb +3 -2
  75. data/smoke/block5.rb +4 -2
  76. data/smoke/block6.rb +3 -2
  77. data/smoke/block7.rb +2 -1
  78. data/smoke/block8.rb +4 -3
  79. data/smoke/block9.rb +2 -1
  80. data/smoke/block_given.rb +37 -0
  81. data/smoke/blown.rb +2 -1
  82. data/smoke/break1.rb +3 -2
  83. data/smoke/break2.rb +2 -1
  84. data/smoke/break3.rb +13 -0
  85. data/smoke/case.rb +2 -1
  86. data/smoke/case2.rb +2 -1
  87. data/smoke/case3.rb +17 -0
  88. data/smoke/class-hierarchy.rb +5 -5
  89. data/smoke/class-hierarchy2.rb +3 -3
  90. data/smoke/class-new.rb +15 -0
  91. data/smoke/class_instance_var.rb +1 -1
  92. data/smoke/class_method.rb +2 -2
  93. data/smoke/class_method2.rb +2 -2
  94. data/smoke/class_method3.rb +4 -2
  95. data/smoke/constant1.rb +6 -6
  96. data/smoke/constant2.rb +6 -4
  97. data/smoke/constant3.rb +2 -1
  98. data/smoke/constant4.rb +2 -1
  99. data/smoke/context-sensitive1.rb +2 -1
  100. data/smoke/cvar.rb +7 -5
  101. data/smoke/cvar2.rb +2 -2
  102. data/smoke/define_method.rb +2 -2
  103. data/smoke/define_method2.rb +2 -2
  104. data/smoke/define_method3.rb +14 -0
  105. data/smoke/define_method3.rbs +3 -0
  106. data/smoke/define_method4.rb +15 -0
  107. data/smoke/define_method4.rbs +3 -0
  108. data/smoke/define_method5.rb +12 -0
  109. data/smoke/define_method6.rb +19 -0
  110. data/smoke/demo.rb +7 -6
  111. data/smoke/demo1.rb +2 -1
  112. data/smoke/demo10.rb +3 -2
  113. data/smoke/demo11.rb +2 -1
  114. data/smoke/demo2.rb +2 -1
  115. data/smoke/demo3.rb +2 -1
  116. data/smoke/demo4.rb +3 -3
  117. data/smoke/demo5.rb +1 -1
  118. data/smoke/demo6.rb +4 -3
  119. data/smoke/demo7.rb +2 -1
  120. data/smoke/demo8.rb +3 -2
  121. data/smoke/demo9.rb +4 -2
  122. data/smoke/dummy-execution1.rb +3 -2
  123. data/smoke/dummy-execution2.rb +2 -2
  124. data/smoke/dummy_element.rb +14 -0
  125. data/smoke/ensure1.rb +3 -2
  126. data/smoke/enum_for.rb +15 -0
  127. data/smoke/enum_for2.rb +17 -0
  128. data/smoke/enumerator.rb +3 -2
  129. data/smoke/expandarray1.rb +2 -1
  130. data/smoke/expandarray2.rb +2 -1
  131. data/smoke/fib.rb +2 -2
  132. data/smoke/flip-flop.rb +28 -0
  133. data/smoke/flow1.rb +2 -1
  134. data/smoke/flow10.rb +17 -0
  135. data/smoke/flow2.rb +2 -1
  136. data/smoke/flow3.rb +2 -1
  137. data/smoke/flow5.rb +2 -1
  138. data/smoke/flow6.rb +2 -1
  139. data/smoke/flow7.rb +2 -1
  140. data/smoke/flow8.rb +2 -1
  141. data/smoke/flow9.rb +12 -0
  142. data/smoke/freeze.rb +2 -1
  143. data/smoke/function.rb +3 -2
  144. data/smoke/gvar.rb +3 -2
  145. data/smoke/gvar2.rb +4 -3
  146. data/smoke/hash-bot.rb +12 -0
  147. data/smoke/hash-fetch.rb +4 -3
  148. data/smoke/hash-merge-bang.rb +2 -1
  149. data/smoke/hash1.rb +3 -2
  150. data/smoke/hash2.rb +2 -1
  151. data/smoke/hash3.rb +2 -1
  152. data/smoke/hash4.rb +2 -1
  153. data/smoke/hash5.rb +1 -1
  154. data/smoke/inheritance.rb +4 -4
  155. data/smoke/inheritance2.rb +2 -2
  156. data/smoke/initialize.rb +7 -5
  157. data/smoke/instance_eval.rb +2 -2
  158. data/smoke/instance_eval2.rb +10 -0
  159. data/smoke/instance_eval3.rb +25 -0
  160. data/smoke/int_times.rb +2 -1
  161. data/smoke/integer.rb +2 -1
  162. data/smoke/ivar.rb +6 -4
  163. data/smoke/ivar2.rb +4 -4
  164. data/smoke/ivar3.rb +4 -3
  165. data/smoke/ivar4.rb +21 -0
  166. data/smoke/kernel-class.rb +2 -1
  167. data/smoke/keyword1.rb +2 -1
  168. data/smoke/keyword2.rb +2 -1
  169. data/smoke/keyword3.rb +2 -1
  170. data/smoke/keyword4.rb +2 -1
  171. data/smoke/keyword5.rb +2 -1
  172. data/smoke/kwrest.rb +3 -2
  173. data/smoke/kwsplat1.rb +5 -4
  174. data/smoke/kwsplat2.rb +2 -1
  175. data/smoke/lit-complex.rb +10 -0
  176. data/smoke/lit-encoding.rb +10 -0
  177. data/smoke/manual-rbs.rb +6 -4
  178. data/smoke/manual-rbs2.rb +2 -1
  179. data/smoke/manual-rbs3.rb +3 -2
  180. data/smoke/masgn1.rb +2 -1
  181. data/smoke/masgn2.rb +3 -2
  182. data/smoke/masgn3.rb +2 -1
  183. data/smoke/method_in_branch.rb +4 -3
  184. data/smoke/method_missing.rb +5 -4
  185. data/smoke/module1.rb +2 -2
  186. data/smoke/module2.rb +1 -1
  187. data/smoke/module3.rb +3 -3
  188. data/smoke/module4.rb +3 -2
  189. data/smoke/module5.rb +17 -0
  190. data/smoke/module6.rb +40 -0
  191. data/smoke/module_function1.rb +4 -3
  192. data/smoke/module_function2.rb +4 -3
  193. data/smoke/multiple-include.rb +2 -1
  194. data/smoke/multiple-superclass.rb +1 -1
  195. data/smoke/next1.rb +3 -2
  196. data/smoke/next2.rb +2 -1
  197. data/smoke/object-send1.rb +4 -3
  198. data/smoke/object-send2.rb +10 -0
  199. data/smoke/object-send3.rb +18 -0
  200. data/smoke/once.rb +2 -1
  201. data/smoke/optional1.rb +2 -1
  202. data/smoke/optional2.rb +2 -1
  203. data/smoke/optional3.rb +2 -1
  204. data/smoke/parameterizedd-self.rb +4 -2
  205. data/smoke/parameterizedd-self2.rb +1 -1
  206. data/smoke/pathname1.rb +2 -1
  207. data/smoke/pathname2.rb +2 -1
  208. data/smoke/pattern-match1.rb +2 -1
  209. data/smoke/pattern-match2.rb +2 -1
  210. data/smoke/prepend1.rb +33 -0
  211. data/smoke/prepend2.rb +10 -0
  212. data/smoke/prepend2.rbs +9 -0
  213. data/smoke/primitive_method.rb +19 -0
  214. data/smoke/printf.rb +2 -2
  215. data/smoke/proc.rb +3 -2
  216. data/smoke/proc2.rb +2 -1
  217. data/smoke/proc3.rb +2 -1
  218. data/smoke/proc4.rb +2 -1
  219. data/smoke/proc5.rb +19 -0
  220. data/smoke/public.rb +38 -0
  221. data/smoke/range.rb +2 -1
  222. data/smoke/rbs-alias.rb +2 -1
  223. data/smoke/rbs-attr.rb +6 -5
  224. data/smoke/rbs-attr2.rb +1 -1
  225. data/smoke/rbs-extend.rb +2 -1
  226. data/smoke/rbs-interface.rb +5 -4
  227. data/smoke/rbs-module.rb +26 -0
  228. data/smoke/rbs-module.rbs +4 -0
  229. data/smoke/rbs-opt-and-rest.rb +10 -0
  230. data/smoke/rbs-opt-and-rest.rbs +3 -0
  231. data/smoke/rbs-proc1.rb +2 -1
  232. data/smoke/rbs-proc2.rb +3 -2
  233. data/smoke/rbs-proc3.rb +2 -1
  234. data/smoke/rbs-record.rb +3 -2
  235. data/smoke/rbs-tyvar.rb +3 -2
  236. data/smoke/rbs-tyvar2.rb +3 -2
  237. data/smoke/rbs-tyvar3.rb +3 -2
  238. data/smoke/rbs-tyvar4.rb +4 -3
  239. data/smoke/rbs-tyvar5.rb +2 -1
  240. data/smoke/rbs-tyvar6.rb +4 -3
  241. data/smoke/rbs-tyvar7.rb +2 -1
  242. data/smoke/rbs-vars.rb +7 -6
  243. data/smoke/redo1.rb +3 -2
  244. data/smoke/redo2.rb +3 -2
  245. data/smoke/req-keyword.rb +2 -1
  246. data/smoke/rescue1.rb +3 -2
  247. data/smoke/rescue2.rb +3 -2
  248. data/smoke/rescue3.rb +20 -0
  249. data/smoke/rescue4.rb +17 -0
  250. data/smoke/respond_to.rb +2 -1
  251. data/smoke/rest-farg.rb +2 -1
  252. data/smoke/rest1.rb +3 -2
  253. data/smoke/rest2.rb +2 -1
  254. data/smoke/rest3.rb +7 -6
  255. data/smoke/rest4.rb +3 -2
  256. data/smoke/rest5.rb +2 -1
  257. data/smoke/rest6.rb +2 -1
  258. data/smoke/retry1.rb +3 -2
  259. data/smoke/return.rb +2 -1
  260. data/smoke/simple.rb +12 -0
  261. data/smoke/singleton_method.rb +1 -1
  262. data/smoke/step.rb +4 -3
  263. data/smoke/string-split.rb +2 -1
  264. data/smoke/struct-keyword_init.rb +10 -0
  265. data/smoke/struct.rb +1 -1
  266. data/smoke/struct2.rb +5 -4
  267. data/smoke/struct3.rb +2 -2
  268. data/smoke/struct4.rb +7 -0
  269. data/smoke/struct5.rb +16 -0
  270. data/smoke/struct6.rb +15 -0
  271. data/smoke/struct7.rb +17 -0
  272. data/smoke/stub-keyword.rb +10 -0
  273. data/smoke/super1.rb +5 -4
  274. data/smoke/super2.rb +1 -1
  275. data/smoke/super3.rb +4 -3
  276. data/smoke/super4.rb +7 -5
  277. data/smoke/super5.rb +6 -4
  278. data/smoke/svar1.rb +2 -1
  279. data/smoke/symbol-proc-attr.rb +22 -0
  280. data/smoke/symbol-proc-attr2.rb +15 -0
  281. data/smoke/symbol-proc-bot.rb +13 -0
  282. data/smoke/symbol-proc.rb +4 -3
  283. data/smoke/tap1.rb +3 -2
  284. data/smoke/toplevel.rb +2 -1
  285. data/smoke/two-map.rb +3 -2
  286. data/smoke/type_var.rb +4 -3
  287. data/smoke/typed_method.rb +2 -1
  288. data/smoke/uninitialize-var.rb +2 -1
  289. data/smoke/union-recv.rb +2 -2
  290. data/smoke/user-demo.rb +3 -3
  291. data/smoke/wrong-extend.rb +3 -2
  292. data/smoke/wrong-include.rb +3 -2
  293. data/smoke/wrong-include2.rb +17 -0
  294. data/typeprof.gemspec +1 -1
  295. metadata +57 -5
  296. data/tools/stackprof-wrapper.rb +0 -10
@@ -48,6 +48,8 @@ module TypeProf
48
48
  end
49
49
  opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| options[:show_errors] = v }
50
50
  opt.on("--[no-]show-untyped", "Display \"Foo | untyped\" instead of \"Foo\"") {|v| options[:show_untyped] = v }
51
+ opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| options[:show_parameter_names] = v }
52
+ opt.on("--[no-]show-source-locations", "Display definition source locations for methods") {|v| options[:show_source_locations] = v }
51
53
 
52
54
  opt.separator ""
53
55
  opt.separator "Analysis limit options:"
@@ -14,6 +14,13 @@ module TypeProf
14
14
  keyword_init: true
15
15
  )
16
16
 
17
+ class TypeProfError < StandardError
18
+ def report(output)
19
+ output.puts "# Analysis Error"
20
+ output.puts message
21
+ end
22
+ end
23
+
17
24
  class ConfigData
18
25
  def initialize(**opt)
19
26
  opt[:output] ||= $stdout
@@ -25,6 +32,8 @@ module TypeProf
25
32
  show_indicator: true,
26
33
  show_untyped: false,
27
34
  show_errors: false,
35
+ show_parameter_names: true,
36
+ show_source_locations: false,
28
37
  stub_execution: true,
29
38
  type_depth_limit: 5,
30
39
  stackprof: nil,
@@ -69,7 +78,7 @@ module TypeProf
69
78
 
70
79
  prologue_ctx = Context.new(nil, nil, nil)
71
80
  prologue_ep = ExecutionPoint.new(prologue_ctx, -1, nil)
72
- prologue_env = Env.new(StaticEnv.new(:top, Type.nil, false), [], [], Utils::HashWrapper.new({}))
81
+ prologue_env = Env.new(StaticEnv.new(Type.bot, Type.nil, false, true), [], [], Utils::HashWrapper.new({}))
73
82
 
74
83
  Config.rb_files.each do |rb|
75
84
  if rb.is_a?(Array) # [String name, String content]
@@ -100,6 +109,9 @@ module TypeProf
100
109
  end
101
110
  end
102
111
 
112
+ rescue TypeProfError => exc
113
+ exc.report(Config.output)
114
+
103
115
  ensure
104
116
  if Config.options[:stackprof] && defined?(StackProf)
105
117
  StackProf.stop
@@ -113,7 +125,7 @@ module TypeProf
113
125
  ctx = Context.new(iseq, cref, nil)
114
126
  ep = ExecutionPoint.new(ctx, 0, nil)
115
127
  locals = [Type.nil] * iseq.locals.size
116
- env = Env.new(StaticEnv.new(recv, Type.nil, false), locals, [], Utils::HashWrapper.new({}))
128
+ env = Env.new(StaticEnv.new(recv, Type.nil, false, false), locals, [], Utils::HashWrapper.new({}))
117
129
 
118
130
  return ep, env
119
131
  end
@@ -208,10 +208,6 @@ module TypeProf
208
208
  @base_type = base_type
209
209
  end
210
210
 
211
- def self.dummy_elements
212
- Elements.new([], Type.any)
213
- end
214
-
215
211
  attr_reader :elems, :base_type
216
212
 
217
213
  def inspect
@@ -264,6 +260,10 @@ module TypeProf
264
260
  @lead_tys, @rest_ty = lead_tys, rest_ty
265
261
  end
266
262
 
263
+ def self.dummy_elements
264
+ Elements.new([], Type.any)
265
+ end
266
+
267
267
  attr_reader :lead_tys, :rest_ty
268
268
 
269
269
  def to_local_type(id, base_ty)
@@ -796,6 +796,7 @@ module TypeProf
796
796
  class Local < ContainerType
797
797
  def initialize(kind, id, base_type)
798
798
  @kind = kind
799
+ raise if @kind != Cell && @kind != Array && @kind != Hash
799
800
  @id = id
800
801
  raise unless base_type
801
802
  @base_type = base_type
@@ -72,7 +72,7 @@ module TypeProf
72
72
  gvars.dump.each do |gvar_name, entry|
73
73
  next if entry.type == Type.bot
74
74
  s = entry.rbs_declared ? "#" : ""
75
- output.puts s + "#{ gvar_name } : #{ entry.type.screen_name(scratch) }"
75
+ output.puts s + "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
76
76
  end
77
77
  output.puts
78
78
  end
@@ -105,19 +105,20 @@ module TypeProf
105
105
  consts[name] = ty.screen_name(@scratch)
106
106
  end
107
107
 
108
- included_mods = class_def.modules[false].filter_map do |mod_def, _type_args, absolute_paths|
109
- next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
110
- Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
111
- end
112
-
113
- extended_mods = class_def.modules[true].filter_map do |mod_def, _type_args, absolute_paths|
114
- next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
115
- Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
108
+ modules = class_def.modules.to_h do |kind, mods|
109
+ mods = mods.to_h do |singleton, mods|
110
+ mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
111
+ next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
112
+ Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
113
+ end
114
+ [singleton, mods]
115
+ end
116
+ [kind, mods]
116
117
  end
117
118
 
118
- explicit_methods = {}
119
- iseq_methods = {}
120
- attr_methods = {}
119
+ visibilities = {}
120
+ source_locations = {}
121
+ methods = {}
121
122
  ivars = class_def.ivars.dump
122
123
  cvars = class_def.cvars.dump
123
124
 
@@ -135,28 +136,47 @@ module TypeProf
135
136
  method_name = ctx.mid
136
137
  method_name = "self.#{ method_name }" if singleton
137
138
 
138
- iseq_methods[method_name] ||= []
139
- iseq_methods[method_name] << @scratch.show_method_signature(ctx)
139
+ key = [:iseq, method_name]
140
+ visibilities[key] ||= mdef.pub_meth
141
+ source_locations[key] ||= ctx.iseq.source_location(0)
142
+ (methods[key] ||= []) << @scratch.show_method_signature(ctx)
143
+ end
144
+ when AliasMethodDef
145
+ alias_name, orig_name = mid, mdef.orig_mid
146
+ if singleton
147
+ alias_name = "self.#{ alias_name }"
148
+ orig_name = "self.#{ orig_name }"
140
149
  end
150
+ key = [:alias, alias_name]
151
+ visibilities[key] ||= mdef.pub_meth
152
+ source_locations[key] ||= mdef.def_ep&.source_location
153
+ methods[key] = orig_name
141
154
  when AttrMethodDef
142
- next if !mdef.absolute_path || Config.check_dir_filter(mdef.absolute_path) == :exclude
155
+ next if !mdef.def_ep
156
+ absolute_path = mdef.def_ep.ctx.iseq.absolute_path
157
+ next if !absolute_path || Config.check_dir_filter(absolute_path) == :exclude
143
158
  mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
144
159
  method_name = mid
145
160
  method_name = "self.#{ mid }" if singleton
146
161
  method_name = [method_name, :"@#{ mid }" != mdef.ivar]
147
- if attr_methods[method_name]
148
- if attr_methods[method_name][0] != mdef.kind
149
- attr_methods[method_name][0] = :accessor
162
+ key = [:attr, method_name]
163
+ visibilities[key] ||= mdef.pub_meth
164
+ source_locations[key] ||= mdef.def_ep.source_location
165
+ if methods[key]
166
+ if methods[key][0] != mdef.kind
167
+ methods[key][0] = :accessor
150
168
  end
151
169
  else
152
170
  entry = ivars[[singleton, mdef.ivar]]
153
171
  ty = entry ? entry.type : Type.any
154
- attr_methods[method_name] = [mdef.kind, ty.screen_name(@scratch)]
172
+ methods[key] = [mdef.kind, ty.screen_name(@scratch)]
155
173
  end
156
174
  when TypedMethodDef
157
175
  if mdef.rbs_source
158
176
  method_name, sigs = mdef.rbs_source
159
- explicit_methods[method_name] = sigs
177
+ key = [:rbs, method_name]
178
+ methods[key] = sigs
179
+ visibilities[key] ||= mdef.pub_meth
160
180
  end
161
181
  end
162
182
  end
@@ -167,7 +187,7 @@ module TypeProf
167
187
  ty = entry.type
168
188
  next unless var.to_s.start_with?("@")
169
189
  var = "self.#{ var }" if singleton
170
- next if attr_methods[[singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]
190
+ next if methods[[:attr, [singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]]
171
191
  next if entry.rbs_declared
172
192
  [var, ty.screen_name(@scratch)]
173
193
  end.compact
@@ -179,7 +199,9 @@ module TypeProf
179
199
  end.compact
180
200
 
181
201
  if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
182
- return nil if consts.empty? && included_mods.empty? && extended_mods.empty? && ivars.empty? && cvars.empty? && iseq_methods.empty? && attr_methods.empty? && inner_classes.empty?
202
+ if methods.keys.all? {|type,| type == :rbs }
203
+ return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty? && inner_classes.empty?
204
+ end
183
205
  end
184
206
 
185
207
  @scratch.namespace = nil
@@ -189,18 +211,17 @@ module TypeProf
189
211
  name: class_def.name,
190
212
  superclass: superclass,
191
213
  consts: consts,
192
- included_mods: included_mods,
193
- extended_mods: extended_mods,
214
+ modules: modules,
194
215
  ivars: ivars,
195
216
  cvars: cvars,
196
- attr_methods: attr_methods,
197
- explicit_methods: explicit_methods,
198
- iseq_methods: iseq_methods,
217
+ methods: methods,
218
+ visibilities: visibilities,
219
+ source_locations: source_locations,
199
220
  inner_classes: inner_classes,
200
221
  )
201
222
  end
202
223
 
203
- ClassData = Struct.new(:kind, :name, :superclass, :consts, :included_mods, :extended_mods, :ivars, :cvars, :attr_methods, :explicit_methods, :iseq_methods, :inner_classes, keyword_init: true)
224
+ ClassData = Struct.new(:kind, :name, :superclass, :consts, :modules, :ivars, :cvars, :methods, :visibilities, :source_locations, :inner_classes, keyword_init: true)
204
225
 
205
226
  def show(stat_eps, output)
206
227
  # make the class hierarchy
@@ -217,7 +238,16 @@ module TypeProf
217
238
 
218
239
  output.puts "# Classes" # and Modules
219
240
 
220
- show_class_hierarchy(0, hierarchy, output, true)
241
+ prev_nil = true
242
+ show_class_hierarchy(0, hierarchy).each do |line|
243
+ if line == nil
244
+ output.puts line unless prev_nil
245
+ prev_nil = true
246
+ else
247
+ output.puts line
248
+ prev_nil = false
249
+ end
250
+ end
221
251
 
222
252
  if ENV["TP_STAT"]
223
253
  output.puts ""
@@ -245,13 +275,13 @@ module TypeProf
245
275
  end.compact
246
276
  end
247
277
 
248
- def show_class_hierarchy(depth, hierarchy, output, first)
278
+ def show_class_hierarchy(depth, hierarchy)
279
+ lines = []
249
280
  hierarchy.each do |class_data|
250
- output.puts unless first
251
- first = false
252
-
253
- show_class_data(depth, class_data, output)
281
+ lines << nil
282
+ lines.concat show_class_data(depth, class_data)
254
283
  end
284
+ lines
255
285
  end
256
286
 
257
287
  def show_const(namespace, path)
@@ -261,48 +291,69 @@ module TypeProf
261
291
  path[i..].join("::")
262
292
  end
263
293
 
264
- def show_class_data(depth, class_data, output)
294
+ def show_class_data(depth, class_data)
265
295
  indent = " " * depth
266
296
  name = class_data.name.last
267
297
  superclass = " < " + class_data.superclass if class_data.superclass
268
- output.puts indent + "#{ class_data.kind } #{ name }#{ superclass }"
269
- first = true
298
+ first_line = indent + "#{ class_data.kind } #{ name }#{ superclass }"
299
+ lines = []
270
300
  class_data.consts.each do |name, ty|
271
- output.puts indent + " #{ name } : #{ ty }"
272
- first = false
301
+ lines << (indent + " #{ name }: #{ ty }")
273
302
  end
274
- class_data.included_mods.sort.each do |mod|
275
- output.puts indent + " include #{ mod }"
276
- first = false
277
- end
278
- class_data.extended_mods.sort.each do |mod|
279
- output.puts indent + " extend #{ mod }"
280
- first = false
303
+ class_data.modules.each do |kind, mods|
304
+ mods.each do |singleton, mods|
305
+ case
306
+ when kind == :before && singleton then directive = nil
307
+ when kind == :before && !singleton then directive = "prepend"
308
+ when kind == :after && singleton then directive = "extend"
309
+ when kind == :after && !singleton then directive = "include"
310
+ end
311
+ mods.each do |mod|
312
+ lines << (indent + " #{ directive } #{ mod }") if directive
313
+ end
314
+ end
281
315
  end
282
316
  class_data.ivars.each do |var, ty|
283
- output.puts indent + " #{ var } : #{ ty }" unless var.start_with?("_")
284
- first = false
317
+ lines << (indent + " #{ var }: #{ ty }") unless var.start_with?("_")
285
318
  end
286
319
  class_data.cvars.each do |var, ty|
287
- output.puts indent + " #{ var } : #{ ty }"
288
- first = false
289
- end
290
- class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
291
- output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" } : #{ ty }"
292
- first = false
320
+ lines << (indent + " #{ var }: #{ ty }")
293
321
  end
294
- class_data.explicit_methods.each do |method_name, sigs|
295
- sigs = sigs.sort.join("\n" + indent + "#" + " " * (method_name.size + 6) + "| ")
296
- output.puts indent + "# def #{ method_name } : #{ sigs }"
297
- first = false
298
- end
299
- class_data.iseq_methods.each do |method_name, sigs|
300
- sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 7) + "| ")
301
- output.puts indent + " def #{ method_name } : #{ sigs }"
302
- first = false
322
+ lines << nil
323
+ prev_vis = true
324
+ class_data.methods.each do |key, arg|
325
+ vis = class_data.visibilities[key]
326
+ if prev_vis != vis
327
+ lines << nil
328
+ lines << (indent + " #{ vis ? "public" : "private" }")
329
+ prev_vis = vis
330
+ end
331
+ source_location = class_data.source_locations[key]
332
+ if Config.options[:show_source_locations] && source_location
333
+ lines << nil
334
+ lines << (indent + " # #{ source_location }")
335
+ end
336
+ type, (method_name, hidden) = key
337
+ case type
338
+ when :attr
339
+ kind, ty = *arg
340
+ lines << (indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
341
+ when :rbs
342
+ sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
343
+ lines << (indent + "# def #{ method_name }: #{ sigs }")
344
+ when :iseq
345
+ sigs = arg.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
346
+ lines << (indent + " def #{ method_name }: #{ sigs }")
347
+ when :alias
348
+ orig_name = arg
349
+ lines << (indent + " alias #{ method_name } #{ orig_name }")
350
+ end
303
351
  end
304
- show_class_hierarchy(depth + 1, class_data.inner_classes, output, first)
305
- output.puts indent + "end"
352
+ lines.concat show_class_hierarchy(depth + 1, class_data.inner_classes)
353
+ lines.shift until lines.empty? || lines.first
354
+ lines.pop until lines.empty? || lines.last
355
+ lines.unshift first_line
356
+ lines << (indent + "end")
306
357
  end
307
358
  end
308
359
  end
@@ -26,6 +26,13 @@ module TypeProf
26
26
  def load_library(lib)
27
27
  loader = RBS::EnvironmentLoader.new(core_root: nil)
28
28
  loader.add(library: lib)
29
+
30
+ case lib
31
+ when "yaml"
32
+ loader.add(library: "pstore")
33
+ loader.add(library: "dbm")
34
+ end
35
+
29
36
  new_decls = loader.load(env: @env).map {|decl,| decl }
30
37
  RBSReader.load_rbs(@env, new_decls)
31
38
  end
@@ -62,7 +69,6 @@ module TypeProf
62
69
  class RBS2JSON
63
70
  def initialize(all_env, cur_env)
64
71
  @all_env, @cur_env = all_env, cur_env
65
- @env_walker = RBS::EnvironmentWalker.new(env: @cur_env) # Currently, only each_type_name is used
66
72
  end
67
73
 
68
74
  def dump_json
@@ -110,13 +116,13 @@ module TypeProf
110
116
  end
111
117
 
112
118
  type_params = nil
113
- included_modules = []
114
- extended_modules = []
119
+ modules = { include: [], extend: [], prepend: [] }
115
120
  methods = {}
116
121
  attr_methods = {}
117
122
  ivars = {}
118
123
  cvars = {}
119
124
  rbs_sources = {}
125
+ visibility = true
120
126
 
121
127
  decls.each do |decl|
122
128
  decl = decl.decl
@@ -137,7 +143,7 @@ module TypeProf
137
143
  end
138
144
  end
139
145
 
140
- method_def = conv_method_def(method_types)
146
+ method_def = conv_method_def(method_types, visibility)
141
147
  rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
142
148
  if member.instance?
143
149
  methods[[false, name]] = method_def
@@ -149,13 +155,13 @@ module TypeProf
149
155
  end
150
156
  when RBS::AST::Members::AttrReader
151
157
  ty = conv_type(member.type)
152
- attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
158
+ attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty, visibility)
153
159
  when RBS::AST::Members::AttrWriter
154
160
  ty = conv_type(member.type)
155
- attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
161
+ attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty, visibility)
156
162
  when RBS::AST::Members::AttrAccessor
157
163
  ty = conv_type(member.type)
158
- attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
164
+ attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty, visibility)
159
165
  when RBS::AST::Members::Alias
160
166
  # XXX: an alias to attr methods?
161
167
  if member.instance?
@@ -172,7 +178,7 @@ module TypeProf
172
178
  if name.kind == :class
173
179
  mod = conv_type_name(name)
174
180
  type_args = member.args.map {|type| conv_type(type) }
175
- included_modules << [mod, type_args]
181
+ modules[:include] << [mod, type_args]
176
182
  else
177
183
  # including an interface is not supported yet
178
184
  end
@@ -182,7 +188,17 @@ module TypeProf
182
188
  if name.kind == :class
183
189
  mod = conv_type_name(name)
184
190
  type_args = member.args.map {|type| conv_type(type) }
185
- extended_modules << [mod, type_args]
191
+ modules[:extend] << [mod, type_args]
192
+ else
193
+ # extending a module with an interface is not supported yet
194
+ end
195
+
196
+ when RBS::AST::Members::Prepend
197
+ name = member.name
198
+ if name.kind == :class
199
+ mod = conv_type_name(name)
200
+ type_args = member.args.map {|type| conv_type(type) }
201
+ modules[:prepend] << [mod, type_args]
186
202
  else
187
203
  # extending a module with an interface is not supported yet
188
204
  end
@@ -192,7 +208,10 @@ module TypeProf
192
208
  when RBS::AST::Members::ClassVariable
193
209
  cvars[member.name] = conv_type(member.type)
194
210
 
195
- when RBS::AST::Members::Public, RBS::AST::Members::Private # XXX
211
+ when RBS::AST::Members::Public
212
+ visibility = true
213
+ when RBS::AST::Members::Private
214
+ visibility = false
196
215
 
197
216
  # The following declarations are ignoreable because they are handled in other level
198
217
  when RBS::AST::Declarations::Constant
@@ -210,8 +229,7 @@ module TypeProf
210
229
  type_params: type_params,
211
230
  superclass: superclass,
212
231
  members: {
213
- included_modules: included_modules,
214
- extended_modules: extended_modules,
232
+ modules: modules,
215
233
  methods: methods,
216
234
  attr_methods: attr_methods,
217
235
  ivars: ivars,
@@ -259,19 +277,16 @@ module TypeProf
259
277
  yield decl.name
260
278
  if decl.super_class
261
279
  name = decl.super_class.name
262
- args = decl.super_class.args
263
- if args
264
- args.each do |ty|
265
- @env_walker.each_type_name(ty, &blk)
266
- end
267
- end
268
280
  else
269
281
  name = RBS::BuiltinNames::Object.name
270
282
  end
271
283
  return if decl.name == RBS::BuiltinNames::BasicObject.name
272
284
  return if decl.name == name
273
- @all_env.class_decls[name].decls.each do |decl|
274
- each_reference(decl.decl, &blk)
285
+ decls = @all_env.class_decls[name]
286
+ if decls
287
+ decls.decls.each do |decl|
288
+ each_reference(decl.decl, &blk)
289
+ end
275
290
  end
276
291
  end
277
292
 
@@ -294,10 +309,14 @@ module TypeProf
294
309
  return RBS::BuiltinNames::Object.name, []
295
310
  end
296
311
 
297
- def conv_method_def(rbs_method_types)
298
- rbs_method_types.map do |method_type|
312
+ def conv_method_def(rbs_method_types, visibility)
313
+ sig_rets = rbs_method_types.map do |method_type|
299
314
  conv_func(method_type.type_params, method_type.type, method_type.block)
300
315
  end
316
+ {
317
+ sig_rets: sig_rets,
318
+ visibility: visibility,
319
+ }
301
320
  end
302
321
 
303
322
  def conv_func(type_params, func, block)
@@ -327,11 +346,12 @@ module TypeProf
327
346
  }
328
347
  end
329
348
 
330
- def attr_method_def(kind, name, ty)
349
+ def attr_method_def(kind, name, ty, visibility)
331
350
  {
332
351
  kind: kind,
333
352
  ivar: name,
334
353
  ty: ty,
354
+ visibility: visibility,
335
355
  }
336
356
  end
337
357
 
@@ -445,6 +465,8 @@ module TypeProf
445
465
  json = scratch.rbs_reader.load_library(feature)
446
466
  rescue RBS::EnvironmentLoader::UnknownLibraryError
447
467
  return nil
468
+ rescue RBS::DuplicatedDeclarationError
469
+ return true
448
470
  end
449
471
  # need cache?
450
472
  Import.new(scratch, json).import
@@ -476,8 +498,7 @@ module TypeProf
476
498
 
477
499
  klass = @scratch.get_constant(base_klass, name)
478
500
  if klass.is_a?(Type::Any)
479
- superclass_type_args = superclass_type_args&.map {|ty| conv_type(ty) }
480
- klass = @scratch.new_class(base_klass, name, type_params, superclass, superclass_type_args, nil)
501
+ klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
481
502
 
482
503
  # There builtin classes are needed to interpret RBS declarations
483
504
  case classpath
@@ -493,26 +514,30 @@ module TypeProf
493
514
  end
494
515
  end
495
516
 
496
- [klass, members]
517
+ [klass, superclass_type_args, members]
497
518
  end
498
519
 
499
- classes.each do |klass, members|
500
- included_modules = members[:included_modules]
501
- extended_modules = members[:extended_modules]
520
+ classes.each do |klass, superclass_type_args, members|
521
+ @scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
522
+ modules = members[:modules]
502
523
  methods = members[:methods]
503
524
  attr_methods = members[:attr_methods]
504
525
  ivars = members[:ivars]
505
526
  cvars = members[:cvars]
506
527
  rbs_sources = members[:rbs_sources]
507
528
 
508
- included_modules.each do |mod, type_args|
509
- type_args = type_args&.map {|ty| conv_type(ty) }
510
- @scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
511
- end
512
-
513
- extended_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, true, nil)
529
+ modules.each do |kind, mods|
530
+ mods.each do |mod, type_args|
531
+ type_args = type_args&.map {|ty| conv_type(ty) }
532
+ case kind
533
+ when :include
534
+ @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, false, nil)
535
+ when :extend
536
+ @scratch.mix_module(:after, klass, path_to_klass(mod), type_args, true, nil)
537
+ when :prepend
538
+ @scratch.mix_module(:before, klass, path_to_klass(mod), type_args, false, nil)
539
+ end
540
+ end
516
541
  end
517
542
 
518
543
  methods.each do |(singleton, method_name), mdef|
@@ -525,7 +550,7 @@ module TypeProf
525
550
  kind = mdef[:kind]
526
551
  ivar = mdef[:ivar]
527
552
  ty = conv_type(mdef[:ty]).remove_type_vars
528
- @scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
553
+ @scratch.add_attr_method(klass, ivar, :"@#{ ivar }", kind, mdef[:visibility], nil)
529
554
  @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
530
555
  end
531
556
 
@@ -555,11 +580,11 @@ module TypeProf
555
580
  end
556
581
 
557
582
  def conv_method_def(method_name, mdef, rbs_source)
558
- sig_rets = mdef.flat_map do |sig_ret|
583
+ sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
559
584
  conv_func(sig_ret)
560
585
  end
561
586
 
562
- TypedMethodDef.new(sig_rets, rbs_source)
587
+ TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
563
588
  end
564
589
 
565
590
  def conv_func(sig_ret)
@@ -659,7 +684,9 @@ module TypeProf
659
684
  klass = Type::Builtin[:obj]
660
685
  path.each do |name|
661
686
  klass = @scratch.get_constant(klass, name)
662
- raise path.inspect if klass == Type.any
687
+ if klass == Type.any
688
+ raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
689
+ end
663
690
  end
664
691
  klass
665
692
  end