typeprof 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -2
  3. data/lib/typeprof/analyzer.rb +82 -59
  4. data/lib/typeprof/block.rb +34 -0
  5. data/lib/typeprof/builtin.rb +169 -64
  6. data/lib/typeprof/cli.rb +2 -0
  7. data/lib/typeprof/config.rb +13 -1
  8. data/lib/typeprof/export.rb +114 -69
  9. data/lib/typeprof/import.rb +50 -28
  10. data/lib/typeprof/iseq.rb +23 -4
  11. data/lib/typeprof/method.rb +29 -7
  12. data/lib/typeprof/type.rb +41 -13
  13. data/lib/typeprof/version.rb +1 -1
  14. data/smoke/alias.rb +4 -4
  15. data/smoke/alias2.rb +3 -1
  16. data/smoke/arguments.rb +2 -2
  17. data/smoke/arguments2.rb +5 -5
  18. data/smoke/array-each.rb +1 -1
  19. data/smoke/array-each3.rb +1 -1
  20. data/smoke/array-map.rb +1 -1
  21. data/smoke/array-map2.rb +1 -1
  22. data/smoke/array-map3.rb +3 -3
  23. data/smoke/array-mul.rb +2 -2
  24. data/smoke/array-plus1.rb +1 -1
  25. data/smoke/array-plus2.rb +1 -0
  26. data/smoke/array-range-aref.rb +11 -11
  27. data/smoke/array-replace.rb +1 -1
  28. data/smoke/array1.rb +5 -5
  29. data/smoke/array10.rb +1 -1
  30. data/smoke/array11.rb +1 -1
  31. data/smoke/array12.rb +1 -1
  32. data/smoke/array14.rb +1 -1
  33. data/smoke/array15.rb +1 -1
  34. data/smoke/array2.rb +2 -2
  35. data/smoke/array3.rb +1 -0
  36. data/smoke/array6.rb +2 -1
  37. data/smoke/array8.rb +1 -1
  38. data/smoke/array9.rb +1 -1
  39. data/smoke/attr-module.rb +1 -0
  40. data/smoke/attr-vis.rb +43 -0
  41. data/smoke/attr-vis.rbs +4 -0
  42. data/smoke/attr.rb +2 -2
  43. data/smoke/block-ambiguous.rb +4 -4
  44. data/smoke/block-args1-rest.rb +6 -5
  45. data/smoke/block-args1.rb +5 -5
  46. data/smoke/block-args2-rest.rb +6 -5
  47. data/smoke/block-args2.rb +5 -5
  48. data/smoke/block-args3-rest.rb +7 -6
  49. data/smoke/block-args3.rb +6 -6
  50. data/smoke/block-blockarg.rb +3 -3
  51. data/smoke/block-kwarg.rb +4 -4
  52. data/smoke/block1.rb +1 -1
  53. data/smoke/block10.rb +1 -1
  54. data/smoke/block11.rb +2 -2
  55. data/smoke/block2.rb +1 -1
  56. data/smoke/block3.rb +1 -1
  57. data/smoke/block5.rb +1 -0
  58. data/smoke/block_given.rb +37 -0
  59. data/smoke/class_method.rb +2 -2
  60. data/smoke/class_method2.rb +2 -2
  61. data/smoke/constant2.rb +3 -2
  62. data/smoke/context-sensitive1.rb +1 -1
  63. data/smoke/cvar.rb +3 -2
  64. data/smoke/define_method.rb +2 -2
  65. data/smoke/define_method3.rb +1 -0
  66. data/smoke/define_method4.rb +1 -1
  67. data/smoke/define_method6.rb +19 -0
  68. data/smoke/demo.rb +6 -6
  69. data/smoke/demo1.rb +1 -1
  70. data/smoke/demo11.rb +1 -1
  71. data/smoke/demo2.rb +1 -1
  72. data/smoke/demo3.rb +1 -1
  73. data/smoke/demo4.rb +3 -3
  74. data/smoke/demo5.rb +1 -1
  75. data/smoke/demo6.rb +2 -1
  76. data/smoke/demo7.rb +1 -1
  77. data/smoke/demo9.rb +1 -0
  78. data/smoke/dummy-execution1.rb +1 -1
  79. data/smoke/dummy-execution2.rb +1 -1
  80. data/smoke/dummy_element.rb +1 -1
  81. data/smoke/ensure1.rb +1 -1
  82. data/smoke/enum_for.rb +15 -0
  83. data/smoke/enum_for2.rb +17 -0
  84. data/smoke/fib.rb +2 -2
  85. data/smoke/flow1.rb +1 -1
  86. data/smoke/flow10.rb +17 -0
  87. data/smoke/flow2.rb +1 -1
  88. data/smoke/flow3.rb +1 -1
  89. data/smoke/flow5.rb +1 -1
  90. data/smoke/flow6.rb +1 -1
  91. data/smoke/flow7.rb +1 -1
  92. data/smoke/flow8.rb +1 -1
  93. data/smoke/flow9.rb +1 -1
  94. data/smoke/function.rb +1 -1
  95. data/smoke/gvar.rb +1 -1
  96. data/smoke/gvar2.rb +1 -1
  97. data/smoke/hash-fetch.rb +3 -3
  98. data/smoke/inheritance.rb +4 -4
  99. data/smoke/initialize.rb +3 -2
  100. data/smoke/instance_eval.rb +1 -1
  101. data/smoke/int_times.rb +1 -1
  102. data/smoke/integer.rb +1 -1
  103. data/smoke/ivar.rb +3 -2
  104. data/smoke/ivar2.rb +2 -2
  105. data/smoke/ivar3.rb +2 -1
  106. data/smoke/ivar4.rb +1 -0
  107. data/smoke/kernel-class.rb +1 -1
  108. data/smoke/keyword4.rb +1 -1
  109. data/smoke/kwrest.rb +1 -0
  110. data/smoke/kwsplat1.rb +2 -2
  111. data/smoke/kwsplat2.rb +1 -1
  112. data/smoke/manual-rbs.rb +1 -0
  113. data/smoke/manual-rbs3.rb +1 -0
  114. data/smoke/method_missing.rb +4 -3
  115. data/smoke/module3.rb +1 -1
  116. data/smoke/module4.rb +1 -0
  117. data/smoke/module5.rb +1 -1
  118. data/smoke/module_function1.rb +3 -2
  119. data/smoke/module_function2.rb +3 -2
  120. data/smoke/multiple-include.rb +1 -0
  121. data/smoke/next1.rb +1 -1
  122. data/smoke/object-send1.rb +3 -3
  123. data/smoke/optional1.rb +1 -1
  124. data/smoke/optional2.rb +1 -1
  125. data/smoke/optional3.rb +1 -1
  126. data/smoke/parameterizedd-self.rb +2 -1
  127. data/smoke/prepend1.rb +33 -0
  128. data/smoke/prepend2.rb +10 -0
  129. data/smoke/prepend2.rbs +9 -0
  130. data/smoke/primitive_method.rb +19 -0
  131. data/smoke/proc4.rb +1 -1
  132. data/smoke/public.rb +4 -0
  133. data/smoke/range.rb +1 -1
  134. data/smoke/rbs-attr.rb +2 -2
  135. data/smoke/rbs-proc2.rb +1 -1
  136. data/smoke/rbs-proc3.rb +1 -1
  137. data/smoke/rbs-tyvar4.rb +3 -2
  138. data/smoke/rbs-tyvar6.rb +3 -3
  139. data/smoke/redo1.rb +1 -1
  140. data/smoke/redo2.rb +1 -1
  141. data/smoke/rescue1.rb +1 -1
  142. data/smoke/rescue2.rb +1 -1
  143. data/smoke/rescue3.rb +1 -0
  144. data/smoke/rescue4.rb +1 -1
  145. data/smoke/respond_to.rb +1 -1
  146. data/smoke/rest1.rb +2 -2
  147. data/smoke/rest2.rb +1 -1
  148. data/smoke/rest3.rb +6 -6
  149. data/smoke/rest4.rb +2 -2
  150. data/smoke/rest5.rb +1 -1
  151. data/smoke/rest6.rb +1 -1
  152. data/smoke/retry1.rb +2 -2
  153. data/smoke/simple.rb +1 -1
  154. data/smoke/step.rb +3 -3
  155. data/smoke/struct-keyword_init.rb +5 -15
  156. data/smoke/struct5.rb +1 -1
  157. data/smoke/struct6.rb +1 -1
  158. data/smoke/super1.rb +4 -4
  159. data/smoke/super3.rb +3 -2
  160. data/smoke/super4.rb +7 -5
  161. data/smoke/super5.rb +6 -4
  162. data/smoke/symbol-proc-attr.rb +1 -1
  163. data/smoke/tap1.rb +2 -2
  164. data/smoke/toplevel.rb +1 -1
  165. data/smoke/type_var.rb +3 -3
  166. data/smoke/user-demo.rb +1 -1
  167. data/smoke/wrong-extend.rb +1 -0
  168. data/smoke/wrong-include.rb +1 -0
  169. data/smoke/wrong-include2.rb +1 -1
  170. metadata +14 -3
@@ -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