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 |