const maxSize … type Expr … type TagExpr … func (x *TagExpr) isExpr() { … } func (x *TagExpr) Eval(ok func(tag string) bool) bool { … } func (x *TagExpr) String() string { … } func tag(tag string) Expr { … } type NotExpr … func (x *NotExpr) isExpr() { … } func (x *NotExpr) Eval(ok func(tag string) bool) bool { … } func (x *NotExpr) String() string { … } func not(x Expr) Expr { … } type AndExpr … func (x *AndExpr) isExpr() { … } func (x *AndExpr) Eval(ok func(tag string) bool) bool { … } func (x *AndExpr) String() string { … } func andArg(x Expr) string { … } func and(x, y Expr) Expr { … } type OrExpr … func (x *OrExpr) isExpr() { … } func (x *OrExpr) Eval(ok func(tag string) bool) bool { … } func (x *OrExpr) String() string { … } func orArg(x Expr) string { … } func or(x, y Expr) Expr { … } type SyntaxError … func (e *SyntaxError) Error() string { … } var errNotConstraint … // Parse parses a single build constraint line of the form “//go:build ...” or “// +build ...” // and returns the corresponding boolean expression. func Parse(line string) (Expr, error) { … } // IsGoBuild reports whether the line of text is a “//go:build” constraint. // It only checks the prefix of the text, not that the expression itself parses. func IsGoBuild(line string) bool { … } // splitGoBuild splits apart the leading //go:build prefix in line from the build expression itself. // It returns "", false if the input is not a //go:build line or if the input contains multiple lines. func splitGoBuild(line string) (expr string, ok bool) { … } type exprParser … // parseExpr parses a boolean build tag expression. func parseExpr(text string) (x Expr, err error) { … } // or parses a sequence of || expressions. // On entry, the next input token has not yet been lexed. // On exit, the next input token has been lexed and is in p.tok. func (p *exprParser) or() Expr { … } // and parses a sequence of && expressions. // On entry, the next input token has not yet been lexed. // On exit, the next input token has been lexed and is in p.tok. func (p *exprParser) and() Expr { … } // not parses a ! expression. // On entry, the next input token has not yet been lexed. // On exit, the next input token has been lexed and is in p.tok. func (p *exprParser) not() Expr { … } // atom parses a tag or a parenthesized expression. // On entry, the next input token HAS been lexed. // On exit, the next input token has been lexed and is in p.tok. func (p *exprParser) atom() Expr { … } // lex finds and consumes the next token in the input stream. // On return, p.tok is set to the token text, // p.isTag reports whether the token was a tag, // and p.pos records the byte offset of the start of the token in the input stream. // If lex reaches the end of the input, p.tok is set to the empty string. // For any other syntax error, lex panics with a SyntaxError. func (p *exprParser) lex() { … } // IsPlusBuild reports whether the line of text is a “// +build” constraint. // It only checks the prefix of the text, not that the expression itself parses. func IsPlusBuild(line string) bool { … } // splitPlusBuild splits apart the leading // +build prefix in line from the build expression itself. // It returns "", false if the input is not a // +build line or if the input contains multiple lines. func splitPlusBuild(line string) (expr string, ok bool) { … } // parsePlusBuildExpr parses a legacy build tag expression (as used with “// +build”). func parsePlusBuildExpr(text string) (Expr, error) { … } // isValidTag reports whether the word is a valid build tag. // Tags must be letters, digits, underscores or dots. // Unlike in Go identifiers, all digits are fine (e.g., "386"). func isValidTag(word string) bool { … } var errComplex … // PlusBuildLines returns a sequence of “// +build” lines that evaluate to the build expression x. // If the expression is too complex to convert directly to “// +build” lines, PlusBuildLines returns an error. func PlusBuildLines(x Expr) ([]string, error) { … } // pushNot applies DeMorgan's law to push negations down the expression, // so that only tags are negated in the result. // (It applies the rewrites !(X && Y) => (!X || !Y) and !(X || Y) => (!X && !Y).) func pushNot(x Expr, not bool) Expr { … } // appendSplitAnd appends x to list while splitting apart any top-level && expressions. // For example, appendSplitAnd({W}, X && Y && Z) = {W, X, Y, Z}. func appendSplitAnd(list []Expr, x Expr) []Expr { … } // appendSplitOr appends x to list while splitting apart any top-level || expressions. // For example, appendSplitOr({W}, X || Y || Z) = {W, X, Y, Z}. func appendSplitOr(list []Expr, x Expr) []Expr { … }