Skip to content

Commit 8ecbfe1

Browse files
author
Jay Conrod
committed
modfile: copy from cmd/go/internal/modfile
Copied from 4be6b4a73d (CL 202565). No changes other than import paths. Updates golang/go#34924 Updates golang/go#31761 Change-Id: Ic25cb983f6641045fc24edf76953b06d4aa5cd43 Reviewed-on: https://go-review.googlesource.com/c/mod/+/202543 Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 85dfc4d commit 8ecbfe1

19 files changed

+2473
-0
lines changed

modfile/print.go

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
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.
4+
5+
// Module file printer.
6+
7+
package modfile
8+
9+
import (
10+
"bytes"
11+
"fmt"
12+
"strings"
13+
)
14+
15+
// Format returns a go.mod file as a byte slice, formatted in standard style.
16+
func Format(f *FileSyntax) []byte {
17+
pr := &printer{}
18+
pr.file(f)
19+
return pr.Bytes()
20+
}
21+
22+
// A printer collects the state during printing of a file or expression.
23+
type printer struct {
24+
bytes.Buffer // output buffer
25+
comment []Comment // pending end-of-line comments
26+
margin int // left margin (indent), a number of tabs
27+
}
28+
29+
// printf prints to the buffer.
30+
func (p *printer) printf(format string, args ...interface{}) {
31+
fmt.Fprintf(p, format, args...)
32+
}
33+
34+
// indent returns the position on the current line, in bytes, 0-indexed.
35+
func (p *printer) indent() int {
36+
b := p.Bytes()
37+
n := 0
38+
for n < len(b) && b[len(b)-1-n] != '\n' {
39+
n++
40+
}
41+
return n
42+
}
43+
44+
// newline ends the current line, flushing end-of-line comments.
45+
func (p *printer) newline() {
46+
if len(p.comment) > 0 {
47+
p.printf(" ")
48+
for i, com := range p.comment {
49+
if i > 0 {
50+
p.trim()
51+
p.printf("\n")
52+
for i := 0; i < p.margin; i++ {
53+
p.printf("\t")
54+
}
55+
}
56+
p.printf("%s", strings.TrimSpace(com.Token))
57+
}
58+
p.comment = p.comment[:0]
59+
}
60+
61+
p.trim()
62+
p.printf("\n")
63+
for i := 0; i < p.margin; i++ {
64+
p.printf("\t")
65+
}
66+
}
67+
68+
// trim removes trailing spaces and tabs from the current line.
69+
func (p *printer) trim() {
70+
// Remove trailing spaces and tabs from line we're about to end.
71+
b := p.Bytes()
72+
n := len(b)
73+
for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') {
74+
n--
75+
}
76+
p.Truncate(n)
77+
}
78+
79+
// file formats the given file into the print buffer.
80+
func (p *printer) file(f *FileSyntax) {
81+
for _, com := range f.Before {
82+
p.printf("%s", strings.TrimSpace(com.Token))
83+
p.newline()
84+
}
85+
86+
for i, stmt := range f.Stmt {
87+
switch x := stmt.(type) {
88+
case *CommentBlock:
89+
// comments already handled
90+
p.expr(x)
91+
92+
default:
93+
p.expr(x)
94+
p.newline()
95+
}
96+
97+
for _, com := range stmt.Comment().After {
98+
p.printf("%s", strings.TrimSpace(com.Token))
99+
p.newline()
100+
}
101+
102+
if i+1 < len(f.Stmt) {
103+
p.newline()
104+
}
105+
}
106+
}
107+
108+
func (p *printer) expr(x Expr) {
109+
// Emit line-comments preceding this expression.
110+
if before := x.Comment().Before; len(before) > 0 {
111+
// Want to print a line comment.
112+
// Line comments must be at the current margin.
113+
p.trim()
114+
if p.indent() > 0 {
115+
// There's other text on the line. Start a new line.
116+
p.printf("\n")
117+
}
118+
// Re-indent to margin.
119+
for i := 0; i < p.margin; i++ {
120+
p.printf("\t")
121+
}
122+
for _, com := range before {
123+
p.printf("%s", strings.TrimSpace(com.Token))
124+
p.newline()
125+
}
126+
}
127+
128+
switch x := x.(type) {
129+
default:
130+
panic(fmt.Errorf("printer: unexpected type %T", x))
131+
132+
case *CommentBlock:
133+
// done
134+
135+
case *LParen:
136+
p.printf("(")
137+
case *RParen:
138+
p.printf(")")
139+
140+
case *Line:
141+
sep := ""
142+
for _, tok := range x.Token {
143+
p.printf("%s%s", sep, tok)
144+
sep = " "
145+
}
146+
147+
case *LineBlock:
148+
for _, tok := range x.Token {
149+
p.printf("%s ", tok)
150+
}
151+
p.expr(&x.LParen)
152+
p.margin++
153+
for _, l := range x.Line {
154+
p.newline()
155+
p.expr(l)
156+
}
157+
p.margin--
158+
p.newline()
159+
p.expr(&x.RParen)
160+
}
161+
162+
// Queue end-of-line comments for printing when we
163+
// reach the end of the line.
164+
p.comment = append(p.comment, x.Comment().Suffix...)
165+
}

0 commit comments

Comments
 (0)