Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(371)

Side by Side Diff: observatory_pub_packages/analyzer/src/generated/utilities_collection.dart

Issue 816693004: Add observatory_pub_packages snapshot to third_party (Closed) Base URL: http://dart.googlecode.com/svn/third_party/
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 // This code was auto-generated, is not intended to be edited, and is subject to
6 // significant change. Please see the README file for more information.
7
8 library engine.utilities.collection;
9
10 import 'dart:collection';
11 import 'java_core.dart';
12 import 'scanner.dart' show Token;
13
14 /**
15 * The class `BooleanArray` defines methods for operating on integers as if they were arrays
16 * of booleans. These arrays can be indexed by either integers or by enumeration constants.
17 */
18 class BooleanArray {
19 /**
20 * Return the value of the element at the given index.
21 *
22 * @param array the array being accessed
23 * @param index the index of the element being accessed
24 * @return the value of the element at the given index
25 * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
26 */
27 static bool get(int array, int index) {
28 _checkIndex(index);
29 return (array & (1 << index)) > 0;
30 }
31
32 /**
33 * Return the value of the element at the given index.
34 *
35 * @param array the array being accessed
36 * @param index the index of the element being accessed
37 * @return the value of the element at the given index
38 * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
39 */
40 static bool getEnum(int array, Enum index) => get(array, index.ordinal);
41
42 /**
43 * Set the value of the element at the given index to the given value.
44 *
45 * @param array the array being modified
46 * @param index the index of the element being set
47 * @param value the value to be assigned to the element
48 * @return the updated value of the array
49 * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
50 */
51 static int set(int array, int index, bool value) {
52 _checkIndex(index);
53 if (value) {
54 return array | (1 << index);
55 } else {
56 return array & ~(1 << index);
57 }
58 }
59
60 /**
61 * Set the value of the element at the given index to the given value.
62 *
63 * @param array the array being modified
64 * @param index the index of the element being set
65 * @param value the value to be assigned to the element
66 * @return the updated value of the array
67 * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
68 */
69 static int setEnum(int array, Enum index, bool value) => set(array, index.ordi nal, value);
70
71 /**
72 * Throw an exception if the index is not within the bounds allowed for an int eger-encoded array
73 * of boolean values.
74 *
75 * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
76 */
77 static void _checkIndex(int index) {
78 if (index < 0 || index > 30) {
79 throw new RangeError("Index not between 0 and 30: ${index}");
80 }
81 }
82 }
83
84 /**
85 * Instances of the class `DirectedGraph` implement a directed graph in which th e nodes are
86 * arbitrary (client provided) objects and edges are represented implicitly. The graph will allow an
87 * edge from any node to any other node, including itself, but will not represen t multiple edges
88 * between the same pair of nodes.
89 *
90 * @param N the type of the nodes in the graph
91 */
92 class DirectedGraph<N> {
93 /**
94 * The table encoding the edges in the graph. An edge is represented by an ent ry mapping the head
95 * to a set of tails. Nodes that are not the head of any edge are represented by an entry mapping
96 * the node to an empty set of tails.
97 */
98 HashMap<N, HashSet<N>> _edges = new HashMap<N, HashSet<N>>();
99
100 /**
101 * Add an edge from the given head node to the given tail node. Both nodes wil l be a part of the
102 * graph after this method is invoked, whether or not they were before.
103 *
104 * @param head the node at the head of the edge
105 * @param tail the node at the tail of the edge
106 */
107 void addEdge(N head, N tail) {
108 //
109 // First, ensure that the tail is a node known to the graph.
110 //
111 if (_edges[tail] == null) {
112 _edges[tail] = new HashSet<N>();
113 }
114 //
115 // Then create the edge.
116 //
117 HashSet<N> tails = _edges[head];
118 if (tails == null) {
119 tails = new HashSet<N>();
120 _edges[head] = tails;
121 }
122 tails.add(tail);
123 }
124
125 /**
126 * Add the given node to the set of nodes in the graph.
127 *
128 * @param node the node to be added
129 */
130 void addNode(N node) {
131 HashSet<N> tails = _edges[node];
132 if (tails == null) {
133 _edges[node] = new HashSet<N>();
134 }
135 }
136
137 /**
138 * Run a topological sort of the graph. Since the graph may contain cycles, th is results in a list
139 * of strongly connected components rather than a list of nodes. The nodes in each strongly
140 * connected components only have edges that point to nodes in the same compon ent or earlier
141 * components.
142 */
143 List<List<N>> computeTopologicalSort() {
144 DirectedGraph_SccFinder<N> finder = new DirectedGraph_SccFinder<N>(this);
145 return finder.computeTopologicalSort();
146 }
147
148 /**
149 * Return true if the graph contains at least one path from `source` to `desti nation`.
150 */
151 bool containsPath(N source, N destination) {
152 HashSet<N> nodesVisited = new HashSet<N>();
153 return _containsPathInternal(source, destination, nodesVisited);
154 }
155
156 /**
157 * Return a list of nodes that form a cycle containing the given node. If the node is not part of
158 * this graph, then a list containing only the node itself will be returned.
159 *
160 * @return a list of nodes that form a cycle containing the given node
161 */
162 List<N> findCycleContaining(N node) {
163 if (node == null) {
164 throw new IllegalArgumentException();
165 }
166 DirectedGraph_SccFinder<N> finder = new DirectedGraph_SccFinder<N>(this);
167 return finder.componentContaining(node);
168 }
169
170 /**
171 * Return the number of nodes in this graph.
172 *
173 * @return the number of nodes in this graph
174 */
175 int get nodeCount => _edges.length;
176
177 /**
178 * Return a set of all nodes in the graph.
179 */
180 Set<N> get nodes => _edges.keys.toSet();
181
182 /**
183 * Return a set containing the tails of edges that have the given node as thei r head. The set will
184 * be empty if there are no such edges or if the node is not part of the graph . Clients must not
185 * modify the returned set.
186 *
187 * @param head the node at the head of all of the edges whose tails are to be returned
188 * @return a set containing the tails of edges that have the given node as the ir head
189 */
190 Set<N> getTails(N head) {
191 HashSet<N> tails = _edges[head];
192 if (tails == null) {
193 return new HashSet<N>();
194 }
195 return tails;
196 }
197
198 /**
199 * Return `true` if this graph is empty.
200 *
201 * @return `true` if this graph is empty
202 */
203 bool get isEmpty => _edges.isEmpty;
204
205 /**
206 * Remove all of the given nodes from this graph. As a consequence, any edges for which those
207 * nodes were either a head or a tail will also be removed.
208 *
209 * @param nodes the nodes to be removed
210 */
211 void removeAllNodes(List<N> nodes) {
212 for (N node in nodes) {
213 removeNode(node);
214 }
215 }
216
217 /**
218 * Remove the edge from the given head node to the given tail node. If there w as no such edge then
219 * the graph will be unmodified: the number of edges will be the same and the set of nodes will be
220 * the same (neither node will either be added or removed).
221 *
222 * @param head the node at the head of the edge
223 * @param tail the node at the tail of the edge
224 * @return `true` if the graph was modified as a result of this operation
225 */
226 void removeEdge(N head, N tail) {
227 HashSet<N> tails = _edges[head];
228 if (tails != null) {
229 tails.remove(tail);
230 }
231 }
232
233 /**
234 * Remove the given node from this graph. As a consequence, any edges for whic h that node was
235 * either a head or a tail will also be removed.
236 *
237 * @param node the node to be removed
238 */
239 void removeNode(N node) {
240 _edges.remove(node);
241 for (HashSet<N> tails in _edges.values) {
242 tails.remove(node);
243 }
244 }
245
246 /**
247 * Find one node (referred to as a sink node) that has no outgoing edges (that is, for which there
248 * are no edges that have that node as the head of the edge) and remove it fro m this graph. Return
249 * the node that was removed, or `null` if there are no such nodes either beca use the graph
250 * is empty or because every node in the graph has at least one outgoing edge. As a consequence of
251 * removing the node from the graph any edges for which that node was a tail w ill also be removed.
252 *
253 * @return the sink node that was removed
254 */
255 N removeSink() {
256 N sink = _findSink();
257 if (sink == null) {
258 return null;
259 }
260 removeNode(sink);
261 return sink;
262 }
263
264 bool _containsPathInternal(N source, N destination, HashSet<N> nodesVisited) {
265 if (identical(source, destination)) {
266 return true;
267 }
268 HashSet<N> tails = _edges[source];
269 if (tails != null) {
270 nodesVisited.add(source);
271 for (N tail in tails) {
272 if (!nodesVisited.contains(tail)) {
273 if (_containsPathInternal(tail, destination, nodesVisited)) {
274 return true;
275 }
276 }
277 }
278 }
279 return false;
280 }
281
282 /**
283 * Return one node that has no outgoing edges (that is, for which there are no edges that have
284 * that node as the head of the edge), or `null` if there are no such nodes.
285 *
286 * @return a sink node
287 */
288 N _findSink() {
289 for (N key in _edges.keys) {
290 if (_edges[key].isEmpty) return key;
291 }
292 return null;
293 }
294 }
295
296 /**
297 * Instances of the class `NodeInfo` are used by the [SccFinder] to maintain
298 * information about the nodes that have been examined.
299 *
300 * @param N the type of the nodes corresponding to the entries
301 */
302 class DirectedGraph_NodeInfo<N> {
303 /**
304 * The depth of this node.
305 */
306 int index = 0;
307
308 /**
309 * The depth of the first node in a cycle.
310 */
311 int lowlink = 0;
312
313 /**
314 * A flag indicating whether the corresponding node is on the stack. Used to r emove the need for
315 * searching a collection for the node each time the question needs to be aske d.
316 */
317 bool onStack = false;
318
319 /**
320 * The component that contains the corresponding node.
321 */
322 List<N> component;
323
324 /**
325 * Initialize a newly created information holder to represent a node at the gi ven depth.
326 *
327 * @param depth the depth of the node being represented
328 */
329 DirectedGraph_NodeInfo(int depth) {
330 index = depth;
331 lowlink = depth;
332 onStack = false;
333 }
334 }
335
336 /**
337 * Instances of the class `SccFinder` implement Tarjan's Algorithm for finding t he strongly
338 * connected components in a graph.
339 */
340 class DirectedGraph_SccFinder<N> {
341 /**
342 * The graph to work with.
343 */
344 final DirectedGraph<N> _graph;
345
346 /**
347 * The index used to uniquely identify the depth of nodes.
348 */
349 int _index = 0;
350
351 /**
352 * The stack of nodes that are being visited in order to identify components.
353 */
354 List<N> _stack = new List<N>();
355
356 /**
357 * A table mapping nodes to information about the nodes that is used by this a lgorithm.
358 */
359 HashMap<N, DirectedGraph_NodeInfo<N>> _nodeMap = new HashMap<N, DirectedGraph_ NodeInfo<N>>();
360
361 /**
362 * A list of all strongly connected components found, in topological sort orde r (each node in a
363 * strongly connected component only has edges that point to nodes in the same component or
364 * earlier components).
365 */
366 List<List<N>> _allComponents = new List<List<N>>();
367
368 /**
369 * Initialize a newly created finder.
370 */
371 DirectedGraph_SccFinder(this._graph) : super();
372
373 /**
374 * Return a list containing the nodes that are part of the strongly connected component that
375 * contains the given node.
376 *
377 * @param node the node used to identify the strongly connected component to b e returned
378 * @return the nodes that are part of the strongly connected component that co ntains the given
379 * node
380 */
381 List<N> componentContaining(N node) => _strongConnect(node).component;
382
383 /**
384 * Run Tarjan's algorithm and return the resulting list of strongly connected components. The
385 * list is in topological sort order (each node in a strongly connected compon ent only has edges
386 * that point to nodes in the same component or earlier components).
387 */
388 List<List<N>> computeTopologicalSort() {
389 for (N node in _graph._edges.keys.toSet()) {
390 DirectedGraph_NodeInfo<N> nodeInfo = _nodeMap[node];
391 if (nodeInfo == null) {
392 _strongConnect(node);
393 }
394 }
395 return _allComponents;
396 }
397
398 /**
399 * Remove and return the top-most element from the stack.
400 *
401 * @return the element that was removed
402 */
403 N _pop() {
404 N node = _stack.removeAt(_stack.length - 1);
405 _nodeMap[node].onStack = false;
406 return node;
407 }
408
409 /**
410 * Add the given node to the stack.
411 *
412 * @param node the node to be added to the stack
413 */
414 void _push(N node) {
415 _nodeMap[node].onStack = true;
416 _stack.add(node);
417 }
418
419 /**
420 * Compute the strongly connected component that contains the given node as we ll as any
421 * components containing nodes that are reachable from the given component.
422 *
423 * @param v the node from which the search will begin
424 * @return the information about the given node
425 */
426 DirectedGraph_NodeInfo<N> _strongConnect(N v) {
427 //
428 // Set the depth index for v to the smallest unused index
429 //
430 DirectedGraph_NodeInfo<N> vInfo = new DirectedGraph_NodeInfo<N>(_index++);
431 _nodeMap[v] = vInfo;
432 _push(v);
433 //
434 // Consider successors of v
435 //
436 HashSet<N> tails = _graph._edges[v];
437 if (tails != null) {
438 for (N w in tails) {
439 DirectedGraph_NodeInfo<N> wInfo = _nodeMap[w];
440 if (wInfo == null) {
441 // Successor w has not yet been visited; recurse on it
442 wInfo = _strongConnect(w);
443 vInfo.lowlink = Math.min(vInfo.lowlink, wInfo.lowlink);
444 } else if (wInfo.onStack) {
445 // Successor w is in stack S and hence in the current SCC
446 vInfo.lowlink = Math.min(vInfo.lowlink, wInfo.index);
447 }
448 }
449 }
450 //
451 // If v is a root node, pop the stack and generate an SCC
452 //
453 if (vInfo.lowlink == vInfo.index) {
454 List<N> component = new List<N>();
455 N w;
456 do {
457 w = _pop();
458 component.add(w);
459 _nodeMap[w].component = component;
460 } while (!identical(w, v));
461 _allComponents.add(component);
462 }
463 return vInfo;
464 }
465 }
466
467 /**
468 * The class `ListUtilities` defines utility methods useful for working with [Li st
469 ].
470 */
471 class ListUtilities {
472 /**
473 * Add all of the elements in the given array to the given list.
474 *
475 * @param list the list to which the elements are to be added
476 * @param elements the elements to be added to the list
477 */
478 static void addAll(List list, List<Object> elements) {
479 int count = elements.length;
480 for (int i = 0; i < count; i++) {
481 list.add(elements[i]);
482 }
483 }
484 }
485
486 /**
487 * The interface `MapIterator` defines the behavior of objects that iterate over the entries
488 * in a map.
489 *
490 * This interface defines the concept of a current entry and provides methods to access the key and
491 * value in the current entry. When an iterator is first created it will be posi tioned before the
492 * first entry and there is no current entry until [moveNext] is invoked. When a ll of the
493 * entries have been accessed there will also be no current entry.
494 *
495 * There is no guarantee made about the order in which the entries are accessibl e.
496 */
497 abstract class MapIterator<K, V> {
498 /**
499 * Return the key associated with the current element.
500 *
501 * @return the key associated with the current element
502 * @throws NoSuchElementException if there is no current element
503 */
504 K get key;
505
506 /**
507 * Return the value associated with the current element.
508 *
509 * @return the value associated with the current element
510 * @throws NoSuchElementException if there is no current element
511 */
512 V get value;
513
514 /**
515 * Advance to the next entry in the map. Return `true` if there is a current e lement that
516 * can be accessed after this method returns. It is safe to invoke this method even if the
517 * previous invocation returned `false`.
518 *
519 * @return `true` if there is a current element that can be accessed
520 */
521 bool moveNext();
522
523 /**
524 * Set the value associated with the current element to the given value.
525 *
526 * @param newValue the new value to be associated with the current element
527 * @throws NoSuchElementException if there is no current element
528 */
529 void set value(V newValue);
530 }
531
532 /**
533 * Instances of the class `MultipleMapIterator` implement an iterator that can b e used to
534 * sequentially access the entries in multiple maps.
535 */
536 class MultipleMapIterator<K, V> implements MapIterator<K, V> {
537 /**
538 * The iterators used to access the entries.
539 */
540 List<MapIterator<K, V>> _iterators;
541
542 /**
543 * The index of the iterator currently being used to access the entries.
544 */
545 int _iteratorIndex = -1;
546
547 /**
548 * The current iterator, or `null` if there is no current iterator.
549 */
550 MapIterator<K, V> _currentIterator;
551
552 /**
553 * Initialize a newly created iterator to return the entries from the given ma ps.
554 *
555 * @param maps the maps containing the entries to be iterated
556 */
557 MultipleMapIterator(List<Map<K, V>> maps) {
558 int count = maps.length;
559 _iterators = new List<MapIterator>(count);
560 for (int i = 0; i < count; i++) {
561 _iterators[i] = new SingleMapIterator<K, V>(maps[i]);
562 }
563 }
564
565 @override
566 K get key {
567 if (_currentIterator == null) {
568 throw new NoSuchElementException();
569 }
570 return _currentIterator.key;
571 }
572
573 @override
574 V get value {
575 if (_currentIterator == null) {
576 throw new NoSuchElementException();
577 }
578 return _currentIterator.value;
579 }
580
581 @override
582 bool moveNext() {
583 if (_iteratorIndex < 0) {
584 if (_iterators.length == 0) {
585 _currentIterator = null;
586 return false;
587 }
588 if (_advanceToNextIterator()) {
589 return true;
590 } else {
591 _currentIterator = null;
592 return false;
593 }
594 }
595 if (_currentIterator.moveNext()) {
596 return true;
597 } else if (_advanceToNextIterator()) {
598 return true;
599 } else {
600 _currentIterator = null;
601 return false;
602 }
603 }
604
605 @override
606 void set value(V newValue) {
607 if (_currentIterator == null) {
608 throw new NoSuchElementException();
609 }
610 _currentIterator.value = newValue;
611 }
612
613 /**
614 * Under the assumption that there are no more entries that can be returned us ing the current
615 * iterator, advance to the next iterator that has entries.
616 *
617 * @return `true` if there is a current iterator that has entries
618 */
619 bool _advanceToNextIterator() {
620 _iteratorIndex++;
621 while (_iteratorIndex < _iterators.length) {
622 MapIterator<K, V> iterator = _iterators[_iteratorIndex];
623 if (iterator.moveNext()) {
624 _currentIterator = iterator;
625 return true;
626 }
627 _iteratorIndex++;
628 }
629 return false;
630 }
631 }
632
633 /**
634 * Instances of the class `TokenMap` map one set of tokens to another set of tok ens.
635 */
636 class TokenMap {
637 /**
638 * A table mapping tokens to tokens. This should be replaced by a more perform ant implementation.
639 * One possibility is a pair of parallel arrays, with keys being sorted by the ir offset and a
640 * cursor indicating where to start searching.
641 */
642 HashMap<Token, Token> _map = new HashMap<Token, Token>();
643
644 /**
645 * Return the token that is mapped to the given token, or `null` if there is n o token
646 * corresponding to the given token.
647 *
648 * @param key the token being mapped to another token
649 * @return the token that is mapped to the given token
650 */
651 Token get(Token key) => _map[key];
652
653 /**
654 * Map the key to the value.
655 *
656 * @param key the token being mapped to the value
657 * @param value the token to which the key will be mapped
658 */
659 void put(Token key, Token value) {
660 _map[key] = value;
661 }
662 }
663
664 /**
665 * Instances of the class `SingleMapIterator` implement an iterator that can be used to access
666 * the entries in a single map.
667 */
668 class SingleMapIterator<K, V> implements MapIterator<K, V> {
669 /**
670 * Returns a new [SingleMapIterator] instance for the given [Map].
671 */
672 static SingleMapIterator forMap(Map map) => new SingleMapIterator(map);
673
674 /**
675 * The [Map] containing the entries to be iterated over.
676 */
677 final Map<K, V> _map;
678
679 /**
680 * The iterator used to access the entries.
681 */
682 Iterator<K> _keyIterator;
683
684 /**
685 * The current key, or `null` if there is no current key.
686 */
687 K _currentKey;
688
689 /**
690 * The current value.
691 */
692 V _currentValue;
693
694 /**
695 * Initialize a newly created iterator to return the entries from the given ma p.
696 *
697 * @param map the map containing the entries to be iterated over
698 */
699 SingleMapIterator(this._map) {
700 this._keyIterator = _map.keys.iterator;
701 }
702
703 @override
704 K get key {
705 if (_currentKey == null) {
706 throw new NoSuchElementException();
707 }
708 return _currentKey;
709 }
710
711 @override
712 V get value {
713 if (_currentKey == null) {
714 throw new NoSuchElementException();
715 }
716 return _currentValue;
717 }
718
719 @override
720 bool moveNext() {
721 if (_keyIterator.moveNext()) {
722 _currentKey = _keyIterator.current;
723 _currentValue = _map[_currentKey];
724 return true;
725 } else {
726 _currentKey = null;
727 return false;
728 }
729 }
730
731 @override
732 void set value(V newValue) {
733 if (_currentKey == null) {
734 throw new NoSuchElementException();
735 }
736 _currentValue = newValue;
737 _map[_currentKey] = newValue;
738 }
739 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698