rbs 0.16.0 → 0.17.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.
@@ -1168,14 +1168,21 @@ end
1168
1168
 
1169
1169
  def new_token(type, value = input.matched)
1170
1170
  charpos = charpos(input)
1171
- start_index = charpos - input.matched.size
1172
- end_index = charpos
1171
+ matched = input.matched
1173
1172
 
1174
- location = RBS::Location.new(buffer: buffer,
1175
- start_pos: start_index,
1176
- end_pos: end_index)
1173
+ if matched
1174
+ start_index = charpos - matched.size
1175
+ end_index = charpos
1177
1176
 
1178
- [type, LocatedValue.new(location: location, value: value)]
1177
+ location = RBS::Location.new(buffer: buffer,
1178
+ start_pos: start_index,
1179
+ end_pos: end_index)
1180
+
1181
+ [type, LocatedValue.new(location: location, value: value)]
1182
+ else
1183
+ # scanner hasn't matched yet
1184
+ [false, nil]
1185
+ end
1179
1186
  end
1180
1187
 
1181
1188
  def charpos(scanner)
@@ -1294,10 +1301,10 @@ def next_token
1294
1301
  return [:"type_#{type}", nil]
1295
1302
  end
1296
1303
 
1297
- return if @eof
1304
+ return new_token(false, '') if @eof
1298
1305
 
1299
1306
  while true
1300
- return if input.eos?
1307
+ return new_token(false, '') if input.eos?
1301
1308
 
1302
1309
  case
1303
1310
  when input.scan(/\s+/)
@@ -411,7 +411,8 @@ module RBS
411
411
  when :HASH
412
412
  list = node.children[0]
413
413
  if list
414
- children = list.children.compact
414
+ children = list.children
415
+ children.pop
415
416
  else
416
417
  children = []
417
418
  end
@@ -419,8 +420,13 @@ module RBS
419
420
  key_types = []
420
421
  value_types = []
421
422
  children.each_slice(2) do |k, v|
422
- key_types << literal_to_type(k)
423
- value_types << literal_to_type(v)
423
+ if k
424
+ key_types << literal_to_type(k)
425
+ value_types << literal_to_type(v)
426
+ else
427
+ key_types << untyped
428
+ value_types << untyped
429
+ end
424
430
  end
425
431
 
426
432
  if !key_types.empty? && key_types.all? { |t| t.is_a?(Types::Literal) }
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.16.0"
2
+ VERSION = "0.17.0"
3
3
  end
@@ -21,13 +21,13 @@ module RBS
21
21
  attr_reader defined_in: TypeName
22
22
  attr_reader implemented_in: TypeName?
23
23
 
24
- def initialize: (type: MethodType, member: method_member, defined_in: TypeName?, implemented_in: TypeName?) -> void
24
+ def initialize: (type: MethodType, member: method_member, defined_in: TypeName, implemented_in: TypeName?) -> void
25
25
 
26
26
  def comment: () -> AST::Comment?
27
27
 
28
28
  def annotations: () -> Array[AST::Annotation]
29
29
 
30
- def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName?, ?implemented_in: TypeName?) -> TypeDef
30
+ def update: (?type: MethodType, ?member: method_member, ?defined_in: TypeName, ?implemented_in: TypeName?) -> TypeDef
31
31
 
32
32
  def overload?: () -> bool
33
33
  end
@@ -42,8 +42,13 @@ module RBS
42
42
  attr_reader comments: Array[AST::Comment]
43
43
  attr_reader annotations: Array[AST::Annotation]
44
44
  attr_reader members: Array[method_member]
45
+ attr_reader alias_of: Method?
45
46
 
46
- def initialize: (super_method: Method?, defs: Array[TypeDef], accessibility: accessibility, ?annotations: Array[AST::Annotation]) -> void
47
+ def initialize: (super_method: Method?,
48
+ defs: Array[TypeDef],
49
+ accessibility: accessibility,
50
+ alias_of: Method?,
51
+ ?annotations: Array[AST::Annotation]) -> void
47
52
 
