typeprof 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -147,7 +147,7 @@ module TypeProf
147
147
 
148
148
  def module_include(recv, mid, aargs, ep, env, scratch, &ctn)
149
149
  arg = aargs.lead_tys[0]
150
- scratch.include_module(recv, arg)
150
+ scratch.include_module(recv, arg, ep.ctx.iseq.absolute_path)
151
151
  ctn[recv, ep, env]
152
152
  end
153
153
 
@@ -155,7 +155,7 @@ module TypeProf
155
155
  arg = aargs.lead_tys[0]
156
156
  arg.each_child do |arg|
157
157
  if arg.is_a?(Type::Class)
158
- scratch.extend_module(recv, arg)
158
+ scratch.extend_module(recv, arg, ep.ctx.iseq.absolute_path)
159
159
  end
160
160
  end
161
161
  ctn[recv, ep, env]
@@ -180,7 +180,7 @@ module TypeProf
180
180
  aargs.lead_tys.each do |aarg|
181
181
  sym = get_sym("attr_accessor", aarg, ep, scratch) or next
182
182
  cref = ep.ctx.cref
183
- scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :accessor)
183
+ scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :accessor)
184
184
  end
185
185
  ctn[Type.nil, ep, env]
186
186
  end
@@ -189,7 +189,7 @@ module TypeProf
189
189
  aargs.lead_tys.each do |aarg|
190
190
  sym = get_sym("attr_reader", aarg, ep, scratch) or next
191
191
  cref = ep.ctx.cref
192
- scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :reader)
192
+ scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :reader)
193
193
  end
194
194
  ctn[Type.nil, ep, env]
195
195
  end
@@ -198,7 +198,7 @@ module TypeProf
198
198
  aargs.lead_tys.each do |aarg|
199
199
  sym = get_sym("attr_writer", aarg, ep, scratch) or next
200
200
  cref = ep.ctx.cref
201
- scratch.add_attr_method(cref.klass, sym, :"@#{ sym }", :writer)
201
+ scratch.add_attr_method(cref.klass, ep.ctx.iseq.absolute_path, sym, :"@#{ sym }", :writer)
202
202
  end
203
203
  ctn[Type.nil, ep, env]
204
204
  end
@@ -283,8 +283,6 @@ module TypeProf
283
283
  return
284
284
  end
285
285
  idx = aargs.lead_tys.first
286
- #idx = scratch.globalize_type(idx, env, ep)
287
- # XXX: recv may be a union
288
286
  recv.each_child do |recv|
289
287
  if recv.is_a?(Type::LocalHash)
290
288
  ty = scratch.get_hash_elem_type(env, ep, recv.id, idx)
@@ -358,21 +356,21 @@ module TypeProf
358
356
  fields = aargs.lead_tys.map {|ty| get_sym("Struct.new", ty, ep, scratch) }.compact
359
357
  struct_klass = scratch.new_struct(ep)
360
358
 
361
- scratch.add_singleton_custom_method(struct_klass, :new, Builtin.method(:struct_i_new))
362
- scratch.add_singleton_custom_method(struct_klass, :[], Builtin.method(:struct_i_new))
359
+ scratch.set_singleton_custom_method(struct_klass, :new, Builtin.method(:struct_i_new))
360
+ scratch.set_singleton_custom_method(struct_klass, :[], Builtin.method(:struct_i_new))
363
361
  fields.each do |field|
364
- scratch.add_attr_method(struct_klass, field, field, :accessor)
362
+ scratch.add_attr_method(struct_klass, ep.ctx.iseq.absolute_path, field, field, :accessor)
365
363
  end
366
364
  fields = fields.map {|field| Type::Symbol.new(field, Type::Instance.new(Type::Builtin[:sym])) }
367
365
  base_ty = Type::Instance.new(Type::Builtin[:ary])
368
366
  fields = Type::Array.new(Type::Array::Elements.new(fields), base_ty)
369
367
  scratch.set_instance_variable(Type::Instance.new(struct_klass), :_members, fields, ep, env)
370
- #add_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
368
+ #set_singleton_custom_method(struct_klass, :members, Builtin.method(:...))
371
369
 
372
370
  ctn[struct_klass, ep, env]
373
371
  end
374
372
 
375
- def file_load(path, ep, env, scratch, &ctn)
373
+ def self.file_load(path, ep, env, scratch, &ctn)
376
374
  iseq = ISeq.compile(path)
377
375
  callee_ep, callee_env = CLI.starting_state(iseq)
