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

Side by Side Diff: tools/gn/parse_tree.cc

Issue 962003002: gn format: Have format sort sources (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 9 months 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
OLDNEW
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 <string> 7 #include <string>
8 8
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 187 }
188 188
189 if (!result) { 189 if (!result) {
190 *err = Err(member_.get(), "No value named \"" + 190 *err = Err(member_.get(), "No value named \"" +
191 member_->value().value() + "\" in scope \"" + base_.value() + "\""); 191 member_->value().value() + "\" in scope \"" + base_.value() + "\"");
192 return Value(); 192 return Value();
193 } 193 }
194 return *result; 194 return *result;
195 } 195 }
196 196
197 void AccessorNode::SetNewLocation(int line_number) {
198 Location old = base_.location();
199 base_.set_location(
200 Location(old.file(), line_number, old.char_offset(), old.byte()));
201 }
202
197 // BinaryOpNode --------------------------------------------------------------- 203 // BinaryOpNode ---------------------------------------------------------------
198 204
199 BinaryOpNode::BinaryOpNode() { 205 BinaryOpNode::BinaryOpNode() {
200 } 206 }
201 207
202 BinaryOpNode::~BinaryOpNode() { 208 BinaryOpNode::~BinaryOpNode() {
203 } 209 }
204 210
205 const BinaryOpNode* BinaryOpNode::AsBinaryOp() const { 211 const BinaryOpNode* BinaryOpNode::AsBinaryOp() const {
206 return this; 212 return this;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 Err IdentifierNode::MakeErrorDescribing(const std::string& msg, 435 Err IdentifierNode::MakeErrorDescribing(const std::string& msg,
430 const std::string& help) const { 436 const std::string& help) const {
431 return Err(value_, msg, help); 437 return Err(value_, msg, help);
432 } 438 }
433 439
434 void IdentifierNode::Print(std::ostream& out, int indent) const { 440 void IdentifierNode::Print(std::ostream& out, int indent) const {
435 out << IndentFor(indent) << "IDENTIFIER(" << value_.value() << ")\n"; 441 out << IndentFor(indent) << "IDENTIFIER(" << value_.value() << ")\n";
436 PrintComments(out, indent); 442 PrintComments(out, indent);
437 } 443 }
438 444
445 void IdentifierNode::SetNewLocation(int line_number) {
446 Location old = value_.location();
447 value_.set_location(
448 Location(old.file(), line_number, old.char_offset(), old.byte()));
449 }
450
439 // ListNode ------------------------------------------------------------------- 451 // ListNode -------------------------------------------------------------------
440 452
441 ListNode::ListNode() : prefer_multiline_(false) { 453 ListNode::ListNode() : prefer_multiline_(false) {
442 } 454 }
443 455
444 ListNode::~ListNode() { 456 ListNode::~ListNode() {
445 STLDeleteContainerPointers(contents_.begin(), contents_.end()); 457 STLDeleteContainerPointers(contents_.begin(), contents_.end());
446 } 458 }
447 459
448 const ListNode* ListNode::AsList() const { 460 const ListNode* ListNode::AsList() const {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 void ListNode::Print(std::ostream& out, int indent) const { 495 void ListNode::Print(std::ostream& out, int indent) const {
484 out << IndentFor(indent) << "LIST" << (prefer_multiline_ ? " multiline" : "") 496 out << IndentFor(indent) << "LIST" << (prefer_multiline_ ? " multiline" : "")
485 << "\n"; 497 << "\n";
486 PrintComments(out, indent); 498 PrintComments(out, indent);
487 for (const auto& cur : contents_) 499 for (const auto& cur : contents_)
488 cur->Print(out, indent + 1); 500 cur->Print(out, indent + 1);
489 if (end_ && end_->comments()) 501 if (end_ && end_->comments())
490 end_->Print(out, indent + 1); 502 end_->Print(out, indent + 1);
491 } 503 }
492 504
505 using Range = std::pair<std::vector<const ParseNode*>::iterator,
506 std::vector<const ParseNode*>::iterator>;
507
508 bool IsSeparatorComment(const ParseNode* node, const ParseNode* prev) {
brettw 2015/02/27 22:27:27 Seems like these standalone functions should be in
scottmg 2015/02/27 23:17:44 Done.
509 // If it's a block comment, or has an attached comment with a blank line
510 // before it, then we break the range at this point.
511 return node->AsBlockComment() != nullptr ||
512 (prev && node->comments() && !node->comments()->before().empty() &&
513 (node->GetRange().begin().line_number() >
514 prev->GetRange().end().line_number() +
515 static_cast<int>(node->comments()->before().size() + 1)));
516 }
517
518 std::vector<Range> GetSortRanges(std::vector<const ParseNode*>& contents) {
brettw 2015/02/27 22:27:27 Can you provide a function level comment of what t
scottmg 2015/02/27 23:17:44 Done.
519 std::vector<Range> ranges;
520 auto begin = contents.begin();
521 const ParseNode* prev = nullptr;
522 for (auto it = begin; it != contents.end(); prev = *(it++)) {
brettw 2015/02/27 22:27:27 This is pretty hard to wrap one's head around. Wou
scottmg 2015/02/27 23:17:44 Switched to size_ts. Not sure it helps, I think it
523 if (IsSeparatorComment(*it, prev)) {
524 if (it > begin) {
525 ranges.push_back(std::make_pair(begin, it));
526 if (!(*it)->AsBlockComment())
527 begin = it;
528 else
529 begin = it + 1;
530 } else {
531 begin = it + 1;
532 }
533 if (it == contents.end())
brettw 2015/02/27 22:27:27 This could also go away if you used ints
scottmg 2015/02/27 23:17:44 Might not have been necessary either way I think.
534 break;
535 }
536 }
537 if (begin != contents.end())
538 ranges.push_back(std::make_pair(begin, contents.end()));
539 return ranges;
540 }
541
542 base::StringPiece GetStringRepresentation(const ParseNode* node) {
543 DCHECK(node->AsLiteral() || node->AsIdentifier() || node->AsAccessor());
544 if (node->AsLiteral())
545 return node->AsLiteral()->value().value();
546 else if (node->AsIdentifier())
547 return node->AsIdentifier()->value().value();
548 else if (node->AsAccessor())
549 return node->AsAccessor()->base().value();
550 return base::StringPiece();
551 }
552
553 void ListNode::SortAsStringsList() {
554 // Sorts alphabetically. Partitions first on BlockCommentNodes and sorts each
555 // partition separately.
556 std::vector<Range> ranges = GetSortRanges(contents_);
557 for (auto range : ranges) {
brettw 2015/02/27 22:27:27 You couldn't do for (auto range : GetSortRanges(co
scottmg 2015/02/27 23:17:44 Done.
558 // 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
560 // 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
562 // or not.
563 int start_line = (*range.first)->GetRange().begin().line_number();
564 const ParseNode* original_first = *range.first;
565 std::sort(range.first, range.second,
566 [](const ParseNode* a, const ParseNode* b) {
567 base::StringPiece astr = GetStringRepresentation(a);
568 base::StringPiece bstr = GetStringRepresentation(b);
569 return astr < bstr;
570 });
571 // If the beginning of the range had before comments, and the first node
572 // moved during the sort, then move its comments to the new head of the
573 // range.
574 if (original_first->comments() && *range.first != original_first) {
575 for (const auto& hc : original_first->comments()->before()) {
576 const_cast<ParseNode*>(*range.first)
577 ->comments_mutable()
578 ->append_before(hc);
579 }
580 const_cast<ParseNode*>(original_first)
581 ->comments_mutable()
582 ->clear_before();
583 }
584 const ParseNode* prev = nullptr;
585 for (auto it = range.first; it != range.second; ++it) {
586 const ParseNode* node = *it;
587 DCHECK(node->AsLiteral() || node->AsIdentifier() || node->AsAccessor());
588 int line_number =
589 prev ? prev->GetRange().end().line_number() + 1 : start_line;
590 if (node->AsLiteral()) {
591 const_cast<LiteralNode*>(node->AsLiteral())
592 ->SetNewLocation(line_number);
593 } else if (node->AsIdentifier()) {
594 const_cast<IdentifierNode*>(node->AsIdentifier())
595 ->SetNewLocation(line_number);
596 } else if (node->AsAccessor()) {
597 const_cast<AccessorNode*>(node->AsAccessor())
598 ->SetNewLocation(line_number);
599 }
600 prev = node;
601 }
602 }
603 }
604
493 // LiteralNode ----------------------------------------------------------------- 605 // LiteralNode -----------------------------------------------------------------
494 606
495 LiteralNode::LiteralNode() { 607 LiteralNode::LiteralNode() {
496 } 608 }
497 609
498 LiteralNode::LiteralNode(const Token& token) : value_(token) { 610 LiteralNode::LiteralNode(const Token& token) : value_(token) {
499 } 611 }
500 612
501 LiteralNode::~LiteralNode() { 613 LiteralNode::~LiteralNode() {
502 } 614 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 Err LiteralNode::MakeErrorDescribing(const std::string& msg, 649 Err LiteralNode::MakeErrorDescribing(const std::string& msg,
538 const std::string& help) const { 650 const std::string& help) const {
539 return Err(value_, msg, help); 651 return Err(value_, msg, help);
540 } 652 }
541 653
542 void LiteralNode::Print(std::ostream& out, int indent) const { 654 void LiteralNode::Print(std::ostream& out, int indent) const {
543 out << IndentFor(indent) << "LITERAL(" << value_.value() << ")\n"; 655 out << IndentFor(indent) << "LITERAL(" << value_.value() << ")\n";
544 PrintComments(out, indent); 656 PrintComments(out, indent);
545 } 657 }
546 658
659 void LiteralNode::SetNewLocation(int line_number) {
660 Location old = value_.location();
661 value_.set_location(
662 Location(old.file(), line_number, old.char_offset(), old.byte()));
663 }
664
547 // UnaryOpNode ---------------------------------------------------------------- 665 // UnaryOpNode ----------------------------------------------------------------
548 666
549 UnaryOpNode::UnaryOpNode() { 667 UnaryOpNode::UnaryOpNode() {
550 } 668 }
551 669
552 UnaryOpNode::~UnaryOpNode() { 670 UnaryOpNode::~UnaryOpNode() {
553 } 671 }
554 672
555 const UnaryOpNode* UnaryOpNode::AsUnaryOp() const { 673 const UnaryOpNode* UnaryOpNode::AsUnaryOp() const {
556 return this; 674 return this;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 Err BlockCommentNode::MakeErrorDescribing(const std::string& msg, 719 Err BlockCommentNode::MakeErrorDescribing(const std::string& msg,
602 const std::string& help) const { 720 const std::string& help) const {
603 return Err(comment_, msg, help); 721 return Err(comment_, msg, help);
604 } 722 }
605 723
606 void BlockCommentNode::Print(std::ostream& out, int indent) const { 724 void BlockCommentNode::Print(std::ostream& out, int indent) const {
607 out << IndentFor(indent) << "BLOCK_COMMENT(" << comment_.value() << ")\n"; 725 out << IndentFor(indent) << "BLOCK_COMMENT(" << comment_.value() << ")\n";
608 PrintComments(out, indent); 726 PrintComments(out, indent);
609 } 727 }
610 728
611
612 // EndNode --------------------------------------------------------------------- 729 // EndNode ---------------------------------------------------------------------
613 730
614 EndNode::EndNode(const Token& token) : value_(token) { 731 EndNode::EndNode(const Token& token) : value_(token) {
615 } 732 }
616 733
617 EndNode::~EndNode() { 734 EndNode::~EndNode() {
618 } 735 }
619 736
620 const EndNode* EndNode::AsEnd() const { 737 const EndNode* EndNode::AsEnd() const {
621 return this; 738 return this;
622 } 739 }
623 740
624 Value EndNode::Execute(Scope* scope, Err* err) const { 741 Value EndNode::Execute(Scope* scope, Err* err) const {
625 return Value(); 742 return Value();
626 } 743 }
627 744
628 LocationRange EndNode::GetRange() const { 745 LocationRange EndNode::GetRange() const {
629 return value_.range(); 746 return value_.range();
630 } 747 }
631 748
632 Err EndNode::MakeErrorDescribing(const std::string& msg, 749 Err EndNode::MakeErrorDescribing(const std::string& msg,
633 const std::string& help) const { 750 const std::string& help) const {
634 return Err(value_, msg, help); 751 return Err(value_, msg, help);
635 } 752 }
636 753
637 void EndNode::Print(std::ostream& out, int indent) const { 754 void EndNode::Print(std::ostream& out, int indent) const {
638 out << IndentFor(indent) << "END(" << value_.value() << ")\n"; 755 out << IndentFor(indent) << "END(" << value_.value() << ")\n";
639 PrintComments(out, indent); 756 PrintComments(out, indent);
640 } 757 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698