| Index: tools/gn/parse_tree.cc
|
| diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc
|
| index 5e5b9ea01b719b1e5f1ca69fe06868dd570c74a3..d22adca5c4b5f2d380d1f7167a769e1ec6bb985c 100644
|
| --- a/tools/gn/parse_tree.cc
|
| +++ b/tools/gn/parse_tree.cc
|
| @@ -5,6 +5,7 @@
|
| #include "tools/gn/parse_tree.h"
|
|
|
| #include <string>
|
| +#include <tuple>
|
|
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_number_conversions.h"
|
| @@ -15,6 +16,20 @@
|
|
|
| namespace {
|
|
|
| +std::tuple<base::StringPiece, base::StringPiece> SplitAtFirst(
|
| + base::StringPiece str,
|
| + char c) {
|
| + if (!str.starts_with("\"") || !str.ends_with("\""))
|
| + return std::make_tuple(str, base::StringPiece());
|
| +
|
| + str = str.substr(1, str.length() - 2);
|
| + size_t index_of_first = str.find(c);
|
| + return std::make_tuple(str.substr(0, index_of_first),
|
| + index_of_first != base::StringPiece::npos
|
| + ? str.substr(index_of_first + 1)
|
| + : base::StringPiece());
|
| +}
|
| +
|
| std::string IndentFor(int value) {
|
| return std::string(value, ' ');
|
| }
|
| @@ -502,10 +517,21 @@ void ListNode::Print(std::ostream& out, int indent) const {
|
| end_->Print(out, indent + 1);
|
| }
|
|
|
| -void ListNode::SortAsStringsList() {
|
| - // Sorts alphabetically. Partitions first on BlockCommentNodes and sorts each
|
| - // partition separately.
|
| +template <typename Comparator>
|
| +void ListNode::SortList(Comparator comparator) {
|
| + // Partitions first on BlockCommentNodes and sorts each partition separately.
|
| for (auto sr : GetSortRanges()) {
|
| + bool skip = false;
|
| + for (size_t i = sr.begin; i != sr.end; ++i) {
|
| + // Bails out if any of the nodes are unsupported.
|
| + const ParseNode* node = contents_[i];
|
| + if (!node->AsLiteral() && !node->AsIdentifier() && !node->AsAccessor()) {
|
| + skip = true;
|
| + continue;
|
| + }
|
| + }
|
| + if (skip)
|
| + continue;
|
| // Save the original line number so that we can re-assign ranges. We assume
|
| // they're contiguous lines because GetSortRanges() does so above. We need
|
| // to re-assign these line numbers primiarily because `gn format` uses them
|
| @@ -514,11 +540,7 @@ void ListNode::SortAsStringsList() {
|
| int start_line = contents_[sr.begin]->GetRange().begin().line_number();
|
| const ParseNode* original_first = contents_[sr.begin];
|
| std::sort(contents_.begin() + sr.begin, contents_.begin() + sr.end,
|
| - [](const ParseNode* a, const ParseNode* b) {
|
| - base::StringPiece astr = GetStringRepresentation(a);
|
| - base::StringPiece bstr = GetStringRepresentation(b);
|
| - return astr < bstr;
|
| - });
|
| + comparator);
|
| // If the beginning of the range had before comments, and the first node
|
| // moved during the sort, then move its comments to the new head of the
|
| // range.
|
| @@ -553,6 +575,25 @@ void ListNode::SortAsStringsList() {
|
| }
|
| }
|
|
|
| +void ListNode::SortAsStringsList() {
|
| + // Sorts alphabetically.
|
| + SortList([](const ParseNode* a, const ParseNode* b) {
|
| + base::StringPiece astr = GetStringRepresentation(a);
|
| + base::StringPiece bstr = GetStringRepresentation(b);
|
| + return astr < bstr;
|
| + });
|
| +}
|
| +
|
| +void ListNode::SortAsDepsList() {
|
| + // Sorts first relative targets, then absolute, each group is sorted
|
| + // alphabetically.
|
| + SortList([](const ParseNode* a, const ParseNode* b) {
|
| + base::StringPiece astr = GetStringRepresentation(a);
|
| + base::StringPiece bstr = GetStringRepresentation(b);
|
| + return SplitAtFirst(astr, ':') < SplitAtFirst(bstr, ':');
|
| + });
|
| +}
|
| +
|
| // Breaks the ParseNodes of |contents| up by ranges that should be separately
|
| // sorted. In particular, we break at a block comment, or an item that has an
|
| // attached "before" comment and is separated by a blank line from the item
|
|
|