rbs 1.0.3 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +2 -2
  3. data/CHANGELOG.md +65 -0
  4. data/Gemfile +0 -1
  5. data/Rakefile +3 -2
  6. data/Steepfile +2 -0
  7. data/bin/rbs-prof +1 -1
  8. data/core/array.rbs +10 -6
  9. data/core/complex.rbs +1 -1
  10. data/core/enumerable.rbs +15 -1
  11. data/core/enumerator.rbs +4 -0
  12. data/core/file.rbs +2 -1
  13. data/core/integer.rbs +2 -1
  14. data/core/module.rbs +1 -1
  15. data/core/rational.rbs +2 -1
  16. data/core/string.rbs +2 -1
  17. data/core/symbol.rbs +2 -1
  18. data/core/thread.rbs +14 -1
  19. data/core/time.rbs +2 -1
  20. data/docs/stdlib.md +1 -1
  21. data/lib/rbs.rb +3 -0
  22. data/lib/rbs/ancestor_graph.rb +90 -0
  23. data/lib/rbs/ast/members.rb +13 -0
  24. data/lib/rbs/char_scanner.rb +20 -0
  25. data/lib/rbs/definition_builder.rb +50 -25
  26. data/lib/rbs/definition_builder/method_builder.rb +23 -2
  27. data/lib/rbs/environment.rb +42 -5
  28. data/lib/rbs/environment_walker.rb +4 -4
  29. data/lib/rbs/errors.rb +32 -17
  30. data/lib/rbs/parser.rb +437 -416
  31. data/lib/rbs/parser.y +29 -16
  32. data/lib/rbs/test/type_check.rb +7 -3
  33. data/lib/rbs/version.rb +1 -1
  34. data/sig/ancestor_graph.rbs +40 -0
  35. data/sig/char_scanner.rbs +9 -0
  36. data/sig/definition_builder.rbs +5 -1
  37. data/sig/environment.rbs +22 -2
  38. data/sig/environment_walker.rbs +39 -0
  39. data/sig/errors.rbs +42 -17
  40. data/sig/members.rbs +2 -0
  41. data/sig/method_builder.rbs +2 -0
  42. data/sig/parser.rbs +11 -4
  43. data/sig/polyfill.rbs +0 -14
  44. data/sig/types.rbs +7 -1
  45. data/stdlib/bigdecimal/0/big_decimal.rbs +1 -1
  46. data/stdlib/cgi/0/core.rbs +595 -0
  47. data/stdlib/date/0/date.rbs +1 -1
  48. data/stdlib/json/0/json.rbs +288 -0
  49. data/stdlib/pathname/0/pathname.rbs +2 -1
  50. data/stdlib/rubygems/0/basic_specification.rbs +3 -0
  51. data/stdlib/rubygems/0/config_file.rbs +3 -0
  52. data/stdlib/rubygems/0/dependency_installer.rbs +5 -0
  53. data/stdlib/rubygems/0/installer.rbs +3 -0
  54. data/stdlib/rubygems/0/path_support.rbs +3 -0
  55. data/stdlib/rubygems/0/platform.rbs +3 -0
  56. data/stdlib/rubygems/0/request_set.rbs +7 -0
  57. data/stdlib/rubygems/0/requirement.rbs +3 -0
  58. data/stdlib/rubygems/0/rubygems.rbs +710 -0
  59. data/stdlib/rubygems/0/source_list.rbs +2 -0
  60. data/stdlib/rubygems/0/specification.rbs +3 -0
  61. data/stdlib/rubygems/0/stream_ui.rbs +3 -0
  62. data/stdlib/rubygems/0/uninstaller.rbs +3 -0
  63. data/stdlib/rubygems/0/version.rbs +228 -0
  64. data/stdlib/set/0/set.rbs +7 -0
  65. data/stdlib/strscan/0/string_scanner.rbs +582 -0
  66. data/stdlib/timeout/0/timeout.rbs +57 -0
  67. data/stdlib/uri/0/rfc2396_parser.rbs +144 -7
  68. data/steep/Gemfile.lock +17 -19
  69. metadata +24 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 036100021b0cbb49dd861874f559cf64e038d283bf6dbcb6068db71fc9900a69
