all: use reflect.TypeFor now available in Go 1.22 (#11078)

Updates #cleanup

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This commit is contained in:
Joe Tsai 2024-02-08 17:34:22 -08:00 committed by GitHub
parent efddad7d7d
commit 94a4f701c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 31 additions and 38 deletions

View File

@ -802,7 +802,7 @@ func TestPrefFlagMapping(t *testing.T) {
}
}
prefType := reflect.TypeOf(ipn.Prefs{})
prefType := reflect.TypeFor[ipn.Prefs]()
for i := 0; i < prefType.NumField(); i++ {
prefName := prefType.Field(i).Name
if prefHasFlag[prefName] {

View File

@ -726,7 +726,7 @@ func init() {
func addPrefFlagMapping(flagName string, prefNames ...string) {
prefsOfFlag[flagName] = prefNames
prefType := reflect.TypeOf(ipn.Prefs{})
prefType := reflect.TypeFor[ipn.Prefs]()
for _, pref := range prefNames {
t := prefType
for _, name := range strings.Split(pref, ".") {

View File

@ -20,7 +20,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
func TestStatusEqual(t *testing.T) {
// Verify that the Equal method stays in sync with reality
equalHandles := []string{"Err", "URL", "NetMap", "Persist", "state"}
if have := fieldsOf(reflect.TypeOf(Status{})); !reflect.DeepEqual(have, equalHandles) {
if have := fieldsOf(reflect.TypeFor[Status]()); !reflect.DeepEqual(have, equalHandles) {
t.Errorf("Status.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, equalHandles)
}

View File

@ -538,7 +538,7 @@ var nodeFields = sync.OnceValue(getNodeFields)
// getNodeFields returns the fails of tailcfg.Node.
func getNodeFields() []string {
rt := reflect.TypeOf((*tailcfg.Node)(nil)).Elem()
rt := reflect.TypeFor[tailcfg.Node]()
ret := make([]string, rt.NumField())
for i := 0; i < rt.NumField(); i++ {
ret[i] = rt.Field(i).Name

View File

@ -15,7 +15,7 @@ func TestAsDebugJSON(t *testing.T) {
}
k := new(Knobs)
got := k.AsDebugJSON()
if want := reflect.TypeOf(Knobs{}).NumField(); len(got) != want {
if want := reflect.TypeFor[Knobs]().NumField(); len(got) != want {
t.Errorf("AsDebugJSON map has %d fields; want %v", len(got), want)
}
}

View File

@ -64,7 +64,7 @@ func TestPrefsEqual(t *testing.T) {
"NetfilterKind",
"Persist",
}
if have := fieldsOf(reflect.TypeOf(Prefs{})); !reflect.DeepEqual(have, prefsHandles) {
if have := fieldsOf(reflect.TypeFor[Prefs]()); !reflect.DeepEqual(have, prefsHandles) {
t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, prefsHandles)
}
@ -615,14 +615,14 @@ func TestLoadPrefsFileWithZeroInIt(t *testing.T) {
func TestMaskedPrefsFields(t *testing.T) {
have := map[string]bool{}
for _, f := range fieldsOf(reflect.TypeOf(Prefs{})) {
for _, f := range fieldsOf(reflect.TypeFor[Prefs]()) {
if f == "Persist" {
// This one can't be edited.
continue
}
have[f] = true
}
for _, f := range fieldsOf(reflect.TypeOf(MaskedPrefs{})) {
for _, f := range fieldsOf(reflect.TypeFor[MaskedPrefs]()) {
if f == "Prefs" {
continue
}
@ -644,8 +644,8 @@ func TestMaskedPrefsFields(t *testing.T) {
// And also make sure they line up in the right order, which
// ApplyEdits assumes.
pt := reflect.TypeOf(Prefs{})
mt := reflect.TypeOf(MaskedPrefs{})
pt := reflect.TypeFor[Prefs]()
mt := reflect.TypeFor[MaskedPrefs]()
for i := 0; i < mt.NumField(); i++ {
name := mt.Field(i).Name
if i == 0 {

View File

@ -1154,7 +1154,7 @@ func TestPathFromPAMEnvLineOnNixOS(t *testing.T) {
}
func TestStdOsUserUserAssumptions(t *testing.T) {
v := reflect.TypeOf(user.User{})
v := reflect.TypeFor[user.User]()
if got, want := v.NumField(), 5; got != want {
t.Errorf("os/user.User has %v fields; this package assumes %v", got, want)
}

View File

@ -67,7 +67,7 @@ func TestHostinfoEqual(t *testing.T) {
"AppConnector",
"Location",
}
if have := fieldsOf(reflect.TypeOf(Hostinfo{})); !reflect.DeepEqual(have, hiHandles) {
if have := fieldsOf(reflect.TypeFor[Hostinfo]()); !reflect.DeepEqual(have, hiHandles) {
t.Errorf("Hostinfo.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, hiHandles)
}
@ -364,7 +364,7 @@ func TestNodeEqual(t *testing.T) {
"DataPlaneAuditLogID", "Expired", "SelfNodeV4MasqAddrForThisPeer",
"SelfNodeV6MasqAddrForThisPeer", "IsWireGuardOnly", "ExitNodeDNSResolvers",
}
if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) {
if have := fieldsOf(reflect.TypeFor[Node]()); !reflect.DeepEqual(have, nodeHandles) {
t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, nodeHandles)
}
@ -632,7 +632,7 @@ func TestNetInfoFields(t *testing.T) {
"DERPLatency",
"FirewallMode",
}
if have := fieldsOf(reflect.TypeOf(NetInfo{})); !reflect.DeepEqual(have, handled) {
if have := fieldsOf(reflect.TypeFor[NetInfo]()); !reflect.DeepEqual(have, handled) {
t.Errorf("NetInfo.Clone/BasicallyEqually check might be out of sync\nfields: %q\nhandled: %q\n",
have, handled)
}

View File

@ -13,7 +13,7 @@ import (
func TestResolverEqual(t *testing.T) {
var fieldNames []string
for _, field := range reflect.VisibleFields(reflect.TypeOf(Resolver{})) {
for _, field := range reflect.VisibleFields(reflect.TypeFor[Resolver]()) {
fieldNames = append(fieldNames, field.Name)
}
sort.Strings(fieldNames)

View File

@ -72,7 +72,7 @@ func (m NodeMutationLastSeen) Apply(n *tailcfg.Node) {
var peerChangeFields = sync.OnceValue(func() []reflect.StructField {
var fields []reflect.StructField
rt := reflect.TypeOf((*tailcfg.PeerChange)(nil)).Elem()
rt := reflect.TypeFor[tailcfg.PeerChange]()
for i := 0; i < rt.NumField(); i++ {
fields = append(fields, rt.Field(i))
}

View File

@ -27,7 +27,7 @@ func TestMapResponseContainsNonPatchFields(t *testing.T) {
case reflect.Bool:
return reflect.ValueOf(true)
case reflect.String:
if reflect.TypeOf(opt.Bool("")) == t {
if reflect.TypeFor[opt.Bool]() == t {
return reflect.ValueOf("true").Convert(t)
}
return reflect.ValueOf("foo").Convert(t)
@ -43,7 +43,7 @@ func TestMapResponseContainsNonPatchFields(t *testing.T) {
panic(fmt.Sprintf("unhandled %v", t))
}
rt := reflect.TypeOf(tailcfg.MapResponse{})
rt := reflect.TypeFor[tailcfg.MapResponse]()
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)

View File

@ -22,7 +22,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
func TestPersistEqual(t *testing.T) {
persistHandles := []string{"LegacyFrontendPrivateMachineKey", "PrivateNodeKey", "OldPrivateNodeKey", "Provider", "UserProfile", "NetworkLockKey", "NodeID", "DisallowedTKAStateIDs"}
if have := fieldsOf(reflect.TypeOf(Persist{})); !reflect.DeepEqual(have, persistHandles) {
if have := fieldsOf(reflect.TypeFor[Persist]()); !reflect.DeepEqual(have, persistHandles) {
t.Errorf("Persist.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
have, persistHandles)
}

View File

@ -24,11 +24,6 @@ import (
"reflect"
)
// TODO(https://go.dev/issue/60088): Use reflect.TypeFor instead.
func reflectTypeFor[T any]() reflect.Type {
return reflect.TypeOf((*T)(nil)).Elem()
}
// Key is a generic key type associated with a specific value type.
//
// A zero Key is valid where the Value type itself is used as the context key.
@ -65,7 +60,7 @@ func New[Value any](name string, defaultValue Value) Key[Value] {
// since newly allocated pointers are globally unique within a process.
key := Key[Value]{name: new(stringer[string])}
if name == "" {
name = reflectTypeFor[Value]().String()
name = reflect.TypeFor[Value]().String()
}
key.name.v = name
if v := reflect.ValueOf(defaultValue); v.IsValid() && !v.IsZero() {
@ -78,7 +73,7 @@ func New[Value any](name string, defaultValue Value) Key[Value] {
func (key Key[Value]) contextKey() any {
if key.name == nil {
// Use the reflect.Type of the Value (implies key not created by New).
return reflectTypeFor[Value]()
return reflect.TypeFor[Value]()
} else {
// Use the name pointer directly (implies key created by New).
return key.name
@ -119,7 +114,7 @@ func (key Key[Value]) Has(ctx context.Context) (ok bool) {
// String returns the name of the key.
func (key Key[Value]) String() string {
if key.name == nil {
return reflectTypeFor[Value]().String()
return reflect.TypeFor[Value]().String()
}
return key.name.String()
}

View File

@ -248,7 +248,7 @@ func Hash[T any](v *T) Sum {
// Always treat the Hash input as if it were an interface by including
// a hash of the type. This ensures that hashing of two different types
// but with the same value structure produces different hashes.
t := reflect.TypeOf(v).Elem()
t := reflect.TypeFor[T]()
h.hashType(t)
if v == nil {
h.HashUint8(0) // indicates nil
@ -300,8 +300,7 @@ func ExcludeFields[T any](fields ...string) Option {
}
func newFieldFilter[T any](include bool, fields []string) Option {
var zero T
t := reflect.TypeOf(&zero).Elem()
t := reflect.TypeFor[T]()
fieldSet := set.Set[string]{}
for _, f := range fields {
if _, ok := t.FieldByName(f); !ok {
@ -321,12 +320,11 @@ func newFieldFilter[T any](include bool, fields []string) Option {
// be removed in the future, along with documentation about their precedence
// when combined.
func HasherForType[T any](opts ...Option) func(*T) Sum {
var v *T
seedOnce.Do(initSeed)
if len(opts) > 1 {
panic("HasherForType only accepts one optional argument") // for now
}
t := reflect.TypeOf(v).Elem()
t := reflect.TypeFor[T]()
var hash typeHasherFunc
for _, o := range opts {
switch o := o.(type) {

View File

@ -823,7 +823,7 @@ func TestHashMapAcyclic(t *testing.T) {
hb := &hashBuffer{Hash: sha256.New()}
hash := lookupTypeHasher(reflect.TypeOf(m))
hash := lookupTypeHasher(reflect.TypeFor[map[int]string]())
for i := 0; i < 20; i++ {
va := reflect.ValueOf(&m).Elem()
hb.Reset()

View File

@ -10,9 +10,9 @@ import (
)
var (
timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
netipAddrType = reflect.TypeOf((*netip.Addr)(nil)).Elem()
selfHasherType = reflect.TypeOf((*SelfHasher)(nil)).Elem()
timeTimeType = reflect.TypeFor[time.Time]()
netipAddrType = reflect.TypeFor[netip.Addr]()
selfHasherType = reflect.TypeFor[SelfHasher]()
)
// typeIsSpecialized reports whether this type has specialized hashing.

View File

@ -26,7 +26,7 @@ func TestConfigEqual(t *testing.T) {
"SubnetRoutes", "SNATSubnetRoutes", "NetfilterMode",
"NetfilterKind",
}
configType := reflect.TypeOf(Config{})
configType := reflect.TypeFor[Config]()
configFields := []string{}
for i := 0; i < configType.NumField(); i++ {
configFields = append(configFields, configType.Field(i).Name)

View File

@ -20,7 +20,7 @@ var (
)
func getPeerStatsOffset(name string) uintptr {
peerType := reflect.TypeOf(device.Peer{})
peerType := reflect.TypeFor[device.Peer]()
field, ok := peerType.FieldByName(name)
if !ok {
panic("no " + name + " field in device.Peer")