48
53
  def public?: () -> bool
49
54
 
@@ -62,7 +62,7 @@ module RBS
62
62
  def ensure_namespace!: (Namespace, location: Location?) -> void
63
63
 
64
64
  def build_singleton: (TypeName) -> Definition
65
-
65
+
66
66
  def build_instance: (TypeName) -> Definition
67
67
 
68
68
  def build_interface: (TypeName) -> Definition
@@ -71,11 +71,12 @@ module RBS
71
71
 
72
72
  def build_one_singleton: (TypeName) -> Definition
73
73
 
74
+ type ancestors = Definition::InstanceAncestors | Definition::SingletonAncestors | nil
74
75
  def merge_definitions: (TypeName,
75
76
  Array[[Definition::Ancestor::t, Definition]],
76
77
  entry: Environment::ModuleEntry | Environment::ClassEntry,
77
78
  self_type: Definition::self_type,
78
- ancestors: Array[Definition::Ancestor::t]) -> Definition
79
+ ancestors: ancestors) -> Definition
79
80
 
80
81
  type method_kind = :instance | :singleton
81
82
  def merge_method: (TypeName, Hash[Symbol, Definition::Method], Symbol, Definition::Method, Substitution, kind: method_kind) -> void
@@ -159,7 +159,7 @@
159
159
  # with it.
160
160
  #
161
161
  class CSV < Object
162
- include Enumerable[untyped, untyped]
162
+ include Enumerable[untyped]
163
163
 
164
164
  # This method is intended as the primary interface for reading CSV files. You
165
165
  # pass a `path` and any `options` you wish to set for the read. Each row of file
@@ -407,7 +407,7 @@ CSV::VERSION: String
407
407
  # processing is activated.
408
408
  #
409
409
  class CSV::Row < Object
410
- include Enumerable[untyped, untyped]
410
+ include Enumerable[untyped]
411
411
 
412
412
  # If a two-element Array is provided, it is assumed to be a header and field and
413
413
  # the pair is appended. A Hash works the same way with the key being the header
@@ -578,7 +578,7 @@ end
578
578
  # processing is activated.
579
579
  #
580
580
  class CSV::Table[out Elem] < Object
581
- include Enumerable[untyped, untyped]
581
+ include Enumerable[untyped]
582
582
 
583
583
  # Constructs a new CSV::Table from `array_of_rows`, which are expected to be
584
584
  # CSV::Row objects. All rows are assumed to have the same headers.
@@ -61,7 +61,7 @@
61
61
  # puts db['822']
62
62
  #
63
63
  class DBM
64
- include Enumerable[untyped, untyped]
64
+ include Enumerable[untyped]
65
65
 
66
66
  # Open a dbm database and yields it if a block is given. See also `DBM.new`.
67
67
  #
@@ -137,7 +137,7 @@ class Prime
137
137
  class PseudoPrimeGenerator
138
138
  def initialize: (?Integer?) -> void
139
139
 
140
- include Enumerable[Integer, void]
140
+ include Enumerable[Integer]
141
141
 
142
142
  attr_accessor upper_bound (): Integer?
143
143
 
@@ -51,8 +51,8 @@ class Set[A]
51
51
  # Set.new(1..5) #=> #<Set: {1, 2, 3, 4, 5}>
52
52
  # Set.new([1, 2, 3]) { |x| x * x } #=> #<Set: {1, 4, 9}>
53
53
  #
54
- def initialize: (_Each[A, untyped]) -> untyped
55
- | [X] (_Each[X, untyped]) { (X) -> A } -> untyped
54
+ def initialize: (_Each[A]) -> untyped
55
+ | [X] (_Each[X]) { (X) -> A } -> untyped
56
56
  | (?nil) -> untyped
57
57
 
58
58
  # Creates a new set containing the given objects.
