typeprof 0.21.3 → 0.21.5

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: 87b881146ffc3f78049ac01775f0bd6cae8efeec13a77da7eab2a61e3027a802
4
- data.tar.gz: 61507f6552b6440fa58ea298ed80956a32e97b149b46d0969a594e8d1b0920bc
3
+ metadata.gz: 3f5c0fba3561953bdf7db3fe5c326cd4a8375376189928270d919f23dffd78ce
4
+ data.tar.gz: b3d7aabe2f15298c41de661308e3d757ed0643df079092fe184f6046cc9336c6
5
5
  SHA512:
6
- metadata.gz: dce6a8c024aa553089224545ca89a6148a590390791f9411b6a70791ad23cb70a9e97d4405264882c3cfccc8cd30e69443cc6330cb81c33f996fa2363dc0369a
7
- data.tar.gz: c6f6e02dc30a6c8b7ecbee01f05f171b467a95526b4541173b303803287ea208eb816223353a704866b7f0b87b266462560554bb997bdbe67d3b5c9373385a4f
6
+ metadata.gz: b861fb63e8cfb3d39fdf5a5f753ea88041e730d5c8518098c05fa07f360eae8f3f808697e5e0462ffc76def30e7163c184a95e3bd14a941063c3dc523a9fad53
7
+ data.tar.gz: 6b061ce0869738ea048e85c74a018adc8894f1c05d71c61b0e91d93b0714c177ef2bc48499640a97fc5f43fd29ace9227ef13924df006a81239cf2ac50480087
@@ -0,0 +1,6 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: 'github-actions'
4
+ directory: '/'
5
+ schedule:
6
+ interval: 'weekly'
@@ -1,25 +1,38 @@
1
1
  name: Ruby
2
2
 
3
- on: [push,pull_request]
3
+ on:
4
+ push:
5
+ pull_request:
6
+ workflow_dispatch:
7
+ schedule:
8
+ - cron: '11 24 * * 5'
4
9
 
5
10
  jobs:
11
+ ruby-versions:
12
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
13
+ with:
14
+ engine: cruby-truffleruby
15
+ min_version: 2.7
16
+
6
17
  build:
18
+ needs: ruby-versions
19
+ name: build (${{ matrix.ruby }})
7
20
  strategy:
8
21
  fail-fast: false
9
22
  matrix:
10
- ruby-version: [2.7, 3.0, 3.1, head]
23
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
11
24
  runs-on: ubuntu-latest
12
25
  steps:
13
26
  - uses: actions/checkout@v3
14
- with:
15
- submodules: true
16
27
  - name: Set up Ruby
17
28
  uses: ruby/setup-ruby@v1
18
29
  with:
19
- ruby-version: ${{ matrix.ruby-version }}
30
+ ruby-version: ${{ matrix.ruby }}
20
31
  - name: Bundle install
21
32
  run: |
22
33
  bundle install
34
+ - run: bundle exec typeprof --version
23
35
  - name: Run the test suite
24
36
  run: |
25
37
  bundle exec rake TESTOPT=-v
38
+ if: ${{ !startsWith(matrix.ruby, 'truffle') }}
data/Gemfile CHANGED
@@ -1,11 +1,15 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in typeprof.gemspec
4
- gemspec
3
+ if ENV["RBS_VERSION"]
4
+ gem "rbs", github: "ruby/rbs", ref: ENV["RBS_VERSION"]
5
+ else
6
+ # Specify your gem's dependencies in typeprof.gemspec
7
+ gemspec
8
+ end
5
9
 
6
10
  group :development do
7
11
  gem "rake"
8
- gem "stackprof"
12
+ gem "stackprof", platforms: :mri
9
13
  gem "test-unit"
10
14
  gem "simplecov"
11
15
  gem "simplecov-html"
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- typeprof (0.21.3)
4
+ typeprof (0.21.5)
5
5
  rbs (>= 1.8.1)
6
6
 
7
7
  GEM
@@ -10,8 +10,8 @@ GEM
10
10
  coverage-helpers (1.0.0)
11
11
  docile (1.4.0)
12
12
  power_assert (2.0.1)
13
- rake (13.0.6)
14
- rbs (2.6.0)
13
+ rake (13.0.1)
14
+ rbs (3.0.0)
15
15
  simplecov (0.21.2)
