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
@@ -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(TopStaticEnv.new, [], [], 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
@@ -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,29 +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] ||= [true, []]
139
- iseq_methods[method_name][0] &&= mdef.pub_meth
140
- iseq_methods[method_name][1] << @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 }"
141
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
142
154
  when AttrMethodDef
143
- 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
144
158
  mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
145
159
  method_name = mid
146
160
  method_name = "self.#{ mid }" if singleton
147
161
  method_name = [method_name, :"@#{ mid }" != mdef.ivar]
148
- if attr_methods[method_name]
149
- if attr_methods[method_name][0] != mdef.kind
150
- 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
151
168
  end
152
169
  else
153
170
  entry = ivars[[singleton, mdef.ivar]]
154
171
  ty = entry ? entry.type : Type.any
155
- attr_methods[method_name] = [mdef.kind, ty.screen_name(@scratch)]
172
+ methods[key] = [mdef.kind, ty.screen_name(@scratch)]
156
173
  end
157
174
  when TypedMethodDef
158
175
  if mdef.rbs_source
159
176
  method_name, sigs = mdef.rbs_source
160
- explicit_methods[method_name] = sigs
177
+ key = [:rbs, method_name]
178
+ methods[key] = sigs
179
+ visibilities[key] ||= mdef.pub_meth
161
180
  end
162
181
  end
163
182
  end
@@ -168,7 +187,7 @@ module TypeProf
168
187
  ty = entry.type
169
188
  next unless var.to_s.start_with?("@")
170
189
  var = "self.#{ var }" if singleton
171
- 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]]]
172
191
  next if entry.rbs_declared
173
192
  [var, ty.screen_name(@scratch)]
174
193
  end.compact
@@ -180,7 +199,9 @@ module TypeProf
180
199
  end.compact
181
200
 
182
201
  if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
183
- 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
184
205
  end
185
206
 
186
207
  @scratch.namespace = nil
@@ -190,18 +211,17 @@ module TypeProf
190
211
  name: class_def.name,
191
212
  superclass: superclass,
192
213
  consts: consts,
193
- included_mods: included_mods,
194
- extended_mods: extended_mods,
214
+ modules: modules,
195
215
  ivars: ivars,
196
216
  cvars: cvars,
197
- attr_methods: attr_methods,
198
- explicit_methods: explicit_methods,
199
- iseq_methods: iseq_methods,
217
+ methods: methods,
218
+ visibilities: visibilities,
219
+ source_locations: source_locations,
200
220
  inner_classes: inner_classes,
201
221
  )
202
222
  end
203
223
 
204
- 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)
205
225
 
206
226
  def show(stat_eps, output)
207
227
  # make the class hierarchy
@@ -218,7 +238,16 @@ module TypeProf
218
238
 
219
239
  output.puts "# Classes" # and Modules
220
240
 
221
- 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
222
251
 
223
252
  if ENV["TP_STAT"]
224
253
  output.puts ""
@@ -246,13 +275,13 @@ module TypeProf
246
275
  end.compact
247
276
  end
248
277
 
249
- def show_class_hierarchy(depth, hierarchy, output, first)
278
+ def show_class_hierarchy(depth, hierarchy)
279
+ lines = []
250
280
  hierarchy.each do |class_data|
251
- output.puts unless first
252
- first = false
253
-
254
- show_class_data(depth, class_data, output)
281
+ lines << nil
282
+ lines.concat show_class_data(depth, class_data)
255
283
  end
284
+ lines
256
285
  end
257
286
 
258
287
  def show_const(namespace, path)
@@ -262,53 +291,69 @@ module TypeProf
262
291
  path[i..].join("::")
263
292
  end
264
293
 
265
- def show_class_data(depth, class_data, output)
294
+ def show_class_data(depth, class_data)
266
295
  indent = " " * depth
267
296
  name = class_data.name.last
268
297
  superclass = " < " + class_data.superclass if class_data.superclass
269
- output.puts indent + "#{ class_data.kind } #{ name }#{ superclass }"
270
- first = true
298
+ first_line = indent + "#{ class_data.kind } #{ name }#{ superclass }"
299
+ lines = []
271
300
  class_data.consts.each do |name, ty|
272
- output.puts indent + " #{ name }: #{ ty }"
273
- first = false
274
- end
275
- class_data.included_mods.sort.each do |mod|
276
- output.puts indent + " include #{ mod }"
277
- first = false
301
+ lines << (indent + " #{ name }: #{ ty }")
278
302
  end
279
- class_data.extended_mods.sort.each do |mod|
280
- output.puts indent + " extend #{ mod }"
281
- 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
282
315
  end
283
316
  class_data.ivars.each do |var, ty|
284
- output.puts indent + " #{ var }: #{ ty }" unless var.start_with?("_")
285
- first = false
317
+ lines << (indent + " #{ var }: #{ ty }") unless var.start_with?("_")
286
318
  end
287
319
  class_data.cvars.each do |var, ty|
288
- output.puts indent + " #{ var }: #{ ty }"
289
- first = false
320
+ lines << (indent + " #{ var }: #{ ty }")
290
321
  end
291
- class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
292
- output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }"
293
- first = false
294
- end
295
- class_data.explicit_methods.each do |method_name, sigs|
296
- sigs = sigs.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
297
- output.puts indent + "# def #{ method_name }: #{ sigs }"
298
- first = false
299
- end
300
- prev_pub_meth = true
301
- class_data.iseq_methods.each do |method_name, (pub_meth, sigs)|
302
- sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
303
- if prev_pub_meth != pub_meth
304
- output.puts indent + " #{ pub_meth ? "public" : "private" }"
305
- prev_pub_meth = pub_meth
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 }")
306
350
  end
