// Copyright 2020 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.package printerimport ()func ( *printer) () {iflen(.goBuild)+len(.plusBuild) == 0 {return }// Find latest possible placement of //go:build and // +build comments. // That's just after the last blank line before we find a non-comment. // (We'll add another blank line after our comment block.) // When we start dropping // +build comments, we can skip over /* */ comments too. // Note that we are processing tabwriter input, so every comment // begins and ends with a tabwriter.Escape byte. // And some newlines have turned into \f bytes. := 0for := 0; ; {// Skip leading space at beginning of line. := truefor < len(.output) && (.output[] == ' ' || .output[] == '\t') { ++ }// Skip over // comment if any.if +3 < len(.output) && .output[] == tabwriter.Escape && .output[+1] == '/' && .output[+2] == '/' { = falsefor < len(.output) && !isNL(.output[]) { ++ } }// Skip over \n at end of line.if >= len(.output) || !isNL(.output[]) {break } ++if { = } }// If there is a //go:build comment before the place we identified, // use that point instead. (Earlier in the file is always fine.)iflen(.goBuild) > 0 && .goBuild[0] < { = .goBuild[0] } elseiflen(.plusBuild) > 0 && .plusBuild[0] < { = .plusBuild[0] }varconstraint.Exprswitchlen(.goBuild) {case0:// Synthesize //go:build expression from // +build lines.for , := range .plusBuild { , := constraint.Parse(.commentTextAt())if != nil { = nilbreak }if == nil { = } else { = &constraint.AndExpr{X: , Y: } } }case1:// Parse //go:build expression. , _ = constraint.Parse(.commentTextAt(.goBuild[0])) }var []byteif == nil {// Don't have a valid //go:build expression to treat as truth. // Bring all the lines together but leave them alone. // Note that these are already tabwriter-escaped.for , := range .goBuild { = append(, .lineAt()...) }for , := range .plusBuild { = append(, .lineAt()...) } } else { = append(, tabwriter.Escape) = append(, "//go:build "...) = append(, .String()...) = append(, tabwriter.Escape, '\n')iflen(.plusBuild) > 0 { , := constraint.PlusBuildLines()if != nil { = []string{"// +build error: " + .Error()} }for , := range { = append(, tabwriter.Escape) = append(, ...) = append(, tabwriter.Escape, '\n') } } } = append(, '\n')// Build sorted list of lines to delete from remainder of output. := append(.goBuild, .plusBuild...)slices.Sort()// Collect output after insertion point, with lines deleted, into after.var []byte := for , := range {if < {continue } = appendLines(, .output[:]) = + len(.lineAt()) } = appendLines(, .output[:])if := len(); >= 2 && isNL([-1]) && isNL([-2]) { = [:-1] } .output = .output[:] .output = append(.output, ...) .output = append(.output, ...)}// appendLines is like append(x, y...)// but it avoids creating doubled blank lines,// which would not be gofmt-standard output.// It assumes that only whole blocks of lines are being appended,// not line fragments.func appendLines(, []byte) []byte {iflen() > 0 && isNL([0]) && // y starts in blank line (len() == 0 || len() >= 2 && isNL([len()-1]) && isNL([len()-2])) { // x is empty or ends in blank line = [1:] // delete y's leading blank line }returnappend(, ...)}func ( *printer) ( int) []byte { := for < len(.output) && !isNL(.output[]) { ++ }if < len(.output) { ++ }return .output[:]}func ( *printer) ( int) string {if < len(.output) && .output[] == tabwriter.Escape { ++ } := for < len(.output) && .output[] != tabwriter.Escape && !isNL(.output[]) { ++ }returnstring(.output[:])}func isNL( byte) bool {return == '\n' || == '\f'}
The pages are generated with Goldsv0.7.0-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.