From 56d3e84bb0195913e1d932d6fe8251047091076b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 31 Jul 2023 15:18:12 -0700 Subject: [PATCH] encoding/json: use reflect.TypeFor for known types MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For #60088 Change-Id: I2e471c76de62944b14472966b63f5778124b9b8b Reviewed-on: https://go-review.googlesource.com/c/go/+/514655 TryBot-Result: Gopher Robot Run-TryBot: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Run-TryBot: Joseph Tsai Auto-Submit: Ian Lance Taylor Reviewed-by: Ian Lance Taylor Reviewed-by: Joseph Tsai Reviewed-by: David Chase Reviewed-by: Daniel Martí --- src/encoding/json/bench_test.go | 2 +- src/encoding/json/decode.go | 6 ++--- src/encoding/json/decode_test.go | 40 ++++++++++++++++---------------- src/encoding/json/encode.go | 4 ++-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/encoding/json/bench_test.go b/src/encoding/json/bench_test.go index bafccdf193..b7e2b6974a 100644 --- a/src/encoding/json/bench_test.go +++ b/src/encoding/json/bench_test.go @@ -450,7 +450,7 @@ func BenchmarkTypeFieldsCache(b *testing.B) { // Dynamically generate many new types. types := make([]reflect.Type, maxTypes) fs := []reflect.StructField{{ - Type: reflect.TypeOf(""), + Type: reflect.TypeFor[string](), Index: []int{0}, }} for i := range types { diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go index 2142816d88..1119275f51 100644 --- a/src/encoding/json/decode.go +++ b/src/encoding/json/decode.go @@ -591,7 +591,7 @@ func (d *decodeState) array(v reflect.Value) error { } var nullLiteral = []byte("null") -var textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +var textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]() // object consumes an object from d.data[d.off-1:], decoding into v. // The first byte ('{') of the object has been read already. @@ -829,12 +829,12 @@ func (d *decodeState) convertNumber(s string) (any, error) { } f, err := strconv.ParseFloat(s, 64) if err != nil { - return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeOf(0.0), Offset: int64(d.off)} + return nil, &UnmarshalTypeError{Value: "number " + s, Type: reflect.TypeFor[float64](), Offset: int64(d.off)} } return f, nil } -var numberType = reflect.TypeOf(Number("")) +var numberType = reflect.TypeFor[Number]() // literalStore decodes a literal stored in item into v. // diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go index c2c036b609..5c34139d92 100644 --- a/src/encoding/json/decode_test.go +++ b/src/encoding/json/decode_test.go @@ -57,7 +57,7 @@ type PP struct { type SS string func (*SS) UnmarshalJSON(data []byte) error { - return &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(SS(""))} + return &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[SS]()} } // ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and @@ -421,11 +421,11 @@ var unmarshalTests = []unmarshalTest{ {in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"}, {in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"}, {in: "null", ptr: new(any), out: nil}, - {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf(""), 7, "T", "X"}}, - {in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(""), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, + {in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeFor[string](), 7, "T", "X"}}, + {in: `{"X": 23}`, ptr: new(T), out: T{}, err: &UnmarshalTypeError{"number", reflect.TypeFor[string](), 8, "T", "X"}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, {in: `{"x": 1}`, ptr: new(tx), out: tx{}}, {in: `{"x": 1}`, ptr: new(tx), err: fmt.Errorf("json: unknown field \"x\""), disallowUnknownFields: true}, - {in: `{"S": 23}`, ptr: new(W), out: W{}, err: &UnmarshalTypeError{"number", reflect.TypeOf(SS("")), 0, "W", "S"}}, + {in: `{"S": 23}`, ptr: new(W), out: W{}, err: &UnmarshalTypeError{"number", reflect.TypeFor[SS](), 0, "W", "S"}}, {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}}, {in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true}, {in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(any), out: ifaceNumAsFloat64}, @@ -545,32 +545,32 @@ var unmarshalTests = []unmarshalTest{ { in: `{"abc":"abc"}`, ptr: new(map[int]string), - err: &UnmarshalTypeError{Value: "number abc", Type: reflect.TypeOf(0), Offset: 2}, + err: &UnmarshalTypeError{Value: "number abc", Type: reflect.TypeFor[int](), Offset: 2}, }, { in: `{"256":"abc"}`, ptr: new(map[uint8]string), - err: &UnmarshalTypeError{Value: "number 256", Type: reflect.TypeOf(uint8(0)), Offset: 2}, + err: &UnmarshalTypeError{Value: "number 256", Type: reflect.TypeFor[uint8](), Offset: 2}, }, { in: `{"128":"abc"}`, ptr: new(map[int8]string), - err: &UnmarshalTypeError{Value: "number 128", Type: reflect.TypeOf(int8(0)), Offset: 2}, + err: &UnmarshalTypeError{Value: "number 128", Type: reflect.TypeFor[int8](), Offset: 2}, }, { in: `{"-1":"abc"}`, ptr: new(map[uint8]string), - err: &UnmarshalTypeError{Value: "number -1", Type: reflect.TypeOf(uint8(0)), Offset: 2}, + err: &UnmarshalTypeError{Value: "number -1", Type: reflect.TypeFor[uint8](), Offset: 2}, }, { in: `{"F":{"a":2,"3":4}}`, ptr: new(map[string]map[int]int), - err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeOf(int(0)), Offset: 7}, + err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeFor[int](), Offset: 7}, }, { in: `{"F":{"a":2,"3":4}}`, ptr: new(map[string]map[uint]int), - err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeOf(uint(0)), Offset: 7}, + err: &UnmarshalTypeError{Value: "number a", Type: reflect.TypeFor[uint](), Offset: 7}, }, // Map keys can be encoding.TextUnmarshalers. @@ -715,12 +715,12 @@ var unmarshalTests = []unmarshalTest{ { in: `{"2009-11-10T23:00:00Z": "hello world"}`, ptr: new(map[Point]string), - err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[Point]string{}), Offset: 1}, + err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeFor[map[Point]string](), Offset: 1}, }, { in: `{"asdf": "hello world"}`, ptr: new(map[unmarshaler]string), - err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(map[unmarshaler]string{}), Offset: 1}, + err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeFor[map[unmarshaler]string](), Offset: 1}, }, // related to issue 13783. @@ -820,7 +820,7 @@ var unmarshalTests = []unmarshalTest{ Value: "string", Struct: "V", Field: "V.F2", - Type: reflect.TypeOf(int32(0)), + Type: reflect.TypeFor[int32](), Offset: 20, }, }, @@ -831,7 +831,7 @@ var unmarshalTests = []unmarshalTest{ Value: "string", Struct: "V", Field: "V.F2", - Type: reflect.TypeOf(int32(0)), + Type: reflect.TypeFor[int32](), Offset: 30, }, }, @@ -907,24 +907,24 @@ var unmarshalTests = []unmarshalTest{ { in: `{"data":{"test1": "bob", "test2": 123}}`, ptr: new(mapStringToStringData), - err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 37, Struct: "mapStringToStringData", Field: "data"}, + err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: 37, Struct: "mapStringToStringData", Field: "data"}, }, { in: `{"data":{"test1": 123, "test2": "bob"}}`, ptr: new(mapStringToStringData), - err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeOf(""), Offset: 21, Struct: "mapStringToStringData", Field: "data"}, + err: &UnmarshalTypeError{Value: "number", Type: reflect.TypeFor[string](), Offset: 21, Struct: "mapStringToStringData", Field: "data"}, }, // trying to decode JSON arrays or objects via TextUnmarshaler { in: `[1, 2, 3]`, ptr: new(MustNotUnmarshalText), - err: &UnmarshalTypeError{Value: "array", Type: reflect.TypeOf(&MustNotUnmarshalText{}), Offset: 1}, + err: &UnmarshalTypeError{Value: "array", Type: reflect.TypeFor[*MustNotUnmarshalText](), Offset: 1}, }, { in: `{"foo": "bar"}`, ptr: new(MustNotUnmarshalText), - err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeOf(&MustNotUnmarshalText{}), Offset: 1}, + err: &UnmarshalTypeError{Value: "object", Type: reflect.TypeFor[*MustNotUnmarshalText](), Offset: 1}, }, // #22369 { @@ -934,7 +934,7 @@ var unmarshalTests = []unmarshalTest{ Value: "string", Struct: "T", Field: "PP.T.Y", - Type: reflect.TypeOf(int(0)), + Type: reflect.TypeFor[int](), Offset: 29, }, }, @@ -945,7 +945,7 @@ var unmarshalTests = []unmarshalTest{ Value: "string", Struct: "T", Field: "Ts.Y", - Type: reflect.TypeOf(int(0)), + Type: reflect.TypeFor[int](), Offset: 29, }, }, diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go index 614662d54b..bba57fdf4f 100644 --- a/src/encoding/json/encode.go +++ b/src/encoding/json/encode.go @@ -371,8 +371,8 @@ func typeEncoder(t reflect.Type) encoderFunc { } var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() - textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() + marshalerType = reflect.TypeFor[Marshaler]() + textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]() ) // newTypeEncoder constructs an encoderFunc for a type. -- 2.48.1