307
- output.puts indent + " def #{ method_name }: #{ sigs }"
308
- first = false
309
351
  end
310
- show_class_hierarchy(depth + 1, class_data.inner_classes, output, first)
311
- 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")
312
357
  end
313
358
  end
314
359
  end
@@ -116,13 +116,13 @@ module TypeProf
116
116
  end
117
117
 
118
118
  type_params = nil
119
- included_modules = []
120
- extended_modules = []
119
+ modules = { include: [], extend: [], prepend: [] }
121
120
  methods = {}
122
121
  attr_methods = {}
123
122
  ivars = {}
124
123
  cvars = {}
125
124
  rbs_sources = {}
125
+ visibility = true
126
126
 
127
127
  decls.each do |decl|
128
128
  decl = decl.decl
@@ -143,7 +143,7 @@ module TypeProf
143
143
  end
144
144
  end
145
145
 
146
- method_def = conv_method_def(method_types)
146
+ method_def = conv_method_def(method_types, visibility)
147
147
  rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
148
148
  if member.instance?
149
149
  methods[[false, name]] = method_def
@@ -155,13 +155,13 @@ module TypeProf
155
155
  end
156
156
  when RBS::AST::Members::AttrReader
157
157
  ty = conv_type(member.type)
158
- 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)
159
159
  when RBS::AST::Members::AttrWriter
160
160
  ty = conv_type(member.type)
161
- 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)
162
162
  when RBS::AST::Members::AttrAccessor
163
163
  ty = conv_type(member.type)
164
- 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)
165
165
  when RBS::AST::Members::Alias
166
166
  # XXX: an alias to attr methods?
167
167
  if member.instance?
@@ -178,7 +178,7 @@ module TypeProf
178
178
  if name.kind == :class
179
179
  mod = conv_type_name(name)
180
180
  type_args = member.args.map {|type| conv_type(type) }
181
- included_modules << [mod, type_args]
181
+ modules[:include] << [mod, type_args]
182
182
  else
183
183
  # including an interface is not supported yet
184
184
  end
@@ -188,7 +188,17 @@ module TypeProf
188
188
  if name.kind == :class
189
189
  mod = conv_type_name(name)
190
190
  type_args = member.args.map {|type| conv_type(type) }
191
- 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]
192
202
  else
193
203
  # extending a module with an interface is not supported yet
194
204
  end
@@ -198,7 +208,10 @@ module TypeProf
198
208
  when RBS::AST::Members::ClassVariable
199
209
  cvars[member.name] = conv_type(member.type)
200
210
 
201
- 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
202
215
 
203
216
  # The following declarations are ignoreable because they are handled in other level
204
217
  when RBS::AST::Declarations::Constant
@@ -216,8 +229,7 @@ module TypeProf
216
229
  type_params: type_params,
217
230
  superclass: superclass,
218
231
  members: {
219
- included_modules: included_modules,
220
- extended_modules: extended_modules,
232
+ modules: modules,
221
233
  methods: methods,
222
234
  attr_methods: attr_methods,
223
235
  ivars: ivars,
@@ -297,10 +309,14 @@ module TypeProf
297
309
  return RBS::BuiltinNames::Object.name, []
298
310
  end
299
311
 
300
- def conv_method_def(rbs_method_types)
301
- 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|
302
314
  conv_func(method_type.type_params, method_type.type, method_type.block)
303
315
  end
316
+ {
317
+ sig_rets: sig_rets,
318
+ visibility: visibility,
319
+ }
304
320
  end
305
321
 
306
322
  def conv_func(type_params, func, block)
@@ -330,11 +346,12 @@ module TypeProf
330
346
  }
331
347
  end
332
348
 
333
- def attr_method_def(kind, name, ty)
349
+ def attr_method_def(kind, name, ty, visibility)
334
350
  {
335
351
  kind: kind,
336
352
  ivar: name,
337
353
  ty: ty,
354
+ visibility: visibility,
338
355
  }
339
356
  end
340
357
 
@@ -502,22 +519,25 @@ module TypeProf
502
519
 
503
520
  classes.each do |klass, superclass_type_args, members|
504
521
  @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]
522
+ modules = members[:modules]
507
523
  methods = members[:methods]
508
524
  attr_methods = members[:attr_methods]
509
525
  ivars = members[:ivars]
510
526
  cvars = members[:cvars]
511
527
  rbs_sources = members[:rbs_sources]
512
528
 
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)
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
521
541
  end
522
542
 
523
543
  methods.each do |(singleton, method_name), mdef|
@@ -530,7 +550,7 @@ module TypeProf
530
550
  kind = mdef[:kind]
531
551
  ivar = mdef[:ivar]
532
552
  ty = conv_type(mdef[:ty]).remove_type_vars
533
- @scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
553
+ @scratch.add_attr_method(klass, ivar, :"@#{ ivar }", kind, mdef[:visibility], nil)
534
554
  @scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
535
555
  end
536
556
 
@@ -560,11 +580,11 @@ module TypeProf
560
580
  end
561
581
 
562
582
  def conv_method_def(method_name, mdef, rbs_source)
563
- sig_rets = mdef.flat_map do |sig_ret|
583
+ sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
564
584
  conv_func(sig_ret)
565
585
  end
566
586
 
567
- TypedMethodDef.new(sig_rets, rbs_source)
587
+ TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
568
588
  end
569
589
 
570
590
  def conv_func(sig_ret)
@@ -664,7 +684,9 @@ module TypeProf
664
684
  klass = Type::Builtin[:obj]
665
685
  path.each do |name|
666
686
  klass = @scratch.get_constant(klass, name)
667
- 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
668
690
  end
669
691
  klass
670
692
  end