4
- data.tar.gz: 9bdf796be6710ae9f9a7c1ab50e7ce1871d86e34b9712fb03fa7418652499e25
3
+ metadata.gz: 8d83588e6a5f96ce5953f7c94eaf6f745eddadd1446e91946f18d4b81efb70bc
4
+ data.tar.gz: 3d7c3148afbe2a6041de6c909ddf08d7991e17c6fa2cebd4393a920582539263
5
5
  SHA512:
6
- metadata.gz: c70a2e6caa836c06d8136806b45d307f46b40e5cb21a6d4b4eaf49850fa884be0b240e1c8617e3f5d2cca75be25d91cfb0573613fff5ad8c945d0f9f45f8bdb0
7
- data.tar.gz: fdc96f11d612bdc16672620fd135360a0ff31cb6d32d181aa70785a0b15bf63d13588be95ade7a702d1c64091f22378c1a864a80dbcdf81c129dcdbb091f5afe
6
+ metadata.gz: e8a99b1a837a8cf4c7f1ce6b148c25e66433db2800d356a51ad58cc9b41280b097d3db7a3138679bc34f3c536415473a1b5423fac44f1048359d8556c938c298
7
+ data.tar.gz: 145caea219b5fb1d209e37f03ae0d4999f788895cf6a6dc4150d9ee4864be46ee7dc1126b95d0ddb0b1f1a4576c46f502c415aef56143900be61b726f81a291f
@@ -27,10 +27,10 @@ jobs:
27
27
  run: |
28
28
  apt-get update
29
29
  apt-get install -y libdb-dev
30
- - name: Install bundler
30
+ - name: Update rubygems & bundler
31
31
  run: |
32
32
  ruby -v
33
- gem install bundler
33
+ gem update --system
34
34
  - name: bundle config set with
35
35
  run: |
36
36
  echo "NO_MINITEST=true" >> $GITHUB_ENV
