mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-25 11:05:45 +00:00
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:
parent
efddad7d7d
commit
94a4f701c2
@ -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++ {
|
for i := 0; i < prefType.NumField(); i++ {
|
||||||
prefName := prefType.Field(i).Name
|
prefName := prefType.Field(i).Name
|
||||||
if prefHasFlag[prefName] {
|
if prefHasFlag[prefName] {
|
||||||
|
@ -726,7 +726,7 @@ func init() {
|
|||||||
|
|
||||||
func addPrefFlagMapping(flagName string, prefNames ...string) {
|
func addPrefFlagMapping(flagName string, prefNames ...string) {
|
||||||
prefsOfFlag[flagName] = prefNames
|
prefsOfFlag[flagName] = prefNames
|
||||||
prefType := reflect.TypeOf(ipn.Prefs{})
|
prefType := reflect.TypeFor[ipn.Prefs]()
|
||||||
for _, pref := range prefNames {
|
for _, pref := range prefNames {
|
||||||
t := prefType
|
t := prefType
|
||||||
for _, name := range strings.Split(pref, ".") {
|
for _, name := range strings.Split(pref, ".") {
|
||||||
|
@ -20,7 +20,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
|
|||||||
func TestStatusEqual(t *testing.T) {
|
func TestStatusEqual(t *testing.T) {
|
||||||
// Verify that the Equal method stays in sync with reality
|
// Verify that the Equal method stays in sync with reality
|
||||||
equalHandles := []string{"Err", "URL", "NetMap", "Persist", "state"}
|
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",
|
t.Errorf("Status.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, equalHandles)
|
have, equalHandles)
|
||||||
}
|
}
|
||||||
|
@ -538,7 +538,7 @@ func (ms *mapSession) patchifyPeersChanged(resp *tailcfg.MapResponse) {
|
|||||||
|
|
||||||
// getNodeFields returns the fails of tailcfg.Node.
|
// getNodeFields returns the fails of tailcfg.Node.
|
||||||
func getNodeFields() []string {
|
func getNodeFields() []string {
|
||||||
rt := reflect.TypeOf((*tailcfg.Node)(nil)).Elem()
|
rt := reflect.TypeFor[tailcfg.Node]()
|
||||||
ret := make([]string, rt.NumField())
|
ret := make([]string, rt.NumField())
|
||||||
for i := 0; i < rt.NumField(); i++ {
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
ret[i] = rt.Field(i).Name
|
ret[i] = rt.Field(i).Name
|
||||||
|
@ -15,7 +15,7 @@ func TestAsDebugJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
k := new(Knobs)
|
k := new(Knobs)
|
||||||
got := k.AsDebugJSON()
|
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)
|
t.Errorf("AsDebugJSON map has %d fields; want %v", len(got), want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func TestPrefsEqual(t *testing.T) {
|
|||||||
"NetfilterKind",
|
"NetfilterKind",
|
||||||
"Persist",
|
"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",
|
t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, prefsHandles)
|
have, prefsHandles)
|
||||||
}
|
}
|
||||||
@ -615,14 +615,14 @@ func TestLoadPrefsFileWithZeroInIt(t *testing.T) {
|
|||||||
|
|
||||||
func TestMaskedPrefsFields(t *testing.T) {
|
func TestMaskedPrefsFields(t *testing.T) {
|
||||||
have := map[string]bool{}
|
have := map[string]bool{}
|
||||||
for _, f := range fieldsOf(reflect.TypeOf(Prefs{})) {
|
for _, f := range fieldsOf(reflect.TypeFor[Prefs]()) {
|
||||||
if f == "Persist" {
|
if f == "Persist" {
|
||||||
// This one can't be edited.
|
// This one can't be edited.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
have[f] = true
|
have[f] = true
|
||||||
}
|
}
|
||||||
for _, f := range fieldsOf(reflect.TypeOf(MaskedPrefs{})) {
|
for _, f := range fieldsOf(reflect.TypeFor[MaskedPrefs]()) {
|
||||||
if f == "Prefs" {
|
if f == "Prefs" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -644,8 +644,8 @@ func TestMaskedPrefsFields(t *testing.T) {
|
|||||||
|
|
||||||
// And also make sure they line up in the right order, which
|
// And also make sure they line up in the right order, which
|
||||||
// ApplyEdits assumes.
|
// ApplyEdits assumes.
|
||||||
pt := reflect.TypeOf(Prefs{})
|
pt := reflect.TypeFor[Prefs]()
|
||||||
mt := reflect.TypeOf(MaskedPrefs{})
|
mt := reflect.TypeFor[MaskedPrefs]()
|
||||||
for i := 0; i < mt.NumField(); i++ {
|
for i := 0; i < mt.NumField(); i++ {
|
||||||
name := mt.Field(i).Name
|
name := mt.Field(i).Name
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
@ -1154,7 +1154,7 @@ func TestPathFromPAMEnvLineOnNixOS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestStdOsUserUserAssumptions(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 {
|
if got, want := v.NumField(), 5; got != want {
|
||||||
t.Errorf("os/user.User has %v fields; this package assumes %v", got, want)
|
t.Errorf("os/user.User has %v fields; this package assumes %v", got, want)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ func TestHostinfoEqual(t *testing.T) {
|
|||||||
"AppConnector",
|
"AppConnector",
|
||||||
"Location",
|
"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",
|
t.Errorf("Hostinfo.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, hiHandles)
|
have, hiHandles)
|
||||||
}
|
}
|
||||||
@ -364,7 +364,7 @@ func TestNodeEqual(t *testing.T) {
|
|||||||
"DataPlaneAuditLogID", "Expired", "SelfNodeV4MasqAddrForThisPeer",
|
"DataPlaneAuditLogID", "Expired", "SelfNodeV4MasqAddrForThisPeer",
|
||||||
"SelfNodeV6MasqAddrForThisPeer", "IsWireGuardOnly", "ExitNodeDNSResolvers",
|
"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",
|
t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, nodeHandles)
|
have, nodeHandles)
|
||||||
}
|
}
|
||||||
@ -632,7 +632,7 @@ func TestNetInfoFields(t *testing.T) {
|
|||||||
"DERPLatency",
|
"DERPLatency",
|
||||||
"FirewallMode",
|
"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",
|
t.Errorf("NetInfo.Clone/BasicallyEqually check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, handled)
|
have, handled)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
func TestResolverEqual(t *testing.T) {
|
func TestResolverEqual(t *testing.T) {
|
||||||
var fieldNames []string
|
var fieldNames []string
|
||||||
for _, field := range reflect.VisibleFields(reflect.TypeOf(Resolver{})) {
|
for _, field := range reflect.VisibleFields(reflect.TypeFor[Resolver]()) {
|
||||||
fieldNames = append(fieldNames, field.Name)
|
fieldNames = append(fieldNames, field.Name)
|
||||||
}
|
}
|
||||||
sort.Strings(fieldNames)
|
sort.Strings(fieldNames)
|
||||||
|
@ -72,7 +72,7 @@ func (m NodeMutationLastSeen) Apply(n *tailcfg.Node) {
|
|||||||
|
|
||||||
var peerChangeFields = sync.OnceValue(func() []reflect.StructField {
|
var peerChangeFields = sync.OnceValue(func() []reflect.StructField {
|
||||||
var fields []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++ {
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
fields = append(fields, rt.Field(i))
|
fields = append(fields, rt.Field(i))
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ func TestMapResponseContainsNonPatchFields(t *testing.T) {
|
|||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
return reflect.ValueOf(true)
|
return reflect.ValueOf(true)
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
if reflect.TypeOf(opt.Bool("")) == t {
|
if reflect.TypeFor[opt.Bool]() == t {
|
||||||
return reflect.ValueOf("true").Convert(t)
|
return reflect.ValueOf("true").Convert(t)
|
||||||
}
|
}
|
||||||
return reflect.ValueOf("foo").Convert(t)
|
return reflect.ValueOf("foo").Convert(t)
|
||||||
@ -43,7 +43,7 @@ func TestMapResponseContainsNonPatchFields(t *testing.T) {
|
|||||||
panic(fmt.Sprintf("unhandled %v", t))
|
panic(fmt.Sprintf("unhandled %v", t))
|
||||||
}
|
}
|
||||||
|
|
||||||
rt := reflect.TypeOf(tailcfg.MapResponse{})
|
rt := reflect.TypeFor[tailcfg.MapResponse]()
|
||||||
for i := 0; i < rt.NumField(); i++ {
|
for i := 0; i < rt.NumField(); i++ {
|
||||||
f := rt.Field(i)
|
f := rt.Field(i)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
|
|||||||
|
|
||||||
func TestPersistEqual(t *testing.T) {
|
func TestPersistEqual(t *testing.T) {
|
||||||
persistHandles := []string{"LegacyFrontendPrivateMachineKey", "PrivateNodeKey", "OldPrivateNodeKey", "Provider", "UserProfile", "NetworkLockKey", "NodeID", "DisallowedTKAStateIDs"}
|
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",
|
t.Errorf("Persist.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, persistHandles)
|
have, persistHandles)
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,6 @@
|
|||||||
"reflect"
|
"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.
|
// 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.
|
// 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.
|
// since newly allocated pointers are globally unique within a process.
|
||||||
key := Key[Value]{name: new(stringer[string])}
|
key := Key[Value]{name: new(stringer[string])}
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = reflectTypeFor[Value]().String()
|
name = reflect.TypeFor[Value]().String()
|
||||||
}
|
}
|
||||||
key.name.v = name
|
key.name.v = name
|
||||||
if v := reflect.ValueOf(defaultValue); v.IsValid() && !v.IsZero() {
|
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 {
|
func (key Key[Value]) contextKey() any {
|
||||||
if key.name == nil {
|
if key.name == nil {
|
||||||
// Use the reflect.Type of the Value (implies key not created by New).
|
// Use the reflect.Type of the Value (implies key not created by New).
|
||||||
return reflectTypeFor[Value]()
|
return reflect.TypeFor[Value]()
|
||||||
} else {
|
} else {
|
||||||
// Use the name pointer directly (implies key created by New).
|
// Use the name pointer directly (implies key created by New).
|
||||||
return key.name
|
return key.name
|
||||||
@ -119,7 +114,7 @@ func (key Key[Value]) Has(ctx context.Context) (ok bool) {
|
|||||||
// String returns the name of the key.
|
// String returns the name of the key.
|
||||||
func (key Key[Value]) String() string {
|
func (key Key[Value]) String() string {
|
||||||
if key.name == nil {
|
if key.name == nil {
|
||||||
return reflectTypeFor[Value]().String()
|
return reflect.TypeFor[Value]().String()
|
||||||
}
|
}
|
||||||
return key.name.String()
|
return key.name.String()
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ func Hash[T any](v *T) Sum {
|
|||||||
// Always treat the Hash input as if it were an interface by including
|
// 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
|
// a hash of the type. This ensures that hashing of two different types
|
||||||
// but with the same value structure produces different hashes.
|
// but with the same value structure produces different hashes.
|
||||||
t := reflect.TypeOf(v).Elem()
|
t := reflect.TypeFor[T]()
|
||||||
h.hashType(t)
|
h.hashType(t)
|
||||||
if v == nil {
|
if v == nil {
|
||||||
h.HashUint8(0) // indicates 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 {
|
func newFieldFilter[T any](include bool, fields []string) Option {
|
||||||
var zero T
|
t := reflect.TypeFor[T]()
|
||||||
t := reflect.TypeOf(&zero).Elem()
|
|
||||||
fieldSet := set.Set[string]{}
|
fieldSet := set.Set[string]{}
|
||||||
for _, f := range fields {
|
for _, f := range fields {
|
||||||
if _, ok := t.FieldByName(f); !ok {
|
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
|
// be removed in the future, along with documentation about their precedence
|
||||||
// when combined.
|
// when combined.
|
||||||
func HasherForType[T any](opts ...Option) func(*T) Sum {
|
func HasherForType[T any](opts ...Option) func(*T) Sum {
|
||||||
var v *T
|
|
||||||
seedOnce.Do(initSeed)
|
seedOnce.Do(initSeed)
|
||||||
if len(opts) > 1 {
|
if len(opts) > 1 {
|
||||||
panic("HasherForType only accepts one optional argument") // for now
|
panic("HasherForType only accepts one optional argument") // for now
|
||||||
}
|
}
|
||||||
t := reflect.TypeOf(v).Elem()
|
t := reflect.TypeFor[T]()
|
||||||
var hash typeHasherFunc
|
var hash typeHasherFunc
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
switch o := o.(type) {
|
switch o := o.(type) {
|
||||||
|
@ -823,7 +823,7 @@ func TestHashMapAcyclic(t *testing.T) {
|
|||||||
|
|
||||||
hb := &hashBuffer{Hash: sha256.New()}
|
hb := &hashBuffer{Hash: sha256.New()}
|
||||||
|
|
||||||
hash := lookupTypeHasher(reflect.TypeOf(m))
|
hash := lookupTypeHasher(reflect.TypeFor[map[int]string]())
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
va := reflect.ValueOf(&m).Elem()
|
va := reflect.ValueOf(&m).Elem()
|
||||||
hb.Reset()
|
hb.Reset()
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
|
timeTimeType = reflect.TypeFor[time.Time]()
|
||||||
netipAddrType = reflect.TypeOf((*netip.Addr)(nil)).Elem()
|
netipAddrType = reflect.TypeFor[netip.Addr]()
|
||||||
selfHasherType = reflect.TypeOf((*SelfHasher)(nil)).Elem()
|
selfHasherType = reflect.TypeFor[SelfHasher]()
|
||||||
)
|
)
|
||||||
|
|
||||||
// typeIsSpecialized reports whether this type has specialized hashing.
|
// typeIsSpecialized reports whether this type has specialized hashing.
|
||||||
|
@ -26,7 +26,7 @@ func TestConfigEqual(t *testing.T) {
|
|||||||
"SubnetRoutes", "SNATSubnetRoutes", "NetfilterMode",
|
"SubnetRoutes", "SNATSubnetRoutes", "NetfilterMode",
|
||||||
"NetfilterKind",
|
"NetfilterKind",
|
||||||
}
|
}
|
||||||
configType := reflect.TypeOf(Config{})
|
configType := reflect.TypeFor[Config]()
|
||||||
configFields := []string{}
|
configFields := []string{}
|
||||||
for i := 0; i < configType.NumField(); i++ {
|
for i := 0; i < configType.NumField(); i++ {
|
||||||
configFields = append(configFields, configType.Field(i).Name)
|
configFields = append(configFields, configType.Field(i).Name)
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
func getPeerStatsOffset(name string) uintptr {
|
func getPeerStatsOffset(name string) uintptr {
|
||||||
peerType := reflect.TypeOf(device.Peer{})
|
peerType := reflect.TypeFor[device.Peer]()
|
||||||
field, ok := peerType.FieldByName(name)
|
field, ok := peerType.FieldByName(name)
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("no " + name + " field in device.Peer")
|
panic("no " + name + " field in device.Peer")
|
||||||
|
Loading…
Reference in New Issue
Block a user