Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new reflect.TypeFor function available in Go 1.22 #28

Merged
merged 1 commit into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading