OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 package formatter | 5 package formatter |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
10 "mojom/mojom_parser/lexer" | 10 "mojom/mojom_parser/lexer" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 if len(mojomFile.Imports) > 0 { | 89 if len(mojomFile.Imports) > 0 { |
90 p.writeImportedFiles(mojomFile.Imports) | 90 p.writeImportedFiles(mojomFile.Imports) |
91 } | 91 } |
92 | 92 |
93 for _, declaredObject := range mojomFile.DeclaredObjects { | 93 for _, declaredObject := range mojomFile.DeclaredObjects { |
94 p.writeDeclaredObject(declaredObject) | 94 p.writeDeclaredObject(declaredObject) |
95 p.nl() | 95 p.nl() |
96 } | 96 } |
97 | 97 |
98 if mojomFile.FinalComments != nil { | 98 if mojomFile.FinalComments != nil { |
99 » » finalComments := trimEmptyLines(mojomFile.FinalComments) | 99 » » finalComments := trimEmptyLinesEnd(mojomFile.FinalComments) |
100 if len(finalComments) > 0 { | 100 if len(finalComments) > 0 { |
101 p.nl() | 101 p.nl() |
102 p.writeCommentBlocks(finalComments, true) | 102 p.writeCommentBlocks(finalComments, true) |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 p.eofNoFormat() | 106 p.eofNoFormat() |
107 } | 107 } |
108 | 108 |
109 // writeModuleNamespace writes a mojom file's module statement and associated | 109 // writeModuleNamespace writes a mojom file's module statement and associated |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 p.writef("%v {", container.(mojom.DeclaredObject).NameToken().Text) | 368 p.writef("%v {", container.(mojom.DeclaredObject).NameToken().Text) |
369 if len(container.GetDeclaredObjects()) == 0 && !containsFinalComments(co
ntainer.(mojom.MojomElement)) { | 369 if len(container.GetDeclaredObjects()) == 0 && !containsFinalComments(co
ntainer.(mojom.MojomElement)) { |
370 p.writef("};") | 370 p.writef("};") |
371 return | 371 return |
372 } | 372 } |
373 p.writeRightComments(container.(mojom.MojomElement)) | 373 p.writeRightComments(container.(mojom.MojomElement)) |
374 p.incIndent() | 374 p.incIndent() |
375 p.nl() | 375 p.nl() |
376 declaredObjects := container.GetDeclaredObjects() | 376 declaredObjects := container.GetDeclaredObjects() |
377 for i, declaredObject := range declaredObjects { | 377 for i, declaredObject := range declaredObjects { |
| 378 if i == 0 { |
| 379 trimEmptyLinesDeclaredObject(declaredObject) |
| 380 } |
378 p.writeDeclaredObject(declaredObject) | 381 p.writeDeclaredObject(declaredObject) |
379 if i < len(declaredObjects)-1 { | 382 if i < len(declaredObjects)-1 { |
380 p.nl() | 383 p.nl() |
381 } | 384 } |
382 } | 385 } |
383 | 386 |
384 // Write the comments at the end of the struct, enum, union or interface
body. | 387 // Write the comments at the end of the struct, enum, union or interface
body. |
385 p.writeFinalComments(container) | 388 p.writeFinalComments(container) |
386 | 389 |
387 p.decIndent() | 390 p.decIndent() |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 // line is written after all the comments are written. | 628 // line is written after all the comments are written. |
626 func (p *printer) writeCommentBlocks(comments []lexer.Token, finalEol bool) { | 629 func (p *printer) writeCommentBlocks(comments []lexer.Token, finalEol bool) { |
627 for i, comment := range comments { | 630 for i, comment := range comments { |
628 switch comment.Kind { | 631 switch comment.Kind { |
629 case lexer.SingleLineComment: | 632 case lexer.SingleLineComment: |
630 if comment.Text == "// no-format" { | 633 if comment.Text == "// no-format" { |
631 p.startNoFormat(comment) | 634 p.startNoFormat(comment) |
632 } else if comment.Text == "// end-no-format" { | 635 } else if comment.Text == "// end-no-format" { |
633 p.endNoFormat(comment) | 636 p.endNoFormat(comment) |
634 } | 637 } |
635 » » » p.write(comment.Text) | 638 » » » p.writeSingleLineComment(comment) |
636 if finalEol || i < len(comments)-1 { | 639 if finalEol || i < len(comments)-1 { |
637 p.nl() | 640 p.nl() |
638 } | 641 } |
639 case lexer.MultiLineComment: | 642 case lexer.MultiLineComment: |
640 p.writeMultiLineComment(comment) | 643 p.writeMultiLineComment(comment) |
641 if finalEol || i < len(comments)-1 { | 644 if finalEol || i < len(comments)-1 { |
642 p.nl() | 645 p.nl() |
643 } | 646 } |
644 case lexer.EmptyLine: | 647 case lexer.EmptyLine: |
645 // We only use EmptyLine here to separate comment blocks
. And we collapse | 648 // We only use EmptyLine here to separate comment blocks
. And we collapse |
646 // sequences of empty lines to a single empty line. | 649 // sequences of empty lines to a single empty line. |
647 if i != 0 && comments[i-1].Kind != lexer.EmptyLine { | 650 if i != 0 && comments[i-1].Kind != lexer.EmptyLine { |
648 p.nl() | 651 p.nl() |
649 } | 652 } |
650 default: | 653 default: |
651 panic(fmt.Sprintf("%s is not a comment.", comment)) | 654 panic(fmt.Sprintf("%s is not a comment.", comment)) |
652 } | 655 } |
653 } | 656 } |
654 } | 657 } |
655 | 658 |
| 659 func (p *printer) writeSingleLineComment(comment lexer.Token) { |
| 660 if comment.Kind != lexer.SingleLineComment { |
| 661 panic(fmt.Sprintf("This is not a SingleLineComment: %s", comment
)) |
| 662 } |
| 663 commentText := comment.Text |
| 664 |
| 665 // We expect that the first 2 characters are // followed by a space or t
ab. |
| 666 // If the third character is not a space or tab, we insert a space. |
| 667 space := commentText[2] |
| 668 if space != ' ' && space != '\t' { |
| 669 commentText = "// " + commentText[2:] |
| 670 } |
| 671 p.write(commentText) |
| 672 } |
| 673 |
656 func (p *printer) writeMultiLineComment(comment lexer.Token) { | 674 func (p *printer) writeMultiLineComment(comment lexer.Token) { |
657 if comment.Kind != lexer.MultiLineComment { | 675 if comment.Kind != lexer.MultiLineComment { |
658 panic(fmt.Sprintf("This is not a MultiLineComment: %s", comment)
) | 676 panic(fmt.Sprintf("This is not a MultiLineComment: %s", comment)
) |
659 } | 677 } |
660 | 678 |
661 lines := strings.Split(comment.Text, "\n") | 679 lines := strings.Split(comment.Text, "\n") |
662 for i, line := range lines { | 680 for i, line := range lines { |
663 trimmed := strings.Trim(line, " \t") | 681 trimmed := strings.Trim(line, " \t") |
664 // If a line starts with * we assume the user is trying to use t
he pattern | 682 // If a line starts with * we assume the user is trying to use t
he pattern |
665 // whereby they align the comment with spaces after the *. Other
wise, | 683 // whereby they align the comment with spaces after the *. Other
wise, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 p.buffer.WriteString(s) | 745 p.buffer.WriteString(s) |
728 } | 746 } |
729 } | 747 } |
730 | 748 |
731 // nl writes a new line. Before writing the new line, nl writes the last | 749 // nl writes a new line. Before writing the new line, nl writes the last |
732 // comment on the line. | 750 // comment on the line. |
733 func (p *printer) nl() { | 751 func (p *printer) nl() { |
734 // Before going to the next line, print the last comment on the line. | 752 // Before going to the next line, print the last comment on the line. |
735 if p.eolComment != nil { | 753 if p.eolComment != nil { |
736 if !p.noFormat { | 754 if !p.noFormat { |
737 » » » p.writef(" %s", p.eolComment.Text) | 755 » » » p.write(" ") |
| 756 » » » p.writeSingleLineComment(*p.eolComment) |
738 } | 757 } |
739 p.eolComment = nil | 758 p.eolComment = nil |
740 } | 759 } |
741 | 760 |
742 if !p.noFormat { | 761 if !p.noFormat { |
743 p.buffer.WriteString("\n") | 762 p.buffer.WriteString("\n") |
744 } | 763 } |
745 p.linePos = 0 | 764 p.linePos = 0 |
746 } | 765 } |
747 | 766 |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 } | 880 } |
862 | 881 |
863 for _, comment := range attachedComments.Final { | 882 for _, comment := range attachedComments.Final { |
864 if comment.Kind != lexer.EmptyLine { | 883 if comment.Kind != lexer.EmptyLine { |
865 return true | 884 return true |
866 } | 885 } |
867 } | 886 } |
868 return false | 887 return false |
869 } | 888 } |
870 | 889 |
871 // trimEmptyLines trims out empty line comments at the end of a slice of comment
s. | 890 // trimEmptyLinesEnd trims out empty line comments at the end of a slice of comm
ents. |
872 func trimEmptyLines(comments []lexer.Token) []lexer.Token { | 891 func trimEmptyLinesEnd(comments []lexer.Token) []lexer.Token { |
873 lastNonEmpty := -1 | 892 lastNonEmpty := -1 |
874 for i, comment := range comments { | 893 for i, comment := range comments { |
875 if comment.Kind != lexer.EmptyLine { | 894 if comment.Kind != lexer.EmptyLine { |
876 lastNonEmpty = i | 895 lastNonEmpty = i |
877 } | 896 } |
878 } | 897 } |
879 return comments[:lastNonEmpty+1] | 898 return comments[:lastNonEmpty+1] |
880 } | 899 } |
881 | 900 |
| 901 // trimEmptyLinesBegin trims out empty line comments at the beginning of a slice
of comments. |
| 902 func trimEmptyLinesBegin(comments []lexer.Token) []lexer.Token { |
| 903 for i, comment := range comments { |
| 904 if comment.Kind != lexer.EmptyLine { |
| 905 return comments[i:] |
| 906 } |
| 907 } |
| 908 return comments[len(comments):] |
| 909 } |
| 910 |
| 911 // trimEmptyLinesDeclaredObject trims out empty lines from the beginning of the |
| 912 // comments on a DeclaredObject or its Attributes. |
| 913 func trimEmptyLinesDeclaredObject(declaredObject mojom.DeclaredObject) { |
| 914 if declaredObject.Attributes() != nil { |
| 915 comments := declaredObject.Attributes().AttachedComments() |
| 916 if comments == nil { |
| 917 return |
| 918 } |
| 919 comments.Above = trimEmptyLinesBegin(comments.Above) |
| 920 return |
| 921 } |
| 922 comments := declaredObject.AttachedComments() |
| 923 |
| 924 if comments == nil || len(comments.Above) == 0 { |
| 925 return |
| 926 } |
| 927 comments.Above = trimEmptyLinesBegin(comments.Above) |
| 928 } |
| 929 |
882 // Following is a utility to sort slices of |ImportedFile|s. | 930 // Following is a utility to sort slices of |ImportedFile|s. |
883 | 931 |
884 // sortImportedFiles sorts the slice of imported files it receives. | 932 // sortImportedFiles sorts the slice of imported files it receives. |
885 func sortImportedFiles(imports []*mojom.ImportedFile) { | 933 func sortImportedFiles(imports []*mojom.ImportedFile) { |
886 sort.Sort(&importedFilesSorter{imports}) | 934 sort.Sort(&importedFilesSorter{imports}) |
887 } | 935 } |
888 | 936 |
889 type importedFilesSorter struct { | 937 type importedFilesSorter struct { |
890 imports []*mojom.ImportedFile | 938 imports []*mojom.ImportedFile |
891 } | 939 } |
892 | 940 |
893 // See sort.Interface. | 941 // See sort.Interface. |
894 func (ifs *importedFilesSorter) Len() int { | 942 func (ifs *importedFilesSorter) Len() int { |
895 return len(ifs.imports) | 943 return len(ifs.imports) |
896 } | 944 } |
897 | 945 |
898 // See sort.Interface. | 946 // See sort.Interface. |
899 func (ifs *importedFilesSorter) Less(i, j int) bool { | 947 func (ifs *importedFilesSorter) Less(i, j int) bool { |
900 return ifs.imports[i].SpecifiedName < ifs.imports[j].SpecifiedName | 948 return ifs.imports[i].SpecifiedName < ifs.imports[j].SpecifiedName |
901 } | 949 } |
902 | 950 |
903 // See sort.Interface. | 951 // See sort.Interface. |
904 func (ifs *importedFilesSorter) Swap(i, j int) { | 952 func (ifs *importedFilesSorter) Swap(i, j int) { |
905 ifs.imports[i], ifs.imports[j] = ifs.imports[j], ifs.imports[i] | 953 ifs.imports[i], ifs.imports[j] = ifs.imports[j], ifs.imports[i] |
906 } | 954 } |
OLD | NEW |