From 35f4fd1cd17cc072cd94ac35d5eea0753a4f3ba3 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 19 Jul 2013 11:01:51 -0700 Subject: [PATCH] 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 --- go/types/api.go | 2 +- go/types/call.go | 2 +- go/types/gcimporter.go | 6 +++--- go/types/lookup.go | 6 +++--- go/types/methodset.go | 4 ++-- go/types/objects.go | 23 ++++++++--------------- go/types/sizes.go | 2 +- go/types/types.go | 6 +++--- go/types/typexpr.go | 4 ++-- ssa/promote.go | 4 ++-- ssa/testdata/objlookup.go | 4 ++-- 11 files changed, 28 insertions(+), 35 deletions(-) diff --git a/go/types/api.go b/go/types/api.go index 9d34474da1..d87a98cf89 100644 --- a/go/types/api.go +++ b/go/types/api.go @@ -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 diff --git a/go/types/call.go b/go/types/call.go index b92ca25ae3..8d81d7056c 100644 --- a/go/types/call.go +++ b/go/types/call.go @@ -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 diff --git a/go/types/gcimporter.go b/go/types/gcimporter.go index 7a06f6a869..5c95fa6470 100644 --- a/go/types/gcimporter.go +++ b/go/types/gcimporter.go @@ -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") diff --git a/go/types/lookup.go b/go/types/lookup.go index 296745bca7..bd523dd070 100644 --- a/go/types/lookup.go +++ b/go/types/lookup.go @@ -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 } diff --git a/go/types/methodset.go b/go/types/methodset.go index 783450cc37..9777c1bfe7 100644 --- a/go/types/methodset.go +++ b/go/types/methodset.go @@ -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) } diff --git a/go/types/objects.go b/go/types/objects.go index a188c97143..a1eb03fe91 100644 --- a/go/types/objects.go +++ b/go/types/objects.go @@ -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 { diff --git a/go/types/sizes.go b/go/types/sizes.go index 90cb832c55..ada1cfb4ff 100644 --- a/go/types/sizes.go +++ b/go/types/sizes.go @@ -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 { diff --git a/go/types/types.go b/go/types/types.go index 4b1f433795..0a459d218c 100644 --- a/go/types/types.go +++ b/go/types/types.go @@ -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 { diff --git a/go/types/typexpr.go b/go/types/typexpr.go index 1ed83680d5..345e80cb94 100644 --- a/go/types/typexpr.go +++ b/go/types/typexpr.go @@ -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) } diff --git a/ssa/promote.go b/ssa/promote.go index 7e49cdf208..f287f7eafc 100644 --- a/ssa/promote.go +++ b/ssa/promote.go @@ -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 diff --git a/ssa/testdata/objlookup.go b/ssa/testdata/objlookup.go index 560c30df42..f8230e83c7 100644 --- a/ssa/testdata/objlookup.go +++ b/ssa/testdata/objlookup.go @@ -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