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:
Robert Griesemer 2013-07-19 11:01:51 -07:00
parent 8a9eca10cd
commit 35f4fd1cd1
11 changed files with 28 additions and 35 deletions

View File

@ -76,7 +76,7 @@ type Config struct {
// of the given struct fields, in bytes. Otherwise DefaultOffsetsof // of the given struct fields, in bytes. Otherwise DefaultOffsetsof
// is called. Offsetsof must implement the offset guarantees // is called. Offsetsof must implement the offset guarantees
// required by the spec. // 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 // If Sizeof != nil, it is called to determine the size of the
// given type. Otherwise, DefaultSizeof is called. Sizeof must // given type. Otherwise, DefaultSizeof is called. Sizeof must

View File

@ -261,7 +261,7 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) {
} else { } else {
// regular selector // regular selector
switch obj := obj.(type) { switch obj := obj.(type) {
case *Field: case *Var:
x.mode = variable x.mode = variable
x.typ = obj.typ x.typ = obj.typ

View File

@ -460,7 +460,7 @@ func (p *gcParser) parseName(materializePkg bool) (pkg *Package, name string) {
// Field = Name Type [ string_lit ] . // Field = Name Type [ string_lit ] .
// //
func (p *gcParser) parseField() (*Field, string) { func (p *gcParser) parseField() (*Var, string) {
pkg, name := p.parseName(true) pkg, name := p.parseName(true)
typ := p.parseType() typ := p.parseType()
anonymous := false anonymous := false
@ -482,14 +482,14 @@ func (p *gcParser) parseField() (*Field, string) {
if p.tok == scanner.String { if p.tok == scanner.String {
tag = p.expect(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 ] "}" . // StructType = "struct" "{" [ FieldList ] "}" .
// FieldList = Field { ";" Field } . // FieldList = Field { ";" Field } .
// //
func (p *gcParser) parseStructType() Type { func (p *gcParser) parseStructType() Type {
var fields []*Field var fields []*Var
var tags []string var tags []string
p.expectKeyword("struct") p.expectKeyword("struct")

View File

@ -12,7 +12,7 @@ package types
// indirectly via different packages.) // indirectly via different packages.)
// LookupFieldOrMethod looks up a field or method with given package and name // 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 // and a bool indicating if there were any pointer indirections on the path
// to the field or method. // 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 // start the search with the underlying type *T
if obj2, index2, indirect2 := lookupFieldOrMethod(u, pkg, name); obj2 != nil { if obj2, index2, indirect2 := lookupFieldOrMethod(u, pkg, name); obj2 != nil {
// only if the result is a field can we keep it // 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 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. // 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 == "_" { if name == "_" {
return -1 // blank identifiers are never found return -1 // blank identifiers are never found
} }

View File

@ -238,12 +238,12 @@ func NewMethodSet(typ Type) *MethodSet {
// A fieldSet is a set of fields and name collisions. // A fieldSet is a set of fields and name collisions.
// A collision indicates that multiple fields with the // A collision indicates that multiple fields with the
// same unique name appeared. // 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. // Add adds field f to the field set s.
// If multiples is set, f appears multiple times // If multiples is set, f appears multiple times
// and is treated as a collision. // 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 { if s == nil {
s = make(fieldSet) s = make(fieldSet)
} }

View File

@ -156,32 +156,25 @@ func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
func (obj *TypeName) String() string { return obj.toString("type", obj.typ.Underlying()) } 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 { type Var struct {
object object
anonymous bool // if set, this variable is an anonymous struct field, and name is the type name
visited bool // for initialization cycle detection visited bool // for initialization cycle detection
} }
func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var { 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 NewFieldVar(pos token.Pos, pkg *Package, name string, typ Type, anonymous bool) *Var {
return &Var{object{nil, pos, pkg, name, typ}, anonymous, false}
}
func (obj *Var) Anonymous() bool { return obj.anonymous }
func (obj *Var) String() string { return obj.toString("var", obj.typ) } func (obj *Var) String() string { return obj.toString("var", obj.typ) }
// A Field represents a struct field.
type Field struct {
object
anonymous bool
}
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 }
// A Func represents a declared function. // A Func represents a declared function.
type Func struct { type Func struct {
object object

View File

@ -107,7 +107,7 @@ func align(x, a int64) int64 {
// DefaultOffsetsof implements the default field offset computation // DefaultOffsetsof implements the default field offset computation
// for unsafe.Offsetof. It is used if Config.Offsetsof == nil. // 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)) offsets := make([]int64, len(fields))
var o int64 var o int64
for i, f := range fields { for i, f := range fields {

View File

@ -124,7 +124,7 @@ func (s *Slice) Elem() Type { return s.elt }
// A Struct represents a struct type. // A Struct represents a struct type.
type Struct struct { type Struct struct {
fields []*Field fields []*Var
tags []string // field tags; nil if there are no tags tags []string // field tags; nil if there are no tags
// TODO(gri) access to offsets is not threadsafe - fix this // TODO(gri) access to offsets is not threadsafe - fix this
offsets []int64 // field offsets in bytes, lazily initialized 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 // 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, // 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. // 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} 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) } func (s *Struct) NumFields() int { return len(s.fields) }
// Field returns the i'th field for 0 <= i < NumFields(). // 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(). // Tag returns the i'th field tag for 0 <= i < NumFields().
func (s *Struct) Tag(i int) string { func (s *Struct) Tag(i int) string {

View File

@ -395,7 +395,7 @@ func (check *checker) tag(t *ast.BasicLit) string {
return "" 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 { if list == nil {
return return
} }
@ -412,7 +412,7 @@ func (check *checker) collectFields(list *ast.FieldList, cycleOk bool) (fields [
tags = append(tags, tag) 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) check.declare(scope, ident, fld)
fields = append(fields, fld) fields = append(fields, fld)
} }

View File

@ -27,10 +27,10 @@ import (
type anonFieldPath struct { type anonFieldPath struct {
tail *anonFieldPath tail *anonFieldPath
index int // index of field within enclosing types.Struct.Fields 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 { for ; p != nil; p = p.tail {
if p.field == f { if p.field == f {
return true return true

View File

@ -31,7 +31,7 @@ type I interface {
} }
type S struct { type S struct {
x int x int // x::nil
} }
func main() { func main() {
@ -73,7 +73,7 @@ func main() {
print(v6) // v6::Const print(v6) // v6::Const
var v7 S // v7::UnOp (load from Alloc) 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) var v8 [1]int // v8::UnOp (load from Alloc)
v8[0] = 0 // &v8::Alloc v8[0] = 0 // &v8::Alloc