rbs 0.16.0 → 0.17.0

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