Skip to content

Commit

Permalink
Use new reflect.TypeFor function available in Go 1.22 (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsnet authored Apr 12, 2024
1 parent 8868a69 commit a256f16
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 91 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.21.x
go-version: 1.22.x
- name: Checkout code
uses: actions/checkout@v4
- name: Test
Expand All @@ -23,7 +23,7 @@ jobs:
test-all:
strategy:
matrix:
go-version: [1.21.x]
go-version: [1.22.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
18 changes: 9 additions & 9 deletions arshal_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ const optimizeCommon = true

var (
// Most natural Go type that correspond with each JSON type.
anyType = reflect.TypeOf((*any)(nil)).Elem() // JSON value
boolType = reflect.TypeOf((*bool)(nil)).Elem() // JSON bool
stringType = reflect.TypeOf((*string)(nil)).Elem() // JSON string
float64Type = reflect.TypeOf((*float64)(nil)).Elem() // JSON number
mapStringAnyType = reflect.TypeOf((*map[string]any)(nil)).Elem() // JSON object
sliceAnyType = reflect.TypeOf((*[]any)(nil)).Elem() // JSON array

bytesType = reflect.TypeOf((*[]byte)(nil)).Elem()
emptyStructType = reflect.TypeOf((*struct{})(nil)).Elem()
anyType = reflect.TypeFor[any]() // JSON value
boolType = reflect.TypeFor[bool]() // JSON bool
stringType = reflect.TypeFor[string]() // JSON string
float64Type = reflect.TypeFor[float64]() // JSON number
mapStringAnyType = reflect.TypeFor[map[string]any]() // JSON object
sliceAnyType = reflect.TypeFor[[]any]() // JSON array

bytesType = reflect.TypeFor[[]byte]()
emptyStructType = reflect.TypeFor[struct{}]()
)

const startDetectingCyclesAfter = 1000
Expand Down
8 changes: 4 additions & 4 deletions arshal_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (a *typedArshalers[Coder]) lookup(fnc func(*Coder, addressableValue, *jsono
// The value of T must not be retained outside the function call.
// It may not return [SkipFunc].
func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers {
t := reflect.TypeOf((*T)(nil)).Elem()
t := reflect.TypeFor[T]()
assertCastableTo(t, true)
typFnc := typedMarshaler{
typ: t,
Expand Down Expand Up @@ -200,7 +200,7 @@ func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers {
// The pointer to [jsontext.Encoder], the value of T, and the [Options] value
// must not be retained outside the function call.
func MarshalFuncV2[T any](fn func(*jsontext.Encoder, T, Options) error) *Marshalers {
t := reflect.TypeOf((*T)(nil)).Elem()
t := reflect.TypeFor[T]()
assertCastableTo(t, true)
typFnc := typedMarshaler{
typ: t,
Expand Down Expand Up @@ -241,7 +241,7 @@ func MarshalFuncV2[T any](fn func(*jsontext.Encoder, T, Options) error) *Marshal
// The input []byte and value T must not be retained outside the function call.
// It may not return [SkipFunc].
func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers {
t := reflect.TypeOf((*T)(nil)).Elem()
t := reflect.TypeFor[T]()
assertCastableTo(t, false)
typFnc := typedUnmarshaler{
typ: t,
Expand Down Expand Up @@ -274,7 +274,7 @@ func UnmarshalFuncV1[T any](fn func([]byte, T) error) *Unmarshalers {
// The pointer to [jsontext.Decoder], the value of T, and [Options] value
// must not be retained outside the function call.
func UnmarshalFuncV2[T any](fn func(*jsontext.Decoder, T, Options) error) *Unmarshalers {
t := reflect.TypeOf((*T)(nil)).Elem()
t := reflect.TypeFor[T]()
assertCastableTo(t, false)
typFnc := typedUnmarshaler{
typ: t,
Expand Down
2 changes: 1 addition & 1 deletion arshal_inlined.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
// represent any arbitrary JSON object member. Explicitly named fields take
// precedence over the inlined fallback. Only one inlined fallback is allowed.

var jsontextValueType = reflect.TypeOf((*jsontext.Value)(nil)).Elem()
var jsontextValueType = reflect.TypeFor[jsontext.Value]()

// marshalInlinedFallbackAll marshals all the members in an inlined fallback.
func marshalInlinedFallbackAll(enc *jsontext.Encoder, va addressableValue, mo *jsonopts.Struct, f *structField, insertUnquotedName func([]byte) bool) error {
Expand Down
16 changes: 8 additions & 8 deletions arshal_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ import (

// Interfaces for custom serialization.
var (
jsonMarshalerV1Type = reflect.TypeOf((*MarshalerV1)(nil)).Elem()
jsonMarshalerV2Type = reflect.TypeOf((*MarshalerV2)(nil)).Elem()
jsonUnmarshalerV1Type = reflect.TypeOf((*UnmarshalerV1)(nil)).Elem()
jsonUnmarshalerV2Type = reflect.TypeOf((*UnmarshalerV2)(nil)).Elem()
textAppenderType = reflect.TypeOf((*encodingTextAppender)(nil)).Elem()
textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
jsonMarshalerV1Type = reflect.TypeFor[MarshalerV1]()
jsonMarshalerV2Type = reflect.TypeFor[MarshalerV2]()
jsonUnmarshalerV1Type = reflect.TypeFor[UnmarshalerV1]()
jsonUnmarshalerV2Type = reflect.TypeFor[UnmarshalerV2]()
textAppenderType = reflect.TypeFor[encodingTextAppender]()
textMarshalerType = reflect.TypeFor[encoding.TextMarshaler]()
textUnmarshalerType = reflect.TypeFor[encoding.TextUnmarshaler]()

// TODO(https://go.dev/issue/62384): Use encoding.TextAppender instead of this hack.
// This exists for now to provide performance benefits to netip types.
// There is no semantic difference with this change.
appenderToType = reflect.TypeOf((*interface{ AppendTo([]byte) []byte })(nil)).Elem()
appenderToType = reflect.TypeFor[interface{ AppendTo([]byte) []byte }]()
)

// TODO(https://go.dev/issue/62384): Use encoding.TextAppender instead
Expand Down
106 changes: 53 additions & 53 deletions arshal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -600,54 +600,54 @@ func (valueStringer) String() string { return "" }
func (*pointerStringer) String() string { return "" }

var (
namedBoolType = reflect.TypeOf((*namedBool)(nil)).Elem()
intType = reflect.TypeOf((*int)(nil)).Elem()
int8Type = reflect.TypeOf((*int8)(nil)).Elem()
int16Type = reflect.TypeOf((*int16)(nil)).Elem()
int32Type = reflect.TypeOf((*int32)(nil)).Elem()
int64Type = reflect.TypeOf((*int64)(nil)).Elem()
uintType = reflect.TypeOf((*uint)(nil)).Elem()
uint8Type = reflect.TypeOf((*uint8)(nil)).Elem()
uint16Type = reflect.TypeOf((*uint16)(nil)).Elem()
uint32Type = reflect.TypeOf((*uint32)(nil)).Elem()
uint64Type = reflect.TypeOf((*uint64)(nil)).Elem()
float32Type = reflect.TypeOf((*float32)(nil)).Elem()
sliceStringType = reflect.TypeOf((*[]string)(nil)).Elem()
array1StringType = reflect.TypeOf((*[1]string)(nil)).Elem()
array0ByteType = reflect.TypeOf((*[0]byte)(nil)).Elem()
array1ByteType = reflect.TypeOf((*[1]byte)(nil)).Elem()
array2ByteType = reflect.TypeOf((*[2]byte)(nil)).Elem()
array3ByteType = reflect.TypeOf((*[3]byte)(nil)).Elem()
array4ByteType = reflect.TypeOf((*[4]byte)(nil)).Elem()
mapStringStringType = reflect.TypeOf((*map[string]string)(nil)).Elem()
structAllType = reflect.TypeOf((*structAll)(nil)).Elem()
structConflictingType = reflect.TypeOf((*structConflicting)(nil)).Elem()
structNoneExportedType = reflect.TypeOf((*structNoneExported)(nil)).Elem()
structMalformedTagType = reflect.TypeOf((*structMalformedTag)(nil)).Elem()
structUnexportedTagType = reflect.TypeOf((*structUnexportedTag)(nil)).Elem()
structUnexportedEmbeddedType = reflect.TypeOf((*structUnexportedEmbedded)(nil)).Elem()
structUnknownTextValueType = reflect.TypeOf((*structUnknownTextValue)(nil)).Elem()
allMethodsType = reflect.TypeOf((*allMethods)(nil)).Elem()
allMethodsExceptJSONv2Type = reflect.TypeOf((*allMethodsExceptJSONv2)(nil)).Elem()
allMethodsExceptJSONv1Type = reflect.TypeOf((*allMethodsExceptJSONv1)(nil)).Elem()
allMethodsExceptTextType = reflect.TypeOf((*allMethodsExceptText)(nil)).Elem()
onlyMethodJSONv2Type = reflect.TypeOf((*onlyMethodJSONv2)(nil)).Elem()
onlyMethodJSONv1Type = reflect.TypeOf((*onlyMethodJSONv1)(nil)).Elem()
onlyMethodTextType = reflect.TypeOf((*onlyMethodText)(nil)).Elem()
structMethodJSONv2Type = reflect.TypeOf((*structMethodJSONv2)(nil)).Elem()
structMethodJSONv1Type = reflect.TypeOf((*structMethodJSONv1)(nil)).Elem()
structMethodTextType = reflect.TypeOf((*structMethodText)(nil)).Elem()
marshalJSONv2FuncType = reflect.TypeOf((*marshalJSONv2Func)(nil)).Elem()
marshalJSONv1FuncType = reflect.TypeOf((*marshalJSONv1Func)(nil)).Elem()
appendTextFuncType = reflect.TypeOf((*appendTextFunc)(nil)).Elem()
marshalTextFuncType = reflect.TypeOf((*marshalTextFunc)(nil)).Elem()
unmarshalJSONv2FuncType = reflect.TypeOf((*unmarshalJSONv2Func)(nil)).Elem()
unmarshalJSONv1FuncType = reflect.TypeOf((*unmarshalJSONv1Func)(nil)).Elem()
unmarshalTextFuncType = reflect.TypeOf((*unmarshalTextFunc)(nil)).Elem()
nocaseStringType = reflect.TypeOf((*nocaseString)(nil)).Elem()
ioReaderType = reflect.TypeOf((*io.Reader)(nil)).Elem()
fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
chanStringType = reflect.TypeOf((*chan string)(nil)).Elem()
namedBoolType = reflect.TypeFor[namedBool]()
intType = reflect.TypeFor[int]()
int8Type = reflect.TypeFor[int8]()
int16Type = reflect.TypeFor[int16]()
int32Type = reflect.TypeFor[int32]()
int64Type = reflect.TypeFor[int64]()
uintType = reflect.TypeFor[uint]()
uint8Type = reflect.TypeFor[uint8]()
uint16Type = reflect.TypeFor[uint16]()
uint32Type = reflect.TypeFor[uint32]()
uint64Type = reflect.TypeFor[uint64]()
float32Type = reflect.TypeFor[float32]()
sliceStringType = reflect.TypeFor[[]string]()
array1StringType = reflect.TypeFor[[1]string]()
array0ByteType = reflect.TypeFor[[0]byte]()
array1ByteType = reflect.TypeFor[[1]byte]()
array2ByteType = reflect.TypeFor[[2]byte]()
array3ByteType = reflect.TypeFor[[3]byte]()
array4ByteType = reflect.TypeFor[[4]byte]()
mapStringStringType = reflect.TypeFor[map[string]string]()
structAllType = reflect.TypeFor[structAll]()
structConflictingType = reflect.TypeFor[structConflicting]()
structNoneExportedType = reflect.TypeFor[structNoneExported]()
structMalformedTagType = reflect.TypeFor[structMalformedTag]()
structUnexportedTagType = reflect.TypeFor[structUnexportedTag]()
structUnexportedEmbeddedType = reflect.TypeFor[structUnexportedEmbedded]()
structUnknownTextValueType = reflect.TypeFor[structUnknownTextValue]()
allMethodsType = reflect.TypeFor[allMethods]()
allMethodsExceptJSONv2Type = reflect.TypeFor[allMethodsExceptJSONv2]()
allMethodsExceptJSONv1Type = reflect.TypeFor[allMethodsExceptJSONv1]()
allMethodsExceptTextType = reflect.TypeFor[allMethodsExceptText]()
onlyMethodJSONv2Type = reflect.TypeFor[onlyMethodJSONv2]()
onlyMethodJSONv1Type = reflect.TypeFor[onlyMethodJSONv1]()
onlyMethodTextType = reflect.TypeFor[onlyMethodText]()
structMethodJSONv2Type = reflect.TypeFor[structMethodJSONv2]()
structMethodJSONv1Type = reflect.TypeFor[structMethodJSONv1]()
structMethodTextType = reflect.TypeFor[structMethodText]()
marshalJSONv2FuncType = reflect.TypeFor[marshalJSONv2Func]()
marshalJSONv1FuncType = reflect.TypeFor[marshalJSONv1Func]()
appendTextFuncType = reflect.TypeFor[appendTextFunc]()
marshalTextFuncType = reflect.TypeFor[marshalTextFunc]()
unmarshalJSONv2FuncType = reflect.TypeFor[unmarshalJSONv2Func]()
unmarshalJSONv1FuncType = reflect.TypeFor[unmarshalJSONv1Func]()
unmarshalTextFuncType = reflect.TypeFor[unmarshalTextFunc]()
nocaseStringType = reflect.TypeFor[nocaseString]()
ioReaderType = reflect.TypeFor[io.Reader]()
fmtStringerType = reflect.TypeFor[fmt.Stringer]()
chanStringType = reflect.TypeFor[chan string]()
)

func addr[T any](v T) *T {
Expand Down Expand Up @@ -913,7 +913,7 @@ func TestMarshal(t *testing.T) {
name: jsontest.Name("Maps/DuplicateName/NoCaseString"),
in: map[nocaseString]string{"hello": "", "HELLO": ""},
want: `{"hello":""`,
wantErr: &SemanticError{action: "marshal", JSONKind: '"', GoType: reflect.TypeOf(nocaseString("")), Err: export.NewDuplicateNameError([]byte(`"hello"`), len64(`{"hello":"",`))},
wantErr: &SemanticError{action: "marshal", JSONKind: '"', GoType: reflect.TypeFor[nocaseString](), Err: export.NewDuplicateNameError([]byte(`"hello"`), len64(`{"hello":"",`))},
}, {
name: jsontest.Name("Maps/DuplicateName/NaNs/Deterministic+AllowDuplicateNames"),
opts: []Options{
Expand Down Expand Up @@ -1036,7 +1036,7 @@ func TestMarshal(t *testing.T) {
return m
}(),
want: strings.Repeat(`{"k":`, startDetectingCyclesAfter) + `{"k"`,
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeOf(recursiveMap{}), Err: errors.New("encountered a cycle")},
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeFor[recursiveMap](), Err: errors.New("encountered a cycle")},
}, {
name: jsontest.Name("Maps/IgnoreInvalidFormat"),
opts: []Options{invalidFormatOption},
Expand Down Expand Up @@ -1813,7 +1813,7 @@ func TestMarshal(t *testing.T) {
for i := 0; i < 100; i++ {
fields = append(fields, reflect.StructField{
Name: fmt.Sprintf("X%d", i),
Type: reflect.TypeOf(stringMarshalEmpty("")),
Type: reflect.TypeFor[stringMarshalEmpty](),
Tag: `json:",omitempty"`,
})
}
Expand Down Expand Up @@ -2661,7 +2661,7 @@ func TestMarshal(t *testing.T) {
return s
}(),
want: strings.Repeat(`[`, startDetectingCyclesAfter) + `[`,
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeOf(recursiveSlice{}), Err: errors.New("encountered a cycle")},
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeFor[recursiveSlice](), Err: errors.New("encountered a cycle")},
}, {
name: jsontest.Name("Slices/NonCyclicSlice"),
in: func() []any {
Expand Down Expand Up @@ -2756,7 +2756,7 @@ func TestMarshal(t *testing.T) {
return p
}(),
want: strings.Repeat(`{"P":`, startDetectingCyclesAfter) + `{"P"`,
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeOf((*recursivePointer)(nil)), Err: errors.New("encountered a cycle")},
wantErr: &SemanticError{action: "marshal", GoType: reflect.TypeFor[*recursivePointer](), Err: errors.New("encountered a cycle")},
}, {
name: jsontest.Name("Pointers/IgnoreInvalidFormat"),
opts: []Options{invalidFormatOption},
Expand Down
4 changes: 2 additions & 2 deletions arshal_time.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import (
)

var (
timeDurationType = reflect.TypeOf((*time.Duration)(nil)).Elem()
timeTimeType = reflect.TypeOf((*time.Time)(nil)).Elem()
timeDurationType = reflect.TypeFor[time.Duration]()
timeTimeType = reflect.TypeFor[time.Time]()
)

func makeTimeArshaler(fncs *arshaler, t reflect.Type) *arshaler {
Expand Down
18 changes: 9 additions & 9 deletions errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,31 @@ func TestSemanticError(t *testing.T) {
err: &SemanticError{action: "marshal", JSONKind: '"'},
want: "json: cannot marshal JSON string",
}, {
err: &SemanticError{GoType: reflect.TypeOf(bool(false))},
err: &SemanticError{GoType: reflect.TypeFor[bool]()},
want: "json: cannot handle Go value of type bool",
}, {
err: &SemanticError{action: "marshal", GoType: reflect.TypeOf(int(0))},
err: &SemanticError{action: "marshal", GoType: reflect.TypeFor[int]()},
want: "json: cannot marshal Go value of type int",
}, {
err: &SemanticError{action: "unmarshal", GoType: reflect.TypeOf(uint(0))},
err: &SemanticError{action: "unmarshal", GoType: reflect.TypeFor[uint]()},
want: "json: cannot unmarshal Go value of type uint",
}, {
err: &SemanticError{JSONKind: '0', GoType: reflect.TypeOf(tar.Header{})},
err: &SemanticError{JSONKind: '0', GoType: reflect.TypeFor[tar.Header]()},
want: "json: cannot handle JSON number with Go value of type tar.Header",
}, {
err: &SemanticError{action: "marshal", JSONKind: '{', GoType: reflect.TypeOf(bytes.Buffer{})},
err: &SemanticError{action: "marshal", JSONKind: '{', GoType: reflect.TypeFor[bytes.Buffer]()},
want: "json: cannot marshal JSON object from Go value of type bytes.Buffer",
}, {
err: &SemanticError{action: "unmarshal", JSONKind: ']', GoType: reflect.TypeOf(strings.Reader{})},
err: &SemanticError{action: "unmarshal", JSONKind: ']', GoType: reflect.TypeFor[strings.Reader]()},
want: "json: cannot unmarshal JSON array into Go value of type strings.Reader",
}, {
err: &SemanticError{action: "unmarshal", JSONKind: '{', GoType: reflect.TypeOf(float64(0)), ByteOffset: 123},
err: &SemanticError{action: "unmarshal", JSONKind: '{', GoType: reflect.TypeFor[float64](), ByteOffset: 123},
want: "json: cannot unmarshal JSON object into Go value of type float64 after byte offset 123",
}, {
err: &SemanticError{action: "marshal", JSONKind: 'f', GoType: reflect.TypeOf(complex128(0)), ByteOffset: 123, JSONPointer: "/foo/2/bar/3"},
err: &SemanticError{action: "marshal", JSONKind: 'f', GoType: reflect.TypeFor[complex128](), ByteOffset: 123, JSONPointer: "/foo/2/bar/3"},
want: "json: cannot marshal JSON boolean from Go value of type complex128 within JSON value at \"/foo/2/bar/3\"",
}, {
err: &SemanticError{action: "unmarshal", JSONKind: '}', GoType: reflect.TypeOf((*io.Reader)(nil)).Elem(), ByteOffset: 123, JSONPointer: "/foo/2/bar/3", Err: errors.New("some underlying error")},
err: &SemanticError{action: "unmarshal", JSONKind: '}', GoType: reflect.TypeFor[io.Reader](), ByteOffset: 123, JSONPointer: "/foo/2/bar/3", Err: errors.New("some underlying error")},
want: "json: cannot unmarshal JSON object into Go value of type io.Reader within JSON value at \"/foo/2/bar/3\": some underlying error",
}, {
err: &SemanticError{Err: errors.New("some underlying error")},
Expand Down
2 changes: 1 addition & 1 deletion fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type isZeroer interface {
IsZero() bool
}

var isZeroerType = reflect.TypeOf((*isZeroer)(nil)).Elem()
var isZeroerType = reflect.TypeFor[isZeroer]()

type structFields struct {
flattened []structField // listed in depth-first ordering
Expand Down
2 changes: 1 addition & 1 deletion fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func TestMakeStructFields(t *testing.T) {
X map[string]jsontext.Value `json:",unknown"`
}{},
want: structFields{
inlinedFallback: &structField{id: 0, index: []int{2}, typ: reflect.TypeOf(map[string]jsontext.Value(nil)), fieldOptions: fieldOptions{name: "X", quotedName: `"X"`, unknown: true}},
inlinedFallback: &structField{id: 0, index: []int{2}, typ: reflect.TypeFor[map[string]jsontext.Value](), fieldOptions: fieldOptions{name: "X", quotedName: `"X"`, unknown: true}},
},
}, {
name: jsontest.Name("InvalidUTF8"),
Expand Down
2 changes: 1 addition & 1 deletion fold_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func runUnmarshalUnknown(tb testing.TB) {
for i := 0; i < n; i++ {
fields = append(fields, reflect.StructField{
Name: fmt.Sprintf("Name%d", i),
Type: reflect.TypeOf(0),
Type: reflect.TypeFor[int](),
Tag: `json:",nocase"`,
})
}
Expand Down

0 comments on commit a256f16

Please sign in to comment.