typeprof 0.11.0 → 0.12.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88521dfb48f311cdb5b651e88afc2627a28040a466a22b50303415531e663cfd
4
- data.tar.gz: 4bd17f9d016d6e7a60ed72804eb050a5611af0869275e63d3486700a53befaaf
3
+ metadata.gz: 239b17dbe8d61c729346c5dde966f6abff491951c88bc33c57c4c34cc99dc497
4
+ data.tar.gz: 2696c83796a6af5c498cca59a3d98b7faccaf187fe60c0057ac3f052622009ff
5
5
  SHA512:
6
- metadata.gz: f88b069345f02729a09c0516baf4ff31c8aef640adf5a2c53f62f72a9fb8b96b4309993ae79e37ece4ec33972f762005b3898ca7c894cda65c3727513b812b6b
7
- data.tar.gz: aa5fec1acd9dd6395d3d16e044f08e7b72fac0f41dc6168683c631fcadca33daf2415b9956ba00cd22c573c6732719fad9eeef3d601a16943d59be6986703c20
6
+ metadata.gz: 23a7a3313dadd2d0c63a5d83a3afd112893134a049861e6a9e11cf5097aaa78c19494326b6a07b44cf4d93f5dec5a2c893b91fe2c4f5571726229d1e8dc13229
7
+ data.tar.gz: 3273f1bb24290af32db23aaae8cafa84905d4d2d576b5ab96178130fe843b73e4365827b60d47a022a2812621f7fe09a3801c32c205c9805516873ed9ac88659
@@ -7,7 +7,7 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- ruby-version: [2.7.1, head]
10
+ ruby-version: [2.7, 3.0, head]
11
11
  runs-on: ubuntu-latest
12
12
  steps:
13
13
  - uses: actions/checkout@v2
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- typeprof (0.11.0)
4
+ typeprof (0.12.0)
5
5
  rbs (>= 1.0.0)
6
6
 
7
7
  GEM
@@ -11,7 +11,7 @@ GEM
11
11
  docile (1.3.4)
12
12
  power_assert (1.2.0)
13
13
  rake (13.0.1)
14
- rbs (1.0.0)
14
+ rbs (1.0.3)
15
15
  simplecov (0.20.0)
16
16
  docile (~> 1.1)
17
17
  simplecov-html (~> 0.11)
@@ -190,7 +190,7 @@ p [:a, :b, :c] #=> [:a, :b, :c]
190
190
  # A Hash is a "type-to-type" map
191
191
  h = { "int" => 1, "float" => 1.0 }
192
192
  p h #=> {String=>Float | Integer}
193
- p h["int"] #=> Float | Intger
193
+ p h["int"] #=> Float | Integer
194
194
 
195
195
  # Symbol-key hashes (a.k.a. records) can have distinct types for each key as Symbols are concrete
196
196
  h = { int: 1, float: 1.0 }
@@ -2192,10 +2192,13 @@ module TypeProf
2192
2192
  farg_tys = @method_signatures[ctx]
2193
2193
  ret_ty = @return_values[ctx] || Type.bot
2194
2194
 
2195
+ untyped = farg_tys.include_untyped?(self) || ret_ty.include_untyped?(self)
2196
+
2195
2197
  farg_tys = farg_tys.screen_name(ctx.iseq, self)
2196
2198
  ret_ty = ret_ty.screen_name(self)
2197
2199
  ret_ty = (ret_ty.include?("|") ? "(#{ ret_ty })" : ret_ty) # XXX?
2198
- "#{ (farg_tys.empty? ? "" : "#{ farg_tys } ") }-> #{ ret_ty }"
2200
+
2201
+ ["#{ (farg_tys.empty? ? "" : "#{ farg_tys } ") }-> #{ ret_ty }", untyped]
2199
2202
  end
2200
2203
  end
2201
2204
  end
@@ -557,8 +557,6 @@ module TypeProf
557
557
  end
558
558
 
559
559
  def struct_s_new(recv, mid, aargs, ep, env, scratch, &ctn)
560
- # TODO: keyword_init
561
-
562
560
  keyword_init = false
563
561
  if aargs.kw_tys && aargs.kw_tys[:keyword_init] # XXX: more canonical way to extract keyword...
564
562
  if aargs.kw_tys[:keyword_init] == Type::Instance.new(Type::Builtin[:true])
@@ -48,6 +48,8 @@ module TypeProf
48
48
  dir_filter ||= ConfigData::DEFAULT_DIR_FILTER
49
49
  dir_filter << [:exclude, File.expand_path(dir)]
50
50
  end
51
+ opt.on("--exclude-untyped", "Exclude (comment out) all entries including untyped") {|v| options[:exclude_untyped] = v }
52
+ opt.on("--[no-]show-typeprof-version", "Display TypeProf version in a header") {|v| options[:show_typeprof_version] = v }
51
53
  opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| options[:show_errors] = v }