378
376
  scratch.merge_env(callee_ep, callee_env)
@@ -383,51 +381,60 @@ module TypeProf
383
381
  end
384
382
  end
385
383
 
384
+ def self.file_require(feature, scratch)
385
+ return :done, :false if scratch.loaded_features[feature]
386
+ scratch.loaded_features[feature] = true
387
+
388
+ # XXX: dynamic RBS load is really needed?? Another idea:
389
+ #
390
+ # * RBS should be loaded in advance of analysis
391
+ # * require "some_gem/foo" should be ignored
392
+ # * require "app/foo" should always load .rb file (in this case, app/foo.rb)
393
+ return :done, :true if Import.import_library(scratch, feature)
394
+
395
+ # Try to analyze the source code of the gem
396
+ begin
397
+ gem feature
398
+ rescue Gem::MissingSpecError, Gem::LoadError
399
+ end
400
+
401
+ begin
402
+ filetype, path = $LOAD_PATH.resolve_feature_path(feature)
403
+ if filetype == :rb
404
+ return :do, path if File.readable?(path)
405
+
406
+ return :error, "failed to load: #{ path }"
407
+ else
408
+ return :error, "cannot load a .so file: #{ path }"
409
+ end
410
+ rescue LoadError
411
+ return :error, "failed to require: #{ feature }"
412
+ end
413
+ end
414
+
386
415
  def kernel_require(recv, mid, aargs, ep, env, scratch, &ctn)
387
416
  raise NotImplementedError if aargs.lead_tys.size != 1
388
417
  feature = aargs.lead_tys.first
389
418
  if feature.is_a?(Type::Literal)
390
419
  feature = feature.lit
391
420
 
392
- begin
393
- if scratch.loaded_features[feature]
394
- result = Type::Instance.new(Type::Builtin[:false])
395
- return ctn[result, ep, env]
396
- end
397
- scratch.loaded_features[feature] = true
398
-
399
- # XXX: dynamic RBS load is really needed?? Another idea:
400
- #
401
- # * RBS should be loaded in advance of analysis
402
- # * require "some_gem/foo" should be ignored
403
- # * require "app/foo" should always load .rb file (in this case, app/foo.rb)
404
- if RubySignatureImporter.import_library(scratch, feature)
405
- result = Type::Instance.new(Type::Builtin[:true])
406
- return ctn[result, ep, env]
407
- end
408
-
409
- begin
410
- gem feature
411
- rescue Gem::MissingSpecError, Gem::LoadError
412
- end
413
- filetype, path = $LOAD_PATH.resolve_feature_path(feature)
414
- if filetype == :rb
415
- # TODO: if there is RBS file for the library, do not read the source code
416
- return file_load(path, ep, env, scratch, &ctn) if File.readable?(path)
417
-
418
- scratch.warn(ep, "failed to load: #{ path }")
419
- else
420
- scratch.warn(ep, "cannot load a .so file: #{ path }")
421
- end
422
- rescue LoadError
423
- scratch.warn(ep, "failed to require: #{ feature }")
421
+ action, arg = Builtin.file_require(feature, scratch)
422
+ case action
423
+ when :do
424
+ Builtin.file_load(arg, ep, env, scratch, &ctn)
425
+ when :done
426
+ result = Type::Instance.new(Type::Builtin[arg])
427
+ ctn[result, ep, env]
428
+ when :error
429
+ scratch.warn(ep, arg)
430
+ result = Type::Instance.new(Type.bool)
431
+ ctn[result, ep, env]
424
432
  end
425
433
  else
426
434
  scratch.warn(ep, "require target cannot be identified statically")
435
+ result = Type::Instance.new(Type.bool)
436
+ ctn[result, ep, env]
427
437
  end
428
-
429
- result = Type::Instance.new(Type::Builtin[:true])
430
- ctn[result, ep, env]
431
438
  end
432
439
 
433
440
  def kernel_require_relative(recv, mid, aargs, ep, env, scratch, &ctn)
@@ -443,7 +450,7 @@ module TypeProf
443
450
  scratch.loaded_features[feature] = true
444
451
 
445
452
  path = File.join(File.dirname(ep.ctx.iseq.path), feature) + ".rb" # XXX
446
- return file_load(path, ep, env, scratch, &ctn) if File.readable?(path)
453
+ return Builtin.file_load(path, ep, env, scratch, &ctn) if File.readable?(path)
447
454
 