16
16
  docile (~> 1.1)
17
17
  simplecov-html (~> 0.11)
@@ -36,4 +36,4 @@ DEPENDENCIES
36
36
  typeprof!
37
37
 
38
38
  BUNDLED WITH
39
- 2.2.15
39
+ 2.3.11
@@ -1997,7 +1997,8 @@ module TypeProf
1997
1997
  env = env.push(Type.any) # or String | NilClass only?
1998
1998
  when 1 # VM_SVAR_BACKREF ($~)
1999
1999
  merge_env(ep.next, env.push(Type::Instance.new(Type::Builtin[:matchdata])))
2000
- merge_env(ep.next, env.push(Type.nil))
2000
+ # tentatively disabled; it is too conservative
2001
+ #merge_env(ep.next, env.push(Type.nil))
2001
2002
  return
2002
2003
  else # flip-flop
2003
2004
  env = env.push(Type.bool)
@@ -2005,7 +2006,8 @@ module TypeProf
2005
2006
  else
2006
2007
  # NTH_REF ($1, $2, ...) / BACK_REF ($&, $+, ...)
2007
2008
  merge_env(ep.next, env.push(Type::Instance.new(Type::Builtin[:str])))
2008
- merge_env(ep.next, env.push(Type.nil))
2009
+ # tentatively disabled; it is too conservative
2010
+ #merge_env(ep.next, env.push(Type.nil))
2009
2011
  return
2010
2012
  end
2011
2013
  when :setspecial
@@ -7,6 +7,7 @@ module TypeProf
7
7
  collection_path = Config.current.collection_path
8
8
  if collection_path&.exist?
9
9
  collection_lock = RBS::Collection::Config.lockfile_of(collection_path)
10
+ raise "Please execute 'rbs collection install'" if collection_lock.nil?
10
11
  @repo.add(collection_lock.repo_path)
11
12
  end
12
13
  @env, @loaded_gems, @builtin_env_json = RBSReader.get_builtin_env
@@ -77,19 +78,37 @@ module TypeProf
77
78
  def load_rbs_string(name, content)
78
79
  buffer = RBS::Buffer.new(name: name, content: content)
79
80
  new_decls = []
80
- RBS::Parser.parse_signature(buffer).each do |decl|
81
- @env << decl
82
- new_decls << decl
81
+ ret = RBS::Parser.parse_signature(buffer)
82
+ if ret[0].is_a?(RBS::Buffer)
83
+ # rbs 3.0
84
+ buffer, directives, decls = ret
85
+ @env.add_signature(buffer: buffer, directives: directives, decls: decls)
86
+ new_decls.concat(decls)
87
+ else
88
+ ret.each do |decl|
89
+ @env << decl
90
+ new_decls << decl
91
+ end
83
92
  end
84
93
  RBSReader.load_rbs(@env, new_decls)
85
94
  end
86
95
 
87
96
  def self.load_rbs(env, new_decls)
88
97
  all_env = env.resolve_type_names
89
- resolver = RBS::TypeNameResolver.from_env(all_env)
90
98
  cur_env = RBS::Environment.new
91
- new_decls.each do |decl|
92
- cur_env << env.resolve_declaration(resolver, decl, outer: [], prefix: RBS::Namespace.root)
99
+ if defined?(RBS::TypeNameResolver)
100
+ resolver = RBS::TypeNameResolver.from_env(all_env)
101
+ new_decls.each do |decl|
102
+ cur_env << env.resolve_declaration(resolver, decl, outer: [], prefix: RBS::Namespace.root)
103
+ end
104
+ else
105
+ resolver = RBS::Resolver::TypeNameResolver.new(all_env)
106
+ table = RBS::Environment::UseMap::Table.new()
107
+ table.compute_children
108
+ map = RBS::Environment::UseMap.new(table: table)
109
+ new_decls.each do |decl|
110
+ cur_env << s = env.resolve_declaration(resolver, map, decl, outer: [], prefix: RBS::Namespace.root)
111
+ end
93
112
  end
94
113
 
95
114
  RBS2JSON.new(all_env, cur_env).dump_json
@@ -134,6 +153,9 @@ module TypeProf
134
153
  gvars
