go.tools/go/types: use *Var instead of *Field for struct fields
Temporarily remove Field objects in favor of Vars for struct fields. In forthcoming CL, Fields will play the symmetric role to Methods, and serve as lookup results including index information. R=adonovan CC=golang-dev https://golang.org/cl/11594043
This commit is contained in:
parent
8a9eca10cd
commit
35f4fd1cd1
|
|
@ -76,7 +76,7 @@ type Config struct {
|
|||
// of the given struct fields, in bytes. Otherwise DefaultOffsetsof
|
||||
// is called. Offsetsof must implement the offset guarantees
|
||||
// required by the spec.
|
||||
Offsetsof func(fields []*Field) []int64
|
||||
Offsetsof func(fields []*Var) []int64
|
||||
|
||||
// If Sizeof != nil, it is called to determine the size of the
|
||||
// given type. Otherwise, DefaultSizeof is called. Sizeof must
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) {
|
|||
} else {
|
||||
// regular selector
|
||||
switch obj := obj.(type) {
|
||||
case *Field:
|
||||
case *Var:
|
||||
x.mode = variable
|
||||
x.typ = obj.typ
|
||||
|
||||
|
|
|
|||
|
|
@ -460,7 +460,7 @@ func (p *gcParser) parseName(materializePkg bool) (pkg *Package, name string) {
|
|||
|
||||
// Field = Name Type [ string_lit ] .
|
||||
//
|
||||
func (p *gcParser) parseField() (*Field, string) {
|
||||
func (p *gcParser) parseField() (*Var, string) {
|
||||
pkg, name := p.parseName(true)
|
||||
typ := p.parseType()
|
||||
anonymous := false
|
||||
|
|
@ -482,14 +482,14 @@ func (p *gcParser) parseField() (*Field, string) {
|
|||
if p.tok == scanner.String {
|
||||
tag = p.expect(scanner.String)
|
||||
}
|
||||
return NewField(token.NoPos, pkg, name, typ, anonymous), tag
|
||||
return NewFieldVar(token.NoPos, pkg, name, typ, anonymous), tag
|
||||
}
|
||||
|
||||
// StructType = "struct" "{" [ FieldList ] "}" .
|
||||
// FieldList = Field { ";" Field } .
|
||||
//
|
||||
func (p *gcParser) parseStructType() Type {
|
||||
var fields []*Field
|
||||
var fields []*Var
|
||||
var tags []string
|
||||
|
||||
p.expectKeyword("struct")
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ package types
|
|||
// indirectly via different packages.)
|
||||
|
||||
// LookupFieldOrMethod looks up a field or method with given package and name
|
||||
// in typ and returns the corresponding *Field or *Func, an index sequence,
|
||||
// in typ and returns the corresponding *Var or *Func, an index sequence,
|
||||
// and a bool indicating if there were any pointer indirections on the path
|
||||
// to the field or method.
|
||||
//
|
||||
|
|
@ -61,7 +61,7 @@ func LookupFieldOrMethod(typ Type, pkg *Package, name string) (obj Object, index
|
|||
// start the search with the underlying type *T
|
||||
if obj2, index2, indirect2 := lookupFieldOrMethod(u, pkg, name); obj2 != nil {
|
||||
// only if the result is a field can we keep it
|
||||
if _, ok := obj2.(*Field); ok {
|
||||
if _, ok := obj2.(*Var); ok {
|
||||
return obj2, index2, indirect2
|
||||
}
|
||||
}
|
||||
|
|
@ -293,7 +293,7 @@ func concat(list []int, i int) []int {
|
|||
}
|
||||
|
||||
// fieldIndex returns the index for the field with matching package and name, or a value < 0.
|
||||
func fieldIndex(fields []*Field, pkg *Package, name string) int {
|
||||
func fieldIndex(fields []*Var, pkg *Package, name string) int {
|
||||
if name == "_" {
|
||||
return -1 // blank identifiers are never found
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,12 +238,12 @@ func NewMethodSet(typ Type) *MethodSet {
|
|||
// A fieldSet is a set of fields and name collisions.
|
||||
// A collision indicates that multiple fields with the
|
||||
// same unique name appeared.
|
||||
type fieldSet map[string]*Field // a nil entry indicates a name collision
|
||||
type fieldSet map[string]*Var // a nil entry indicates a name collision
|
||||
|
||||
// Add adds field f to the field set s.
|
||||
// If multiples is set, f appears multiple times
|
||||
// and is treated as a collision.
|
||||
func (s fieldSet) add(f *Field, multiples bool) fieldSet {
|
||||
func (s fieldSet) add(f *Var, multiples bool) fieldSet {
|
||||
if s == nil {
|
||||
s = make(fieldSet)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,31 +156,24 @@ func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
|
|||
|
||||
func (obj *TypeName) String() string { return obj.toString("type", obj.typ.Underlying()) }
|
||||
|
||||
// A Variable represents a declared variable (including function parameters and results).
|
||||
// A Variable represents a declared variable (including function parameters and results, and struct fields).
|
||||
type Var struct {
|
||||
object
|
||||
|
||||
visited bool // for initialization cycle detection
|
||||
anonymous bool // if set, this variable is an anonymous struct field, and name is the type name
|
||||
visited bool // for initialization cycle detection
|
||||
}
|
||||
|
||||
func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
|
||||
return &Var{object{nil, pos, pkg, name, typ}, false}
|
||||
return &Var{object{nil, pos, pkg, name, typ}, false, false}
|
||||
}
|
||||
|
||||
func (obj *Var) String() string { return obj.toString("var", obj.typ) }
|
||||
|
||||
// A Field represents a struct field.
|
||||
type Field struct {
|
||||
object
|
||||
anonymous bool
|
||||
func NewFieldVar(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var {
|
||||
return &Var{object{nil, pos, pkg, name, typ}, anonymous, false}
|
||||
}
|
||||
|
||||
func NewField(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Field {
|
||||
return &Field{object{nil, pos, pkg, name, typ}, anonymous}
|
||||
}
|
||||
|
||||
func (obj *Field) String() string { return obj.toString("field", obj.typ) }
|
||||
func (obj *Field) Anonymous() bool { return obj.anonymous }
|
||||
func (obj *Var) Anonymous() bool { return obj.anonymous }
|
||||
func (obj *Var) String() string { return obj.toString("var", obj.typ) }
|
||||
|
||||
// A Func represents a declared function.
|
||||
type Func struct {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ func align(x, a int64) int64 {
|
|||
|
||||
// DefaultOffsetsof implements the default field offset computation
|
||||
// for unsafe.Offsetof. It is used if Config.Offsetsof == nil.
|
||||
func DefaultOffsetsof(fields []*Field) []int64 {
|
||||
func DefaultOffsetsof(fields []*Var) []int64 {
|
||||
offsets := make([]int64, len(fields))
|
||||
var o int64
|
||||
for i, f := range fields {
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ func (s *Slice) Elem() Type { return s.elt }
|
|||
|
||||
// A Struct represents a struct type.
|
||||
type Struct struct {
|
||||
fields []*Field
|
||||
fields []*Var
|
||||
tags []string // field tags; nil if there are no tags
|
||||
// TODO(gri) access to offsets is not threadsafe - fix this
|
||||
offsets []int64 // field offsets in bytes, lazily initialized
|
||||
|
|
@ -135,7 +135,7 @@ type Struct struct {
|
|||
// 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 []*Field, tags []string) *Struct {
|
||||
func NewStruct(fields []*Var, tags []string) *Struct {
|
||||
return &Struct{fields: fields, tags: tags}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +143,7 @@ func NewStruct(fields []*Field, tags []string) *Struct {
|
|||
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) *Field { return s.fields[i] }
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -395,7 +395,7 @@ func (check *checker) tag(t *ast.BasicLit) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields []*Field, tags []string) {
|
||||
func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields []*Var, tags []string) {
|
||||
if list == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -412,7 +412,7 @@ func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields [
|
|||
tags = append(tags, tag)
|
||||
}
|
||||
|
||||
fld := NewField(pos, check.pkg, name, typ, anonymous)
|
||||
fld := NewFieldVar(pos, check.pkg, name, typ, anonymous)
|
||||
check.declare(scope, ident, fld)
|
||||
fields = append(fields, fld)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ import (
|
|||
type anonFieldPath struct {
|
||||
tail *anonFieldPath
|
||||
index int // index of field within enclosing types.Struct.Fields
|
||||
field *types.Field
|
||||
field *types.Var
|
||||
}
|
||||
|
||||
func (p *anonFieldPath) contains(f *types.Field) bool {
|
||||
func (p *anonFieldPath) contains(f *types.Var) bool {
|
||||
for ; p != nil; p = p.tail {
|
||||
if p.field == f {
|
||||
return true
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ type I interface {
|
|||
}
|
||||
|
||||
type S struct {
|
||||
x int
|
||||
x int // x::nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
@ -73,7 +73,7 @@ func main() {
|
|||
print(v6) // v6::Const
|
||||
|
||||
var v7 S // v7::UnOp (load from Alloc)
|
||||
v7.x = 1 // &v7::Alloc
|
||||
v7.x = 1 // &v7::Alloc x::nil TODO(adonovan): do better for x
|
||||
|
||||
var v8 [1]int // v8::UnOp (load from Alloc)
|
||||
v8[0] = 0 // &v8::Alloc
|
||||
|
|
|
|||
Loading…
Reference in New Issue