data/CHANGELOG.md CHANGED
@@ -2,6 +2,71 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.1.1 (2021-03-12)
6
+
7
+ ### Signature updates
8
+
9
+ * rubygem ([#630](https://github.com/ruby/rbs/pull/630))
10
+
11
+ ## 1.1.0 (2021-03-08)
12
+
13
+ ### Summary
14
+
15
+ Errors are now organized by `RBS::BaseError`, `RBS::ParsingError`, `RBS::LoadingError`, and `RBS::DefinitionError`.
16
+ The library users can rescue RBS related errors with `RBS::BaseError`, parsing errors with `RBS::ParsingError`, and other errors with `RBS::LoadingError` and `RBS::DefinitionErrors`.
17
+
18
+ Updating a part of environments are supported. Library users can remove declarations read from a set of files, adding new declarations, running name resolution related to the new decls, and deleting `DefinitionBuilder` caches related to the changes.
19
+ See `RBS::Environment#reject`, `RBS::Environment#resolve_type_names`, `RBS::AncestorGraph`, and `RBS::DefinitionBuilder#update`.
20
+
21
+ `RBS::DefinitionBuilder#build_singleton` now returns definitions containing `instance` type, which had returned resolved class instance types. This is a breaking change, but we consider it a bug fix because `RBS::DefinitionBuilder#build_instance` has returned `instance` types and `#build_singleton` has returned `class` type.
22
+
23
+ ### Signature updates
24
+
25
+ * rubygem ([\#605](https://github.com/ruby/rbs/pull/605), [\#610](https://github.com/ruby/rbs/pull/610))
26
+ * Array ([\#612](https://github.com/ruby/rbs/pull/612), [\#614](https://github.com/ruby/rbs/pull/614))
27
+ * cgi/core ([\#599](https://github.com/ruby/rbs/pull/599))
28
+ * Thread ([\#618](https://github.com/ruby/rbs/pull/618))
29
+
30
+ ### Language updates
31
+
32
+ * Allow trailing comma for Record and Tuple types ([\#606](https://github.com/ruby/rbs/pull/606))
33
+
34
+ ### Library changes
35
+
36
+ * Allow partial update of RBS declarations ([\#608](https://github.com/ruby/rbs/pull/608), [\#621](https://github.com/ruby/rbs/pull/621))
37
+ * Let errors have `TypeName` ([\#611](https://github.com/ruby/rbs/pull/611))
38
+ * Add `Parser::LexerError` ([\#615](https://github.com/ruby/rbs/pull/615))
39
+ * Performance improvement ([\#617](https://github.com/ruby/rbs/pull/617), [\#620](https://github.com/ruby/rbs/pull/620))
40
+ * No substitute `instance` types on `#build_singleton` ([\#619](https://github.com/ruby/rbs/pull/619))
41
+
42
+ ### Miscellaneous
43
+
44
+ * Make racc name customizable by `RACC` environment variable ([\#602](https://github.com/ruby/rbs/pull/602))
45
+ * Suppress warnings ([\#624](https://github.com/ruby/rbs/pull/624))
46
+ * Remove needless `Gem::Version` polyfill ([\#622](https://github.com/ruby/rbs/pull/622))
47
+
48
+ ## 1.0.6 (2021-02-17)
49
+
50
+ * Signature Updates
51
+ * `Enumerable` ([\#595](https://github.com/ruby/rbs/pull/595), [\#596](https://github.com/ruby/rbs/pull/596), [\#601](https://github.com/ruby/rbs/pull/601))
52
+ * `#as_json` ([\#597](https://github.com/ruby/rbs/pull/597))
53
+
54
+ ## 1.0.5 (2021-02-13)
55
+
56
+ * Signature Updates
57
+ * Enumerable ([\#596](https://github.com/ruby/rbs/pull/596))
58
+ * Set ([\#595](https://github.com/ruby/rbs/pull/595))
59
+ * `#to_json` ([\#592](https://github.com/ruby/rbs/pull/592))
60
+ * `<=>` ([\#593](https://github.com/ruby/rbs/pull/593))
61
+ * Timeout ([\#586](https://github.com/ruby/rbs/pull/586))
62
+ * URI::RFC2396_Parser ([\#587](https://github.com/ruby/rbs/pull/587))
63
+ * Rename generic class parameters on re-open ([\#594](https://github.com/ruby/rbs/pull/594))
64
+ * Make `refute_send_type` check that method call doesn't match with types in RBS ([\#588](https://github.com/ruby/rbs/pull/588))
65
+
66
+ ## 1.0.4 (2021-01-31)
67
+
68
+ * Unbundle `rr` to run test in `ruby/ruby` repo ([#585](https://github.com/ruby/rbs/pull/585))
69
+
5
70
  ## 1.0.3 (2021-01-28)
6
71
 
7
72
  * Set up `#ancestors` and `#location` of `RecursiveAncestorError` ([#583](https://github.com/ruby/rbs/pull/583))
data/Gemfile CHANGED
@@ -6,7 +6,6 @@ gemspec
6
6
  # Development dependencies
7
7
  gem "rake"
8
8
  gem "test-unit"
9
- gem "test-unit-rr"
10
9
  gem "rspec"
11
10
  gem "racc"
12
11
  gem "rubocop"
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require "rake/testtask"
3
3
  require "rbconfig"
4
4
 
5
5
  ruby = ENV["RUBY"] || RbConfig.ruby
6
+ racc = ENV.fetch("RACC", "racc")
6
7
  rbs = File.join(__dir__, "exe/rbs")
7
8
  bin = File.join(__dir__, "bin")
8
9
 
@@ -67,7 +68,7 @@ task :rubocop do
67
68
  end
68
69
 
69
70
  rule ".rb" => ".y" do |t|
70
- sh "racc -v -o #{t.name} #{t.source}"
71
+ sh "#{racc} -v -o #{t.name} #{t.source}"
71
72
  end
72
73
 
73
74
  task :parser => "lib/rbs/parser.rb"
@@ -77,7 +78,7 @@ task :build => :parser
77
78
 
78
79
  task :confirm_parser do
79
80
  puts "Testing if parser.rb is updated with respect to parser.y"
80
- sh "racc -v -o lib/rbs/parser.rb lib/rbs/parser.y"
81
+ sh "#{racc} -v -o lib/rbs/parser.rb lib/rbs/parser.y"
81
82
  sh "git diff --exit-code lib/rbs/parser.rb"
82
83
  end
83
84
 
data/Steepfile CHANGED
@@ -5,6 +5,8 @@ target :lib do
5
5
  ignore "lib/rbs/prototype", "lib/rbs/test", "lib/rbs/test.rb"
6
6
 
7
7
  library "set", "pathname", "json", "logger", "monitor", "tsort"
8
+ signature "stdlib/strscan/0/"
9
+ signature "stdlib/rubygems/0/"
8
10
  end
9
11
 
10
12
  # target :lib do
data/bin/rbs-prof CHANGED
@@ -4,6 +4,6 @@ require "stackprof"
4
4
 
5
5
  out = ENV["RBS_STACKPROF_OUT"] || 'tmp/stackprof-cpu-rbs.dump'
6
6
 
7
- StackProf.run(mode: :cpu, out: out) do
7
+ StackProf.run(mode: :cpu, out: out, raw: true) do
8
8
  load File.join(__dir__, "../exe/rbs")
9
9
  end
data/core/array.rbs CHANGED
@@ -1584,8 +1584,8 @@ class Array[unchecked out Elem] < Object
1584
1584
  # a.sample(random: Random.new(1)) #=> 6
1585
1585
  # a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2]
1586
1586
  #
1587
- def sample: (?random: Random rng) -> Elem?
1588
- | (?int n, ?random: Random rng) -> ::Array[Elem]
1587
+ def sample: (?random: _Rand rng) -> Elem?
1588
+ | (?int n, ?random: _Rand rng) -> ::Array[Elem]
1589
1589
 
1590
1590
  # Returns a new array containing all elements of `ary` for which the given
1591
1591
  # `block` returns a true value.
@@ -1649,7 +1649,7 @@ class Array[unchecked out Elem] < Object
1649
1649
  #
1650
1650
  # a.shuffle(random: Random.new(1)) #=> [1, 3, 2]
1651
1651
  #
1652
- def shuffle: (?random: Random rng) -> ::Array[Elem]
1652
+ def shuffle: (?random: _Rand rng) -> ::Array[Elem]
1653
1653
 
1654
1654
  # Shuffles elements in `self` in place.
1655
1655
  #
@@ -1661,7 +1661,7 @@ class Array[unchecked out Elem] < Object
1661
1661
  #
1662
1662
  # a.shuffle!(random: Random.new(1)) #=> [1, 3, 2]
1663
1663
  #
1664
- def shuffle!: (?random: Random rng) -> self
1664
+ def shuffle!: (?random: _Rand rng) -> self
1665
1665
 
1666
1666
  alias size length
1667
1667
 
@@ -1736,7 +1736,7 @@ class Array[unchecked out Elem] < Object
1736
1736
  # See also Enumerable#sort_by.
1737
1737
  #
1738
1738
  def sort: () -> ::Array[Elem]
1739
- | () { (Elem a, Elem b) -> ::Integer? } -> ::Array[Elem]
1739
+ | () { (Elem a, Elem b) -> ::Integer } -> ::Array[Elem]
1740
1740
 
1741
1741
  # Sorts `self` in place.
1742
1742
  #
@@ -1757,7 +1757,7 @@ class Array[unchecked out Elem] < Object
1757
1757
  # See also Enumerable#sort_by.
1758
1758
  #
1759
1759
  def sort!: () -> self
1760
- | () { (Elem a, Elem b) -> ::Integer? } -> self
1760
+ | () { (Elem a, Elem b) -> ::Integer } -> self
1761
1761
 
1762
1762
  # Sorts `self` in place using a set of keys generated by mapping the values in
1763
1763
  # `self` through the given block.
@@ -1997,6 +1997,10 @@ interface _ToAry[T]
1997
1997
  def to_ary: () -> ::Array[T]
1998
1998
  end
1999
1999
 
2000
+ interface _Rand
2001
+ def rand: (::Integer max) -> ::Integer
2002
+ end
2003
+
2000
2004
  interface Array::_Pattern[T]
2001
2005
  def ===: (T) -> bool
2002
2006
  end
data/core/complex.rbs CHANGED
@@ -121,7 +121,7 @@ class Complex < Numeric
121
121
  # Complex(2) <=> 2 #=> 0
122
122
  # Complex(2) <=> 3 #=> -1
123
123
  #
124
- def <=>: (Numeric) -> Integer?
124
+ def <=>: (untyped) -> Integer?
125
125
 
126
126
  # Returns true if cmp equals object numerically.
127
127
  #
data/core/enumerable.rbs CHANGED
@@ -286,8 +286,22 @@ module Enumerable[unchecked out Elem]: _Each[Elem]
286
286
  def sort_by: () { (Elem arg0) -> (Comparable | ::Array[untyped]) } -> ::Array[Elem]
287
287
  | () -> ::Enumerator[Elem, ::Array[Elem]]
288
288
 
289
- def take: (Integer n) -> ::Array[Elem]?
289
+ # Returns first n elements from *enum*.
290
+ #
291
+ # a = [1, 2, 3, 4, 5, 0]
292
+ # a.take(3) #=> [1, 2, 3]
293
+ # a.take(30) #=> [1, 2, 3, 4, 5, 0]
294
+ #
295
+ def take: (Integer n) -> ::Array[Elem]
290
296
 
297
+ # Passes elements to the block until the block returns `nil` or `false`, then
298
+ # stops iterating and returns an array of all prior elements.
299
+ #
300
+ # If no block is given, an enumerator is returned instead.
301
+ #
302
+ # a = [1, 2, 3, 4, 5, 0]
303
+ # a.take_while { |i| i < 3 } #=> [1, 2]
304
+ #
291
305
  def take_while: () { (Elem) -> boolish } -> ::Array[Elem]
292
306
  | () -> ::Enumerator[Elem, ::Array[Elem]]
293
307
 
data/core/enumerator.rbs CHANGED
@@ -244,6 +244,8 @@ end
244
244
 
245
245
  class Enumerator::Generator[out Elem] < Object
246
246
  include Enumerable[Elem]
247
+
248
+ def each: () { (Elem) -> void } -> void
247
249
  end
248
250
 
249
251
  class Enumerator::Lazy[out Elem, out Return] < Enumerator[Elem, Return]
@@ -259,4 +261,6 @@ end
259
261
 
260
262
  class Enumerator::Chain[out Elem] < Object
261
263
  include Enumerable[Elem]
264
+
265
+ def each: () { (Elem) -> void } -> void
262
266
  end
data/core/file.rbs CHANGED
@@ -985,7 +985,8 @@ class File::Stat < Object
985
985
  include Comparable
986
986
 
987
987
  def initialize: (String file) -> Object
988
- def <=>: (File::Stat other) -> Integer?
988
+ def <=>: (File::Stat other) -> Integer
989
+ | (untyped) -> nil
989
990
 
990
991
  def atime: () -> Time
991
992
 
data/core/integer.rbs CHANGED
@@ -112,7 +112,8 @@ class Integer < Numeric
112
112
  #
113
113
  # `nil` is returned if the two values are incomparable.
114
114
  #
115
- def <=>: (Numeric) -> Integer?
115
+ def <=>: (Integer | Rational) -> Integer
116
+ | (untyped) -> Integer?
116
117
 
117
118
  # Returns `true` if `int` equals `other` numerically. Contrast this with
118
119
  # Integer#eql?, which requires `other` to be an Integer.
data/core/module.rbs CHANGED
@@ -90,7 +90,7 @@ class Module < Object
90
90
  # Returns `nil` if `module` has no relationship with `other_module`, if
91
91
  # `other_module` is not a module, or if the two values are incomparable.
92
92
  #
93
- def <=>: (Module other) -> Integer?
93
+ def <=>: (untyped other) -> Integer?
94
94
 
95
95
  # Equality --- At the Object level, #== returns `true` only if `obj` and `other`
96
96
  # are the same object. Typically, this method is overridden in descendant
data/core/rational.rbs CHANGED
@@ -125,7 +125,8 @@ class Rational < Numeric
125
125
  #
126
126
  # Rational(1, 3) <=> "0.3" #=> nil
127
127
  #
128
- def <=>: (Numeric) -> Integer?
128
+ def <=>: (Integer | Rational) -> Integer
129
+ | (untyped) -> Integer?
129
130
 
130
131
  # Returns `true` if `rat` equals `object` numerically.
131
132
  #
data/core/string.rbs CHANGED
@@ -91,7 +91,8 @@ class String
91
91
  # "abcdef" <=> "ABCDEF" #=> 1
92
92
  # "abcdef" <=> 1 #=> nil
93
93
  #
94
- def <=>: (untyped other) -> Integer?
94
+ def <=>: (string other) -> Integer
95
+ | (untyped other) -> Integer?
95
96
 
96
97
  # Equality---Returns whether `str` == `obj`, similar to Object#==.
97
98
  #
data/core/symbol.rbs CHANGED
@@ -47,7 +47,8 @@ class Symbol
47
47
  #
48
48
  # See String#<=> for more information.
49
49
  #
50
- def <=>: (untyped other) -> Integer?
50
+ def <=>: (Symbol other) -> Integer
51
+ | (untyped other) -> Integer?
51
52
 
52
53
  # Equality---If *sym* and *obj* are exactly the same symbol, returns `true`.
53
54
  #
data/core/thread.rbs CHANGED
@@ -287,7 +287,20 @@ class Thread < Object
287
287
 
288
288
  def group: () -> ThreadGroup?
289
289
 
290
- def initialize: (*untyped args) -> Thread
290
+ # Creates a new thread executing the given block.
291
+ #
292
+ # Any `args` given to ::new will be passed to the block:
293
+ #
294
+ # arr = []
295
+ # a, b, c = 1, 2, 3
296
+ # Thread.new(a,b,c) { |d,e,f| arr << d << e << f }.join
297
+ # arr #=> [1, 2, 3]
298
+ #
299
+ # A ThreadError exception is raised if ::new is called without a block.
300
+ #
301
+ # If you're going to subclass Thread, be sure to call super in your `initialize`
302
+ # method, otherwise a ThreadError will be raised.
303
+ def initialize: (*untyped) { (*untyped) -> void } -> void
291
304
 
292
305
  # The calling thread will suspend execution and run this `thr` .
293
306
  #
data/core/time.rbs CHANGED
@@ -230,7 +230,8 @@ class Time < Object
230
230
  # t2 <=> t #=> 1
231
231
  # t <=> t #=> 0
232
232
  #
233
- def <=>: (Time other) -> Integer?
233
+ def <=>: (Time other) -> Integer
234
+ | (untyped other) -> Integer?
234
235
 
235
236
  def >: (Time arg0) -> bool
236
237
 
data/docs/stdlib.md CHANGED
@@ -70,7 +70,7 @@ One non-trivial but absolutely better solution is to make a tool:
70
70
  The next step should be importing RDoc documents.
71
71
 
72
72
  ```
73
- $ bin/annotate-with-rdoc stdlib/pathname/pathname.rbs
73
+ $ bin/annotate-with-rdoc stdlib/pathname/0/pathname.rbs
74
74
  Loading store from /Users/soutaro/.rbenv/versions/2.7.0-dev/share/ri/2.7.0/system...
75
75
  Loading store from /Users/soutaro/.rbenv/versions/2.7.0-dev/share/ri/2.7.0/site...
76
76
  Opening stdlib/pathname/pathname.rbs...
data/lib/rbs.rb CHANGED
@@ -7,7 +7,9 @@ require "pp"
7
7
  require "ripper"
8
8
  require "logger"
9
9
  require "tsort"
10
+ require "strscan"
10
11
 
12
+ require "rbs/char_scanner"
11
13
  require "rbs/errors"
12
14
  require "rbs/buffer"
13
15
  require "rbs/location"
@@ -40,6 +42,7 @@ require "rbs/vendorer"
40
42
  require "rbs/validator"
41
43
  require "rbs/factory"
42
44
  require "rbs/repository"
45
+ require "rbs/ancestor_graph"
43
46
 
44
47
  begin
45
48
  require "rbs/parser"
@@ -0,0 +1,90 @@
1
+ module RBS
2
+ class AncestorGraph
3
+ InstanceNode = _ = Struct.new(:type_name, keyword_init: true)
4
+ SingletonNode = _ = Struct.new(:type_name, keyword_init: true)
5
+
6
+ attr_reader :env
7
+ attr_reader :ancestor_builder
8
+ attr_reader :parents
9
+ attr_reader :children
10
+
11
+ def initialize(env:, ancestor_builder: DefinitionBuilder::AncestorBuilder.new(env: env))
12
+ @env = env
13
+ @ancestor_builder = ancestor_builder
14
+ build()
15
+ end
16
+
17
+ def build()
18
+ @parents = {}
19
+ @children = {}
20
+
21
+ env.class_decls.each_key do |type_name|
22
+ build_ancestors(InstanceNode.new(type_name: type_name), ancestor_builder.one_instance_ancestors(type_name))
23
+ build_ancestors(SingletonNode.new(type_name: type_name), ancestor_builder.one_singleton_ancestors(type_name))
24
+ end
25
+ env.interface_decls.each_key do |type_name|
26
+ build_ancestors(InstanceNode.new(type_name: type_name), ancestor_builder.one_interface_ancestors(type_name))
27
+ end
28
+ end
29
+
30
+ def build_ancestors(node, ancestors)
31
+ ancestors.each_ancestor do |ancestor|
32
+ case ancestor
33
+ when Definition::Ancestor::Instance
34
+ register(child: node, parent: InstanceNode.new(type_name: ancestor.name))
35
+ when Definition::Ancestor::Singleton
36
+ register(child: node, parent: SingletonNode.new(type_name: ancestor.name))
37
+ end
38
+ end
39
+ end
40
+
41
+ def register(parent:, child:)
42
+ (parents[child] ||= Set[]) << parent
43
+ (children[parent] ||= Set[]) << child
44
+ end
45
+
46
+ def each_parent(node, &block)
47
+ if block
48
+ parents[node]&.each(&block)
49
+ else
50
+ enum_for :each_parent, node
51
+ end
52
+ end
53
+
54
+ def each_child(node, &block)
55
+ if block
56
+ children[node]&.each(&block)
57
+ else
58
+ enum_for :each_child, node
59
+ end
60
+ end
61
+
62
+ def each_ancestor(node, yielded: Set[], &block)
63
+ if block
64
+ each_parent(node) do |parent|
65
+ unless yielded.member?(parent)
66
+ yielded << parent
67
+ yield parent
68
+ each_ancestor(parent, yielded: yielded, &block)
69
+ end
70
+ end
71
+ else
72
+ enum_for :each_ancestor, node
73
+ end
74
+ end
75
+
76
+ def each_descendant(node, yielded: Set[], &block)
77
+ if block
78
+ each_child(node) do |child|
79
+ unless yielded.member?(child)
80
+ yielded << child
81
+ yield child
82
+ each_descendant(child, yielded: yielded, &block)
83
+ end
84
+ end
85
+ else
86
+ enum_for :each_descendant, node
87
+ end
88
+ end
89
+ end
90
+ end