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
// 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

View File

@ -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

View File

@ -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")

View File

@ -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
}

View File

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

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

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

View File

@ -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

View File

@ -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