...
Source file src/pkg/cmd/go/internal/modfile/print.go
1
2
3
4
5
6
7 package modfile
8
9 import (
10 "bytes"
11 "fmt"
12 "strings"
13 )
14
15 func Format(f *FileSyntax) []byte {
16 pr := &printer{}
17 pr.file(f)
18 return pr.Bytes()
19 }
20
21
22 type printer struct {
23 bytes.Buffer
24 comment []Comment
25 margin int
26 }
27
28
29 func (p *printer) printf(format string, args ...interface{}) {
30 fmt.Fprintf(p, format, args...)
31 }
32
33
34 func (p *printer) indent() int {
35 b := p.Bytes()
36 n := 0
37 for n < len(b) && b[len(b)-1-n] != '\n' {
38 n++
39 }
40 return n
41 }
42
43
44 func (p *printer) newline() {
45 if len(p.comment) > 0 {
46 p.printf(" ")
47 for i, com := range p.comment {
48 if i > 0 {
49 p.trim()
50 p.printf("\n")
51 for i := 0; i < p.margin; i++ {
52 p.printf("\t")
53 }
54 }
55 p.printf("%s", strings.TrimSpace(com.Token))
56 }
57 p.comment = p.comment[:0]
58 }
59
60 p.trim()
61 p.printf("\n")
62 for i := 0; i < p.margin; i++ {
63 p.printf("\t")
64 }
65 }
66
67
68 func (p *printer) trim() {
69
70 b := p.Bytes()
71 n := len(b)
72 for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') {
73 n--
74 }
75 p.Truncate(n)
76 }
77
78
79 func (p *printer) file(f *FileSyntax) {
80 for _, com := range f.Before {
81 p.printf("%s", strings.TrimSpace(com.Token))
82 p.newline()
83 }
84
85 for i, stmt := range f.Stmt {
86 switch x := stmt.(type) {
87 case *CommentBlock:
88
89 p.expr(x)
90
91 default:
92 p.expr(x)
93 p.newline()
94 }
95
96 for _, com := range stmt.Comment().After {
97 p.printf("%s", strings.TrimSpace(com.Token))
98 p.newline()
99 }
100
101 if i+1 < len(f.Stmt) {
102 p.newline()
103 }
104 }
105 }
106
107 func (p *printer) expr(x Expr) {
108
109 if before := x.Comment().Before; len(before) > 0 {
110
111
112 p.trim()
113 if p.indent() > 0 {
114
115 p.printf("\n")
116 }
117
118 for i := 0; i < p.margin; i++ {
119 p.printf("\t")
120 }
121 for _, com := range before {
122 p.printf("%s", strings.TrimSpace(com.Token))
123 p.newline()
124 }
125 }
126
127 switch x := x.(type) {
128 default:
129 panic(fmt.Errorf("printer: unexpected type %T", x))
130
131 case *CommentBlock:
132
133
134 case *LParen:
135 p.printf("(")
136 case *RParen:
137 p.printf(")")
138
139 case *Line:
140 sep := ""
141 for _, tok := range x.Token {
142 p.printf("%s%s", sep, tok)
143 sep = " "
144 }
145
146 case *LineBlock:
147 for _, tok := range x.Token {
148 p.printf("%s ", tok)
149 }
150 p.expr(&x.LParen)
151 p.margin++
152 for _, l := range x.Line {
153 p.newline()
154 p.expr(l)
155 }
156 p.margin--
157 p.newline()
158 p.expr(&x.RParen)
159 }
160
161
162
163 p.comment = append(p.comment, x.Comment().Suffix...)
164 }
165
View as plain text