448
455
  scratch.warn(ep, "failed to load: #{ path }")
449
456
  else
@@ -473,20 +480,17 @@ module TypeProf
473
480
  end
474
481
 
475
482
  def self.setup_initial_global_env(scratch)
476
- klass_obj = scratch.new_class(nil, :Object, [], :__root__) # cbase, name, superclass
483
+ klass_basic_obj = scratch.new_class(nil, :BasicObject, [], :__root__, nil) # cbase, name, superclass
484
+ klass_obj = scratch.new_class(nil, :Object, [], klass_basic_obj, nil)
477
485
  scratch.add_constant(klass_obj, "Object", klass_obj)
478
- klass_true = scratch.new_class(klass_obj, :TrueClass, [], klass_obj) # ???
479
- klass_false = scratch.new_class(klass_obj, :FalseClass, [], klass_obj) # ???
480
- klass_nil = scratch.new_class(klass_obj, :NilClass, [], klass_obj) # ???
486
+ scratch.add_constant(klass_obj, "BasicObject", klass_basic_obj)
481
487
 
488
+ Type::Builtin[:basic_obj] = klass_basic_obj
482
489
  Type::Builtin[:obj] = klass_obj
483
- Type::Builtin[:true] = klass_true
484
- Type::Builtin[:false] = klass_false
485
- Type::Builtin[:nil] = klass_nil
486
490
 
487
- RubySignatureImporter.import_builtin(scratch)
491
+ Import.import_builtin(scratch)
488
492
 
489
- Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj)
493
+ Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
490
494
  Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
491
495
  Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
492
496
  Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
@@ -511,41 +515,41 @@ module TypeProf
511
515
  klass_proc = Type::Builtin[:proc]
512
516
  klass_module = Type::Builtin[:module]
513
517
 