135
154
  end
136
155
 
156
+ AliasDecl = defined?(RBS::AST::Declarations::Alias) ? RBS::AST::Declarations::Alias : RBS::AST::Declarations::AliasDecl
157
+ TypeAlias = defined?(RBS::AST::Declarations::TypeAlias) ? RBS::AST::Declarations::TypeAlias : nil
158
+
137
159
  def conv_classes
138
160
  json = {}
139
161
 
@@ -170,7 +192,12 @@ module TypeProf
170
192
  when RBS::AST::Members::MethodDefinition
171
193
  name = member.name
172
194
 
173
- method_types = member.types.map do |method_type|
195
+ if member.respond_to?(:overloads)
196
+ types = member.overloads.map {|overload| overload.method_type }
197
+ else
198
+ types = member.types
199
+ end
200
+ method_types = types.map do |method_type|
174
201
  case method_type
175
202
  when RBS::MethodType then method_type
176
203
  when :super then raise NotImplementedError
@@ -180,7 +207,7 @@ module TypeProf
180
207
  method_def = conv_method_def(method_types, visibility)
181
208
  rbs_source = [
182
209
  (member.kind == :singleton ? "self." : "") + member.name.to_s,
183
- member.types.map {|type| type.location.source },
210
+ types.map {|type| type.location.source },
184
211
  [member.location.name, CodeRange.from_rbs(member.location)],
185
212
  ]
186
213
  if member.instance?
@@ -260,9 +287,10 @@ module TypeProf
260
287
 
261
288
  # The following declarations are ignoreable because they are handled in other level
262
289
  when RBS::AST::Declarations::Constant
263
- when RBS::AST::Declarations::Alias # type alias
290
+ when AliasDecl # type alias
264
291
  when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
265
292
  when RBS::AST::Declarations::Interface
293
+ when TypeAlias
266
294
 
267
295
  else
268
296
  warn "Importing #{ member.class.name } is not supported yet"
@@ -487,7 +515,7 @@ module TypeProf
487
515
  else
488
516
  begin
489
517
  @alias_resolution_stack[ty.name] = true
490
- alias_decl = @all_env.alias_decls[ty.name]
518
+ alias_decl = (@all_env.respond_to?(:alias_decls) ? @all_env.alias_decls : @all_env.type_alias_decls)[ty.name]
491
519
  alias_decl ? conv_type(alias_decl.decl.type) : [:any]
492
520
  ensure
493
521
  @alias_resolution_stack.delete(ty.name)
data/lib/typeprof/iseq.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  module TypeProf
2
2
  class ISeq
3
- # https://github.com/ruby/ruby/pull/4468
4
- CASE_WHEN_CHECKMATCH = RubyVM::InstructionSequence.compile("case 1; when Integer; end").to_a.last.any? {|insn,| insn == :checkmatch }
5
- # https://github.com/ruby/ruby/blob/v3_0_2/vm_core.h#L1206
6
- VM_ENV_DATA_SIZE = 3
7
- # Check if Ruby 3.1 or later
8
- RICH_AST = begin RubyVM::AbstractSyntaxTree.parse("1", keep_script_lines: true).node_id; true; rescue; false; end
3
+ if defined?(RubyVM::InstructionSequence)
4
+ # https://github.com/ruby/ruby/pull/4468
5
+ CASE_WHEN_CHECKMATCH = RubyVM::InstructionSequence.compile("case 1; when Integer; end").to_a.last.any? {|insn,| insn == :checkmatch }
6
+ # https://github.com/ruby/ruby/blob/v3_0_2/vm_core.h#L1206
7
+ VM_ENV_DATA_SIZE = 3
8
+ # Check if Ruby 3.1 or later
9
+ RICH_AST = begin RubyVM::AbstractSyntaxTree.parse("1", keep_script_lines: true).node_id; true; rescue; false; end
10
+ end
9
11
 
