mirror of
https://github.com/golang/go
synced 2024-11-23 10:00:03 -07:00
go/types: simplify method set computation
After fixing #37081 we don't need to explicitly keep track of field collisions in the method set computation anymore; we only need to know which field (names) exists at each embedding level. Simplify the code by removing the dedicated fieldSet data type in favor of a simple string set. Follow-up on https://golang.org/cl/218617; separate CL to make it easier to identify a problem with these two changes, should there be one. Updates #37081. Change-Id: I5c259c63c75a148a42d5c3e1e4860e1ffe5631bd Reviewed-on: https://go-review.googlesource.com/c/go/+/218618 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
ca3dd1d36b
commit
117297cf42
@ -99,8 +99,8 @@ func NewMethodSet(T Type) *MethodSet {
|
||||
for len(current) > 0 {
|
||||
var next []embeddedType // embedded types found at current depth
|
||||
|
||||
// field and method sets at current depth, allocated lazily
|
||||
var fset fieldSet
|
||||
// field and method sets at current depth, indexed by names (Id's), and allocated lazily
|
||||
var fset map[string]bool // we only care about the field names
|
||||
var mset methodSet
|
||||
|
||||
for _, e := range current {
|
||||
@ -131,7 +131,10 @@ func NewMethodSet(T Type) *MethodSet {
|
||||
switch t := typ.(type) {
|
||||
case *Struct:
|
||||
for i, f := range t.fields {
|
||||
fset = fset.add(f, e.multiples)
|
||||
if fset == nil {
|
||||
fset = make(map[string]bool)
|
||||
}
|
||||
fset[f.Id()] = true
|
||||
|
||||
// Embedded fields are always of the form T or *T where
|
||||
// T is a type name. If typ appeared multiple times at
|
||||
@ -156,7 +159,7 @@ func NewMethodSet(T Type) *MethodSet {
|
||||
for k, m := range mset {
|
||||
if _, found := base[k]; !found {
|
||||
// Fields collide with methods of the same name at this depth.
|
||||
if _, found := fset[k]; found {
|
||||
if fset[k] {
|
||||
m = nil // collision
|
||||
}
|
||||
if base == nil {
|
||||
@ -166,9 +169,8 @@ func NewMethodSet(T Type) *MethodSet {
|
||||
}
|
||||
}
|
||||
|
||||
// Add all fields at this depth as collisions (since they will hide any
|
||||
// method further down) to base if no entries with matching names exist
|
||||
// already.
|
||||
// Add all (remaining) fields at this depth as collisions (since they will
|
||||
// hide any method further down) if no entries with matching names exist already.
|
||||
for k := range fset {
|
||||
if _, found := base[k]; !found {
|
||||
if base == nil {
|
||||
@ -205,30 +207,6 @@ func NewMethodSet(T Type) *MethodSet {
|
||||
return &MethodSet{list}
|
||||
}
|
||||
|
||||
// A fieldSet is a set of fields and name collisions.
|
||||
// A collision indicates that multiple fields with the
|
||||
// same unique id appeared.
|
||||
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 *Var, multiples bool) fieldSet {
|
||||
if s == nil {
|
||||
s = make(fieldSet)
|
||||
}
|
||||
key := f.Id()
|
||||
// if f is not in the set, add it
|
||||
if !multiples {
|
||||
if _, found := s[key]; !found {
|
||||
s[key] = f
|
||||
return s
|
||||
}
|
||||
}
|
||||
s[key] = nil // collision
|
||||
return s
|
||||
}
|
||||
|
||||
// A methodSet is a set of methods and name collisions.
|
||||
// A collision indicates that multiple methods with the
|
||||
// same unique id, or a field with that id appeared.
|
||||
|
Loading…
Reference in New Issue
Block a user