514
- scratch.add_custom_method(klass_vmcore, :"core#set_method_alias", Builtin.method(:vmcore_set_method_alias))
515
- scratch.add_custom_method(klass_vmcore, :"core#undef_method", Builtin.method(:vmcore_undef_method))
516
- scratch.add_custom_method(klass_vmcore, :"core#hash_merge_kwd", Builtin.method(:vmcore_hash_merge_kwd))
517
- scratch.add_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
518
- scratch.add_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
519
- scratch.add_singleton_custom_method(klass_obj, :"attr_accessor", Builtin.method(:module_attr_accessor))
520
- scratch.add_singleton_custom_method(klass_obj, :"attr_reader", Builtin.method(:module_attr_reader))
521
- scratch.add_singleton_custom_method(klass_obj, :"attr_writer", Builtin.method(:module_attr_writer))
522
- scratch.add_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
523
- scratch.add_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
524
- scratch.add_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
525
- scratch.add_custom_method(klass_obj, :class, Builtin.method(:object_class))
526
- scratch.add_custom_method(klass_obj, :send, Builtin.method(:object_send))
527
- scratch.add_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
528
-
529
- scratch.add_custom_method(klass_module, :include, Builtin.method(:module_include))
530
- scratch.add_custom_method(klass_module, :extend, Builtin.method(:module_extend))
531
- scratch.add_custom_method(klass_module, :module_function, Builtin.method(:module_module_function))
532
-
533
- scratch.add_custom_method(klass_proc, :[], Builtin.method(:proc_call))
534
- scratch.add_custom_method(klass_proc, :call, Builtin.method(:proc_call))
535
-
536
- scratch.add_custom_method(klass_ary, :[], Builtin.method(:array_aref))
537
- scratch.add_custom_method(klass_ary, :[]=, Builtin.method(:array_aset))
538
- scratch.add_custom_method(klass_ary, :pop, Builtin.method(:array_pop))
539
-
540
- scratch.add_custom_method(klass_hash, :[], Builtin.method(:hash_aref))
541
- scratch.add_custom_method(klass_hash, :[]=, Builtin.method(:hash_aset))
542
-
543
- scratch.add_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
544
- scratch.add_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
545
-
546
- scratch.add_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
547
- scratch.add_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
548
- scratch.add_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array))
518
+ scratch.set_custom_method(klass_vmcore, :"core#set_method_alias", Builtin.method(:vmcore_set_method_alias))
519
+ scratch.set_custom_method(klass_vmcore, :"core#undef_method", Builtin.method(:vmcore_undef_method))
520
+ scratch.set_custom_method(klass_vmcore, :"core#hash_merge_kwd", Builtin.method(:vmcore_hash_merge_kwd))
521
+ scratch.set_custom_method(klass_vmcore, :lambda, Builtin.method(:lambda))
522
+ scratch.set_singleton_custom_method(klass_obj, :"new", Builtin.method(:object_s_new))
523
+ scratch.set_singleton_custom_method(klass_obj, :"attr_accessor", Builtin.method(:module_attr_accessor))
524
+ scratch.set_singleton_custom_method(klass_obj, :"attr_reader", Builtin.method(:module_attr_reader))
525
+ scratch.set_singleton_custom_method(klass_obj, :"attr_writer", Builtin.method(:module_attr_writer))
526
+ scratch.set_custom_method(klass_obj, :p, Builtin.method(:kernel_p))
527
+ scratch.set_custom_method(klass_obj, :is_a?, Builtin.method(:object_is_a?))
528
+ scratch.set_custom_method(klass_obj, :respond_to?, Builtin.method(:object_respond_to?))
529
+ scratch.set_custom_method(klass_obj, :class, Builtin.method(:object_class))
530
+ scratch.set_custom_method(klass_obj, :send, Builtin.method(:object_send))
531
+ scratch.set_custom_method(klass_obj, :instance_eval, Builtin.method(:object_instance_eval))
532
+
533
+ scratch.set_custom_method(klass_module, :include, Builtin.method(:module_include))
534
+ scratch.set_custom_method(klass_module, :extend, Builtin.method(:module_extend))
535
+ scratch.set_custom_method(klass_module, :module_function, Builtin.method(:module_module_function))
536
+
537
+ scratch.set_custom_method(klass_proc, :[], Builtin.method(:proc_call))
538
+ scratch.set_custom_method(klass_proc, :call, Builtin.method(:proc_call))
539
+
540
+ scratch.set_custom_method(klass_ary, :[], Builtin.method(:array_aref))
541
+ scratch.set_custom_method(klass_ary, :[]=, Builtin.method(:array_aset))
542
+ scratch.set_custom_method(klass_ary, :pop, Builtin.method(:array_pop))
543
+
544
+ scratch.set_custom_method(klass_hash, :[], Builtin.method(:hash_aref))
545
+ scratch.set_custom_method(klass_hash, :[]=, Builtin.method(:hash_aset))
546
+
547
+ scratch.set_custom_method(klass_struct, :initialize, Builtin.method(:struct_initialize))
548
+ scratch.set_singleton_custom_method(klass_struct, :new, Builtin.method(:struct_s_new))
549
+
550
+ scratch.set_custom_method(klass_obj, :require, Builtin.method(:kernel_require))
551
+ scratch.set_custom_method(klass_obj, :require_relative, Builtin.method(:kernel_require_relative))
552
+ scratch.set_custom_method(klass_obj, :Array, Builtin.method(:kernel_Array))
549
553
 
550
554
  fargs, ret_ty = FormalArguments.new([], [], nil, [], nil, nil, Type.any), Type.any
551
555
  scratch.add_method(klass_obj, :initialize, false, TypedMethodDef.new([[fargs, ret_ty]], nil))
@@ -1,7 +1,15 @@
1
1
  require "optparse"
2
+ require "rbconfig"
2
3
 
3
4
  module TypeProf
4
5
  class CLI
6
+ DEFAULT_DIR_FILTER = [
7
+ [:include],
8
+ [:exclude, RbConfig::CONFIG["prefix"]],
9
+ [:exclude, Gem.dir],
10
+ [:exclude, Gem.user_dir],
11
+ ]
12
+
5
13
  def initialize(argv)
6
14
  opt = OptionParser.new
7
15
 
@@ -18,10 +26,28 @@ module TypeProf
18
26
  pedantic_output: false,
19
27
  show_errors: false,
20
28
  }
29
+ @dir_filter = nil
30
+ @rbs_features_to_load = []
21
31
 
22
32
  opt.on("-o OUTFILE") {|v| @output = v }