10
12
  FileInfo = Struct.new(
11
13
  :node_id2node,
@@ -447,6 +449,11 @@ module TypeProf
447
449
  insn.insn, insn.operands = :branch, [:nil] + insn.operands
448
450
  when :getblockparam, :getblockparamproxy
449
451
  insn.insn = :getlocal
452
+ when :getglobal
453
+ if insn.operands == [:$typeprof]
454
+ insn.insn = :putobject
455
+ insn.operands = [true]
456
+ end
450
457
  end
451
458
  end
452
459
  end
@@ -687,6 +694,27 @@ module TypeProf
687
694
  @insns[i + 1] = Insn.new(:getlocal_branch, [getlocal_operands, branch_operands])
688
695
  end
689
696
  end
697
+
698
+ # find a pattern: putobject, branch
699
+ (@insns.size - 1).times do |i|
700
+ next if branch_targets[i + 1]
701
+ insn0 = @insns[i]
702
+ insn1 = @insns[i + 1]
703
+ if insn0.insn == :putobject && insn1.insn == :branch
704
+ putobject_operands = insn0.operands
705
+ branch_operands = insn1.operands
706
+ obj = putobject_operands[0]
707
+ branch_type = branch_operands[0]
708
+ branch_target = branch_operands[1]
709
+ case branch_type
710
+ when :if then jump = !!obj
711
+ when :unless then jump = !obj
712
+ when :nil then jump = obj == nil
713
+ end
714
+ @insns[i ] = Insn.new(:nop, [])
715
+ @insns[i + 1] = jump ? Insn.new(:jump, [branch_target]) : Insn.new(:nop, [])
716
+ end
717
+ end
690
718
  end
691
719
 
692
720
  def check_send_branch(sp, j)
data/lib/typeprof/type.rb CHANGED
@@ -59,10 +59,13 @@ module TypeProf
59
59
  else
60
60
  if ty2.is_a?(Type::ContainerType)
61
61
  # ty2 may have type variables
62
- return nil if ty1.class != ty2.class
63
- ty1.match?(ty2)
62
+ if ty1.class == ty2.class
63
+ ty1.match?(ty2)
64
+ else
65
+ Type.match?(ty1, ty2.base_type)
66
+ end
64
67
  elsif ty1.is_a?(Type::ContainerType)
65
- nil
68
+ Type.match?(ty1.base_type, ty2)
66
69
  else
67
70
  ty1.consistent?(ty2) ? {} : nil
68
71
  end
@@ -810,7 +813,9 @@ module TypeProf
810
813
  when :$0, :$PROGRAM_NAME
811
814
  Type::Instance.new(Type::Builtin[:str])
812
815
  when :$~
813
- Type.optional(Type::Instance.new(Type::Builtin[:matchdata]))
816
+ # optional type is tentatively disabled; it is too conservative
817
+ #Type.optional(Type::Instance.new(Type::Builtin[:matchdata]))
818
+ Type::Instance.new(Type::Builtin[:matchdata])
814
819
  when :$., :$$
815
820
  Type::Instance.new(Type::Builtin[:int])
816
821
  when :$?
@@ -1,3 +1,3 @@
1
1
  module TypeProf
2
- VERSION = "0.21.3"
2
+ VERSION = "0.21.5"
3
3
  end
data/lib/typeprof.rb CHANGED
@@ -17,4 +17,4 @@ require_relative "typeprof/builtin"
17
17
  require_relative "typeprof/cli"
18
18
  require_relative "typeprof/code-range"
19
19
 
20
- require_relative "typeprof/lsp" if RUBY_VERSION >= "3"
20
+ require_relative "typeprof/lsp" if RUBY_VERSION >= "3" and RUBY_ENGINE != "truffleruby"
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.21.3
4
+ version: 0.21.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yusuke Endoh
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-07-06 00:00:00.000000000 Z
11
+ date: 2023-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbs
@@ -37,6 +37,7 @@ executables:
37
37
  extensions: []
38
38
  extra_rdoc_files: []
39
39
  files:
40
+ - ".github/dependabot.yml"
40
41
  - ".github/workflows/main.yml"
41
42
  - ".gitignore"
42
43
  - Gemfile
@@ -88,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
89
  - !ruby/object:Gem::Version
89
90
  version: '0'
90
91
  requirements: []
91
- rubygems_version: 3.3.7
92
+ rubygems_version: 3.5.0.dev
92
93
  signing_key:
93
94
  specification_version: 4
94
95
  summary: TypeProf is a type analysis tool for Ruby code based on abstract interpretation