| 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 21 matching lines...) Expand all Loading... |
| 32 // buffer is the buffer to which the write.* methods write the pretty-pr
inted | 32 // buffer is the buffer to which the write.* methods write the pretty-pr
inted |
| 33 // mojom file element. | 33 // mojom file element. |
| 34 buffer bytes.Buffer | 34 buffer bytes.Buffer |
| 35 | 35 |
| 36 // indentSize is the current size of the indentation in number of space
runes. | 36 // indentSize is the current size of the indentation in number of space
runes. |
| 37 indentSize int | 37 indentSize int |
| 38 | 38 |
| 39 // eolComment is the comment to be printed at the end of the current lin
e. | 39 // eolComment is the comment to be printed at the end of the current lin
e. |
| 40 eolComment *lexer.Token | 40 eolComment *lexer.Token |
| 41 | 41 |
| 42 » // lineLength is the number of runes that have been written to the curre
nt line. | 42 » // linePos is the number of runes that have been written to the current
line. |
| 43 » lineLength int | 43 » linePos int |
| 44 |
| 45 » // maxLineLength is the maximum number of runes that should be printed o
n a line. |
| 46 » // A negative maxLineLength indicates no maximum line length should be e
nforced. |
| 47 » // This is currently only used to decide when to break up a method on di
fferent lines. |
| 48 » maxLineLength int |
| 44 } | 49 } |
| 45 | 50 |
| 46 // newPrinter is a constructor for printer. | 51 // newPrinter is a constructor for printer. |
| 47 func newPrinter() (p *printer) { | 52 func newPrinter() (p *printer) { |
| 48 p = new(printer) | 53 p = new(printer) |
| 54 p.maxLineLength = 100 |
| 49 return | 55 return |
| 50 } | 56 } |
| 51 | 57 |
| 52 // result returns the pretty-printed version of what was given to the printer. | 58 // result returns the pretty-printed version of what was given to the printer. |
| 53 // Usually, this is a pretty-printed MojomFile. | 59 // Usually, this is a pretty-printed MojomFile. |
| 54 func (p *printer) result() string { | 60 func (p *printer) result() string { |
| 55 return p.buffer.String() | 61 return p.buffer.String() |
| 56 } | 62 } |
| 57 | 63 |
| 58 // writeMojomFile is the entry point of the pretty printer. | 64 // writeMojomFile is the entry point of the pretty printer. |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 p.write("enum ") | 173 p.write("enum ") |
| 168 p.writeDeclaredObjectsContainer(mojomEnum) | 174 p.writeDeclaredObjectsContainer(mojomEnum) |
| 169 } | 175 } |
| 170 | 176 |
| 171 func (p *printer) writeMojomInterface(mojomInterface *mojom.MojomInterface) { | 177 func (p *printer) writeMojomInterface(mojomInterface *mojom.MojomInterface) { |
| 172 p.write("interface ") | 178 p.write("interface ") |
| 173 p.writeDeclaredObjectsContainer(mojomInterface) | 179 p.writeDeclaredObjectsContainer(mojomInterface) |
| 174 } | 180 } |
| 175 | 181 |
| 176 func (p *printer) writeMojomMethod(mojomMethod *mojom.MojomMethod) { | 182 func (p *printer) writeMojomMethod(mojomMethod *mojom.MojomMethod) { |
| 183 splitResponse := false |
| 184 if p.maxLineLength > 0 { |
| 185 scratch := newPrinter() |
| 186 scratch.maxLineLength = -1 |
| 187 scratch.writeMojomMethod(mojomMethod) |
| 188 if len(scratch.result())+p.lineLength() > p.maxLineLength { |
| 189 splitResponse = true |
| 190 } |
| 191 } |
| 192 |
| 177 p.write(mojomMethod.NameToken().Text) | 193 p.write(mojomMethod.NameToken().Text) |
| 178 if mojomMethod.DeclaredOrdinal() >= 0 { | 194 if mojomMethod.DeclaredOrdinal() >= 0 { |
| 179 p.writef("@%v", mojomMethod.DeclaredOrdinal()) | 195 p.writef("@%v", mojomMethod.DeclaredOrdinal()) |
| 180 } | 196 } |
| 181 | 197 |
| 182 totalParams := len(mojomMethod.Parameters.Fields) | |
| 183 if mojomMethod.ResponseParameters != nil { | |
| 184 totalParams += len(mojomMethod.ResponseParameters.Fields) | |
| 185 } | |
| 186 | |
| 187 p.writeMethodParams(mojomMethod.Parameters) | 198 p.writeMethodParams(mojomMethod.Parameters) |
| 188 if mojomMethod.ResponseParameters != nil { | 199 if mojomMethod.ResponseParameters != nil { |
| 189 » » // TODO(azani): Actually enforce a line length limit instead. | 200 » » if splitResponse { |
| 190 » » if totalParams > 2 { | |
| 191 p.nl() | 201 p.nl() |
| 192 p.write(" ") | 202 p.write(" ") |
| 193 } | 203 } |
| 194 p.write(" => ") | 204 p.write(" => ") |
| 195 p.writeMethodParams(mojomMethod.ResponseParameters) | 205 p.writeMethodParams(mojomMethod.ResponseParameters) |
| 196 } | 206 } |
| 197 p.write(";") | 207 p.write(";") |
| 198 p.writeRightComments(mojomMethod) | 208 p.writeRightComments(mojomMethod) |
| 199 } | 209 } |
| 200 | 210 |
| 201 // writeMethodParams writes the pretty-printed method parameters represented by | 211 // writeMethodParams writes the pretty-printed method parameters represented by |
| 202 // a MojomStruct. | 212 // a MojomStruct. |
| 203 func (p *printer) writeMethodParams(params *mojom.MojomStruct) { | 213 func (p *printer) writeMethodParams(params *mojom.MojomStruct) { |
| 214 ownLine := false |
| 215 if p.maxLineLength > 0 { |
| 216 scratch := newPrinter() |
| 217 scratch.maxLineLength = -1 |
| 218 scratch.writeMethodParams(params) |
| 219 if len(scratch.result())+p.lineLength() > p.maxLineLength { |
| 220 ownLine = true |
| 221 } |
| 222 } |
| 204 p.write("(") | 223 p.write("(") |
| 205 declaredObjects := params.GetDeclaredObjects() | 224 declaredObjects := params.GetDeclaredObjects() |
| 206 | 225 |
| 207 » // TODO(azani): Actually enforce a line length limit instead. | 226 » extraIndent := p.lineLength() - p.indentSize |
| 208 » ownLine := len(declaredObjects) > 2 | |
| 209 » extraIndent := p.lineLength - p.indentSize | |
| 210 if ownLine { | 227 if ownLine { |
| 211 p.indentSize += extraIndent | 228 p.indentSize += extraIndent |
| 212 } | 229 } |
| 213 | 230 |
| 214 for i, param := range declaredObjects { | 231 for i, param := range declaredObjects { |
| 215 p.writeMethodParam(param.(*mojom.StructField)) | 232 p.writeMethodParam(param.(*mojom.StructField)) |
| 216 if i < len(declaredObjects)-1 { | 233 if i < len(declaredObjects)-1 { |
| 217 p.write(",") | 234 p.write(",") |
| 218 if ownLine { | 235 if ownLine { |
| 219 p.nl() | 236 p.nl() |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 | 627 |
| 611 // write writes the provided string to the buffer. | 628 // write writes the provided string to the buffer. |
| 612 // If nothing has been written yet on the current line write also writes the | 629 // If nothing has been written yet on the current line write also writes the |
| 613 // current indentation level. | 630 // current indentation level. |
| 614 func (p *printer) write(s string) { | 631 func (p *printer) write(s string) { |
| 615 if strings.ContainsRune(s, '\n') { | 632 if strings.ContainsRune(s, '\n') { |
| 616 panic(fmt.Sprintf("Only the nl method can write a new line: %q",
s)) | 633 panic(fmt.Sprintf("Only the nl method can write a new line: %q",
s)) |
| 617 } | 634 } |
| 618 | 635 |
| 619 // We only print the indentation if the line is not empty. | 636 // We only print the indentation if the line is not empty. |
| 620 » if p.lineLength == 0 { | 637 » if p.linePos == 0 { |
| 621 p.buffer.WriteString(strings.Repeat(" ", p.indentSize)) | 638 p.buffer.WriteString(strings.Repeat(" ", p.indentSize)) |
| 622 » » p.lineLength += p.indentSize | 639 » » p.linePos += p.indentSize |
| 623 } | 640 } |
| 624 » p.lineLength += len(s) | 641 » p.linePos += len(s) |
| 625 p.buffer.WriteString(s) | 642 p.buffer.WriteString(s) |
| 626 } | 643 } |
| 627 | 644 |
| 628 // nl writes a new line. Before writing the new line, nl writes the last | 645 // nl writes a new line. Before writing the new line, nl writes the last |
| 629 // comment on the line. | 646 // comment on the line. |
| 630 func (p *printer) nl() { | 647 func (p *printer) nl() { |
| 631 // Before going to the next line, print the last comment on the line. | 648 // Before going to the next line, print the last comment on the line. |
| 632 if p.eolComment != nil { | 649 if p.eolComment != nil { |
| 633 p.writef(" %s", p.eolComment.Text) | 650 p.writef(" %s", p.eolComment.Text) |
| 634 p.eolComment = nil | 651 p.eolComment = nil |
| 635 } | 652 } |
| 636 | 653 |
| 637 p.buffer.WriteString("\n") | 654 p.buffer.WriteString("\n") |
| 638 » p.lineLength = 0 | 655 » p.linePos = 0 |
| 639 } | 656 } |
| 640 | 657 |
| 641 func (p *printer) incIndent() { | 658 func (p *printer) incIndent() { |
| 642 p.indentSize += 2 | 659 p.indentSize += 2 |
| 643 } | 660 } |
| 644 | 661 |
| 645 func (p *printer) decIndent() { | 662 func (p *printer) decIndent() { |
| 646 p.indentSize -= 2 | 663 p.indentSize -= 2 |
| 647 if p.indentSize < 0 { | 664 if p.indentSize < 0 { |
| 648 panic("The printer is attempting to use negative indentation!") | 665 panic("The printer is attempting to use negative indentation!") |
| 649 } | 666 } |
| 650 } | 667 } |
| 651 | 668 |
| 652 // setEolComment sets the comment that is to be printed at the end of the curren
t line. | 669 // setEolComment sets the comment that is to be printed at the end of the curren
t line. |
| 653 // The last comment on the line is not necessarily associated with the last | 670 // The last comment on the line is not necessarily associated with the last |
| 654 // element on the line. So when the last comment is found, we record that | 671 // element on the line. So when the last comment is found, we record that |
| 655 // comment so we may print it right before going to the next line. | 672 // comment so we may print it right before going to the next line. |
| 656 func (p *printer) setEolComment(comment lexer.Token) { | 673 func (p *printer) setEolComment(comment lexer.Token) { |
| 657 if p.eolComment != nil { | 674 if p.eolComment != nil { |
| 658 panic("There is space for only one comment at the end of the lin
e!") | 675 panic("There is space for only one comment at the end of the lin
e!") |
| 659 } | 676 } |
| 660 | 677 |
| 661 if comment.Kind != lexer.SingleLineComment { | 678 if comment.Kind != lexer.SingleLineComment { |
| 662 panic("Only SingleLineComments need to be handled specially at t
he end of line.") | 679 panic("Only SingleLineComments need to be handled specially at t
he end of line.") |
| 663 } | 680 } |
| 664 | 681 |
| 665 p.eolComment = &comment | 682 p.eolComment = &comment |
| 666 } | 683 } |
| 667 | 684 |
| 685 // lineLength returns the length of the line so far. If nothing has been written |
| 686 // to the line yet, it returns the indent size. |
| 687 // The purpose of lineLenght is to answer the question: If I write something now |
| 688 // how far on the current line will it be written? |
| 689 func (p *printer) lineLength() int { |
| 690 if p.linePos == 0 { |
| 691 return p.indentSize |
| 692 } |
| 693 return p.linePos |
| 694 } |
| 695 |
| 668 // Standalone utilities that do not operate on the buffer. | 696 // Standalone utilities that do not operate on the buffer. |
| 669 | 697 |
| 670 // isNewBlock determines if an empty line should be printed above the element | 698 // isNewBlock determines if an empty line should be printed above the element |
| 671 // under consideration. The purpose is to respect user-intention to separate | 699 // under consideration. The purpose is to respect user-intention to separate |
| 672 // elements in a mojom file. | 700 // elements in a mojom file. |
| 673 // | 701 // |
| 674 // If the element has attributes, and the first "comment" attached above the | 702 // If the element has attributes, and the first "comment" attached above the |
| 675 // attributes is an empty line, the element is a new block. | 703 // attributes is an empty line, the element is a new block. |
| 676 // If the element has no attributes and the first "comment" attached above the | 704 // If the element has no attributes and the first "comment" attached above the |
| 677 // element itself is an empty line, the element is a new block. | 705 // element itself is an empty line, the element is a new block. |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 | 768 |
| 741 // See sort.Interface. | 769 // See sort.Interface. |
| 742 func (ifs *importedFilesSorter) Less(i, j int) bool { | 770 func (ifs *importedFilesSorter) Less(i, j int) bool { |
| 743 return ifs.imports[i].SpecifiedName < ifs.imports[j].SpecifiedName | 771 return ifs.imports[i].SpecifiedName < ifs.imports[j].SpecifiedName |
| 744 } | 772 } |
| 745 | 773 |
| 746 // See sort.Interface. | 774 // See sort.Interface. |
| 747 func (ifs *importedFilesSorter) Swap(i, j int) { | 775 func (ifs *importedFilesSorter) Swap(i, j int) { |
| 748 ifs.imports[i], ifs.imports[j] = ifs.imports[j], ifs.imports[i] | 776 ifs.imports[i], ifs.imports[j] = ifs.imports[j], ifs.imports[i] |
| 749 } | 777 } |
| OLD | NEW |