23
- opt.on("-q", "--quiet") {|v| @verbose = 0 }
24
- opt.on("-v", "--verbose") {|v| @verbose = 2 }
33
+ opt.on("-q", "--quiet") { @verbose = 0 }
34
+ opt.on("-v", "--verbose") { @verbose = 2 }
35
+ opt.on("-I DIR") {|v| $LOAD_PATH << v }
36
+ opt.on("-r FEATURE") {|v| @rbs_features_to_load << v }
37
+
38
+ opt.on("--include-dir DIR") do |dir|
39
+ # When `--include-dir` option is specified as the first directory option,
40
+ # typeprof will exclude any files by default unless a file path matches the explicit option
41
+ @dir_filter ||= [[:exclude]]
42
+ @dir_filter << [:include, File.expand_path(dir)]
43
+ end
44
+ opt.on("--exclude-dir DIR") do |dir|
45
+ # When `--exclude-dir` option is specified as the first directory option,
46
+ # typeprof will include any files by default, except Ruby's install directory and Gem directories
47
+ @dir_filter ||= DEFAULT_DIR_FILTER
48
+ @dir_filter << [:exclude, File.expand_path(dir)]
49
+ end
50
+
25
51
  opt.on("-f OPTION") do |v|
26
52
  key, args = v.split("=", 2)
27
53
  case key
@@ -40,6 +66,7 @@ module TypeProf
40
66
 
41
67
  opt.parse!(argv)
42
68
 
69
+ @dir_filter ||= DEFAULT_DIR_FILTER
43
70
  @rb_files = []
44
71
  @rbs_files = []
45
72
  argv.each do |path|
@@ -59,13 +86,24 @@ module TypeProf
59
86
  exit
60
87
  end
61
88
 
62
- attr_reader :verbose, :options, :files
89
+ attr_reader :verbose, :options, :dir_filter
63
90
  attr_accessor :output
64
91
 
92
+ def check_dir_filter(path)
93
+ @dir_filter.reverse_each do |cond, dir|
94
+ return cond unless dir
95
+ return cond if path.start_with?(dir)
96
+ end
97
+ end
98
+
65
99
  def run
66
100
  scratch = Scratch.new
67
101
  Builtin.setup_initial_global_env(scratch)
68
102
 
103
+ @rbs_features_to_load.each do |feature|
104
+ Import.import_library(scratch, feature)
105
+ end
106
+
69
107
  prologue_ctx = Context.new(nil, nil, nil)
70
108
  prologue_ep = ExecutionPoint.new(prologue_ctx, -1, nil)
71
109
  prologue_env = Env.new(StaticEnv.new(:top, Type.nil, false), [], [], Utils::HashWrapper.new({}))
@@ -82,7 +120,7 @@ module TypeProf
82
120
  end
83
121
 
84
122
  @rbs_files.each do |path|
85
- RubySignatureImporter.import_rbs_file(scratch, path)
123
+ Import.import_rbs_file(scratch, path)
86
124
  end
87
125
 
88
126
  result = scratch.type_profile
@@ -31,13 +31,13 @@ module TypeProf
31
31
 
32
32
  output.puts "# Errors"
33
33
  errors.each do |ep, msg|
34
- if ENV["TYPE_PROFILER_DETAIL"]
34
+ if ENV["TP_DETAIL"]
35
35
  backtrace = filter_backtrace(generate_analysis_trace(ep, {}, backward_edge))
36
36
  else
37
37
  backtrace = [ep]
38
38
  end
39
39
  loc, *backtrace = backtrace.map do |ep|
40
- ep.source_location
40
+ ep&.source_location
41
41
  end
42
42
  output.puts "#{ loc }: #{ msg }"
43
43
  backtrace.each do |loc|
@@ -57,13 +57,15 @@ module TypeProf
57
57
  output.puts
58
58
  end
59
59
 
60
- def show_gvars(scratch, gvar_write, output)
60
+ def show_gvars(scratch, gvars, output)
61
61
  # A signature for global variables is not supported in RBS
62
- return if gvar_write.empty?
62
+ return if gvars.dump.empty?
63
63
 
64
64
  output.puts "# Global variables"
65
- gvar_write.each do |gvar_name, ty|
66
- output.puts "# #{ gvar_name } : #{ ty.screen_name(scratch) }"
65
+ gvars.dump.each do |gvar_name, entry|
66
+ next if entry.type == Type.bot
67
+ s = entry.rbs_declared ? "#" : ""
68
+ output.puts s + "#{ gvar_name } : #{ entry.type.screen_name(scratch) }"
67
69
  end
68
70
  output.puts
69
71
  end
@@ -88,14 +90,18 @@ module TypeProf
88
90
  stat_classes = {}
89
91
  stat_methods = {}
90
92
  first = true
93
+
91
94
  @class_defs.each_value do |class_def|
92
- included_mods = class_def.modules[false].filter_map do |visible, mod_def|
93
- mod_def.name if visible
95
+ included_mods = class_def.modules[false].filter_map do |mod_def, absolute_paths|
96
+ next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
97
+ mod_def.name
94
98
  end
95
99
 
96
100
  explicit_methods = {}
97
101
  iseq_methods = {}
98
102
  attr_methods = {}
103
+ ivars = class_def.ivars.dump
104
+ cvars = class_def.cvars.dump
99
105
  class_def.methods.each do |(singleton, mid), mdefs|
100
106
  mdefs.each do |mdef|
101
107
  case mdef
@@ -105,6 +111,7 @@ module TypeProf
105
111
 
106
112
  ctxs.each do |ctx|
107
113
  next if mid != ctx.mid
114
+ next if Config.check_dir_filter(ctx.iseq.absolute_path) == :exclude
108
115
 
109
116
  method_name = ctx.mid
110
117
  method_name = "self.#{ method_name }" if singleton
@@ -116,6 +123,7 @@ module TypeProf
116
123
  iseq_methods[method_name] << @scratch.show_signature(fargs, @yields[ctx], ret_tys)
117
124
  end
118
125
  when AttrMethodDef
126
+ next if Config.check_dir_filter(mdef.absolute_path) == :exclude
119
127
  mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
120
128
  method_name = mid
121
129
  method_name = "self.#{ mid }" if singleton
@@ -125,7 +133,8 @@ module TypeProf
125
133
  attr_methods[method_name][0] = :accessor
126
134
  end
127
135
  else
128
- ty = class_def.ivars.write[[singleton, mdef.ivar]] || Type.any
136
+ entry = ivars[[singleton, mdef.ivar]]
137
+ ty = entry ? entry.type : Type.any
129
138
  attr_methods[method_name] = [mdef.kind, ty.screen_name(@scratch)]
130
139
  end
131
140
  when TypedMethodDef
@@ -137,36 +146,43 @@ module TypeProf
137
146
  end
138
147
  end
139
148
 
140
- ivars = class_def.ivars.write.map do |(singleton, var), ty|
149
+ ivars = ivars.map do |(singleton, var), entry|
150
+ next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
151
+ ty = entry.type
141
152
  next unless var.to_s.start_with?("@")
142
153
  var = "self.#{ var }" if singleton
143
154
  next if attr_methods[[singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]
144
- [var, ty.screen_name(@scratch)]
155
+ [var, ty.screen_name(@scratch), entry.rbs_declared]
145
156
  end.compact
146
157
 
147
- cvars = class_def.cvars.write.map do |var, ty|
148
- [var, ty.screen_name(@scratch)]
158
+ cvars = cvars.map do |var, entry|
159
+ next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
160
+ [var, entry.type.screen_name(@scratch), entry.rbs_declared]
149
161
  end
150
162
 
151
- next if included_mods.empty? && ivars.empty? && cvars.empty? && iseq_methods.empty? && attr_methods.empty?
163
+ if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
164
+ next if included_mods.empty? && ivars.empty? && cvars.empty? && iseq_methods.empty? && attr_methods.empty?
165
+ end
152
166
 
153
167
  output.puts unless first
154
168
  first = false
155
169
 
156
170
  if class_def.superclass
157
- object = @class_defs[class_def.superclass].klass_obj == Type::Builtin[:obj]
158
- superclass = object ? "" : " < #{ @class_defs[class_def.superclass].name }"
171
+ omit = @class_defs[class_def.superclass].klass_obj == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
172
+ superclass = omit ? "" : " < #{ @class_defs[class_def.superclass].name }"
159
173
  end
160
174
 
161
175
  output.puts "#{ class_def.kind } #{ class_def.name }#{ superclass }"
162
176
  included_mods.sort.each do |ty|
163
177
  output.puts " include #{ ty }"
164
178
  end
165
- ivars.each do |var, ty|
166
- output.puts " #{ var } : #{ ty }" unless var.start_with?("_")
179
+ ivars.each do |var, ty, rbs_declared|
180
+ s = rbs_declared ? "# " : " "
181
+ output.puts s + "#{ var } : #{ ty }" unless var.start_with?("_")
167
182
  end
168
- cvars.each do |var, ty|
169
- output.puts " #{ var } : #{ ty }"
183
+ cvars.each do |var, ty, rbs_declared|
184
+ s = rbs_declared ? "# " : " "
185
+ output.puts s + "#{ var } : #{ ty }"
170
186
  end
171
187
  attr_methods.each do |(method_name, hidden), (kind, ty)|
172
188
  output.puts " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" } : #{ ty }"