$94 GRAYBYTE WORDPRESS FILE MANAGER $17

SERVER : vnpttt-amd7f72-h1.vietnix.vn #1 SMP Fri May 24 12:42:50 UTC 2024
SERVER IP : 103.200.23.149 | ADMIN IP 216.73.216.22
OPTIONS : CRL = ON | WGT = ON | SDO = OFF | PKEX = OFF
DEACTIVATED : NONE

/lib/golang/src/go/types/

HOME
Current File : /lib/golang/src/go/types//struct.go
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package types

import (
	"go/ast"
	"go/token"
	. "internal/types/errors"
	"strconv"
)

// ----------------------------------------------------------------------------
// API

// A Struct represents a struct type.
type Struct struct {
	fields []*Var   // fields != nil indicates the struct is set up (possibly with len(fields) == 0)
	tags   []string // field tags; nil if there are no tags
}

// NewStruct returns a new struct with the given fields and corresponding field tags.
// If a field with index i has a tag, tags[i] must be that tag, but len(tags) may be
// only as long as required to hold the tag with the largest index i. Consequently,
// if no field has a tag, tags may be nil.
func NewStruct(fields []*Var, tags []string) *Struct {
	var fset objset
	for _, f := range fields {
		if f.name != "_" && fset.insert(f) != nil {
			panic("multiple fields with the same name")
		}
	}
	if len(tags) > len(fields) {
		panic("more tags than fields")
	}
	s := &Struct{fields: fields, tags: tags}
	s.markComplete()
	return s
}

// NumFields returns the number of fields in the struct (including blank and embedded fields).
func (s *Struct) NumFields() int { return len(s.fields) }

// Field returns the i'th field for 0 <= i < NumFields().
func (s *Struct) Field(i int) *Var { return s.fields[i] }

// Tag returns the i'th field tag for 0 <= i < NumFields().
func (s *Struct) Tag(i int) string {
	if i < len(s.tags) {
		return s.tags[i]
	}
	return ""
}

func (t *Struct) Underlying() Type { return t }
func (t *Struct) String() string   { return TypeString(t, nil) }

// ----------------------------------------------------------------------------
// Implementation

func (s *Struct) markComplete() {
	if s.fields == nil {
		s.fields = make([]*Var, 0)
	}
}

func (check *Checker) structType(styp *Struct, e *ast.StructType) {
	list := e.Fields
	if list == nil {
		styp.markComplete()
		return
	}

	// struct fields and tags
	var fields []*Var
	var tags []string

	// for double-declaration checks
	var fset objset

	// current field typ and tag
	var typ Type
	var tag string
	add := func(ident *ast.Ident, embedded bool) {
		if tag != "" && tags == nil {
			tags = make([]string, len(fields))
		}
		if tags != nil {
			tags = append(tags, tag)
		}

		pos := ident.Pos()
		name := ident.Name
		fld := NewField(pos, check.pkg, name, typ, embedded)
		// spec: "Within a struct, non-blank field names must be unique."
		if name == "_" || check.declareInSet(&fset, pos, fld) {
			fields = append(fields, fld)
			check.recordDef(ident, fld)
		}
	}

	// addInvalid adds an embedded field of invalid type to the struct for
	// fields with errors; this keeps the number of struct fields in sync
	// with the source as long as the fields are _ or have different names
	// (go.dev/issue/25627).
	addInvalid := func(ident *ast.Ident) {
		typ = Typ[Invalid]
		tag = ""
		add(ident, true)
	}

	for _, f := range list.List {
		typ = check.varType(f.Type)
		tag = check.tag(f.Tag)
		if len(f.Names) > 0 {
			// named fields
			for _, name := range f.Names {
				add(name, false)
			}
		} else {
			// embedded field
			// spec: "An embedded type must be specified as a type name T or as a
			// pointer to a non-interface type name *T, and T itself may not be a
			// pointer type."
			pos := f.Type.Pos() // position of type, for errors
			name := embeddedFieldIdent(f.Type)
			if name == nil {
				check.errorf(f.Type, InvalidSyntaxTree, "embedded field type %s has no name", f.Type)
				name = ast.NewIdent("_")
				name.NamePos = pos
				addInvalid(name)
				continue
			}
			add(name, true) // struct{p.T} field has position of T

			// Because we have a name, typ must be of the form T or *T, where T is the name
			// of a (named or alias) type, and t (= deref(typ)) must be the type of T.
			// We must delay this check to the end because we don't want to instantiate
			// (via under(t)) a possibly incomplete type.

			// for use in the closure below
			embeddedTyp := typ
			embeddedPos := f.Type

			check.later(func() {
				t, isPtr := deref(embeddedTyp)
				switch u := under(t).(type) {
				case *Basic:
					if !isValid(t) {
						// error was reported before
						return
					}
					// unsafe.Pointer is treated like a regular pointer
					if u.kind == UnsafePointer {
						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be unsafe.Pointer")
					}
				case *Pointer:
					check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer")
				case *Interface:
					if isTypeParam(t) {
						// The error code here is inconsistent with other error codes for
						// invalid embedding, because this restriction may be relaxed in the
						// future, and so it did not warrant a new error code.
						check.error(embeddedPos, MisplacedTypeParam, "embedded field type cannot be a (pointer to a) type parameter")
						break
					}
					if isPtr {
						check.error(embeddedPos, InvalidPtrEmbed, "embedded field type cannot be a pointer to an interface")
					}
				}
			}).describef(embeddedPos, "check embedded type %s", embeddedTyp)
		}
	}

	styp.fields = fields
	styp.tags = tags
	styp.markComplete()
}

