typeprof 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
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