typeprof 0.1.4 → 0.2.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.
@@ -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 }"