| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. 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 #include "tools/gn/parse_tree.h" | 5 #include "tools/gn/parse_tree.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <tuple> | 10 #include <tuple> |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 left_->Print(out, indent + 1); | 290 left_->Print(out, indent + 1); |
| 291 right_->Print(out, indent + 1); | 291 right_->Print(out, indent + 1); |
| 292 } | 292 } |
| 293 | 293 |
| 294 // BlockNode ------------------------------------------------------------------ | 294 // BlockNode ------------------------------------------------------------------ |
| 295 | 295 |
| 296 BlockNode::BlockNode() { | 296 BlockNode::BlockNode() { |
| 297 } | 297 } |
| 298 | 298 |
| 299 BlockNode::~BlockNode() { | 299 BlockNode::~BlockNode() { |
| 300 STLDeleteContainerPointers(statements_.begin(), statements_.end()); | |
| 301 } | 300 } |
| 302 | 301 |
| 303 const BlockNode* BlockNode::AsBlock() const { | 302 const BlockNode* BlockNode::AsBlock() const { |
| 304 return this; | 303 return this; |
| 305 } | 304 } |
| 306 | 305 |
| 307 Value BlockNode::Execute(Scope* scope, Err* err) const { | 306 Value BlockNode::Execute(Scope* scope, Err* err) const { |
| 308 for (size_t i = 0; i < statements_.size() && !err->has_error(); i++) { | 307 for (size_t i = 0; i < statements_.size() && !err->has_error(); i++) { |
| 309 // Check for trying to execute things with no side effects in a block. | 308 // Check for trying to execute things with no side effects in a block. |
| 310 const ParseNode* cur = statements_[i]; | 309 const ParseNode* cur = statements_[i].get(); |
| 311 if (cur->AsList() || cur->AsLiteral() || cur->AsUnaryOp() || | 310 if (cur->AsList() || cur->AsLiteral() || cur->AsUnaryOp() || |
| 312 cur->AsIdentifier()) { | 311 cur->AsIdentifier()) { |
| 313 *err = cur->MakeErrorDescribing( | 312 *err = cur->MakeErrorDescribing( |
| 314 "This statement has no effect.", | 313 "This statement has no effect.", |
| 315 "Either delete it or do something with the result."); | 314 "Either delete it or do something with the result."); |
| 316 return Value(); | 315 return Value(); |
| 317 } | 316 } |
| 318 cur->Execute(scope, err); | 317 cur->Execute(scope, err); |
| 319 } | 318 } |
| 320 return Value(); | 319 return Value(); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 value_.set_location( | 484 value_.set_location( |
| 486 Location(old.file(), line_number, old.column_number(), old.byte())); | 485 Location(old.file(), line_number, old.column_number(), old.byte())); |
| 487 } | 486 } |
| 488 | 487 |
| 489 // ListNode ------------------------------------------------------------------- | 488 // ListNode ------------------------------------------------------------------- |
| 490 | 489 |
| 491 ListNode::ListNode() : prefer_multiline_(false) { | 490 ListNode::ListNode() : prefer_multiline_(false) { |
| 492 } | 491 } |
| 493 | 492 |
| 494 ListNode::~ListNode() { | 493 ListNode::~ListNode() { |
| 495 STLDeleteContainerPointers(contents_.begin(), contents_.end()); | |
| 496 } | 494 } |
| 497 | 495 |
| 498 const ListNode* ListNode::AsList() const { | 496 const ListNode* ListNode::AsList() const { |
| 499 return this; | 497 return this; |
| 500 } | 498 } |
| 501 | 499 |
| 502 Value ListNode::Execute(Scope* scope, Err* err) const { | 500 Value ListNode::Execute(Scope* scope, Err* err) const { |
| 503 Value result_value(this, Value::LIST); | 501 Value result_value(this, Value::LIST); |
| 504 std::vector<Value>& results = result_value.list_value(); | 502 std::vector<Value>& results = result_value.list_value(); |
| 505 results.reserve(contents_.size()); | 503 results.reserve(contents_.size()); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 end_->Print(out, indent + 1); | 538 end_->Print(out, indent + 1); |
| 541 } | 539 } |
| 542 | 540 |
| 543 template <typename Comparator> | 541 template <typename Comparator> |
| 544 void ListNode::SortList(Comparator comparator) { | 542 void ListNode::SortList(Comparator comparator) { |
| 545 // Partitions first on BlockCommentNodes and sorts each partition separately. | 543 // Partitions first on BlockCommentNodes and sorts each partition separately. |
| 546 for (auto sr : GetSortRanges()) { | 544 for (auto sr : GetSortRanges()) { |
| 547 bool skip = false; | 545 bool skip = false; |
| 548 for (size_t i = sr.begin; i != sr.end; ++i) { | 546 for (size_t i = sr.begin; i != sr.end; ++i) { |
| 549 // Bails out if any of the nodes are unsupported. | 547 // Bails out if any of the nodes are unsupported. |
| 550 const ParseNode* node = contents_[i]; | 548 const ParseNode* node = contents_[i].get(); |
| 551 if (!node->AsLiteral() && !node->AsIdentifier() && !node->AsAccessor()) { | 549 if (!node->AsLiteral() && !node->AsIdentifier() && !node->AsAccessor()) { |
| 552 skip = true; | 550 skip = true; |
| 553 continue; | 551 continue; |
| 554 } | 552 } |
| 555 } | 553 } |
| 556 if (skip) | 554 if (skip) |
| 557 continue; | 555 continue; |
| 558 // Save the original line number so that we can re-assign ranges. We assume | 556 // Save the original line number so that we can re-assign ranges. We assume |
| 559 // they're contiguous lines because GetSortRanges() does so above. We need | 557 // they're contiguous lines because GetSortRanges() does so above. We need |
| 560 // to re-assign these line numbers primiarily because `gn format` uses them | 558 // to re-assign these line numbers primiarily because `gn format` uses them |
| 561 // to determine whether two nodes were initially separated by a blank line | 559 // to determine whether two nodes were initially separated by a blank line |
| 562 // or not. | 560 // or not. |
| 563 int start_line = contents_[sr.begin]->GetRange().begin().line_number(); | 561 int start_line = contents_[sr.begin]->GetRange().begin().line_number(); |
| 564 const ParseNode* original_first = contents_[sr.begin]; | 562 const ParseNode* original_first = contents_[sr.begin].get(); |
| 565 std::sort(contents_.begin() + sr.begin, contents_.begin() + sr.end, | 563 std::sort(contents_.begin() + sr.begin, contents_.begin() + sr.end, |
| 566 comparator); | 564 [&comparator](const std::unique_ptr<const ParseNode>& a, |
| 565 const std::unique_ptr<const ParseNode>& b) { |
| 566 return comparator(a.get(), b.get()); |
| 567 }); |
| 567 // If the beginning of the range had before comments, and the first node | 568 // If the beginning of the range had before comments, and the first node |
| 568 // moved during the sort, then move its comments to the new head of the | 569 // moved during the sort, then move its comments to the new head of the |
| 569 // range. | 570 // range. |
| 570 if (original_first->comments() && contents_[sr.begin] != original_first) { | 571 if (original_first->comments() && |
| 572 contents_[sr.begin].get() != original_first) { |
| 571 for (const auto& hc : original_first->comments()->before()) { | 573 for (const auto& hc : original_first->comments()->before()) { |
| 572 const_cast<ParseNode*>(contents_[sr.begin]) | 574 const_cast<ParseNode*>(contents_[sr.begin].get()) |
| 573 ->comments_mutable() | 575 ->comments_mutable() |
| 574 ->append_before(hc); | 576 ->append_before(hc); |
| 575 } | 577 } |
| 576 const_cast<ParseNode*>(original_first) | 578 const_cast<ParseNode*>(original_first) |
| 577 ->comments_mutable() | 579 ->comments_mutable() |
| 578 ->clear_before(); | 580 ->clear_before(); |
| 579 } | 581 } |
| 580 const ParseNode* prev = nullptr; | 582 const ParseNode* prev = nullptr; |
| 581 for (size_t i = sr.begin; i != sr.end; ++i) { | 583 for (size_t i = sr.begin; i != sr.end; ++i) { |
| 582 const ParseNode* node = contents_[i]; | 584 const ParseNode* node = contents_[i].get(); |
| 583 DCHECK(node->AsLiteral() || node->AsIdentifier() || node->AsAccessor()); | 585 DCHECK(node->AsLiteral() || node->AsIdentifier() || node->AsAccessor()); |
| 584 int line_number = | 586 int line_number = |
| 585 prev ? prev->GetRange().end().line_number() + 1 : start_line; | 587 prev ? prev->GetRange().end().line_number() + 1 : start_line; |
| 586 if (node->AsLiteral()) { | 588 if (node->AsLiteral()) { |
| 587 const_cast<LiteralNode*>(node->AsLiteral()) | 589 const_cast<LiteralNode*>(node->AsLiteral()) |
| 588 ->SetNewLocation(line_number); | 590 ->SetNewLocation(line_number); |
| 589 } else if (node->AsIdentifier()) { | 591 } else if (node->AsIdentifier()) { |
| 590 const_cast<IdentifierNode*>(node->AsIdentifier()) | 592 const_cast<IdentifierNode*>(node->AsIdentifier()) |
| 591 ->SetNewLocation(line_number); | 593 ->SetNewLocation(line_number); |
| 592 } else if (node->AsAccessor()) { | 594 } else if (node->AsAccessor()) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 620 | 622 |
| 621 // Breaks the ParseNodes of |contents| up by ranges that should be separately | 623 // Breaks the ParseNodes of |contents| up by ranges that should be separately |
| 622 // sorted. In particular, we break at a block comment, or an item that has an | 624 // sorted. In particular, we break at a block comment, or an item that has an |
| 623 // attached "before" comment and is separated by a blank line from the item | 625 // attached "before" comment and is separated by a blank line from the item |
| 624 // before it. The assumption is that both of these indicate a separate 'section' | 626 // before it. The assumption is that both of these indicate a separate 'section' |
| 625 // of a sources block across which items should not be inter-sorted. | 627 // of a sources block across which items should not be inter-sorted. |
| 626 std::vector<ListNode::SortRange> ListNode::GetSortRanges() const { | 628 std::vector<ListNode::SortRange> ListNode::GetSortRanges() const { |
| 627 std::vector<SortRange> ranges; | 629 std::vector<SortRange> ranges; |
| 628 const ParseNode* prev = nullptr; | 630 const ParseNode* prev = nullptr; |
| 629 size_t begin = 0; | 631 size_t begin = 0; |
| 630 for (size_t i = begin; i < contents_.size(); prev = contents_[i++]) { | 632 for (size_t i = begin; i < contents_.size(); prev = contents_[i++].get()) { |
| 631 if (IsSortRangeSeparator(contents_[i], prev)) { | 633 if (IsSortRangeSeparator(contents_[i].get(), prev)) { |
| 632 if (i > begin) { | 634 if (i > begin) { |
| 633 ranges.push_back(SortRange(begin, i)); | 635 ranges.push_back(SortRange(begin, i)); |
| 634 // If |i| is an item with an attached comment, then we start the next | 636 // If |i| is an item with an attached comment, then we start the next |
| 635 // range at that point, because we want to include it in the sort. | 637 // range at that point, because we want to include it in the sort. |
| 636 // Otherwise, it's a block comment which we skip over entirely because | 638 // Otherwise, it's a block comment which we skip over entirely because |
| 637 // we don't want to move or include it in the sort. The two cases are: | 639 // we don't want to move or include it in the sort. The two cases are: |
| 638 // | 640 // |
| 639 // sources = [ | 641 // sources = [ |
| 640 // "a", | 642 // "a", |
| 641 // "b", | 643 // "b", |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 | 833 |
| 832 Err EndNode::MakeErrorDescribing(const std::string& msg, | 834 Err EndNode::MakeErrorDescribing(const std::string& msg, |
| 833 const std::string& help) const { | 835 const std::string& help) const { |
| 834 return Err(value_, msg, help); | 836 return Err(value_, msg, help); |
| 835 } | 837 } |
| 836 | 838 |
| 837 void EndNode::Print(std::ostream& out, int indent) const { | 839 void EndNode::Print(std::ostream& out, int indent) const { |
| 838 out << IndentFor(indent) << "END(" << value_.value() << ")\n"; | 840 out << IndentFor(indent) << "END(" << value_.value() << ")\n"; |
| 839 PrintComments(out, indent); | 841 PrintComments(out, indent); |
| 840 } | 842 } |
| OLD | NEW |