Imports #
"errors"
"strings"
"unicode"
"unicode/utf8"
"strconv"
"strings"
"errors"
"strings"
"unicode"
"unicode/utf8"
"strconv"
"strings"
var errComplex = *ast.CallExpr
var errNotConstraint = *ast.CallExpr
maxSize is a limit used to control the complexity of expressions, in order to prevent stack exhaustion issues due to recursion.
const maxSize = 1000
An Expr is a build tag constraint expression. The underlying concrete type is *[AndExpr], *[OrExpr], *[NotExpr], or *[TagExpr].
type Expr interface {
String() string
Eval(ok func(tag string) bool) bool
isExpr()
}
An AndExpr represents the expression X && Y.
type AndExpr struct {
X Expr
Y Expr
}
A NotExpr represents the expression !X (the negation of X).
type NotExpr struct {
X Expr
}
An OrExpr represents the expression X || Y.
type OrExpr struct {
X Expr
Y Expr
}
A SyntaxError reports a syntax error in a parsed build expression.
type SyntaxError struct {
Offset int
Err string
}
A TagExpr is an [Expr] for the single tag Tag.
type TagExpr struct {
Tag string
}
An exprParser holds state for parsing a build expression.
type exprParser struct {
s string
i int
tok string
isTag bool
pos int
size int
}
func (e *SyntaxError) Error() string
func (x *OrExpr) Eval(ok func(tag string) bool) bool
func (x *TagExpr) Eval(ok func(tag string) bool) bool
func (x *NotExpr) Eval(ok func(tag string) bool) bool
func (x *AndExpr) Eval(ok func(tag string) bool) bool
GoVersion returns the minimum Go version implied by a given build expression. If the expression can be satisfied without any Go version tags, GoVersion returns an empty string. For example: GoVersion(linux && go1.22) = "go1.22" GoVersion((linux && go1.22) || (windows && go1.20)) = "go1.20" => go1.20 GoVersion(linux) = "" GoVersion(linux || (windows && go1.22)) = "" GoVersion(!go1.22) = "" GoVersion assumes that any tag or negated tag may independently be true, so that its analysis can be purely structural, without SAT solving. “Impossible” subexpressions may therefore affect the result. For example: GoVersion((linux && !linux && go1.20) || go1.21) = "go1.20"
func GoVersion(x Expr) string
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
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
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)
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)
func (x *AndExpr) String() string
func (x *TagExpr) String() string
func (x *NotExpr) String() string
func (x *OrExpr) String() string
func and(x Expr, y Expr) 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
func andArg(x Expr) string
andVersion returns the minimum Go version implied by the AND of two minimum Go versions, which is the max of the versions.
func andVersion(x int, y int) int
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
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
func (x *OrExpr) isExpr()
func (x *AndExpr) isExpr()
func (x *NotExpr) isExpr()
func (x *TagExpr) isExpr()
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
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()
minVersion returns the minimum Go major version (9 for go1.9) implied by expression z, or if sign < 0, by expression !z.
func minVersion(z Expr, sign int) int
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
func not(x Expr) Expr
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
func or(x Expr, y Expr) Expr
func orArg(x Expr) string
orVersion returns the minimum Go version implied by the OR of two minimum Go versions, which is the min of the versions.
func orVersion(x int, y int) int
parseExpr parses a boolean build tag expression.
func parseExpr(text string) (x Expr, err error)
parsePlusBuildExpr parses a legacy build tag expression (as used with “// +build”).
func parsePlusBuildExpr(text string) (Expr, 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
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)
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)
func tag(tag string) Expr
Generated with Arrow