func embeddedFieldIdent(e ast.Expr) *ast.Ident {
	switch e := e.(type) {
	case *ast.Ident:
		return e
	case *ast.StarExpr:
		// *T is valid, but **T is not
		if _, ok := e.X.(*ast.StarExpr); !ok {
			return embeddedFieldIdent(e.X)
		}
	case *ast.SelectorExpr:
		return e.Sel
	case *ast.IndexExpr:
		return embeddedFieldIdent(e.X)
	case *ast.IndexListExpr:
		return embeddedFieldIdent(e.X)
	}
	return nil // invalid embedded field
}

func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool {
	if alt := oset.insert(obj); alt != nil {
		err := check.newError(DuplicateDecl)
		err.addf(atPos(pos), "%s redeclared", obj.Name())
		err.addAltDecl(alt)
		err.report()
		return false
	}
	return true
}

func (check *Checker) tag(t *ast.BasicLit) string {
	if t != nil {
		if t.Kind == token.STRING {
			if val, err := strconv.Unquote(t.Value); err == nil {
				return val
			}
		}
		check.errorf(t, InvalidSyntaxTree, "incorrect tag syntax: %q", t.Value)
	}
	return ""
}

Current_dir [ NOT WRITEABLE ] Document_root [ WRITEABLE ]


