Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / mod@v0.3.0 / modfile / print.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/mod@v0.3.0/modfile/print.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/mod@v0.3.0/modfile/print.go
new file mode 100644 (file)
index 0000000..524f930
--- /dev/null
@@ -0,0 +1,174 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Module file printer.
+
+package modfile
+
+import (
+       "bytes"
+       "fmt"
+       "strings"
+)
+
+// Format returns a go.mod file as a byte slice, formatted in standard style.
+func Format(f *FileSyntax) []byte {
+       pr := &printer{}
+       pr.file(f)
+       return pr.Bytes()
+}
+
+// A printer collects the state during printing of a file or expression.
+type printer struct {
+       bytes.Buffer           // output buffer
+       comment      []Comment // pending end-of-line comments
+       margin       int       // left margin (indent), a number of tabs
+}
+
+// printf prints to the buffer.
+func (p *printer) printf(format string, args ...interface{}) {
+       fmt.Fprintf(p, format, args...)
+}
+
+// indent returns the position on the current line, in bytes, 0-indexed.
+func (p *printer) indent() int {
+       b := p.Bytes()
+       n := 0
+       for n < len(b) && b[len(b)-1-n] != '\n' {
+               n++
+       }
+       return n
+}
+
+// newline ends the current line, flushing end-of-line comments.
+func (p *printer) newline() {
+       if len(p.comment) > 0 {
+               p.printf(" ")
+               for i, com := range p.comment {
+                       if i > 0 {
+                               p.trim()
+                               p.printf("\n")
+                               for i := 0; i < p.margin; i++ {
+                                       p.printf("\t")
+                               }
+                       }
+                       p.printf("%s", strings.TrimSpace(com.Token))
+               }
+               p.comment = p.comment[:0]
+       }
+
+       p.trim()
+       p.printf("\n")
+       for i := 0; i < p.margin; i++ {
+               p.printf("\t")
+       }
+}
+
+// trim removes trailing spaces and tabs from the current line.
+func (p *printer) trim() {
+       // Remove trailing spaces and tabs from line we're about to end.
+       b := p.Bytes()
+       n := len(b)
+       for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') {
+               n--
+       }
+       p.Truncate(n)
+}
+
+// file formats the given file into the print buffer.
+func (p *printer) file(f *FileSyntax) {
+       for _, com := range f.Before {
+               p.printf("%s", strings.TrimSpace(com.Token))
+               p.newline()
+       }
+
+       for i, stmt := range f.Stmt {
+               switch x := stmt.(type) {
+               case *CommentBlock:
+                       // comments already handled
+                       p.expr(x)
+
+               default:
+                       p.expr(x)
+                       p.newline()
+               }
+
+               for _, com := range stmt.Comment().After {
+                       p.printf("%s", strings.TrimSpace(com.Token))
+                       p.newline()
+               }
+
+               if i+1 < len(f.Stmt) {
+                       p.newline()
+               }
+       }
+}
+
+func (p *printer) expr(x Expr) {
+       // Emit line-comments preceding this expression.
+       if before := x.Comment().Before; len(before) > 0 {
+               // Want to print a line comment.
+               // Line comments must be at the current margin.
+               p.trim()
+               if p.indent() > 0 {
+                       // There's other text on the line. Start a new line.
+                       p.printf("\n")
+               }
+               // Re-indent to margin.
+               for i := 0; i < p.margin; i++ {
+                       p.printf("\t")
+               }
+               for _, com := range before {
+                       p.printf("%s", strings.TrimSpace(com.Token))
+                       p.newline()
+               }
+       }
+
+       switch x := x.(type) {
+       default:
+               panic(fmt.Errorf("printer: unexpected type %T", x))
+
+       case *CommentBlock:
+               // done
+
+       case *LParen:
+               p.printf("(")
+       case *RParen:
+               p.printf(")")
+
+       case *Line:
+               p.tokens(x.Token)
+
+       case *LineBlock:
+               p.tokens(x.Token)
+               p.printf(" ")
+               p.expr(&x.LParen)
+               p.margin++
+               for _, l := range x.Line {
+                       p.newline()
+                       p.expr(l)
+               }
+               p.margin--
+               p.newline()
+               p.expr(&x.RParen)
+       }
+
+       // Queue end-of-line comments for printing when we
+       // reach the end of the line.
+       p.comment = append(p.comment, x.Comment().Suffix...)
+}
+
+func (p *printer) tokens(tokens []string) {
+       sep := ""
+       for _, t := range tokens {
+               if t == "," || t == ")" || t == "]" || t == "}" {
+                       sep = ""
+               }
+               p.printf("%s%s", sep, t)
+               sep = " "
+               if t == "(" || t == "[" || t == "{" {
+                       sep = ""
+               }
+       }
+}