constraint

Imports

Imports #

"errors"
"strings"
"unicode"
"unicode/utf8"
"strconv"
"strings"

Constants & Variables

errComplex var #

var errComplex = *ast.CallExpr

errNotConstraint var #

var errNotConstraint = *ast.CallExpr

maxSize const #

maxSize is a limit used to control the complexity of expressions, in order to prevent stack exhaustion issues due to recursion.

const maxSize = 1000

Interfaces

Expr interface #

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()
}

Structs

AndExpr struct #

An AndExpr represents the expression X && Y.

type AndExpr struct {
X Expr
Y Expr
}

NotExpr struct #

A NotExpr represents the expression !X (the negation of X).

type NotExpr struct {
X Expr
}

OrExpr struct #

An OrExpr represents the expression X || Y.

type OrExpr struct {
X Expr
Y Expr
}

SyntaxError struct #

A SyntaxError reports a syntax error in a parsed build expression.

type SyntaxError struct {
Offset int
Err string
}

TagExpr struct #

A TagExpr is an [Expr] for the single tag Tag.

type TagExpr struct {
Tag string
}

exprParser struct #

An exprParser holds state for parsing a build expression.

type exprParser struct {
s string
i int
tok string
isTag bool
pos int
size int
}

Functions

Error method #

func (e *SyntaxError) Error() string

Eval method #

func (x *OrExpr) Eval(ok func(tag string) bool) bool

Eval method #

func (x *TagExpr) Eval(ok func(tag string) bool) bool

Eval method #

func (x *NotExpr) Eval(ok func(tag string) bool) bool

Eval method #

func (x *AndExpr) Eval(ok func(tag string) bool) bool

GoVersion function #

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 function #

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 function #

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 function #

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 function #

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)

String method #

func (x *AndExpr) String() string

String method #

func (x *TagExpr) String() string

String method #

func (x *NotExpr) String() string

String method #

func (x *OrExpr) String() string

and function #

func and(x Expr, y Expr) Expr

and method #

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

andArg function #

func andArg(x Expr) string

andVersion function #

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 function #

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 function #

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 method #

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

isExpr method #

func (x *OrExpr) isExpr()

isExpr method #

func (x *AndExpr) isExpr()

isExpr method #

func (x *NotExpr) isExpr()

isExpr method #

func (x *TagExpr) isExpr()

isValidTag function #

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 method #

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 function #

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 method #

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

not function #

func not(x Expr) Expr

or method #

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

or function #

func or(x Expr, y Expr) Expr

orArg function #

func orArg(x Expr) string

orVersion function #

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 function #

parseExpr parses a boolean build tag expression.

func parseExpr(text string) (x Expr, err error)

parsePlusBuildExpr function #

parsePlusBuildExpr parses a legacy build tag expression (as used with “// +build”).

func parsePlusBuildExpr(text string) (Expr, error)

pushNot function #

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 function #

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 function #

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)

tag function #

func tag(tag string) Expr

Generated with Arrow