[ Back ]
NAME
SIZE
LAST TOUCH
USER
CAN-I?
FUNCTIONS
..
--
4 Dec 2025 6.06 PM
root / root
0755
README.md
0.133 KB
4 Dec 2025 6.06 PM
root / root
0644
alias.go
6.063 KB
4 Dec 2025 6.06 PM
root / root
0644
api.go
17.887 KB
4 Dec 2025 6.06 PM
root / root
0644
api_predicates.go
3.451 KB
4 Dec 2025 6.06 PM
root / root
0644
array.go
0.905 KB
4 Dec 2025 6.06 PM
root / root
0644
assignments.go
16.889 KB
4 Dec 2025 6.06 PM
root / root
0644
badlinkname.go
0.686 KB
4 Dec 2025 6.06 PM
root / root
0644
basic.go
1.605 KB
4 Dec 2025 6.06 PM
root / root
0644
builtins.go
29.413 KB
4 Dec 2025 6.06 PM
root / root
0644
call.go
33.833 KB
4 Dec 2025 6.06 PM
root / root
0644
chan.go
1.009 KB
4 Dec 2025 6.06 PM
root / root
0644
check.go
21.786 KB
4 Dec 2025 6.06 PM
root / root
0644
const.go
7.618 KB
4 Dec 2025 6.06 PM
root / root
0644
context.go
4.429 KB
4 Dec 2025 6.06 PM
root / root
0644
conversions.go
9.082 KB
4 Dec 2025 6.06 PM
root / root
0644
decl.go
31.035 KB
4 Dec 2025 6.06 PM
root / root
0644
errors.go
8.49 KB
4 Dec 2025 6.06 PM
root / root
0644
errsupport.go
4.528 KB
4 Dec 2025 6.06 PM
root / root
0644
eval.go
3.069 KB
4 Dec 2025 6.06 PM
root / root
0644
expr.go
39.407 KB
4 Dec 2025 6.06 PM
root / root
0644
exprstring.go
4.781 KB
4 Dec 2025 6.06 PM
root / root
0644
format.go
4.031 KB
4 Dec 2025 6.06 PM
root / root
0644
gccgosizes.go
1.143 KB
4 Dec 2025 6.06 PM
root / root
0644
gcsizes.go
4.357 KB
4 Dec 2025 6.06 PM
root / root
0644
generate.go
0.263 KB
4 Dec 2025 6.06 PM
root / root
0644
gotype.go
8.33 KB
4 Dec 2025 6.06 PM
root / root
0644
index.go
11.772 KB
4 Dec 2025 6.06 PM
root / root
0644
infer.go
27.142 KB
4 Dec 2025 6.06 PM
root / root
0644
initorder.go
10.131 KB
4 Dec 2025 6.06 PM
root / root
0644
instantiate.go
13.211 KB
4 Dec 2025 6.06 PM
root / root
0644
interface.go
8.155 KB
4 Dec 2025 6.06 PM
root / root
0644
iter.go
3.873 KB
4 Dec 2025 6.06 PM
root / root
0644
labels.go
7.295 KB
4 Dec 2025 6.06 PM
root / root
0644
literals.go
12.77 KB
4 Dec 2025 6.06 PM
root / root
0644
lookup.go
22.653 KB
4 Dec 2025 6.06 PM
root / root
0644
map.go
0.763 KB
4 Dec 2025 6.06 PM
root / root
0644
methodset.go
7.058 KB
4 Dec 2025 6.06 PM
root / root
0644
mono.go
9.194 KB
4 Dec 2025 6.06 PM
root / root
0644
named.go
24.34 KB
4 Dec 2025 6.06 PM
root / root
0644
object.go
22.06 KB
4 Dec 2025 6.06 PM
root / root
0644
objset.go
1.028 KB
4 Dec 2025 6.06 PM
root / root
0644
operand.go
12.16 KB
4 Dec 2025 6.06 PM
root / root
0644
package.go
3.05 KB
4 Dec 2025 6.06 PM
root / root
0644
pointer.go
0.743 KB
4 Dec 2025 6.06 PM
root / root
0644
predicates.go
17.609 KB
4 Dec 2025 6.06 PM
root / root
0644
range.go
9.338 KB
4 Dec 2025 6.06 PM
root / root
0644
recording.go
4.648 KB
4 Dec 2025 6.06 PM
root / root
0644
resolver.go
25.255 KB
4 Dec 2025 6.06 PM
root / root
0644
return.go
4.232 KB
4 Dec 2025 6.06 PM
root / root
0644
scope.go
7.632 KB
4 Dec 2025 6.06 PM
root / root
0644
scope2.go
2.554 KB
4 Dec 2025 6.06 PM
root / root
0644
selection.go
5.906 KB
4 Dec 2025 6.06 PM
root / root
0644
signature.go
17.81 KB
4 Dec 2025 6.06 PM
root / root
0644
sizes.go
8.939 KB
4 Dec 2025 6.06 PM
root / root
0644
slice.go
0.685 KB
4 Dec 2025 6.06 PM
root / root
0644
stmt.go
23.696 KB
4 Dec 2025 6.06 PM
root / root
0644
struct.go
6.149 KB
4 Dec 2025 6.06 PM
root / root
0644
subst.go
10.411 KB
4 Dec 2025 6.06 PM
root / root
0644
termlist.go
3.894 KB
4 Dec 2025 6.06 PM
root / root
0644
tuple.go
1.028 KB
4 Dec 2025 6.06 PM
root / root
0644
type.go
0.528 KB
4 Dec 2025 6.06 PM
root / root
0644
typelists.go
1.967 KB
4 Dec 2025 6.06 PM
root / root
0644
typeparam.go
5.224 KB
4 Dec 2025 6.06 PM
root / root
0644
typeset.go
13.31 KB
4 Dec 2025 6.06 PM
root / root
0644
typestring.go
12.479 KB
4 Dec 2025 6.06 PM
root / root
0644
typeterm.go
3.643 KB
4 Dec 2025 6.06 PM
root / root
0644
typexpr.go
16.179 KB
4 Dec 2025 6.06 PM
root / root
0644
under.go
4.331 KB
4 Dec 2025 6.06 PM
root / root
0644
unify.go
27.898 KB
4 Dec 2025 6.06 PM
root / root
0644
union.go
6.225 KB
4 Dec 2025 6.06 PM
root / root
0644
universe.go
9.354 KB
4 Dec 2025 6.06 PM
root / root
0644
util.go
1.9 KB
4 Dec 2025 6.06 PM
root / root
0644
validtype.go
10.345 KB
4 Dec 2025 6.06 PM
root / root
0644
version.go
2.036 KB
4 Dec 2025 6.06 PM
root / root
0644

GRAYBYTE WORDPRESS FILE MANAGER @ 2026 CONTACT ME
Static GIF