1
0
mirror of https://github.com/schollz/cowyo.git synced 2023-08-10 21:13:00 +03:00
cowyo/vendor/github.com/shurcooL/go/generated/generated.go
2017-10-03 14:43:55 -04:00

81 lines
2.5 KiB
Go

// Package generated provides a function that parses a Go file and reports
// whether it contains a "// Code generated … DO NOT EDIT." line comment.
//
// It implements the specification at https://golang.org/s/generatedcode.
//
// The first priority is correctness (no false negatives, no false positives).
// It must return accurate results even if the input Go source code is not gofmted.
//
// The second priority is performance. The current version uses bufio.Reader and
// ReadBytes. Performance can be optimized further by using lower level I/O
// primitives and allocating less. That can be explored later. A lot of the time
// is spent on reading the entire file without being able to stop early,
// since the specification allows the comment to appear anywhere in the file.
package generated
import (
"bufio"
"bytes"
"io"
"os"
)
// Parse parses the source code of a single Go source file
// provided via src, and reports whether the file contains
// a "// Code generated ... DO NOT EDIT." line comment
// matching the specification at https://golang.org/s/generatedcode:
//
// Generated files are marked by a line of text that matches
// the regular expression, in Go syntax:
//
// `^// Code generated .* DO NOT EDIT\.$`
//
// The .* means the tool can put whatever folderol it wants in there,
// but the comment must be a single line and must start with `Code generated`
// and end with `DO NOT EDIT.`, with a period.
//
// The text may appear anywhere in the file.
func Parse(src io.Reader) (hasGeneratedComment bool, err error) {
br := bufio.NewReader(src)
for {
s, err := br.ReadBytes('\n')
if err == io.EOF {
return containsComment(s), nil
} else if err != nil {
return false, err
}
if len(s) >= 2 && s[len(s)-2] == '\r' {
s = s[:len(s)-2] // Trim "\r\n".
} else {
s = s[:len(s)-1] // Trim "\n".
}
if containsComment(s) {
return true, nil
}
}
}
// containsComment reports whether a line of Go source code s (without newline character)
// contains the generated comment.
func containsComment(s []byte) bool {
return len(s) >= len(prefix)+len(suffix) &&
bytes.HasPrefix(s, prefix) &&
bytes.HasSuffix(s, suffix)
}
var (
prefix = []byte("// Code generated ")
suffix = []byte(" DO NOT EDIT.")
)
// ParseFile opens the file specified by filename and uses Parse to parse it.
// If the source couldn't be read, the error indicates the specific failure.
func ParseFile(filename string) (hasGeneratedComment bool, err error) {
f, err := os.Open(filename)
if err != nil {
return false, err
}
defer f.Close()
return Parse(f)
}