//
// It's here in hex for the same reason as rZipBytes above: to avoid
// problems with on-disk virus scanners or other zip processors.
-//
func biggestZipBytes() []byte {
s := `
0000000 50 4b 03 04 14 00 08 00 08 00 00 00 00 00 00 00
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
-//
type Scanner struct {
r io.Reader // The reader provided by the client.
split SplitFunc // The function to split the tokens.
//
// Anything else beginning with "<" logs an error if issueError is
// true, otherwise returns (false, obj.ABI0).
-//
func (p *Parser) symRefAttrs(name string, issueError bool) (bool, obj.ABI) {
abi := obj.ABI0
isStatic := false
// Would be parsed as:
//
// []string{"a", "b:c d", "ef", `g"`}
-//
func splitQuoted(s string) (r []string, err error) {
var args []string
arg := make([]rune, len(s))
// the build.Default build.Context). A relative srcDir is interpreted
// relative to the current working directory.
// If no file was found, an empty filename is returned.
-//
func FindPkg(path, srcDir string) (filename, id string) {
if path == "" {
return
// Import imports a gc-generated package given its import path and srcDir, adds
// the corresponding package object to the packages map, and returns the object.
// The packages map must contain all packages already imported.
-//
func Import(packages map[string]*types2.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types2.Package, err error) {
var rc io.ReadCloser
var id string
//
// %v Go syntax ("+", "<-", "print")
// %+v Debug syntax ("ADD", "RECV", "PRINT")
-//
func (o Op) Format(s fmt.State, verb rune) {
switch verb {
default:
// %v Go syntax
// %L Go syntax followed by " (type T)" if type is known.
// %+v Debug syntax, as in Dump.
-//
func fmtNode(n Node, s fmt.State, verb rune) {
// %+v prints Dump.
// Otherwise we print Go syntax.
// %v Go syntax, semicolon-separated
// %.v Go syntax, comma-separated
// %+v Debug syntax, as in DumpList.
-//
func (l Nodes) Format(s fmt.State, verb rune) {
if s.Flag('+') && verb == 'v' {
// %+v is DumpList output
// The embedding struct should also fill in n.op in its constructor,
// for more useful panic messages when invalid methods are called,
// instead of implementing Op itself.
-//
type miniNode struct {
pos src.XPos // uint32
op Op // uint8
// use bitmaps for objects up to 64 kB in size.
//
// Also known to reflect/type.go.
-//
const maxPtrmaskBytes = 2048
// GCSym returns a data symbol containing GC information for type t, along
// GO_GCFLAGS=-d=ssa/generic_cse/time,ssa/generic_cse/stats,ssa/generic_cse/debug=3 ./make.bash
//
// BOOT_GO_GCFLAGS=-d='ssa/~^.*scc$/off' GO_GCFLAGS='-d=ssa/~^.*scc$/off' ./make.bash
-//
func PhaseOption(phase, flag string, val int, valString string) string {
switch phase {
case "", "help":
// This function examines the live OpArg{Int,Float}Reg values and
// synthesizes new (dead) values for the non-live params or the
// non-live pieces of partially live params.
-//
func PopulateABIInRegArgOps(f *Func) {
pri := f.ABISelf.ABIAnalyzeFuncType(f.Type.FuncType())
// go test debug_test.go -args -u
// (for Delve)
// go test debug_test.go -args -u -d
-//
func TestNexting(t *testing.T) {
testenv.SkipFlaky(t, 37404)
// I extra
// / \
// J K
-//
type poset struct {
lastidx uint32 // last generated dense index
flags uint8 // internal flags
// elements are accepted. list returns the position of the closing token.
//
// list = [ f { sep f } [sep] ] close .
-//
func (p *parser) list(context string, sep, close token, f func() bool) Pos {
if debug && (sep != _Comma && sep != _Semi || close != _Rparen && close != _Rbrace && close != _Rbrack) {
panic("invalid sep or close argument for list")
// error, and the returned syntax tree is nil.
//
// If pragh != nil, it is called with each pragma encountered.
-//
func Parse(base *PosBase, src io.Reader, errh ErrorHandler, pragh PragmaHandler, mode Mode) (_ *File, first error) {
defer func() {
if p := recover(); p != nil {
// depending on the size of the thing that needs to be zeroed out
// (I've verified at the time of the writing of this test that it
// exercises the various cases).
-//
func TestZerorange45372(t *testing.T) {
if r := triggerZerorangeLarge(101, 303, 505); r != 1010 {
t.Errorf("large: wanted %d got %d", 1010, r)
// %v Go syntax: Name for symbols in the local package, PkgName.Name for imported symbols.
// %+v Debug syntax: always include PkgName. prefix even for local names.
// %S Short syntax: Name only, no matter what.
-//
func (s *Sym) Format(f fmt.State, verb rune) {
mode := fmtGo
switch verb {
// %L Go syntax for underlying type if t is named
// %S short Go syntax: drop leading "func" in function type
// %-S special case for method receiver symbol
-//
func (t *Type) Format(s fmt.State, verb rune) {
mode := fmtGo
switch verb {
// TypeOf returns the type of expression e, or nil if not found.
// Precondition: the Types, Uses and Defs maps are populated.
-//
func (info *Info) TypeOf(e syntax.Expr) Type {
if t, ok := info.Types[e]; ok {
return t.Type
// it defines, not the type (*TypeName) it uses.
//
// Precondition: the Uses and Defs maps are populated.
-//
func (info *Info) ObjectOf(id *syntax.Name) Object {
if obj := info.Defs[id]; obj != nil {
return obj
// reports whether the call is valid, with *x holding the result;
// but x.expr is not set. If the call is invalid, the result is
// false, and *x is undefined.
-//
func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (_ bool) {
// append is the only built-in that permits the use of ... for the last argument
bin := predeclaredFuncs[id]
// If hint != nil, it is the type of a composite literal element.
// If allowGeneric is set, the operand type may be an uninstantiated
// parameterized type or function value.
-//
func (check *Checker) rawExpr(x *operand, e syntax.Expr, hint Type, allowGeneric bool) exprKind {
if check.conf.Trace {
check.trace(e.Pos(), "-- expr %s", e)
// exprInternal contains the core of type checking of expressions.
// Must only be called by rawExpr.
-//
func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKind {
// make sure x has a valid state in case of bailout
// (was issue 5770)
// expr typechecks expression e and initializes x with the expression value.
// The result must be a single value.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) expr(x *operand, e syntax.Expr) {
check.rawExpr(x, e, nil, false)
check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
// exprWithHint typechecks expression e and initializes x with the expression value;
// hint is the type of a composite literal element.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) exprWithHint(x *operand, e syntax.Expr, hint Type) {
assert(hint != nil)
check.rawExpr(x, e, hint, false)
// If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
// value.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) exprOrType(x *operand, e syntax.Expr, allowGeneric bool) {
check.rawExpr(x, e, nil, allowGeneric)
check.exclude(x, 1<<novalue)
// - If indirect is set, a method with a pointer receiver type was found
// but there was no pointer on the path from the actual receiver type to
// the method's formal receiver base type, nor was the receiver addressable.
-//
func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
if T == nil {
panic("LookupFieldOrMethod on nil type")
// is not set), MissingMethod only checks that methods of T which are also
// present in V have matching types (e.g., for a type assertion x.(T) where
// x is of interface type V).
-//
func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
m, alt := (*Checker)(nil).missingMethod(V, T, static)
// Only report a wrong type if the alternative method has the same name as m.
// An Object describes a named language entity such as a package,
// constant, type, variable, function (incl. methods), or label.
// All objects implement the Object interface.
-//
type Object interface {
Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
Pos() syntax.Pos // position of object identifier in declaration
// the operand, the operand's type, a value for constants, and an id
// for built-in functions.
// The zero value of operand is a ready to use invalid operand.
-//
type operand struct {
mode operandMode
expr syntax.Expr
// Pos returns the position of the expression corresponding to x.
// If x is invalid the position is nopos.
-//
func (x *operand) Pos() syntax.Pos {
// x.expr may not be set if x is invalid
if x.expr == nil {
//
// cgofunc <expr> (<untyped kind> <mode> )
// cgofunc <expr> ( <mode> of type <typ>)
-//
func operandString(x *operand, qf Qualifier) string {
// special-case nil
if x.mode == nilvalue {
// p.x FieldVal T x int {0} true
// p.m MethodVal *T m func() {1, 0} true
// T.m MethodExpr T m func(T) {1, 0} false
-//
type Selection struct {
kind SelectionKind
recv Type // type of x
// "field (T) f int"
// "method (T) f(X) Y"
// "method expr (T) f(X) Y"
-//
func SelectionString(s *Selection, qf Qualifier) string {
var k string
switch s.kind {
// types are naturally aligned with a maximum alignment MaxAlign.
//
// *StdSizes implements Sizes.
-//
type StdSizes struct {
WordSize int64 // word size in bytes - must be >= 4 (32bits)
MaxAlign int64 // maximum alignment in bytes - must be >= 1
//
// Using a nil Qualifier is equivalent to using (*Package).Path: the
// object is qualified by the import path, e.g., "encoding/json.Marshal".
-//
type Qualifier func(*Package) string
// RelativeTo returns a Qualifier that fully qualifies members of
// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
// T: &term{false, T} == {T} // set of type T
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
-//
type term struct {
tilde bool // valid if typ != nil
typ Type
// If an error occurred, x.mode is set to invalid.
// For the meaning of def, see Checker.definedType, below.
// If wantType is set, the identifier e is expected to denote a type.
-//
func (check *Checker) ident(x *operand, e *syntax.Name, def *Named, wantType bool) {
x.mode = invalid
x.expr = e
// If def != nil, e is the type specification for the defined type def, declared
// in a type declaration, and def.underlying will be set to the type of e before
// any components of e are type-checked.
-//
func (check *Checker) definedType(e syntax.Expr, def *Named) Type {
typ := check.typInternal(e, def)
assert(isTyped(typ))
// typInternal drives type checking of types.
// Must only be called by definedType or genericType.
-//
func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) {
if check.conf.Trace {
check.trace(e0.Pos(), "-- type %s", e0)
// Objects with names containing blanks are internal and not entered into
// a scope. Objects with exported names are inserted in the unsafe package
// scope; other objects are inserted in the universe scope.
-//
func def(obj Object) {
assert(obj.color() == black)
name := obj.Name()
// n;
//
// Also works if b is a string.
-//
func walkCopy(n *ir.BinaryExpr, init *ir.Nodes, runtimecall bool) ir.Node {
if n.X.Type().Elem().HasPointers() {
ir.CurFunc.SetWBPos(n.Pos())
// go build -o testcover
// testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go
// go run ./testdata/main.go ./testdata/test.go
-//
func TestCover(t *testing.T) {
t.Parallel()
testenv.MustHaveGoRun(t)
// package sys
//
// const StackGuardMultiplier = <multiplier value>
-//
func mkzversion(dir, file string) {
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
// package objabi
//
// const stackGuardMultiplierDefault = <multiplier value>
-//
func mkobjabi(file string) {
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by go tool dist; DO NOT EDIT.\n")
// to share a cache directory (for example, if the directory were stored
// in a network file system). File locking is notoriously unreliable in
// network file systems and may not suffice to protect the cache.
-//
func Open(dir string) (*Cache, error) {
info, err := os.Stat(dir)
if err != nil {
// the purpose of satisfying build tags, in order to estimate
// (conservatively) whether a file could ever possibly be used
// in any build.
-//
func ShouldBuild(content []byte, tags map[string]bool) bool {
// Identify leading run of // comments and blank lines,
// which must be followed by a blank line.
// other2 tested by
// other2.test imports
// pkg
-//
func (pkg *loadPkg) stackText() string {
var stack []*loadPkg
for p := pkg; p != nil; p = p.stack {
// implementation. It is also used by tests.
//
// The default behavior (vetTool=="") runs 'go tool vet'.
-//
var vetTool string // -vettool
func init() {
//
// fmtcmd replaces the name of the current directory with dot (.)
// but only when it is at the beginning of a space-separated token.
-//
func (b *Builder) fmtcmd(dir string, format string, args ...any) string {
cmd := fmt.Sprintf(format, args...)
if dir != "" && dir != "/" {
//
// If a is not nil and a.output is not nil, showOutput appends to that slice instead of
// printing to b.Print.
-//
func (b *Builder) showOutput(a *Action, dir, desc, out string) {
prefix := "# " + desc
suffix := "\n" + out
// Keep list and the implementations below sorted by name.
//
// NOTE: If you make changes here, update testdata/script/README too!
-//
var scriptCmds = map[string]func(*testScript, simpleStatus, []string){
"addcrlf": (*testScript).cmdAddcrlf,
"cc": (*testScript).cmdCc,
//
// A nicer version of this diagram can be found on slide 21 of the presentation
// attached to https://golang.org/issue/16922#issuecomment-243748180.
-//
func stackOffset(a *obj.Addr, stacksize int64) {
switch a.Name {
case obj.NAME_AUTO:
// is very slight but negative, so the alignment is disabled by
// setting MaxLoopPad = 0. The code is here for reference and
// for future experiments.
-//
const (
loopAlign = 16
maxLoopPad = 0
// REG_X15 => 15
// REG_R9 => 9
// REG_AX => 0
-//
func regIndex(r int16) int {
lower3bits := reg[r]
high4bit := regrex[r] & Rxr << 1
// i1:0:1 f1:1:1 ~r0:2:2 ~r1:3:2
//
// where each chunk above is of the form NAME:ORDER:INOUTCLASSIFICATION
-//
func processParams(die *dwarf.Entry, ex *dwtest.Examiner) string {
// Values in the returned map are of the form <order>:<varparam>
// where order is the order within the child DIE list of the
//
// Logging an error means that on exit cmd/link will delete any
// output file and return a non-zero error code.
-//
func (reporter *ErrorReporter) Errorf(s Sym, format string, args ...interface{}) {
if s != 0 && reporter.ldr.SymName(s) != "" {
// Note: Replace is needed here because symbol names might have % in them,
// serves as reference to the entire ring. Empty rings are represented
// as nil Ring pointers. The zero value for a Ring is a one-element
// ring with a nil Value.
-//
type Ring struct {
next, prev *Ring
Value any // for use by client; untouched by this library
// Move moves n % r.Len() elements backward (n < 0) or forward (n >= 0)
// in the ring and returns that ring element. r must not be empty.
-//
func (r *Ring) Move(n int) *Ring {
if r.next == nil {
return r.init()
// them creates a single ring with the elements of s inserted
// after r. The result points to the element following the
// last element of s after insertion.
-//
func (r *Ring) Link(s *Ring) *Ring {
n := r.Next()
if s != nil {
// Unlink removes n % r.Len() elements from the ring r, starting
// at r.Next(). If n % r.Len() == 0, r remains unchanged.
// The result is the removed subring. r must not be empty.
-//
func (r *Ring) Unlink(n int) *Ring {
if n <= 0 {
return nil
// Len computes the number of elements in ring r.
// It executes in time proportional to the number of elements.
-//
func (r *Ring) Len() int {
n := 0
if r != nil {
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p224Mul(out1 *p224MontgomeryDomainFieldElement, arg1 *p224MontgomeryDomainFieldElement, arg2 *p224MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m
// 0 ≤ eval out1 < m
-//
func p224Square(out1 *p224MontgomeryDomainFieldElement, arg1 *p224MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p224Add(out1 *p224MontgomeryDomainFieldElement, arg1 *p224MontgomeryDomainFieldElement, arg2 *p224MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p224Sub(out1 *p224MontgomeryDomainFieldElement, arg1 *p224MontgomeryDomainFieldElement, arg2 *p224MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = 1 mod m
// 0 ≤ eval out1 < m
-//
func p224SetOne(out1 *p224MontgomeryDomainFieldElement) {
out1[0] = 0xffffffff00000000
out1[1] = 0xffffffffffffffff
// Postconditions:
// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m
// 0 ≤ eval out1 < m
-//
func p224FromMontgomery(out1 *p224NonMontgomeryDomainFieldElement, arg1 *p224MontgomeryDomainFieldElement) {
x1 := arg1[0]
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = eval arg1 mod m
// 0 ≤ eval out1 < m
-//
func p224ToMontgomery(out1 *p224MontgomeryDomainFieldElement, arg1 *p224NonMontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p384Mul(out1 *p384MontgomeryDomainFieldElement, arg1 *p384MontgomeryDomainFieldElement, arg2 *p384MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m
// 0 ≤ eval out1 < m
-//
func p384Square(out1 *p384MontgomeryDomainFieldElement, arg1 *p384MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p384Add(out1 *p384MontgomeryDomainFieldElement, arg1 *p384MontgomeryDomainFieldElement, arg2 *p384MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p384Sub(out1 *p384MontgomeryDomainFieldElement, arg1 *p384MontgomeryDomainFieldElement, arg2 *p384MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = 1 mod m
// 0 ≤ eval out1 < m
-//
func p384SetOne(out1 *p384MontgomeryDomainFieldElement) {
out1[0] = 0xffffffff00000001
out1[1] = 0xffffffff
// Postconditions:
// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^6) mod m
// 0 ≤ eval out1 < m
-//
func p384FromMontgomery(out1 *p384NonMontgomeryDomainFieldElement, arg1 *p384MontgomeryDomainFieldElement) {
x1 := arg1[0]
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = eval arg1 mod m
// 0 ≤ eval out1 < m
-//
func p384ToMontgomery(out1 *p384MontgomeryDomainFieldElement, arg1 *p384NonMontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p521Mul(out1 *p521MontgomeryDomainFieldElement, arg1 *p521MontgomeryDomainFieldElement, arg2 *p521MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg1)) mod m
// 0 ≤ eval out1 < m
-//
func p521Square(out1 *p521MontgomeryDomainFieldElement, arg1 *p521MontgomeryDomainFieldElement) {
x1 := arg1[1]
x2 := arg1[2]
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p521Add(out1 *p521MontgomeryDomainFieldElement, arg1 *p521MontgomeryDomainFieldElement, arg2 *p521MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m
// 0 ≤ eval out1 < m
-//
func p521Sub(out1 *p521MontgomeryDomainFieldElement, arg1 *p521MontgomeryDomainFieldElement, arg2 *p521MontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = 1 mod m
// 0 ≤ eval out1 < m
-//
func p521SetOne(out1 *p521MontgomeryDomainFieldElement) {
out1[0] = 0x80000000000000
out1[1] = uint64(0x0)
// Postconditions:
// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^9) mod m
// 0 ≤ eval out1 < m
-//
func p521FromMontgomery(out1 *p521NonMontgomeryDomainFieldElement, arg1 *p521MontgomeryDomainFieldElement) {
x1 := arg1[0]
var x2 uint64
// Postconditions:
// eval (from_montgomery out1) mod m = eval arg1 mod m
// 0 ≤ eval out1 < m
-//
func p521ToMontgomery(out1 *p521MontgomeryDomainFieldElement, arg1 *p521NonMontgomeryDomainFieldElement) {
var x1 uint64
var x2 uint64
func p256MulAsm(res, in1, in2 []byte)
// Montgomery square modulo P256
-//
func p256Sqr(res, in []byte) {
p256MulAsm(res, in, in)
}
// The result should be a slice in LE order, but the slice
// from big.Bytes is in BE order.
// TODO: For big endian implementation, do not reverse bytes.
-//
func fromBig(big *big.Int) []byte {
// This could be done a lot more efficiently...
res := big.Bytes()
//
// The relative order of ECDSA and RSA cipher suites doesn't matter,
// as they depend on the certificate. Pick one to get a stable order.
-//
var cipherSuitesPreferenceOrder = []uint16{
// AEADs w/ ECDHE
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
// This could be surprising behavior to retroactively apply to
// driver.String now that Go1 is out, but this is convenient for
// our TestPointerParamsAndScans.
-//
type fakeDriverString struct{}
func (fakeDriverString) ConvertValue(v any) (driver.Value, error) {
// } else {
// // NULL value
// }
-//
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
// A common idiom is to merge the check for nil return with
// the check that the value has the expected dynamic type, as in:
// v, ok := e.Val(AttrSibling).(int64)
-//
func (e *Entry) Val(a Attr) any {
if f := e.AttrField(a); f != nil {
return f.Val
// than wait for the completion of another 32-bit block.
//
// NewDecoder wraps an io.Reader interface around Decode.
-//
func Decode(dst, src []byte, flush bool) (ndst, nsrc int, err error) {
var v uint32
var nb int
// n == 0: buf too small
// n < 0: value larger than 64 bits (overflow)
// and -n is the number of bytes read
-//
func Uvarint(buf []byte) (uint64, int) {
var x uint64
var s uint
// n == 0: buf too small
// n < 0: value larger than 64 bits (overflow)
// and -n is the number of bytes read
-//
func Varint(buf []byte) (int64, int) {
ux, n := Uvarint(buf) // ok to continue in presence of error
x := int64(ux >> 1)
// invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.
-//
func Unmarshal(data []byte, v any) error {
// Check for well-formedness.
// Avoids filling out half a data structure
// JSON cannot represent cyclic data structures and Marshal does not
// handle them. Passing cyclic structures to Marshal will result in
// an error.
-//
func Marshal(v any) ([]byte, error) {
e := newEncodeState()
// Number, for JSON numbers
// string, for JSON string literals
// nil, for JSON null
-//
type Token any
const (
// A CommentGroup represents a sequence of comments
// with no other tokens and no empty lines between.
-//
type CommentGroup struct {
List []*Comment // len(List) > 0
}
// An expression is represented by a tree consisting of one
// or more of the following concrete expression nodes.
-//
type (
// A BadExpr node is a placeholder for an expression containing
// syntax errors for which a correct expression node cannot be
// The direction of a channel type is indicated by a bit
// mask including one or both of the following constants.
-//
type ChanDir int
const (
// A type is represented by a tree consisting of one
// or more of the following type-specific expression
// nodes.
-//
type (
// An ArrayType node represents an array or slice type.
ArrayType struct {
// exprNode() ensures that only expression/type nodes can be
// assigned to an Expr.
-//
func (*BadExpr) exprNode() {}
func (*Ident) exprNode() {}
func (*Ellipsis) exprNode() {}
// NewIdent creates a new Ident without position.
// Useful for ASTs generated by code other than the Go parser.
-//
func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
// IsExported reports whether name starts with an upper-case letter.
-//
func IsExported(name string) bool { return token.IsExported(name) }
// IsExported reports whether id starts with an upper-case letter.
-//
func (id *Ident) IsExported() bool { return token.IsExported(id.Name) }
func (id *Ident) String() string {
// A statement is represented by a tree consisting of one
// or more of the following concrete statement nodes.
-//
type (
// A BadStmt node is a placeholder for statements containing
// syntax errors for which no correct statement nodes can be
// stmtNode() ensures that only statement nodes can be
// assigned to a Stmt.
-//
func (*BadStmt) stmtNode() {}
func (*DeclStmt) stmtNode() {}
func (*EmptyStmt) stmtNode() {}
// A Spec node represents a single (non-parenthesized) import,
// constant, type, or variable declaration.
-//
type (
// The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
Spec interface {
// specNode() ensures that only spec nodes can be
// assigned to a Spec.
-//
func (*ImportSpec) specNode() {}
func (*ValueSpec) specNode() {}
func (*TypeSpec) specNode() {}
// A declaration is represented by one of the following declaration nodes.
-//
type (
// A BadDecl node is a placeholder for a declaration containing
// syntax errors for which a correct declaration node cannot be
// declNode() ensures that only declaration nodes can be
// assigned to a Decl.
-//
func (*BadDecl) declNode() {}
func (*GenDecl) declNode() {}
func (*FuncDecl) declNode() {}
// interpretation of the syntax tree by the manipulating program: Except for Doc
// and Comment comments directly associated with nodes, the remaining comments
// are "free-floating" (see also issues #18593, #20744).
-//
type File struct {
Doc *CommentGroup // associated documentation; or nil
Package token.Pos // position of "package" keyword
// A Package node represents a set of source files
// collectively building a Go package.
-//
type Package struct {
Name string // package name
Scope *Scope // package scope across all files
func (a byPos) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// sortComments sorts the list of comment groups in source order.
-//
func sortComments(list []*CommentGroup) {
// TODO(gri): Does it make sense to check for sorted-ness
// first (because we know that sorted-ness is
// A CommentMap maps an AST node to a list of comment groups
// associated with it. See NewCommentMap for a description of
// the association.
-//
type CommentMap map[Node][]*CommentGroup
func (cmap CommentMap) addComment(n Node, c *CommentGroup) {
func (a byInterval) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
// nodeList returns the list of nodes of the AST n in source order.
-//
func nodeList(n Node) []Node {
var list []Node
Inspect(n, func(n Node) bool {
}
// A commentListReader helps iterating through a list of comment groups.
-//
type commentListReader struct {
fset *token.FileSet
list []*CommentGroup
// A nodeStack keeps track of nested nodes.
// A node lower on the stack lexically contains the nodes higher on the stack.
-//
type nodeStack []Node
// push pops all nodes that appear lexically before n
// and then pushes n on the stack.
-//
func (s *nodeStack) push(n Node) {
s.pop(n.Pos())
*s = append((*s), n)
// pop pops all nodes that appear lexically before pos
// (i.e., whose lexical extent has ended before or at pos).
// It returns the last node popped.
-//
func (s *nodeStack) pop(pos token.Pos) (top Node) {
i := len(*s)
for i > 0 && (*s)[i-1].End() <= pos {
// node possible: For instance, if the comment is a line comment
// trailing an assignment, the comment is associated with the entire
// assignment rather than just the last operand in the assignment.
-//
func NewCommentMap(fset *token.FileSet, node Node, comments []*CommentGroup) CommentMap {
if len(comments) == 0 {
return nil // no comments to map
// Update replaces an old node in the comment map with the new node
// and returns the new node. Comments that were associated with the
// old node are associated with the new node.
-//
func (cmap CommentMap) Update(old, new Node) Node {
if list := cmap[old]; len(list) > 0 {
delete(cmap, old)
// Filter returns a new comment map consisting of only those
// entries of cmap for which a corresponding node exists in
// the AST specified by node.
-//
func (cmap CommentMap) Filter(node Node) CommentMap {
umap := make(CommentMap)
Inspect(node, func(n Node) bool {
// Comments returns the list of comment groups in the comment map.
// The result is sorted in source order.
-//
func (cmap CommentMap) Comments() []*CommentGroup {
list := make([]*CommentGroup, 0, len(cmap))
for _, e := range cmap {
// res maps a key of the form "line number: node type"
// to the associated comments' text.
-//
var res = map[string]string{
" 5: *ast.File": "the very first comment\npackage p\n",
" 5: *ast.Ident": " the name is p\n",
// stripped. The File.Comments list is not changed.
//
// FileExports reports whether there are exported declarations.
-//
func FileExports(src *File) bool {
return filterFile(src, exportFilter, true)
}
//
// PackageExports reports whether there are exported declarations;
// it returns false otherwise.
-//
func PackageExports(pkg *Package) bool {
return filterPackage(pkg, exportFilter, true)
}
// fieldName assumes that x is the type of an anonymous field and
// returns the corresponding field name. If x is not an acceptable
// anonymous field, the result is nil.
-//
func fieldName(x Expr) *Ident {
switch t := x.(type) {
case *Ident:
//
// FilterDecl reports whether there are any declared names left after
// filtering.
-//
func FilterDecl(decl Decl, f Filter) bool {
return filterDecl(decl, f, false)
}
//
// FilterFile reports whether there are any top-level declarations
// left after filtering.
-//
func FilterFile(src *File, f Filter) bool {
return filterFile(src, f, false)
}
//
// FilterPackage reports whether there are any top-level declarations
// left after filtering.
-//
func FilterPackage(pkg *Package, f Filter) bool {
return filterPackage(pkg, f, false)
}
// nameOf returns the function (foo) or method name (foo.bar) for
// the given function declaration. If the AST is incorrect for the
// receiver, it assumes a function instead.
-//
func nameOf(f *FuncDecl) string {
if r := f.Recv; r != nil && len(r.List) == 1 {
// looks like a correct receiver declaration
// separator is an empty //-style comment that is interspersed between
// different comment groups when they are concatenated into a single group
-//
var separator = &Comment{token.NoPos, "//"}
// MergePackageFiles creates a file AST by merging the ASTs of the
// files belonging to a package. The mode flags control merging behavior.
-//
func MergePackageFiles(pkg *Package, mode MergeMode) *File {
// Count the number of package docs, comments and declarations across
// all package files. Also, compute sorted list of filenames, so that
// of one without, and it favors duplicate entries appearing
// later in the source over ones appearing earlier. This is why
// (*t2).f2 is kept and t2.f2 is eliminated in this test case.
-//
const golden = `package p
type t1 struct{}
// belong to different packages, one package name is selected and files with
// different package names are reported and then ignored.
// The result is a package node and a scanner.ErrorList if there were errors.
-//
func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer, universe *Scope) (*Package, error) {
var p pkgBuilder
p.fset = fset
// A Scope maintains the set of named language entities declared
// in the scope and a link to the immediately surrounding (outer)
// scope.
-//
type Scope struct {
Outer *Scope
Objects map[string]*Object
// Lookup returns the object with the given name if it is
// found in scope s, otherwise it returns nil. Outer scopes
// are ignored.
-//
func (s *Scope) Lookup(name string) *Object {
return s.Objects[name]
}
// If the scope already contains an object alt with the same name,
// Insert leaves the scope unchanged and returns alt. Otherwise
// it inserts obj and returns nil.
-//
func (s *Scope) Insert(obj *Object) (alt *Object) {
if alt = s.Objects[obj.Name]; alt == nil {
s.Objects[obj.Name] = obj
// Kind Data type Data value
// Pkg *Scope package scope
// Con int iota for the respective declaration
-//
type Object struct {
Kind ObjKind
Name string // declared name
// v.Visit(node) is not nil, Walk is invoked recursively with visitor
// w for each of the non-nil children of node, followed by a call of
// w.Visit(nil).
-//
func Walk(v Visitor, node Node) {
if v = v.Visit(node); v == nil {
return
// f(node); node must not be nil. If f returns true, Inspect invokes f
// recursively for each of the non-nil children of node, followed by a
// call of f(nil).
-//
func Inspect(node Node, f func(Node) bool) {
Walk(inspector(f), node)
}
//
// If an error occurs, Import returns a non-nil error and a non-nil
// *Package containing partial information.
-//
func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
p := &Package{
ImportPath: path,
// Would be parsed as:
//
// []string{"a", "b:c d", "ef", `g"`}
-//
func splitQuoted(s string) (r []string, err error) {
var args []string
arg := make([]rune, len(s))
//
// All-caps names are pseudo-names for specific points
// in the dependency lattice.
-//
var depsRules = `
# No dependencies allowed for any of these packages.
NONE
// Int int64 or *big.Int
// Float *big.Float or *big.Rat
// everything else nil
-//
func Val(x Value) any {
switch x := x.(type) {
case boolVal:
// *big.Float Float
// *big.Rat Float
// anything else Unknown
-//
func Make(x any) Value {
switch x := x.(type) {
case bool:
// The operation must be defined for the operand.
// If prec > 0 it specifies the ^ (xor) result size in bits.
// If y is Unknown, the result is Unknown.
-//
func UnaryOp(op token.Token, y Value, prec uint) Value {
switch op {
case token.ADD:
// smallest complexity for two values x and y. If one of them is
// numeric, both of them must be numeric. If one of them is Unknown
// or invalid (say, nil) both results are that value.
-//
func match(x, y Value) (_, _ Value) {
switch ox, oy := ord(x), ord(y); {
case ox < oy:
// To force integer division of Int operands, use op == token.QUO_ASSIGN
// instead of token.QUO; the result is guaranteed to be Int in this case.
// Division by zero leads to a run-time panic.
-//
func BinaryOp(x_ Value, op token.Token, y_ Value) Value {
x, y := match(x_, y_)
// Shift returns the result of the shift expression x op s
// with op == token.SHL or token.SHR (<< or >>). x must be
// an Int or an Unknown. If x is Unknown, the result is x.
-//
func Shift(x Value, op token.Token, s uint) Value {
switch x := x.(type) {
case unknownVal:
// The comparison must be defined for the operands.
// If one of the operands is Unknown, the result is
// false.
-//
func Compare(x_ Value, op token.Token, y_ Value) bool {
x, y := match(x_, y_)
// New takes ownership of the AST pkg and may edit or overwrite it.
// To have the Examples fields populated, use NewFromFiles and include
// the package's _test.go files.
-//
func New(pkg *ast.Package, importPath string, mode Mode) *Package {
var r reader
r.readPackage(pkg, mode)
//
// NewFromFiles takes ownership of the AST files and may edit them,
// unless the PreserveAST Mode bit is on.
-//
func NewFromFiles(fset *token.FileSet, files []*ast.File, importPath string, opts ...any) (*Package, error) {
// Check for invalid API usage.
if fset == nil {
// or Foo (with a "bar" suffix).
//
// Examples with malformed names are not associated with anything.
-//
func classifyExamples(p *Package, examples []*Example) {
if len(examples) == 0 {
return
// filterIdentList removes unexported names from list in place
// and returns the resulting list.
-//
func filterIdentList(list []*ast.Ident) []*ast.Ident {
j := 0
for _, x := range list {
}
// hasExportedName reports whether list contains any exported names.
-//
func hasExportedName(list []*ast.Ident) bool {
for _, x := range list {
if x.IsExported() {
// in place and reports whether fields were removed. Anonymous fields are
// recorded with the parent type. filterType is called with the types of
// all remaining fields.
-//
func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) {
if fields == nil {
return
}
// filterParamList applies filterType to each parameter type in fields.
-//
func (r *reader) filterParamList(fields *ast.FieldList) {
if fields != nil {
for _, f := range fields.List {
// filterType strips any unexported struct fields or method types from typ
// in place. If fields (or methods) have been removed, the corresponding
// struct or interface type has the Incomplete field set to true.
-//
func (r *reader) filterType(parent *namedType, typ ast.Expr) {
switch t := typ.(type) {
case *ast.Ident:
// copyConstType returns a copy of typ with position pos.
// typ must be a valid constant type.
// In practice, only (possibly qualified) identifiers are possible.
-//
func copyConstType(typ ast.Expr, pos token.Pos) ast.Expr {
switch typ := typ.(type) {
case *ast.Ident:
}
// fileExports removes unexported declarations from src in place.
-//
func (r *reader) fileExports(src *ast.File) {
j := 0
for _, d := range src.Decls {
// Filter eliminates documentation for names that don't pass through the filter f.
// TODO(gri): Recognize "Type.Method" as a name.
-//
func (p *Package) Filter(f Filter) {
p.Consts = filterValues(p.Consts, f)
p.Vars = filterValues(p.Vars, f)
// A methodSet describes a set of methods. Entries where Decl == nil are conflict
// entries (more than one method with the same name at the same embedding level).
-//
type methodSet map[string]*Func
// recvString returns a string representation of recv of the form "T", "*T",
// "T[A, ...]", "*T[A, ...]" or "BADRECV" (if not a proper receiver type).
-//
func recvString(recv ast.Expr) string {
switch t := recv.(type) {
case *ast.Ident:
// If there are multiple f's with the same name, set keeps the first
// one with documentation; conflicts are ignored. The boolean
// specifies whether to leave the AST untouched.
-//
func (mset methodSet) set(f *ast.FuncDecl, preserveAST bool) {
name := f.Name.Name
if g := mset[name]; g != nil && g.Doc != "" {
// add adds method m to the method set; m is ignored if the method set
// already contains a method with the same name at the same or a higher
// level than m.
-//
func (mset methodSet) add(m *Func) {
old := mset[m.Name]
if old == nil || m.Level < old.Level {
// baseTypeName returns the name of the base type of x (or "")
// and whether the type is imported or not.
-//
func baseTypeName(x ast.Expr) (name string, imported bool) {
switch t := x.(type) {
case *ast.Ident:
// A namedType represents a named unqualified (package local, or possibly
// predeclared) type. The namedType for a type name is always found via
// reader.lookupType.
-//
type namedType struct {
doc string // doc comment for type
name string // type name
// in the respective AST nodes so that they are not printed
// twice (once when printing the documentation and once when
// printing the corresponding AST node).
-//
type reader struct {
mode Mode
// If the base type has not been encountered yet, a new
// type with the given name but no associated declaration
// is added to the type map.
-//
func (r *reader) lookupType(name string) *namedType {
if name == "" || name == "_" {
return nil // no type docs for anonymous types
// anonymous field in the parent type. If the field is imported
// (qualified name) or the parent is nil, the field is ignored.
// The function returns the field name.
-//
func (r *reader) recordAnonymousField(parent *namedType, fieldType ast.Expr) (fname string) {
fname, imp := baseTypeName(fieldType)
if parent == nil || imp {
}
// readValue processes a const or var declaration.
-//
func (r *reader) readValue(decl *ast.GenDecl) {
// determine if decl should be associated with a type
// Heuristic: For each typed entry, determine the type name, if any.
}
// fields returns a struct's fields or an interface's methods.
-//
func fields(typ ast.Expr) (list []*ast.Field, isStruct bool) {
var fields *ast.FieldList
switch t := typ.(type) {
}
// readType processes a type declaration.
-//
func (r *reader) readType(decl *ast.GenDecl, spec *ast.TypeSpec) {
typ := r.lookupType(spec.Name.Name)
if typ == nil {
}
// isPredeclared reports whether n denotes a predeclared type.
-//
func (r *reader) isPredeclared(n string) bool {
return predeclaredTypes[n] && r.types[n] == nil
}
// readFunc processes a func or method declaration.
-//
func (r *reader) readFunc(fun *ast.FuncDecl) {
// strip function body if requested.
if r.mode&PreserveAST == 0 {
)
// readNote collects a single note from a sequence of comments.
-//
func (r *reader) readNote(list []*ast.Comment) {
text := (&ast.CommentGroup{List: list}).Text()
if m := noteMarkerRx.FindStringSubmatchIndex(text); m != nil {
// and is followed by the note body (e.g., "// BUG(gri): fix this").
// The note ends at the end of the comment group or at the start of
// another note in the same comment group, whichever comes first.
-//
func (r *reader) readNotes(comments []*ast.CommentGroup) {
for _, group := range comments {
i := -1 // comment index of most recent note start, valid if >= 0
}
// readFile adds the AST for a source file to the reader.
-//
func (r *reader) readFile(src *ast.File) {
// add package documentation
if src.Doc != nil {
}
// collectEmbeddedMethods collects the embedded methods of typ in mset.
-//
func (r *reader) collectEmbeddedMethods(mset methodSet, typ *namedType, recvTypeName string, embeddedIsPtr bool, level int, visited embeddedSet) {
visited[typ] = true
for embedded, isPtr := range typ.embedded {
}
// computeMethodSets determines the actual method sets for each type encountered.
-//
func (r *reader) computeMethodSets() {
for _, t := range r.types {
// collect embedded methods for t
// types that have no declaration. Instead, these functions and methods
// are shown at the package level. It also removes types with missing
// declarations or which are not visible.
-//
func (r *reader) cleanupTypes() {
for _, t := range r.types {
visible := r.isVisible(t.name)
}
// sortingName returns the name to use when sorting d into place.
-//
func sortingName(d *ast.GenDecl) string {
if len(d.Specs) == 1 {
if s, ok := d.Specs[0].(*ast.ValueSpec); ok {
// noteBodies returns a list of note body strings given a list of notes.
// This is only used to populate the deprecated Package.Bugs field.
-//
func noteBodies(notes []*Note) []string {
var list []string
for _, n := range notes {
// firstSentenceLen returns the length of the first sentence in s.
// The sentence ends after the first period followed by space and
// not preceded by exactly one uppercase letter.
-//
func firstSentenceLen(s string) int {
var ppp, pp, p rune
for i, q := range s {
// has no \n, \r, or \t characters and uses only single spaces between
// words. If s starts with any of the IllegalPrefixes, the result
// is the empty string.
-//
func Synopsis(s string) string {
s = clean(s[0:firstSentenceLen(s)], 0)
for _, prefix := range IllegalPrefixes {
// 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
// 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
// ...
-//
func array1(buf *bytes.Buffer, n int) {
buf.WriteString("var _ = [...]byte{\n")
for i := 0; i < n; {
//
// The function may return early (before the entire result is written)
// and return a formatting error, for instance due to an incorrect AST.
-//
func Node(dst io.Writer, fset *token.FileSet, node any) error {
// Determine if we have a complete source file (file != nil).
var file *ast.File
// is applied to the result (such that it has the same leading and trailing
// space as src), and the result is indented by the same amount as the first
// line of src containing code. Imports are not sorted for partial source files.
-//
func Source(src []byte) ([]byte, error) {
fset := token.NewFileSet()
file, sourceAdj, indentAdj, err := parse(fset, "", src, true)
// getPkg returns the package for a given path. If the package is
// not found but we have a package name, create the package and
// add it to the p.imports map.
-//
func (p *parser) getPkg(pkgpath, name string) *types.Package {
// package unsafe is not in the imports map - handle explicitly
if pkgpath == "unsafe" {
// Type = "<" "type" ( "-" int | int [ TypeSpec ] ) ">" .
//
// parseType updates the type map to t for all type numbers n.
-//
func (p *parser) parseType(pkg *types.Package, n ...any) types.Type {
p.expect('<')
t, _ := p.parseTypeAfterAngle(pkg, n...)
// file by reading from it. The reader must be positioned at the
// start of the file before calling this function. The hdr result
// is the string before the export data, either "$$" or "$$B".
-//
func FindExportData(r *bufio.Reader) (hdr string, err error) {
// Read first line to make sure this is an object file.
line, err := r.ReadSlice('\n')
// the build.Default build.Context). A relative srcDir is interpreted
// relative to the current working directory.
// If no file was found, an empty filename is returned.
-//
func FindPkg(path, srcDir string) (filename, id string) {
if path == "" {
return
// Import imports a gc-generated package given its import path and srcDir, adds
// the corresponding package object to the packages map, and returns the object.
// The packages map must contain all packages already imported.
-//
func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
var rc io.ReadCloser
var id string
// The special form /* ERROR HERE "rx" */ must be used for error
// messages that appear immediately after a token, rather than at
// a token's position.
-//
var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`)
// expectedErrors collects the regular expressions of ERROR comments found
// in files and returns them as a map of error positions to error messages.
-//
func expectedErrors(fset *token.FileSet, filename string, src []byte) map[token.Pos]string {
errors := make(map[token.Pos]string)
// compareErrors compares the map of expected error messages with the list
// of found errors and reports discrepancies.
-//
func compareErrors(t *testing.T, fset *token.FileSet, expected map[token.Pos]string, found scanner.ErrorList) {
t.Helper()
for _, error := range found {
// If src != nil, readSource converts src to a []byte if possible;
// otherwise it returns an error. If src == nil, readSource returns
// the result of reading the file specified by filename.
-//
func readSource(filename string, src any) ([]byte, error) {
if src != nil {
switch s := src.(type) {
// A Mode value is a set of flags (or 0).
// They control the amount of source code parsed and other optional
// parser functionality.
-//
type Mode uint
const (
// errors were found, the result is a partial AST (with ast.Bad* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a scanner.ErrorList which is sorted by source position.
-//
func ParseFile(fset *token.FileSet, filename string, src any, mode Mode) (f *ast.File, err error) {
if fset == nil {
panic("parser.ParseFile: no token.FileSet provided (fset == nil)")
// If the directory couldn't be read, a nil map and the respective error are
// returned. If a parse error occurred, a non-nil but incomplete map and the
// first error encountered are returned.
-//
func ParseDir(fset *token.FileSet, path string, filter func(fs.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error) {
list, err := os.ReadDir(path)
if err != nil {
// errors were found, the result is a partial AST (with ast.Bad* nodes
// representing the fragments of erroneous source code). Multiple errors
// are returned via a scanner.ErrorList which is sorted by source position.
-//
func ParseExprFrom(fset *token.FileSet, filename string, src any, mode Mode) (expr ast.Expr, err error) {
if fset == nil {
panic("parser.ParseExprFrom: no token.FileSet provided (fset == nil)")
// If syntax errors were found, the result is a partial AST (with ast.Bad* nodes
// representing the fragments of erroneous source code). Multiple errors are
// returned via a scanner.ErrorList which is sorted by source position.
-//
func ParseExpr(x string) (ast.Expr, error) {
return ParseExprFrom(token.NewFileSet(), "", []byte(x), 0)
}
// comments list, and return it together with the line at which
// the last comment in the group ends. A non-comment token or n
// empty lines terminate a comment group.
-//
func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
var list []*ast.Comment
endline = p.file.Line(p.pos)
//
// Lead and line comments may be considered documentation that is
// stored in the AST.
-//
func (p *parser) next() {
p.leadComment = nil
p.lineComment = nil
// expectClosing is like expect but provides a better error message
// for the common case of a missing comma before a newline.
-//
func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
p.error(p.pos, "missing ',' before newline in "+context)
// token positions are invalid due to parse errors, the resulting end position
// may be past the file's EOF position, which would lead to panics if used
// later on.
-//
func (p *parser) safePos(pos token.Pos) (res token.Pos) {
defer func() {
if recover() != nil {
// parseOperand may return an expression or a raw type (incl. array
// types of the form [...]T. Callers must verify the result.
-//
func (p *parser) parseOperand() ast.Expr {
if p.trace {
defer un(trace(p, "Operand"))
// checkExprOrType checks that x is an expression or a type
// (and not a raw type such as [...]T).
-//
func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
switch t := unparen(x).(type) {
case *ast.ParenExpr:
// the object it denotes. If no object is found and collectUnresolved is
// set, x is marked as unresolved and collected in the list of unresolved
// identifiers.
-//
func (r *resolver) resolve(ident *ast.Ident, collectUnresolved bool) {
if ident.Obj != nil {
panic(r.sprintf("%v: identifier %s already declared or resolved", ident.Pos(), ident.Name))
// space taken up by them is not considered to reduce the number of
// linebreaks. At the moment there is no easy way to know about
// future (not yet interspersed) comments in this function.
-//
func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (nbreaks int) {
n := nlimit(line - p.pos.Line)
if n < min {
// 3) If there are no level 4 operators or no level 5 operators, then the
// cutoff is 6 (always use spaces) in Normal mode
// and 4 (never use spaces) in Compact mode.
-//
func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) {
prec := x.Op.Precedence()
if prec < prec1 {
// indentList reports whether an expression list would look better if it
// were indented wholesale (starting with the very first element, rather
// than starting at the first line break).
-//
func (p *printer) indentList(list []ast.Expr) bool {
// Heuristic: indentList reports whether there are more than one multi-
// line element in the list, or if there is any element that is not
// - V - V true column must be kept
// - - - - false
// - V V - false V is moved into T column
-//
func keepTypeColumn(specs []ast.Spec) []bool {
m := make([]bool, len(specs))
// The parameter n is the number of specs in the group. If doIndent is set,
// multi-line identifier lists in the spec are indented when the first
// linebreak is encountered.
-//
func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
switch s := spec.(type) {
case *ast.ImportSpec:
// The result is <= maxSize if the node fits on one line with at
// most maxSize chars and the formatted output doesn't contain
// any control chars. Otherwise, the result is > maxSize.
-//
func (p *printer) nodeSize(n ast.Node, maxSize int) (size int) {
// nodeSize invokes the printer, which may invoke nodeSize
// recursively. For deep composite literal nests, this can
// the block is printed on the current line, without line breaks, spaced from the header
// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
// lines for the block's statements and its closing "}".
-//
func (p *printer) funcBody(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
if b == nil {
return
// commentBefore reports whether the current comment group occurs
// before the next position in the source code and printing it does
// not introduce implicit semicolons.
-//
func (p *printer) commentBefore(next token.Position) bool {
return p.commentOffset < next.Offset && (!p.impliedSemi || !p.commentNewline)
}
// commentSizeBefore returns the estimated size of the
// comments on the same line before the next position.
-//
func (p *printer) commentSizeBefore(next token.Position) int {
// save/restore current p.commentInfo (p.nextComment() modifies it)
defer func(info commentInfo) {
// token in *linePtr. It is used to compute an accurate line number for a
// formatted construct, independent of pending (not yet emitted) whitespace
// or comments.
-//
func (p *printer) recordLine(linePtr *int) {
p.linePtr = linePtr
}
// output line and the line argument, ignoring any pending (not yet
// emitted) whitespace or comments. It is used to compute an accurate
// size (in number of lines) for a formatted construct.
-//
func (p *printer) linesFrom(line int) int {
return p.out.Line - line
}
// needed (i.e., when we don't know that s contains no tabs or line breaks)
// avoids processing extra escape characters and reduces run time of the
// printer benchmark by up to 10%.
-//
func (p *printer) writeString(pos token.Position, s string, isLit bool) {
if p.out.Column == 1 {
if p.Config.Mode&SourcePos != 0 {
// pos is the comment position, next the position of the item
// after all pending comments, prev is the previous comment in
// a group of comments (or nil), and tok is the next token.
-//
func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, tok token.Token) {
if len(p.output) == 0 {
// the comment is the first item to be printed - don't write any whitespace
// Returns true if s contains only white space
// (only tabs and blanks can appear in the printer's context).
-//
func isBlank(s string) bool {
for i := 0; i < len(s); i++ {
if s[i] > ' ' {
// The prefix is computed using heuristics such that is likely that the comment
// contents are nicely laid out after re-printing each line using the printer's
// current indentation.
-//
func stripCommonPrefix(lines []string) {
if len(lines) <= 1 {
return // at most one line - nothing to do
// pending whitespace. The writeCommentSuffix result indicates if a
// newline was written or if a formfeed was dropped from the whitespace
// buffer.
-//
func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, droppedFF bool) {
for i, ch := range p.wsbuf {
switch ch {
// that needs to be written before the next token). A heuristic is used to mix
// the comments and whitespace. The intersperseComments result indicates if a
// newline was written or if a formfeed was dropped from the whitespace buffer.
-//
func (p *printer) intersperseComments(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
var last *ast.Comment
for p.commentBefore(next) {
// taking into account the amount and structure of any pending white-
// space for best comment placement. Then, any leftover whitespace is
// printed, followed by the actual token.
-//
func (p *printer) print(args ...any) {
for _, arg := range args {
// information about the current arg
// before the position of the next token tok. The flush result indicates
// if a newline was written or if a formfeed was dropped from the whitespace
// buffer.
-//
func (p *printer) flush(next token.Position, tok token.Token) (wroteNewline, droppedFF bool) {
if p.commentBefore(next) {
// if there are comments before the next item, intersperse them
// and vtab characters into newlines and htabs (in case no tabwriter
// is used). Text bracketed by tabwriter.Escape characters is passed
// through unchanged.
-//
type trimmer struct {
output io.Writer
state int
// A CommentedNode bundles an AST node and corresponding comments.
// It may be provided as argument to any of the Fprint functions.
-//
type CommentedNode struct {
Node any // *ast.File, or ast.Expr, ast.Decl, ast.Spec, or ast.Stmt
Comments []*ast.CommentGroup
// Position information is interpreted relative to the file set fset.
// The node type must be *ast.File, *CommentedNode, []ast.Decl, []ast.Stmt,
// or assignment-compatible to ast.Expr, ast.Decl, ast.Spec, or ast.Stmt.
-//
func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node any) error {
return cfg.fprint(output, fset, node, make(map[ast.Node]int))
}
// It calls Config.Fprint with default settings.
// Note that gofmt uses tabs for indentation but spaces for alignment;
// use format.Node (package go/format) for output that matches gofmt.
-//
func Fprint(output io.Writer, fset *token.FileSet, node any) error {
return (&Config{Tabwidth: 8}).Fprint(output, fset, node)
}
// TestLineComments, using a simple test case, checks that consecutive line
// comments are properly terminated with a newline even if the AST position
// information is incorrect.
-//
func TestLineComments(t *testing.T) {
const src = `// comment 1
// comment 2
// The mode parameter to the Parse* functions is a set of flags (or 0).
// They control the amount of source code parsed and other optional
// parser functionality.
-//
const (
PackageClauseOnly uint = 1 << iota // parsing stops after package clause
ImportsOnly // parsing stops after import declarations
// comments list, and return it together with the line at which
// the last comment in the group ends. An empty line or non-comment
// token terminates a comment group.
-//
func (p *parser) consumeCommentGroup() (comments *ast.CommentGroup, endline int) {
var list []*ast.Comment
endline = p.file.Line(p.pos)
//
// Lead and line comments may be considered documentation that is
// stored in the AST.
-//
func (p *parser) next() {
p.leadComment = nil
p.lineComment = nil
// parseOperand may return an expression or a raw type (incl. array
// types of the form [...]T. Callers must verify the result.
// If lhs is set and the result is an identifier, it is not resolved.
-//
func (p *parser) parseOperand(lhs bool) ast.Expr {
if p.trace {
defer un(trace(p, "Operand"))
// checkExprOrType checks that x is an expression or a type
// (and not a raw type such as [...]T).
-//
func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
switch t := unparen(x).(type) {
case *ast.ParenExpr:
// The position Pos, if valid, points to the beginning of
// the offending token, and the error condition is described
// by Msg.
-//
type Error struct {
Pos token.Position
Msg string
// ErrorList is a list of *Errors.
// The zero value for an ErrorList is an empty ErrorList ready to use.
-//
type ErrorList []*Error
// Add adds an Error with given position and error message to an ErrorList.
// Sort sorts an ErrorList. *Error entries are sorted by position,
// other errors are sorted by error message, and before any *Error
// entry.
-//
func (p ErrorList) Sort() {
sort.Sort(p)
}
// PrintError is a utility function that prints a list of errors to w,
// one error per line, if the err parameter is an ErrorList. Otherwise
// it prints the err string.
-//
func PrintError(w io.Writer, err error) {
if list, ok := err.(ErrorList); ok {
for _, e := range list {
// encountered and a handler was installed, the handler is called with a
// position and an error message. The position points to the beginning of
// the offending token.
-//
type ErrorHandler func(pos token.Position, msg string)
// A Scanner holds the scanner's internal state while processing
// a given text. It can be allocated as part of another data
// structure but must be initialized via Init before use.
-//
type Scanner struct {
// immutable state
file *token.File // source file handle
// A mode value is a set of flags (or 0).
// They control scanner behavior.
-//
type Mode uint
const (
//
// Note that Init may call err if there is an error in the first character
// of the file.
-//
func (s *Scanner) Init(file *token.File, src []byte, err ErrorHandler, mode Mode) {
// Explicitly initialize all fields since a scanner may be reused.
if file.Size() != len(src) {
// Scan adds line information to the file added to the file
// set with Init. Token positions are relative to that file
// and thus relative to the file set.
-//
func (s *Scanner) Scan() (pos token.Pos, tok token.Token, lit string) {
scanAgain:
s.skipWhitespace()
// Position describes an arbitrary source position
// including the file, line, and column location.
// A Position is valid if the line number is > 0.
-//
type Position struct {
Filename string // filename, if any
Offset int // offset, starting at 0
// line valid position without file name and no column (column == 0)
// file invalid position with file name
// - invalid position without file name
-//
func (pos Position) String() string {
s := pos.Filename
if pos.IsValid() {
// equivalent to comparing the respective source file offsets. If p and q
// are in different files, p < q is true if the file implied by p was added
// to the respective file set before the file implied by q.
-//
type Pos int
// The zero value for Pos is NoPos; there is no file and line information
// associated with it, and NoPos.IsValid() is false. NoPos is always
// smaller than any other Pos value. The corresponding Position value
// for NoPos is the zero value for Position.
-//
const NoPos Pos = 0
// IsValid reports whether the position is valid.
// A File is a handle for a file belonging to a FileSet.
// A File has a name, size, and line offset table.
-//
type File struct {
set *FileSet
name string // file name as provided to AddFile
// AddLine adds the line offset for a new line.
// The line offset must be larger than the offset for the previous line
// and smaller than the file size; otherwise the line offset is ignored.
-//
func (f *File) AddLine(offset int) {
f.mutex.Lock()
if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
// the newline character at the end of the line with a space (to not change the
// remaining offsets). To obtain the line number, consult e.g. Position.Line.
// MergeLine will panic if given an invalid line number.
-//
func (f *File) MergeLine(line int) {
if line < 1 {
panic(fmt.Sprintf("invalid line number %d (should be >= 1)", line))
// and smaller than the file size; otherwise SetLines fails and returns
// false.
// Callers must not mutate the provided slice after SetLines returns.
-//
func (f *File) SetLines(lines []int) bool {
// verify validity of lines table
size := f.size
// AddLineInfo is like AddLineColumnInfo with a column = 1 argument.
// It is here for backward-compatibility for code prior to Go 1.11.
-//
func (f *File) AddLineInfo(offset int, filename string, line int) {
f.AddLineColumnInfo(offset, filename, line, 1)
}
//
// AddLineColumnInfo is typically used to register alternative position
// information for line directives such as //line filename:line:column.
-//
func (f *File) AddLineColumnInfo(offset int, filename string, line, column int) {
f.mutex.Lock()
if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
// Pos returns the Pos value for the given file offset;
// the offset must be <= f.Size().
// f.Pos(f.Offset(p)) == p.
-//
func (f *File) Pos(offset int) Pos {
if offset > f.size {
panic(fmt.Sprintf("invalid file offset %d (should be <= %d)", offset, f.size))
// Offset returns the offset for the given file position p;
// p must be a valid Pos value in that file.
// f.Offset(f.Pos(offset)) == offset.
-//
func (f *File) Offset(p Pos) int {
if int(p) < f.base || int(p) > f.base+f.size {
panic(fmt.Sprintf("invalid Pos value %d (should be in [%d, %d])", p, f.base, f.base+f.size))
// Line returns the line number for the given file position p;
// p must be a Pos value in that file or NoPos.
-//
func (f *File) Line(p Pos) int {
return f.Position(p).Line
}
// unpack returns the filename and line and column number for a file offset.
// If adjusted is set, unpack will return the filename and line information
// possibly adjusted by //line comments; otherwise those comments are ignored.
-//
func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
f.mutex.Lock()
defer f.mutex.Unlock()
// If adjusted is set, the position may be adjusted by position-altering
// //line comments; otherwise those comments are ignored.
// p must be a Pos value in f or NoPos.
-//
func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) {
if p != NoPos {
if int(p) < f.base || int(p) > f.base+f.size {
// Position returns the Position value for the given file position p.
// Calling f.Position(p) is equivalent to calling f.PositionFor(p, true).
-//
func (f *File) Position(p Pos) (pos Position) {
return f.PositionFor(p, true)
}
// recently added file, plus one. Unless there is a need to extend an
// interval later, using the FileSet.Base should be used as argument
// for FileSet.AddFile.
-//
type FileSet struct {
mutex sync.RWMutex // protects the file set
base int // base offset for the next file
// Base returns the minimum base offset that must be provided to
// AddFile when adding the next file.
-//
func (s *FileSet) Base() int {
s.mutex.RLock()
b := s.base
// with offs in the range [0, size] and thus p in the range [base, base+size].
// For convenience, File.Pos may be used to create file-specific position
// values from a file offset.
-//
func (s *FileSet) AddFile(filename string, base, size int) *File {
s.mutex.Lock()
defer s.mutex.Unlock()
// Iterate calls f for the files in the file set in the order they were added
// until f returns false.
-//
func (s *FileSet) Iterate(f func(*File) bool) {
for i := 0; ; i++ {
var file *File
// File returns the file that contains the position p.
// If no such file is found (for instance for p == NoPos),
// the result is nil.
-//
func (s *FileSet) File(p Pos) (f *File) {
if p != NoPos {
f = s.file(p)
// If adjusted is set, the position may be adjusted by position-altering
// //line comments; otherwise those comments are ignored.
// p must be a Pos value in s or NoPos.
-//
func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) {
if p != NoPos {
if f := s.file(p); f != nil {
// Position converts a Pos p in the fileset into a Position value.
// Calling s.Position(p) is equivalent to calling s.PositionFor(p, true).
-//
func (s *FileSet) Position(p Pos) (pos Position) {
return s.PositionFor(p, true)
}
// token character sequence (e.g., for the token ADD, the string is
// "+"). For all other tokens the string corresponds to the token
// constant name (e.g. for the token IDENT, the string is "IDENT").
-//
func (tok Token) String() string {
s := ""
if 0 <= tok && tok < Token(len(tokens)) {
// starting with precedence 1 up to unary operators. The highest
// precedence serves as "catch-all" precedence for selector,
// indexing, and other operator and delimiter tokens.
-//
const (
LowestPrec = 0 // non-operators
UnaryPrec = 6
// Precedence returns the operator precedence of the binary
// operator op. If op is not a binary operator, the result
// is LowestPrecedence.
-//
func (op Token) Precedence() int {
switch op {
case LOR:
}
// Lookup maps an identifier to its keyword token or IDENT (if not a keyword).
-//
func Lookup(ident string) Token {
if tok, is_keyword := keywords[ident]; is_keyword {
return tok
// IsLiteral returns true for tokens corresponding to identifiers
// and basic type literals; it returns false otherwise.
-//
func (tok Token) IsLiteral() bool { return literal_beg < tok && tok < literal_end }
// IsOperator returns true for tokens corresponding to operators and
// delimiters; it returns false otherwise.
-//
func (tok Token) IsOperator() bool {
return (operator_beg < tok && tok < operator_end) || tok == TILDE
}
// IsKeyword returns true for tokens corresponding to keywords;
// it returns false otherwise.
-//
func (tok Token) IsKeyword() bool { return keyword_beg < tok && tok < keyword_end }
// IsExported reports whether name starts with an upper-case letter.
-//
func IsExported(name string) bool {
ch, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(ch)
}
// IsKeyword reports whether name is a Go keyword, such as "func" or "return".
-//
func IsKeyword(name string) bool {
// TODO: opt: use a perfect hash function instead of a global map.
_, ok := keywords[name]
// IsIdentifier reports whether name is a Go identifier, that is, a non-empty
// string made up of letters, digits, and underscores, where the first character
// is not a digit. Keywords are not identifiers.
-//
func IsIdentifier(name string) bool {
if name == "" || IsKeyword(name) {
return false
// TypeOf returns the type of expression e, or nil if not found.
// Precondition: the Types, Uses and Defs maps are populated.
-//
func (info *Info) TypeOf(e ast.Expr) Type {
if t, ok := info.Types[e]; ok {
return t.Type
// it defines, not the type (*TypeName) it uses.
//
// Precondition: the Uses and Defs maps are populated.
-//
func (info *Info) ObjectOf(id *ast.Ident) Object {
if obj := info.Defs[id]; obj != nil {
return obj
// reports whether the call is valid, with *x holding the result;
// but x.expr is not set. If the call is invalid, the result is
// false, and *x is undefined.
-//
func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
// append is the only built-in that permits the use of ... for the last argument
bin := predeclaredFuncs[id]
// splitError splits an error's error message into a position string
// and the actual error message. If there's no position information,
// pos is the empty string, and msg is the entire error message.
-//
func splitError(err error) (pos, msg string) {
msg = err.Error()
if m := posMsgRx.FindStringSubmatch(msg); len(m) == 3 {
// Space around "rx" or rx is ignored. Use the form `ERROR HERE "rx"`
// for error messages that are located immediately after rather than
// at a token's position.
-//
var errRx = regexp.MustCompile(`^ *ERROR *(HERE)? *"?([^"]*)"?`)
// errMap collects the regular expressions of ERROR comments found
// functions ignore the context in which an expression is used (e.g., an
// assignment). Thus, top-level untyped constants will return an
// untyped type rather then the respective context-specific type.
-//
func CheckExpr(fset *token.FileSet, pkg *Package, pos token.Pos, expr ast.Expr, info *Info) (err error) {
// determine scope
var scope *Scope
// If hint != nil, it is the type of a composite literal element.
// If allowGeneric is set, the operand type may be an uninstantiated
// parameterized type or function value.
-//
func (check *Checker) rawExpr(x *operand, e ast.Expr, hint Type, allowGeneric bool) exprKind {
if trace {
check.trace(e.Pos(), "-- expr %s", e)
// exprInternal contains the core of type checking of expressions.
// Must only be called by rawExpr.
-//
func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
// make sure x has a valid state in case of bailout
// (was issue 5770)
// expr typechecks expression e and initializes x with the expression value.
// The result must be a single value.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) expr(x *operand, e ast.Expr) {
check.rawExpr(x, e, nil, false)
check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
// exprWithHint typechecks expression e and initializes x with the expression value;
// hint is the type of a composite literal element.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) exprWithHint(x *operand, e ast.Expr, hint Type) {
assert(hint != nil)
check.rawExpr(x, e, hint, false)
// If allowGeneric is set, the operand type may be an uninstantiated parameterized type or function
// value.
// If an error occurred, x.mode is set to invalid.
-//
func (check *Checker) exprOrType(x *operand, e ast.Expr, allowGeneric bool) {
check.rawExpr(x, e, nil, allowGeneric)
check.exclude(x, 1<<novalue)
// against the literal's element type (typ), and the element indices against
// the literal length if known (length >= 0). It returns the length of the
// literal (maximum index value + 1).
-//
func (check *Checker) indexedElts(elts []ast.Expr, typ Type, length int64) int64 {
visited := make(map[int64]bool, len(elts))
var index, max int64
// - If indirect is set, a method with a pointer receiver type was found
// but there was no pointer on the path from the actual receiver type to
// the method's formal receiver base type, nor was the receiver addressable.
-//
func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool) {
if T == nil {
panic("LookupFieldOrMethod on nil type")
// is not set), MissingMethod only checks that methods of T which are also
// present in V have matching types (e.g., for a type assertion x.(T) where
// x is of interface type V).
-//
func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool) {
m, alt := (*Checker)(nil).missingMethod(V, T, static)
// Only report a wrong type if the alternative method has the same name as m.
// An Object describes a named language entity such as a package,
// constant, type, variable, function (incl. methods), or label.
// All objects implement the Object interface.
-//
type Object interface {
Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
Pos() token.Pos // position of object identifier in declaration
// the operand, the operand's type, a value for constants, and an id
// for built-in functions.
// The zero value of operand is a ready to use invalid operand.
-//
type operand struct {
mode operandMode
expr ast.Expr
// Pos returns the position of the expression corresponding to x.
// If x is invalid the position is token.NoPos.
-//
func (x *operand) Pos() token.Pos {
// x.expr may not be set if x is invalid
if x.expr == nil {
//
// cgofunc <expr> (<untyped kind> <mode> )
// cgofunc <expr> ( <mode> of type <typ>)
-//
func operandString(x *operand, qf Qualifier) string {
// special-case nil
if x.mode == value && x.typ == Typ[UntypedNil] {
// p.x FieldVal T x int {0} true
// p.m MethodVal *T m func() {1, 0} true
// T.m MethodExpr T m func(T) {1, 0} false
-//
type Selection struct {
kind SelectionKind
recv Type // type of x
// "field (T) f int"
// "method (T) f(X) Y"
// "method expr (T) f(X) Y"
-//
func SelectionString(s *Selection, qf Qualifier) string {
var k string
switch s.kind {
// types are naturally aligned with a maximum alignment MaxAlign.
//
// *StdSizes implements Sizes.
-//
type StdSizes struct {
WordSize int64 // word size in bytes - must be >= 4 (32bits)
MaxAlign int64 // maximum alignment in bytes - must be >= 1
//
// Using a nil Qualifier is equivalent to using (*Package).Path: the
// object is qualified by the import path, e.g., "encoding/json.Marshal".
-//
type Qualifier func(*Package) string
// RelativeTo returns a Qualifier that fully qualifies members of
// 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse)
// T: &term{false, T} == {T} // set of type T
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
-//
type term struct {
tilde bool // valid if typ != nil
typ Type
// If an error occurred, x.mode is set to invalid.
// For the meaning of def, see Checker.definedType, below.
// If wantType is set, the identifier e is expected to denote a type.
-//
func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, wantType bool) {
x.mode = invalid
x.expr = e
// If def != nil, e is the type specification for the defined type def, declared
// in a type declaration, and def.underlying will be set to the type of e before
// any components of e are type-checked.
-//
func (check *Checker) definedType(e ast.Expr, def *Named) Type {
typ := check.typInternal(e, def)
assert(isTyped(typ))
// typInternal drives type checking of types.
// Must only be called by definedType or genericType.
-//
func (check *Checker) typInternal(e0 ast.Expr, def *Named) (T Type) {
if trace {
check.trace(e0.Pos(), "-- type %s", e0)
// Objects with names containing blanks are internal and not entered into
// a scope. Objects with exported names are inserted in the unsafe package
// scope; other objects are inserted in the universe scope.
-//
func def(obj Object) {
assert(obj.color() == black)
name := obj.Name()
// The operation returns the zero value for the map type's element.
// "missingkey=error"
// Execution stops immediately with an error.
-//
func (t *Template) Option(opt ...string) *Template {
t.text.Option(opt...)
return t
// Bytes returns the data over which the index was created.
// It must not be modified.
-//
func (x *Index) Bytes() []byte {
return x.data
}
// The result is nil if s is empty, s is not found, or n == 0.
// Lookup time is O(log(N)*len(s) + len(result)) where N is the
// size of the indexed data.
-//
func (x *Index) Lookup(s []byte, n int) (result []int) {
if len(s) > 0 && n != 0 {
matches := x.lookupAll(s)
// in successive order. Otherwise, at most n matches are returned and
// they may not be successive. The result is nil if there are no matches,
// or if n == 0.
-//
func (x *Index) FindAllIndex(r *regexp.Regexp, n int) (result [][]int) {
// a non-empty literal prefix is used to determine possible
// match start indices with Lookup
// Otherwise identical arrays compare by length.
// - interface values compare first by reflect.Type describing the concrete type
// and then by concrete value as described in the previous rules.
-//
func Sort(mapValue reflect.Value) *SortedMap {
if mapValue.Type().Kind() != reflect.Map {
return nil
// to bypass the directory read entirely.
// - If a directory read fails, the function is called a second time
// for that directory to report the error.
-//
type WalkDirFunc func(path string, d DirEntry, err error) error
// walkDir recursively descends path, calling walkDirFn.
// -1 if x < 0
// 0 if x is ±0
// +1 if x > 0
-//
func (x *Float) Sign() int {
if debugFloat {
x.validate()
// -1 if x < y
// 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
// +1 if x > y
-//
func (x *Float) Cmp(y *Float) int {
if debugFloat {
x.validate()
// 0 if x == 0 (signed or unsigned)
// +1 if 0 < x < +Inf
// +2 if x == +Inf
-//
func (x *Float) ord() int {
var m int
switch x.form {
// for p, q := uint64(0), uint64(1); p < q; p, q = q, q*5 {
// fmt.Println(q)
// }
-//
var pow5tab = [...]uint64{
1,
5,
//
// The returned *Float f is nil and the value of z is valid but not
// defined if an error is reported.
-//
func (z *Float) Parse(s string, base int) (f *Float, b int, err error) {
// scan doesn't handle ±Inf
if len(s) == 3 && (s == "Inf" || s == "inf") {
// -1 if x < 0
// 0 if x == 0
// +1 if x > 0
-//
func (x *Int) Sign() int {
if len(x.abs) == 0 {
return 0
//
// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.)
// See DivMod for Euclidean division and modulus (unlike Go).
-//
func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
// ACM press.)
// See QuoRem for T-division and modulus (like Go).
-//
func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
y0 := y // save y
if z == y || alias(z.abs, y.abs) {
// -1 if x < y
// 0 if x == y
// +1 if x > y
-//
func (x *Int) Cmp(y *Int) (r int) {
// x cmp y == x cmp y
// x cmp (-y) == x
// -1 if |x| < |y|
// 0 if |x| == |y|
// +1 if |x| > |y|
-//
func (x *Int) CmpAbs(y *Int) int {
return x.abs.cmp(y.abs)
}
// Incorrect placement of underscores is reported as an error if there
// are no other errors. If base != 0, underscores are not recognized
// and act like any other character that is not a valid digit.
-//
func (z *Int) SetString(s string, base int) (*Int, bool) {
return z.setFromScanner(strings.NewReader(s), base)
}
// specification of minimum digits precision, output field
// width, space or zero padding, and '-' for left or right
// justification.
-//
func (x *Int) Format(s fmt.State, ch rune) {
// determine base
var base int
// ``0b'' or ``0B'' selects base 2; a ``0'', ``0o'', or ``0O'' prefix selects
// base 8, and a ``0x'' or ``0X'' prefix selects base 16. Otherwise the selected
// base is 10.
-//
func (z *Int) scan(r io.ByteScanner, base int) (*Int, int, error) {
// determine sign
neg, err := scanSign(r)
// During arithmetic operations, denormalized values may occur but are
// always normalized before returning the final result. The normalized
// representation of 0 is the empty or nil slice (length = 0).
-//
type nat []Word
var (
// parsed. A digit count <= 0 indicates the presence of a period (if fracOk
// is set, only), and -count is the number of fractional digits found.
// In this case, the actual value of the scanned number is res * b**count.
-//
func (z nat) scan(r io.ByteScanner, base int, fracOk bool) (res nat, b, count int, err error) {
// reject invalid bases
baseOk := base == 0 ||
// range 2..64 shows that values of 8 and 16 work well, with a 4x speedup at medium lengths and
// ~30x for 20000 digits. Use nat_test.go's BenchmarkLeafSize tests to optimize leafSize for
// specific hardware.
-//
func (q nat) convertWords(s []byte, b Word, ndigits int, bb Word, table []divisor) {
// split larger blocks recursively
if table != nil {
// -1 if x < 0
// 0 if x == 0
// +1 if x > 0
-//
func (x *Rat) Sign() int {
return x.a.Sign()
}
// -1 if x < y
// 0 if x == y
// +1 if x > y
-//
func (x *Rat) Cmp(y *Rat) int {
var a, b Int
a.scaleDenom(&x.a, y.b.abs)
// callers can adjust the output using:
//
// sample = ExpFloat64() / desiredRateParameter
-//
func (r *Rand) ExpFloat64() float64 {
for {
j := r.Uint32()
// adjust the output using:
//
// sample = NormFloat64() * desiredStdDev + desiredMean
-//
func (r *Rand) NormFloat64() float64 {
for {
j := int32(r.Uint32()) // Possibly negative
// adjust the output using:
//
// sample = NormFloat64() * desiredStdDev + desiredMean
-//
func NormFloat64() float64 { return globalRand.NormFloat64() }
// ExpFloat64 returns an exponentially distributed float64 in the range
// callers can adjust the output using:
//
// sample = ExpFloat64() / desiredRateParameter
-//
func ExpFloat64() float64 { return globalRand.ExpFloat64() }
type lockedSource struct {
// with the expectation that the Jar will insert those mutated cookies
// with the updated values (assuming the origin matches).
// If Jar is nil, the initial cookies are forwarded without change.
-//
type Client struct {
// Transport specifies the mechanism by which individual
// HTTP requests are made.
// To use an fs.FS implementation, use http.FS to convert it:
//
// http.Handle("/", http.FileServer(http.FS(fsys)))
-//
func FileServer(root FileSystem) Handler {
return &fileHandler{root}
}
// socks5://proxy.com|https|foo.com socks5 to proxy, then https to foo.com
// https://proxy.com|https|foo.com https to proxy, then CONNECT to foo.com
// https://proxy.com|http https to proxy, http to anywhere after that
-//
type connectMethod struct {
_ incomparable
proxyURL *url.URL // nil for no proxy, else full proxy URL
// and the second will return "Line 2".
//
// Empty lines are never continued.
-//
func (r *Reader) ReadContinuedLine() (string, error) {
line, err := r.readContinuedLineSlice(noValidation)
return string(line), err
// If the response is multi-line, ReadCodeLine returns an error.
//
// An expectCode <= 0 disables the check of the status code.
-//
func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error) {
code, continued, message, err := r.readCodeLine(expectCode)
if err == nil && continued {
// the status is not in the range [310,319].
//
// An expectCode <= 0 disables the check of the status code.
-//
func (r *Reader) ReadResponse(expectCode int) (code int, message string, err error) {
code, continued, message, err := r.readCodeLine(expectCode)
multi := continued
// "My-Key": {"Value 1", "Value 2"},
// "Long-Key": {"Even Longer Value"},
// }
-//
func (r *Reader) ReadMIMEHeader() (MIMEHeader, error) {
// Avoid lots of small slice allocations later by allocating one
// large one ahead of time which we'll cut up into smaller
// return nil, err
// }
// return c.ReadCodeLine(250)
-//
func (c *Conn) Cmd(format string, args ...any) (id uint, err error) {
id = c.Next()
c.StartRequest(id)
//
// On Windows, escaping is disabled. Instead, '\\' is treated as
// path separator.
-//
func Match(pattern, name string) (matched bool, err error) {
Pattern:
for len(pattern) > 0 {
// Match requires pattern to match all of name, not just a substring.
// The only possible returned error is ErrBadPattern, when pattern
// is malformed.
-//
func Match(pattern, name string) (matched bool, err error) {
Pattern:
for len(pattern) > 0 {
// [false false false false]
// ...
// [true true true true]
-//
type exhaustive struct {
r *rand.Rand
pos int
//
// The Examples section of the documentation includes an illustration
// of how to use MakeFunc to build a swap function for different types.
-//
func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
if typ.Kind() != Func {
panic("reflect: call of MakeFunc with non-Func type")
// v := iter.Value()
// ...
// }
-//
func (v Value) MapRange() *MapIter {
v.mustBe(Map)
return &MapIter{m: v}
// Normally Chan's underlying value must be a channel and Send must be a zero Value.
// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
// When a receive operation is selected, the received Value is returned by Select.
-//
type SelectCase struct {
Dir SelectDir // direction of case
Chan Value // channel to use (for send or receive)
//
// At time of writing, re2-exhaustive.txt is 59 MB but compresses to 385 kB,
// so we store re2-exhaustive.txt.bz2 in the repository and decompress it on the fly.
-//
func TestRE2Search(t *testing.T) {
testRE2(t, "testdata/re2-search.txt")
}
// A(B(C|D)|EF)|BC(X|Y)
// which simplifies by character class introduction to
// A(B[CD]|EF)|BC[XY]
-//
func (p *parser) factor(sub []*Regexp) []*Regexp {
if len(sub) < 2 {
return sub
// } else {
// ... bar
// }
-//
func selectnbsend(c *hchan, elem unsafe.Pointer) (selected bool) {
return chansend(c, elem, false, getcallerpc())
}
// } else {
// ... bar
// }
-//
func selectnbrecv(elem unsafe.Pointer, c *hchan) (selected, received bool) {
return chanrecv(c, elem, false)
}
//
// gc Also known as cmd/compile.
// gccgo The gccgo front end, part of the GCC compiler suite.
-//
const Compiler = "gc"
//
// func semawakeup(mp *m)
// Wake up mp, which is or will soon be sleeping on its semaphore.
-//
const (
locked uintptr = 1
// The CPU profile is not available as a Profile. It has a special API,
// the StartCPUProfile and StopCPUProfile functions, because it streams
// output to a writer during profiling.
-//
type Profile struct {
name string
mu sync.Mutex
//
// Passing skip=0 begins the stack trace at the call to Add inside rpc.NewClient.
// Passing skip=1 begins the stack trace at the call to NewClient inside mypkg.Run.
-//
func (p *Profile) Add(value any, skip int) {
if p.name == "" {
panic("pprof: use of uninitialized Profile")
// if uint32(overflow) > 0 {
// emit entry for uint32(overflow), time
// }
-//
type profBuf struct {
// accessed atomically
r, w profAtomic
// Recommended usage is
//
// defer trace.StartRegion(ctx, "myTracedRegion").End()
-//
func StartRegion(ctx context.Context, regionType string) *Region {
if !IsEnabled() {
return noopRegion
// })
// fmt.Printf("Your number is %d.\n", answer)
// }
-//
func Search(n int, f func(int) bool) int {
// Define f(-1) == false and f(n) == true.
// Invariant: f(i-1) == false, f(j) == true.
// as specified by Search. The return value is the index to insert x if x is
// not present (it could be len(a)).
// The slice must be sorted in ascending order.
-//
func SearchInts(a []int, x int) int {
return Search(len(a), func(i int) bool { return a[i] >= x })
}
// as specified by Search. The return value is the index to insert x if x is not
// present (it could be len(a)).
// The slice must be sorted in ascending order.
-//
func SearchFloat64s(a []float64, x float64) int {
return Search(len(a), func(i int) bool { return a[i] >= x })
}
// as specified by Search. The return value is the index to insert x if x is not
// present (it could be len(a)).
// The slice must be sorted in ascending order.
-//
func SearchStrings(a []string, x string) int {
return Search(len(a), func(i int) bool { return a[i] >= x })
}
// log2 computes the binary logarithm of x, rounded up to the next integer.
// (log2(0) == 0, log2(1) == 0, log2(2) == 1, log2(3) == 2, etc.)
-//
func log2(x int) int {
n := 0
for p := 1; p < x; p += p {
// This implementation of Less places NaN values before any others, by using:
//
// x[i] < x[j] || (math.IsNaN(x[i]) && !math.IsNaN(x[j]))
-//
func (x Float64Slice) Less(i, j int) bool { return x[i] < x[j] || (isNaN(x[i]) && !isNaN(x[j])) }
func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
// set, the string is appended to dst and the resulting byte slice is
// returned as the first result value; otherwise the string is returned
// as the second result value.
-//
func formatBits(dst []byte, u uint64, base int, neg, append_ bool) (d []byte, s string) {
if base < 2 || base > len(digits) {
panic("strconv: illegal AppendInt/FormatInt base")
// }
// ... make use of condition ...
// c.L.Unlock()
-//
func (c *Cond) Wait() {
c.checker.check()
t := runtime_notifyListAdd(&c.notify)
//
// If f panics, Do considers it to have returned; future calls of Do return
// without calling f.
-//
func (o *Once) Do(f func()) {
// Note: Here is an incorrect implementation of Do:
//
// if err := fstest.TestFS(myFS, "file/that/should/be/present"); err != nil {
// t.Fatal(err)
// }
-//
func TestFS(fsys fs.FS, expected ...string) error {
if err := testFS(fsys, expected...); err != nil {
return err
//
// Use GoTokens to configure the Scanner such that it accepts all Go
// literal tokens including Go identifiers. Comments will be skipped.
-//
const (
ScanIdents = 1 << -Ident
ScanInts = 1 << -Int
// The text itself is stored in a separate buffer; cell only describes the
// segment's size in bytes, its width in runes, and whether it's an htab
// ('\t') terminated cell.
-//
type cell struct {
size int // cell size in bytes
width int // cell width in runes
// The Writer must buffer input internally, because proper spacing
// of one line may depend on the cells in future lines. Clients must
// call Flush when done calling Write.
-//
type Writer struct {
// configuration
output io.Writer
// (for correct-looking results, tabwidth must correspond
// to the tab width in the viewer displaying the result)
// flags formatting control
-//
func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer {
if minwidth < 0 || tabwidth < 0 || padding < 0 {
panic("negative minwidth, tabwidth, or padding")
// is the buffer position corresponding to the beginning of line0.
// Returns the buffer position corresponding to the beginning of
// line1 and an error, if any.
-//
func (b *Writer) format(pos0 int, line0, line1 int) (pos int) {
pos = pos0
column := len(b.widths)
// width one for formatting purposes.
//
// The value 0xff was chosen because it cannot appear in a valid UTF-8 sequence.
-//
const Escape = '\xff'
// Start escaped mode.
// is assumed to be zero for formatting purposes; if it was an HTML entity,
// its width is assumed to be one. In all other cases, the width is the
// unicode width of the text.
-//
func (b *Writer) endEscape() {
switch b.endChar {
case Escape:
// Terminate the current cell by adding it to the list of cells of the
// current line. Returns the number of cells in that line.
-//
func (b *Writer) terminateCell(htab bool) int {
b.cell.htab = htab
line := &b.lines[len(b.lines)-1]
// Write writes buf to the writer b.
// The only errors returned are ones encountered
// while writing to the underlying output stream.
-//
func (b *Writer) Write(buf []byte) (n int, err error) {
defer b.handlePanic(&err, "Write")
// NewWriter allocates and initializes a new tabwriter.Writer.
// The parameters are the same as for the Init function.
-//
func NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer {
return new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags)
}
// The operation returns the zero value for the map type's element.
// "missingkey=error"
// Execution stops immediately with an error.
-//
func (t *Template) Option(opt ...string) *Template {
t.init()
for _, s := range opt {
//
// Some valid layouts are invalid time values for time.Parse, due to formats
// such as _ for space padding and Z for zone information.
-//
const (
Layout = "01/02 03:04:05PM '06 -0700" // The reference time, in numerical order.
ANSIC = "Mon Jan _2 15:04:05 2006"
// to t == u, since t.Equal uses the most accurate comparison available and
// correctly handles the case when only one of its arguments has a monotonic
// clock reading.
-//
type Time struct {
// wall and ext encode the wall time seconds, wall time nanoseconds,
// and optional monotonic clock reading in nanoseconds.
// To convert an integer number of units to a Duration, multiply:
// seconds := 10
// fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
-//
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
// SimpleFold('1') = '1'
//
// SimpleFold(-2) = -2
-//
func SimpleFold(r rune) rune {
if r < 0 || r > MaxRune {
return r
// hdr.Data = uintptr(unsafe.Pointer(p))
// hdr.Len = n
// s := *(*string)(unsafe.Pointer(&hdr)) // p possibly already lost
-//
type Pointer *ArbitraryType
// Sizeof takes an expression x of any type and returns the size in bytes