@@ -69,7 +69,7 @@ class Set[A]
69
69
  # Set[1, 3, 5] & Set[3, 2, 1] #=> #<Set: {3, 1}>
70
70
  # Set['a', 'b', 'z'] & ['a', 'b', 'c'] #=> #<Set: {"a", "b"}>
71
71
  #
72
- def &: (_Each[A, untyped]) -> self
72
+ def &: (_Each[A]) -> self
73
73
 
74
74
  alias intersection &
75
75
 
@@ -79,7 +79,7 @@ class Set[A]
79
79
  # Set[1, 2, 3] | Set[2, 4, 5] #=> #<Set: {1, 2, 3, 4, 5}>
80
80
  # Set[1, 5, 'z'] | (1..6) #=> #<Set: {1, 5, "z", 2, 3, 4, 6}>
81
81
  #
82
- def |: (_Each[A, untyped]) -> self
82
+ def |: (_Each[A]) -> self
83
83
 
84
84
  alias union |
85
85
 
@@ -91,7 +91,7 @@ class Set[A]
91
91
  # Set[1, 3, 5] - Set[1, 5] #=> #<Set: {3}>
92
92
  # Set['a', 'b', 'z'] - ['a', 'c'] #=> #<Set: {"b", "z"}>
93
93
  #
94
- def -: (_Each[A, untyped]) -> self
94
+ def -: (_Each[A]) -> self
95
95
 
96
96
  alias difference -
97
97
 
@@ -133,7 +133,7 @@ class Set[A]
133
133
  # Set[1, 2] ^ Set[2, 3] #=> #<Set: {3, 1}>
134
134
  # Set[1, 'b', 'c'] ^ ['b', 'd'] #=> #<Set: {"d", 1, "c"}>
135
135
  #
136
- def ^: (_Each[A, untyped]) -> self
136
+ def ^: (_Each[A]) -> self
137
137
 
138
138
  # Classifies the set by the return value of the given block and returns a hash
139
139
  # of {value => set of elements} pairs. The block is called once for each
@@ -248,7 +248,7 @@ class Set[A]
248
248
  # Merges the elements of the given enumerable object to the set and returns
249
249
  # self.
250
250
  #
251
- def merge: (_Each[A, untyped]) -> self
251
+ def merge: (_Each[A]) -> self
252
252
 
253
253
  # Returns true if the set is a subset of the given set.
254
254
  #
@@ -271,7 +271,7 @@ class Set[A]
271
271
  # set.replace([1, 2]) #=> #<Set: {1, 2}>
272
272
  # set #=> #<Set: {1, 2}>
273
273
  #
274
- def replace: (_Each[A, untyped]) -> self
274
+ def replace: (_Each[A]) -> self
275
275
 
276
276
  # Resets the internal state after modification to existing elements and returns
277
277
  # self.
@@ -288,7 +288,7 @@ class Set[A]
288
288
  # Deletes every element that appears in the given enumerable object and returns
289
289
  # self.
290
290
  #
291
- def subtract: (_Each[A, untyped]) -> self
291
+ def subtract: (_Each[A]) -> self
292
292
 
293
293
  # Converts the set to an array. The order of elements is uncertain.
294
294
  #
@@ -297,5 +297,5 @@ class Set[A]
297
297
  #
298
298
  def to_a: () -> Array[A]
299
299
 
300
- include Enumerable[A, self]
300
+ include Enumerable[A]
301
301
  end