52
54
  opt.on("--[no-]show-untyped", "Display \"Foo | untyped\" instead of \"Foo\"") {|v| options[:show_untyped] = v }
53
55
  opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| options[:show_parameter_names] = v }
@@ -31,6 +31,8 @@ module TypeProf
31
31
  opt[:verbose] ||= 0
32
32
  opt[:options] ||= {}
33
33
  opt[:options] = {
34
+ exclude_untyped: false,
35
+ show_typeprof_version: true,
34
36
  show_indicator: true,
35
37
  show_untyped: false,
36
38
  show_errors: false,
@@ -93,13 +95,19 @@ module TypeProf
93
95
  scratch.add_callsite!(ep.ctx, prologue_ep, prologue_env) {|ty, ep| }
94
96
  end
95
97
 
98
+ rbs_files = []
99
+ rbs_codes = []
96
100
  Config.rbs_files.each do |rbs|
97
101
  if rbs.is_a?(Array) # [String name, String content]
98
- Import.import_rbs_code(scratch, *rbs)
102
+ rbs_codes << rbs
99
103
  else
100
- Import.import_rbs_file(scratch, rbs)
104
+ rbs_files << rbs
101
105
  end
102
106
  end
107
+ Import.import_rbs_files(scratch, rbs_files)
108
+ rbs_codes.each do |name, content|
109
+ Import.import_rbs_code(scratch, name, content)
110
+ end
103
111
 
104
112
  result = scratch.type_profile
105
113
 
@@ -45,6 +45,12 @@ module TypeProf
45
45
  Type::Cell.new(Type::Cell::Elements.new([Type.bot] * klass.type_params.size), base_type)
46
46
  end
47
47
  end
48
+
49
+ def include_untyped?(scratch)
50
+ return true if @base_type.include_untyped?(scratch)
51
+ return true if @elems.include_untyped?(scratch)
52
+ false
53
+ end
48
54
  end
49
55
 
50
56
  # The most basic container type for default type parameter class
@@ -196,6 +202,10 @@ module TypeProf
196
202
  end
197
203
  Elements.new(elems)
198
204
  end
205
+
206
+ def include_untyped?(scratch)
207
+ return @elems.any? {|ty| ty.include_untyped?(scratch) }
208
+ end
199
209
  end
200
210
  end
201
211
 
@@ -531,6 +541,12 @@ module TypeProf
531
541
  return rest_ary_ty, following_tys
532
542
  end
533
543
  end
544
+
545
+ def include_untyped?(scratch)
546
+ return true if @lead_tys.any? {|ty| ty.include_untyped?(scratch) }
547
+ return true if @rest_ty.include_untyped?(scratch)
548
+ false
549
+ end
534
550
  end
535
551
  end
536
552
 
@@ -790,6 +806,14 @@ module TypeProf
790
806
  end
791
807
  kw_tys
792
808
  end
809
+
810
+ def include_untyped?(scratch)
811
+ @map_tys.each do |key, val|
812
+ return true if key.include_untyped?(scratch)
813
+ return true if val.include_untyped?(scratch)
814
+ end
815
+ false
816
+ end
793
817
  end
794
818
  end
795
819
 
@@ -26,6 +26,10 @@ module TypeProf
26
26
  end
27
27
 
28
28
  def show_message(terminated, output)
29
+ if Config.options[:show_typeprof_version]
30
+ output.puts "# TypeProf #{ VERSION }"
31
+ output.puts
32
+ end
29
33
  if terminated
30
34
  output.puts "# CAUTION: Type profiling was terminated prematurely because of the limitation"
31
35
  output.puts
@@ -94,6 +98,10 @@ module TypeProf
94
98
  if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
95
99
  omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
96
100
  superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
101
+ type_args = class_def.klass_obj.superclass_type_args
102
+ if type_args && !type_args.empty?
103
+ superclass += "[#{ type_args.map {|ty| ty.screen_name(@scratch) }.join(", ") }]"
104
+ end
97
105
  end
98
106
 
99
107
  @scratch.namespace = class_def.name
@@ -169,7 +177,7 @@ module TypeProf
169
177
  else
170
178
  entry = ivars[[singleton, mdef.ivar]]
171
179
  ty = entry ? entry.type : Type.any
172
- methods[key] = [mdef.kind, ty.screen_name(@scratch)]
180
+ methods[key] = [mdef.kind, ty.screen_name(@scratch), ty.include_untyped?(@scratch)]
173
181
  end
174
182
  when TypedMethodDef
175
183
  if mdef.rbs_source
@@ -336,14 +344,22 @@ module TypeProf
336
344
  type, (method_name, hidden) = key
337
345
  case type
338
346
  when :attr
339
- kind, ty = *arg
340
- lines << (indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
347
+ kind, ty, untyped = *arg
348
+ exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
349
+ lines << (indent + "#{ exclude } attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
341
350
  when :rbs
342
351
  sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
343
352
  lines << (indent + "# def #{ method_name }: #{ sigs }")
344
353
  when :iseq
345
- sigs = arg.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
346
- lines << (indent + " def #{ method_name }: #{ sigs }")
354
+ sigs = []
355
+ untyped = false
356
+ arg.each do |sig, untyped0|
357
+ sigs << sig
358
+ untyped ||= untyped0
359
+ end
360
+ sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
361
+ exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
362
+ lines << (indent + "#{ exclude } def #{ method_name }: #{ sigs }")
347
363
  when :alias
348
364
  orig_name = arg
349
365
  lines << (indent + " alias #{ method_name } #{ orig_name }")
@@ -32,18 +32,26 @@ module TypeProf
32
32
  loader.add(library: lib)
33
33
 
34
34
  case lib
35
+ when 'bigdecimal-math'
36
+ loader.add(library: 'bigdecimal')
35
37
  when "yaml"
36
38
  loader.add(library: "pstore")
37
39
  loader.add(library: "dbm")
40
+ when "logger"
41
+ loader.add(library: "monitor")
42
+ when "csv"
43
+ loader.add(library: "forwardable")
44
+ when "prime"
45
+ loader.add(library: "singleton")
38
46
  end
39
47
 
40
48
  new_decls = loader.load(env: @env).map {|decl,| decl }
41
49
  RBSReader.load_rbs(@env, new_decls)
42
50
  end
43
51
 
44
- def load_path(path)
52
+ def load_paths(paths)
45
53
  loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
46
- loader.add(path: path)
54
+ paths.each {|path| loader.add(path: path) }
47
55
  new_decls = loader.load(env: @env).map {|decl,| decl }
48
56
  RBSReader.load_rbs(@env, new_decls)
49
57
  end
@@ -73,6 +81,7 @@ module TypeProf
73
81
  class RBS2JSON
74
82
  def initialize(all_env, cur_env)
75
83
  @all_env, @cur_env = all_env, cur_env
84
+ @alias_resolution_stack = {}
76
85
  end
77
86
 
78
87
  def dump_json
@@ -428,8 +437,17 @@ module TypeProf
428
437
  raise NotImplementedError
429
438
  end
430
439
  when RBS::Types::Alias
431
- alias_decl = @all_env.alias_decls[ty.name]
432
- alias_decl ? conv_type(alias_decl.decl.type) : [:any]
440
+ if @alias_resolution_stack[ty.name]
441
+ [:any]
442
+ else
443
+ begin
444
+ @alias_resolution_stack[ty.name] = true
445
+ alias_decl = @all_env.alias_decls[ty.name]
446
+ alias_decl ? conv_type(alias_decl.decl.type) : [:any]
447
+ ensure
448
+ @alias_resolution_stack.delete(ty.name)
449
+ end
450
+ end
433
451
  when RBS::Types::Union
434
452
  [:union, ty.types.map {|ty2| conv_type(ty2) }.compact]
435
453
  when RBS::Types::Optional
@@ -476,9 +494,9 @@ module TypeProf
476
494
  Import.new(scratch, json).import
477
495
  end
478
496
 
479
- def self.import_rbs_file(scratch, rbs_path)
480
- rbs_path = Pathname(rbs_path) unless rbs_path.is_a?(Pathname)
481
- Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
497
+ def self.import_rbs_files(scratch, rbs_paths)
498
+ rbs_paths = rbs_paths.map {|rbs_path| Pathname(rbs_path) }
499
+ Import.new(scratch, scratch.rbs_reader.load_paths(rbs_paths)).import(true)
482
500
  end
483
501
 
484
502
  def self.import_rbs_code(scratch, rbs_name, rbs_code)
@@ -162,6 +162,10 @@ module TypeProf
162
162
  substitute(DummySubstitution, Config.options[:type_depth_limit])
163
163
  end
164
164
 
165
+ def include_untyped?(_scratch)
166
+ false
167
+ end
168
+
165
169
  class Any < Type
166
170
  def initialize
167
171
  end
@@ -185,6 +189,10 @@ module TypeProf
185
189
  def substitute(_subst, _depth)
186
190
  self
187
191
  end
192
+
193
+ def include_untyped?(_scratch)
194
+ true
195
+ end
188
196
  end
189
197
 
190
198
  class Void < Any
@@ -379,6 +387,17 @@ module TypeProf
379
387
  end
380
388
  ty
381
389
  end
390
+
391
+ def include_untyped?(scratch)
392
+ @types.each do |ty|
393
+ return true if ty.include_untyped?(scratch)
394
+ end
395
+ @elems&.each do |(container_kind, base_type), elems|
396
+ return true if base_type.include_untyped?(scratch)
397
+ return true if elems.include_untyped?(scratch)
398
+ end
399
+ false
400
+ end
382
401
  end
383
402
 
384
403
  def self.any
@@ -583,6 +602,10 @@ module TypeProf
583
602
  def screen_name(scratch)
584
603
  scratch.show_proc_signature([self])
585
604
  end
605
+
606
+ def include_untyped?(scratch)
607
+ false # XXX: need to check the block signatures recursively
608
+ end
586
609
  end
587
610
 
588
611
  class Symbol < Type
@@ -869,6 +892,17 @@ module TypeProf
869
892
  @blk_ty = blk_ty
870
893
  end
871
894
 
895
+ def include_untyped?(scratch)
896
+ return true if @lead_tys.any? {|ty| ty.include_untyped?(scratch) }
897
+ return true if @opt_tys.any? {|ty| ty.include_untyped?(scratch) }
898
+ return true if @rest_ty&.include_untyped?(scratch)
899
+ return true if @post_tys.any? {|ty| ty.include_untyped?(scratch) }
900
+ return true if @kw_tys&.any? {|_, _, ty| ty.include_untyped?(scratch) }
901
+ return true if @kw_rest_ty&.include_untyped?(scratch)
902
+ return true if @blk_ty&.include_untyped?(scratch)
903
+ false
904
+ end
905
+
872
906
  attr_reader :lead_tys, :opt_tys, :rest_ty, :post_tys, :kw_tys, :kw_rest_ty, :blk_ty
873
907
 
874
908
  def substitute(subst, depth)
@@ -1,3 +1,3 @@
1
1
  module TypeProf
2
- VERSION = "0.11.0"
2
+ VERSION = "0.12.0"
3
3
  end
@@ -3,7 +3,7 @@ Foo[a: 1, b: "str", c: 1.0]
3
3
 
4
4
  __END__
5
5
  # Classes
6
- class Foo < Struct
6
+ class Foo < Struct[untyped]
7
7
  attr_accessor a(): Integer
8
8
  attr_accessor b(): String
9
9
  attr_accessor c(): Float
@@ -5,7 +5,7 @@ end
5
5
  Foo.new.a = 1
6
6
  __END__
7
7
  # Classes
8
- class AnonymousStruct_generated_1 < Struct
8
+ class AnonymousStruct_generated_1 < Struct[untyped]
9
9
  attr_accessor a(): untyped
10
10
  end
11
11
 
@@ -18,7 +18,7 @@ class Object
18
18
  def gen_foobar: -> FooBar
19
19
  end
20
20
 
21
- class FooBar < Struct
21
+ class FooBar < Struct[untyped]
22
22
  attr_accessor foo(): Integer | String
23
23
  attr_accessor bar(): :sym?
24
24
  def my_foo: -> (Integer | String)
@@ -7,7 +7,7 @@ App::FooBar.new(1, "str")
7
7
  __END__
8
8
  # Classes
9
9
  class App
10
- class FooBar < Struct
10
+ class FooBar < Struct[untyped]
11
11
  attr_accessor foo(): Integer
12
12
  attr_accessor bar(): String
13
13
  end
@@ -2,6 +2,6 @@ UndefinedConstant::Foo = Struct.new(:foo)
2
2
 
3
3
  __END__
4
4
  # Classes
5
- class AnonymousStruct_generated_1 < Struct
5
+ class AnonymousStruct_generated_1 < Struct[untyped]
6
6
  attr_accessor foo(): untyped
7
7
  end
@@ -10,7 +10,7 @@ Foo.new(42)
10
10
 
11
11
  __END__
12
12
  # Classes
13
- class Foo < Struct
13
+ class Foo < Struct[untyped]
14
14
  attr_accessor foo(): String
15
15
  def initialize: (Integer foo) -> Foo
16
16
  end
@@ -6,7 +6,7 @@ end
6
6
 
7
7
  __END__
8
8
  # Classes
9
- class AnonymousStruct_generated_1 < Struct
9
+ class AnonymousStruct_generated_1 < Struct[untyped]
10
10
  attr_accessor foo(): untyped
11
11
  end
12
12
 
@@ -12,6 +12,6 @@ end
12
12
 
13
13
  __END__
14
14
  # Classes
15
- class Foo < Struct
15
+ class Foo < Struct[untyped]
16
16
  def initialize: -> Foo
17
17
  end
@@ -21,7 +21,7 @@ GEM
21
21
  concurrent-ruby (1.1.7)
22
22
  i18n (1.8.5)
23
23
  concurrent-ruby (~> 1.0)
24
- minitest (5.14.2)
24
+ minitest (5.14.3)
25
25
  minitest-reporters (1.4.2)
26
26
  ansi
27
27
  builder
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typeprof
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Endoh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-24 00:00:00.000000000 Z
11
+ date: 2021-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs