Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from compiler.ast import Const | 5 from compiler.ast import Const |
| 6 from compiler.ast import Dict | 6 from compiler.ast import Dict |
| 7 from compiler.ast import Discard | 7 from compiler.ast import Discard |
| 8 from compiler.ast import List | 8 from compiler.ast import List |
| 9 from compiler.ast import Module | 9 from compiler.ast import Module |
| 10 from compiler.ast import Node | 10 from compiler.ast import Node |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 51 'outputs', | 51 'outputs', |
| 52 'sources', | 52 'sources', |
| 53 ] | 53 ] |
| 54 path_sections = set() | 54 path_sections = set() |
| 55 | 55 |
| 56 # These per-process dictionaries are used to cache build file data when loading | 56 # These per-process dictionaries are used to cache build file data when loading |
| 57 # in parallel mode. | 57 # in parallel mode. |
| 58 per_process_data = {} | 58 per_process_data = {} |
| 59 per_process_aux_data = {} | 59 per_process_aux_data = {} |
| 60 | 60 |
| 61 def OrderDeterministically(l, **kwargs): | |
| 62 """ Sorts l so that it is ordered deterministically. """ | |
| 63 return sorted(l, **kwargs) | |
|
mithro-old
2015/12/10 03:15:28
DRY
Zachary Forman
2015/12/30 02:18:43
Done.
| |
| 64 | |
| 61 def IsPathSection(section): | 65 def IsPathSection(section): |
| 62 # If section ends in one of the '=+?!' characters, it's applied to a section | 66 # If section ends in one of the '=+?!' characters, it's applied to a section |
| 63 # without the trailing characters. '/' is notably absent from this list, | 67 # without the trailing characters. '/' is notably absent from this list, |
| 64 # because there's no way for a regular expression to be treated as a path. | 68 # because there's no way for a regular expression to be treated as a path. |
| 65 while section and section[-1:] in '=+?!': | 69 while section and section[-1:] in '=+?!': |
| 66 section = section[:-1] | 70 section = section[:-1] |
| 67 | 71 |
| 68 if section in path_sections: | 72 if section in path_sections: |
| 69 return True | 73 return True |
| 70 | 74 |
| (...skipping 1461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1532 def __repr__(self): | 1536 def __repr__(self): |
| 1533 return '<DependencyGraphNode: %r>' % self.ref | 1537 return '<DependencyGraphNode: %r>' % self.ref |
| 1534 | 1538 |
| 1535 def FlattenToList(self): | 1539 def FlattenToList(self): |
| 1536 # flat_list is the sorted list of dependencies - actually, the list items | 1540 # flat_list is the sorted list of dependencies - actually, the list items |
| 1537 # are the "ref" attributes of DependencyGraphNodes. Every target will | 1541 # are the "ref" attributes of DependencyGraphNodes. Every target will |
| 1538 # appear in flat_list after all of its dependencies, and before all of its | 1542 # appear in flat_list after all of its dependencies, and before all of its |
| 1539 # dependents. | 1543 # dependents. |
| 1540 flat_list = OrderedSet() | 1544 flat_list = OrderedSet() |
| 1541 | 1545 |
| 1546 def ExtractNodeRef(node): | |
| 1547 """Extracts the object that the node represents from the given node.""" | |
| 1548 return node.ref | |
| 1549 | |
| 1542 # in_degree_zeros is the list of DependencyGraphNodes that have no | 1550 # in_degree_zeros is the list of DependencyGraphNodes that have no |
| 1543 # dependencies not in flat_list. Initially, it is a copy of the children | 1551 # dependencies not in flat_list. Initially, it is a copy of the children |
| 1544 # of this node, because when the graph was built, nodes with no | 1552 # of this node, because when the graph was built, nodes with no |
| 1545 # dependencies were made implicit dependents of the root node. | 1553 # dependencies were made implicit dependents of the root node. |
| 1546 in_degree_zeros = set(self.dependents[:]) | 1554 in_degree_zeros = OrderDeterministically(self.dependents[:], |
| 1555 key=ExtractNodeRef) | |
| 1547 | 1556 |
| 1548 while in_degree_zeros: | 1557 while in_degree_zeros: |
| 1549 # Nodes in in_degree_zeros have no dependencies not in flat_list, so they | 1558 # Nodes in in_degree_zeros have no dependencies not in flat_list, so they |
| 1550 # can be appended to flat_list. Take these nodes out of in_degree_zeros | 1559 # can be appended to flat_list. Take these nodes out of in_degree_zeros |
| 1551 # as work progresses, so that the next node to process from the list can | 1560 # as work progresses, so that the next node to process from the list can |
| 1552 # always be accessed at a consistent position. | 1561 # always be accessed at a consistent position. |
| 1553 node = in_degree_zeros.pop() | 1562 node = in_degree_zeros.pop() |
| 1554 flat_list.add(node.ref) | 1563 flat_list.add(node.ref) |
| 1555 | 1564 |
| 1556 # Look at dependents of the node just added to flat_list. Some of them | 1565 # Look at dependents of the node just added to flat_list. Some of them |
| 1557 # may now belong in in_degree_zeros. | 1566 # may now belong in in_degree_zeros. |
| 1558 for node_dependent in node.dependents: | 1567 for node_dependent in OrderDeterministically(node.dependents, |
| 1568 key=ExtractNodeRef): | |
| 1559 is_in_degree_zero = True | 1569 is_in_degree_zero = True |
| 1560 # TODO: We want to check through the | 1570 # TODO: We want to check through the |
| 1561 # node_dependent.dependencies list but if it's long and we | 1571 # node_dependent.dependencies list but if it's long and we |
| 1562 # always start at the beginning, then we get O(n^2) behaviour. | 1572 # always start at the beginning, then we get O(n^2) behaviour. |
| 1563 for node_dependent_dependency in node_dependent.dependencies: | 1573 for node_dependent_dependency in ( |
| 1574 OrderDeterministically(node_dependent.dependencies, | |
| 1575 key=ExtractNodeRef)): | |
| 1564 if not node_dependent_dependency.ref in flat_list: | 1576 if not node_dependent_dependency.ref in flat_list: |
| 1565 # The dependent one or more dependencies not in flat_list. There | 1577 # The dependent one or more dependencies not in flat_list. There |
| 1566 # will be more chances to add it to flat_list when examining | 1578 # will be more chances to add it to flat_list when examining |
| 1567 # it again as a dependent of those other dependencies, provided | 1579 # it again as a dependent of those other dependencies, provided |
| 1568 # that there are no cycles. | 1580 # that there are no cycles. |
| 1569 is_in_degree_zero = False | 1581 is_in_degree_zero = False |
| 1570 break | 1582 break |
| 1571 | 1583 |
| 1572 if is_in_degree_zero: | 1584 if is_in_degree_zero: |
| 1573 # All of the dependent's dependencies are already in flat_list. Add | 1585 # All of the dependent's dependencies are already in flat_list. Add |
| 1574 # it to in_degree_zeros where it will be processed in a future | 1586 # it to in_degree_zeros where it will be processed in a future |
| 1575 # iteration of the outer loop. | 1587 # iteration of the outer loop. |
| 1576 in_degree_zeros.add(node_dependent) | 1588 in_degree_zeros += [node_dependent] |
| 1577 | 1589 |
| 1578 return list(flat_list) | 1590 return list(flat_list) |
| 1579 | 1591 |
| 1580 def FindCycles(self): | 1592 def FindCycles(self): |
| 1581 """ | 1593 """ |
| 1582 Returns a list of cycles in the graph, where each cycle is its own list. | 1594 Returns a list of cycles in the graph, where each cycle is its own list. |
| 1583 """ | 1595 """ |
| 1584 results = [] | 1596 results = [] |
| 1585 visited = set() | 1597 visited = set() |
| 1586 | 1598 |
| (...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2885 ValidateRunAsInTarget(target, target_dict, build_file) | 2897 ValidateRunAsInTarget(target, target_dict, build_file) |
| 2886 ValidateActionsInTarget(target, target_dict, build_file) | 2898 ValidateActionsInTarget(target, target_dict, build_file) |
| 2887 | 2899 |
| 2888 # Generators might not expect ints. Turn them into strs. | 2900 # Generators might not expect ints. Turn them into strs. |
| 2889 TurnIntIntoStrInDict(data) | 2901 TurnIntIntoStrInDict(data) |
| 2890 | 2902 |
| 2891 # TODO(mark): Return |data| for now because the generator needs a list of | 2903 # TODO(mark): Return |data| for now because the generator needs a list of |
| 2892 # build files that came in. In the future, maybe it should just accept | 2904 # build files that came in. In the future, maybe it should just accept |
| 2893 # a list, and not the whole data dict. | 2905 # a list, and not the whole data dict. |
| 2894 return [flat_list, targets, data] | 2906 return [flat_list, targets, data] |
| OLD | NEW |