@@ -0,0 +1,4 @@
1
+ module TSort[Node]
2
+ class Cyclic < StandardError
3
+ end
4
+ end
@@ -0,0 +1,19 @@
1
+ module TSort[Node]
2
+ interface _Sortable[Node]
3
+ # #tsort_each_node is used to iterate for all nodes over a graph.
4
+ #
5
+ def tsort_each_node: () { (Node) -> void } -> void
6
+
7
+ # #tsort_each_child is used to iterate for child nodes of node.
8
+ #
9
+ def tsort_each_child: (Node) { (Node) -> void } -> void
10
+ end
11
+
12
+ interface _EachNode[Node]
13
+ def call: () { (Node) -> void } -> void
14
+ end
15
+
16
+ interface _EachChild[Node]
17
+ def call: (Node) { (Node) -> void } -> void
18
+ end
19
+ end
@@ -0,0 +1,363 @@
1
+ # TSort implements topological sorting using Tarjan's algorithm for strongly
2
+ # connected components.
3
+ #
4
+ # TSort is designed to be able to be used with any object which can be
5
+ # interpreted as a directed graph.
6
+ #
7
+ # TSort requires two methods to interpret an object as a graph, tsort_each_node
8
+ # and tsort_each_child.
9
+ #
10
+ # * tsort_each_node is used to iterate for all nodes over a graph.
11
+ # * tsort_each_child is used to iterate for child nodes of a given node.
12
+ #
13
+ #
14
+ # The equality of nodes are defined by eql? and hash since TSort uses Hash
15
+ # internally.
16
+ #
17
+ # ## A Simple Example
18
+ #
19
+ # The following example demonstrates how to mix the TSort module into an
20
+ # existing class (in this case, Hash). Here, we're treating each key in the hash
21
+ # as a node in the graph, and so we simply alias the required #tsort_each_node
22
+ # method to Hash's #each_key method. For each key in the hash, the associated
23
+ # value is an array of the node's child nodes. This choice in turn leads to our
24
+ # implementation of the required #tsort_each_child method, which fetches the
25
+ # array of child nodes and then iterates over that array using the user-supplied
26
+ # block.
27
+ #
28
+ # require 'tsort'
29
+ #
30
+ # class Hash
31
+ # include TSort
32
+ # alias tsort_each_node each_key
33
+ # def tsort_each_child(node, &block)
34
+ # fetch(node).each(&block)
35
+ # end
36
+ # end
37
+ #
38
+ # {1=>[2, 3], 2=>[3], 3=>[], 4=>[]}.tsort
39
+ # #=> [3, 2, 1, 4]
40
+ #
41
+ # {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}.strongly_connected_components
42
+ # #=> [[4], [2, 3], [1]]
43
+ #
44
+ # ## A More Realistic Example
45
+ #
46
+ # A very simple `make' like tool can be implemented as follows:
47
+ #
48
+ # require 'tsort'
49
+ #
50
+ # class Make
51
+ # def initialize
52
+ # @dep = {}
53
+ # @dep.default = []
54
+ # end
55
+ #
56
+ # def rule(outputs, inputs=[], &block)
57
+ # triple = [outputs, inputs, block]
58
+ # outputs.each {|f| @dep[f] = [triple]}
59
+ # @dep[triple] = inputs
60
+ # end
61
+ #
62
+ # def build(target)
63
+ # each_strongly_connected_component_from(target) {|ns|
64
+ # if ns.length != 1
65
+ # fs = ns.delete_if {|n| Array === n}
66
+ # raise TSort::Cyclic.new("cyclic dependencies: #{fs.join ', '}")
67
+ # end
68
+ # n = ns.first
69
+ # if Array === n
70
+ # outputs, inputs, block = n
71
+ # inputs_time = inputs.map {|f| File.mtime f}.max
72
+ # begin
73
+ # outputs_time = outputs.map {|f| File.mtime f}.min
74
+ # rescue Errno::ENOENT
75
+ # outputs_time = nil
76
+ # end
77
+ # if outputs_time == nil ||
78
+ # inputs_time != nil && outputs_time <= inputs_time
79
+ # sleep 1 if inputs_time != nil && inputs_time.to_i == Time.now.to_i
80
+ # block.call
81
+ # end
82
+ # end
83
+ # }
84
+ # end
85
+ #
86
+ # def tsort_each_child(node, &block)
87
+ # @dep[node].each(&block)
88
+ # end
89
+ # include TSort
90
+ # end
91
+ #
92
+ # def command(arg)
93
+ # print arg, "\n"
94
+ # system arg
95
+ # end
96
+ #
97
+ # m = Make.new
98
+ # m.rule(%w[t1]) { command 'date > t1' }
99
+ # m.rule(%w[t2]) { command 'date > t2' }
100
+ # m.rule(%w[t3]) { command 'date > t3' }
101
+ # m.rule(%w[t4], %w[t1 t3]) { command 'cat t1 t3 > t4' }
102
+ # m.rule(%w[t5], %w[t4 t2]) { command 'cat t4 t2 > t5' }
103
+ # m.build('t5')
104
+ #
105
+ # ## Bugs
106
+ #
107
+ # * 'tsort.rb' is wrong name because this library uses Tarjan's algorithm for
108
+ # strongly connected components. Although 'strongly_connected_components.rb'
109
+ # is correct but too long.
110
+ #
111
+ #
112
+ # ## References
113
+ #
114
+ # 1. Tarjan, "Depth First Search and Linear Graph Algorithms",
115
+ #
116
+ #
117
+ # *SIAM Journal on Computing*, Vol. 1, No. 2, pp. 146-160, June 1972.
118
+ module TSort[Node] : TSort::_Sortable[Node]
119
+ # The iterator version of the TSort.strongly_connected_components method.
120
+ #
121
+ # The graph is represented by *each_node* and *each_child*. *each_node* should
122
+ # have `call` method which yields for each node in the graph. *each_child*
123
+ # should have `call` method which takes a node argument and yields for each
124
+ # child node.
125
+ #
126
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
127
+ # each_node = lambda {|&b| g.each_key(&b) }
128
+ # each_child = lambda {|n, &b| g[n].each(&b) }
129
+ # TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
130
+ # #=> [4]
131
+ # # [2]
132
+ # # [3]
133
+ # # [1]
134
+ #
135
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
136
+ # each_node = lambda {|&b| g.each_key(&b) }
137
+ # each_child = lambda {|n, &b| g[n].each(&b) }
138
+ # TSort.each_strongly_connected_component(each_node, each_child) {|scc| p scc }
139
+ # #=> [4]
140
+ # # [2, 3]
141
+ # # [1]
142
+ #
143
+ def self.each_strongly_connected_component: [T] (_EachNode[T] each_node, _EachChild[T] each_child) { (Array[T]) -> void } -> void
144
+ | [T] (_EachNode[T] each_node, _EachChild[T] each_child) -> Enumerator[Array[T], void]
145
+
146
+ # Iterates over strongly connected components in a graph. The graph is
147
+ # represented by *node* and *each_child*.
148
+ #
149
+ # *node* is the first node. *each_child* should have `call` method which takes a
150
+ # node argument and yields for each child node.
151
+ #
152
+ # Return value is unspecified.
153
+ #
154
+ # #TSort.each_strongly_connected_component_from is a class method and it doesn't
155
+ # need a class to represent a graph which includes TSort.
156
+ #
157
+ # graph = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
158
+ # each_child = lambda {|n, &b| graph[n].each(&b) }
159
+ # TSort.each_strongly_connected_component_from(1, each_child) {|scc|
160
+ # p scc
161
+ # }
162
+ # #=> [4]
163
+ # # [2, 3]
164
+ # # [1]
165
+ #
166
+ def self.each_strongly_connected_component_from: [T] (T node, _EachChild[T] each_child, ?untyped id_map, ?untyped stack) { (Array[T]) -> void } -> void
167
+ | [T] (T node, _EachChild[T] each_child, ?untyped id_map, ?untyped stack) -> Enumerator[Array[T], void]
168
+
169
+ # Returns strongly connected components as an array of arrays of nodes. The
170
+ # array is sorted from children to parents. Each elements of the array
171
+ # represents a strongly connected component.
172
+ #
173
+ # The graph is represented by *each_node* and *each_child*. *each_node* should
174
+ # have `call` method which yields for each node in the graph. *each_child*
175
+ # should have `call` method which takes a node argument and yields for each
176
+ # child node.
177
+ #
178
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
179
+ # each_node = lambda {|&b| g.each_key(&b) }
180
+ # each_child = lambda {|n, &b| g[n].each(&b) }
181
+ # p TSort.strongly_connected_components(each_node, each_child)
182
+ # #=> [[4], [2], [3], [1]]
183
+ #
184
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
185
+ # each_node = lambda {|&b| g.each_key(&b) }
186
+ # each_child = lambda {|n, &b| g[n].each(&b) }
187
+ # p TSort.strongly_connected_components(each_node, each_child)
188
+ # #=> [[4], [2, 3], [1]]
189
+ #
190
+ def self.strongly_connected_components: [T] (_EachNode[T] each_node, _EachChild[T] each_child) -> Array[Array[T]]
191
+
192
+ # Returns a topologically sorted array of nodes. The array is sorted from
193
+ # children to parents, i.e. the first element has no child and the last node has
194
+ # no parent.
195
+ #
196
+ # The graph is represented by *each_node* and *each_child*. *each_node* should
197
+ # have `call` method which yields for each node in the graph. *each_child*
198
+ # should have `call` method which takes a node argument and yields for each
199
+ # child node.
200
+ #
201
+ # If there is a cycle, TSort::Cyclic is raised.
202
+ #
203
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
204
+ # each_node = lambda {|&b| g.each_key(&b) }
205
+ # each_child = lambda {|n, &b| g[n].each(&b) }
206
+ # p TSort.tsort(each_node, each_child) #=> [4, 2, 3, 1]
207
+ #
208
+ # g = {1=>[2], 2=>[3, 4], 3=>[2], 4=>[]}
209
+ # each_node = lambda {|&b| g.each_key(&b) }
210
+ # each_child = lambda {|n, &b| g[n].each(&b) }
211
+ # p TSort.tsort(each_node, each_child) # raises TSort::Cyclic
212
+ #
213
+ def self.tsort: [T] (_EachNode[T] each_node, _EachChild[T] each_child) -> Array[T]
214
+
215
+ # The iterator version of the TSort.tsort method.
216
+ #
217
+ # The graph is represented by *each_node* and *each_child*. *each_node* should
218
+ # have `call` method which yields for each node in the graph. *each_child*
219
+ # should have `call` method which takes a node argument and yields for each
220
+ # child node.
221
+ #
222
+ # g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
223
+ # each_node = lambda {|&b| g.each_key(&b) }
224
+ # each_child = lambda {|n, &b| g[n].each(&b) }
225
+ # TSort.tsort_each(each_node, each_child) {|n| p n }
226
+ # #=> 4
227
+ # # 2
228
+ # # 3
229
+ # # 1
230
+ #
231
+ def self.tsort_each: [T] (_EachNode[T] each_node, _EachChild[T] each_child) { (T) -> void } -> void
232
+ | [T] (_EachNode[T] each_node, _EachChild[T] each_child) -> Enumerator[T, void]
233
+
234
+ # The iterator version of the #strongly_connected_components method.
235
+ # *`obj*.each_strongly_connected_component` is similar to
236
+ # *`obj*.strongly_connected_components.each`, but modification of *obj* during
237
+ # the iteration may lead to unexpected results.
238
+ #
239
+ # #each_strongly_connected_component returns `nil`.
240
+ #
241
+ # class G
242
+ # include TSort
243
+ # def initialize(g)
244
+ # @g = g
245
+ # end
246
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
247
+ # def tsort_each_node(&b) @g.each_key(&b) end
248
+ # end
249
+ #
250
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
251
+ # graph.each_strongly_connected_component {|scc| p scc }
252
+ # #=> [4]
253
+ # # [2]
254
+ # # [3]
255
+ # # [1]
256
+ #
257
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
258
+ # graph.each_strongly_connected_component {|scc| p scc }
259
+ # #=> [4]
260
+ # # [2, 3]
261
+ # # [1]
262
+ #
263
+ def each_strongly_connected_component: () { (Array[Node]) -> void } -> void
264
+ | () -> Enumerator[Array[Node], void]
265
+
266
+ # Iterates over strongly connected component in the subgraph reachable from
267
+ # *node*.
268
+ #
269
+ # Return value is unspecified.
270
+ #
271
+ # #each_strongly_connected_component_from doesn't call #tsort_each_node.
272
+ #
273
+ # class G
274
+ # include TSort
275
+ # def initialize(g)
276
+ # @g = g
277
+ # end
278
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
279
+ # def tsort_each_node(&b) @g.each_key(&b) end
280
+ # end
281
+ #
282
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
283
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
284
+ # #=> [4]
285
+ # # [2]
286
+ #
287
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
288
+ # graph.each_strongly_connected_component_from(2) {|scc| p scc }
289
+ # #=> [4]
290
+ # # [2, 3]
291
+ #
292
+ def each_strongly_connected_component_from: (Node, ?untyped id_map, ?untyped stack) { (Array[Node]) -> void } -> void
293
+ | (Node, ?untyped id_map, ?untyped stack) -> Enumerator[Array[Node], void]
294
+
295
+ # Returns strongly connected components as an array of arrays of nodes. The
296
+ # array is sorted from children to parents. Each elements of the array
297
+ # represents a strongly connected component.
298
+ #
299
+ # class G
300
+ # include TSort
301
+ # def initialize(g)
302
+ # @g = g
303
+ # end
304
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
305
+ # def tsort_each_node(&b) @g.each_key(&b) end
306
+ # end
307
+ #
308
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
309
+ # p graph.strongly_connected_components #=> [[4], [2], [3], [1]]
310
+ #
311
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
312
+ # p graph.strongly_connected_components #=> [[4], [2, 3], [1]]
313
+ #
314
+ def strongly_connected_components: () -> Array[Array[Node]]
315
+
316
+ # Returns a topologically sorted array of nodes. The array is sorted from
317
+ # children to parents, i.e. the first element has no child and the last node has
318
+ # no parent.
319
+ #
320
+ # If there is a cycle, TSort::Cyclic is raised.
321
+ #
322
+ # class G
323
+ # include TSort
324
+ # def initialize(g)
325
+ # @g = g
326
+ # end
327
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
328
+ # def tsort_each_node(&b) @g.each_key(&b) end
329
+ # end
330
+ #
331
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
332
+ # p graph.tsort #=> [4, 2, 3, 1]
333
+ #
334
+ # graph = G.new({1=>[2], 2=>[3, 4], 3=>[2], 4=>[]})
335
+ # p graph.tsort # raises TSort::Cyclic
336
+ #
337
+ def tsort: () -> Array[Node]
338
+
339
+ # The iterator version of the #tsort method. *`obj*.tsort_each` is similar to
340
+ # *`obj*.tsort.each`, but modification of *obj* during the iteration may lead to
341
+ # unexpected results.
342
+ #
343
+ # #tsort_each returns `nil`. If there is a cycle, TSort::Cyclic is raised.
344
+ #
345
+ # class G
346
+ # include TSort
347
+ # def initialize(g)
348
+ # @g = g
349
+ # end
350
+ # def tsort_each_child(n, &b) @g[n].each(&b) end
351
+ # def tsort_each_node(&b) @g.each_key(&b) end
352
+ # end
353
+ #
354
+ # graph = G.new({1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]})
355
+ # graph.tsort_each {|n| p n }
356
+ # #=> 4
357
+ # # 2
358
+ # # 3
359
+ # # 1
360
+ #
361
+ def tsort_each: () { (Node) -> void } -> void
362
+ | () -> Enumerator[Node, void]
363
+ end