1 // Copyright 2018 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package modfile implements parsing and formatting for
15 func Format(f *FileSyntax) []byte {
21 // A printer collects the state during printing of a file or expression.
23 bytes.Buffer // output buffer
24 comment []Comment // pending end-of-line comments
25 margin int // left margin (indent), a number of tabs
28 // printf prints to the buffer.
29 func (p *printer) printf(format string, args ...interface{}) {
30 fmt.Fprintf(p, format, args...)
33 // indent returns the position on the current line, in bytes, 0-indexed.
34 func (p *printer) indent() int {
37 for n < len(b) && b[len(b)-1-n] != '\n' {
43 // newline ends the current line, flushing end-of-line comments.
44 func (p *printer) newline() {
45 if len(p.comment) > 0 {
47 for i, com := range p.comment {
51 for i := 0; i < p.margin; i++ {
55 p.printf("%s", strings.TrimSpace(com.Token))
57 p.comment = p.comment[:0]
62 for i := 0; i < p.margin; i++ {
67 // trim removes trailing spaces and tabs from the current line.
68 func (p *printer) trim() {
69 // Remove trailing spaces and tabs from line we're about to end.
72 for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') {
78 // file formats the given file into the print buffer.
79 func (p *printer) file(f *FileSyntax) {
80 for _, com := range f.Before {
81 p.printf("%s", strings.TrimSpace(com.Token))
85 for i, stmt := range f.Stmt {
86 switch x := stmt.(type) {
88 // comments already handled
96 for _, com := range stmt.Comment().After {
97 p.printf("%s", strings.TrimSpace(com.Token))
101 if i+1 < len(f.Stmt) {
107 func (p *printer) expr(x Expr) {
108 // Emit line-comments preceding this expression.
109 if before := x.Comment().Before; len(before) > 0 {
110 // Want to print a line comment.
111 // Line comments must be at the current margin.
114 // There's other text on the line. Start a new line.
117 // Re-indent to margin.
118 for i := 0; i < p.margin; i++ {
121 for _, com := range before {
122 p.printf("%s", strings.TrimSpace(com.Token))
127 switch x := x.(type) {
129 panic(fmt.Errorf("printer: unexpected type %T", x))
141 for _, tok := range x.Token {
142 p.printf("%s%s", sep, tok)
147 for _, tok := range x.Token {
152 for _, l := range x.Line {
161 // Queue end-of-line comments for printing when we
162 // reach the end of the line.
163 p.comment = append(p.comment, x.Comment().Suffix...)