Skip to content

Commit fc7f017

Browse files
committed
Handle typedef fields in optional validations
Prior to this it would look at the .Kind, see "Alias", and generate calls to (e.g.) `RequiredValue()`. Now calls `RequiredSlice()`.
1 parent 9d519c7 commit fc7f017

File tree

5 files changed

+67
-7
lines changed

5 files changed

+67
-7
lines changed

staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/doc.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,17 @@ type Struct struct {
6969
// +k8s:validateFalse="field Struct.SliceField"
7070
SliceField []string `json:"sliceField"`
7171

72+
// +k8s:optional
73+
// +k8s:validateFalse="field Struct.SliceTypedefField"
74+
SliceTypedefField SliceType `json:"sliceTypedefField"`
75+
7276
// +k8s:optional
7377
// +k8s:validateFalse="field Struct.MapField"
7478
MapField map[string]string `json:"mapField"`
79+
80+
// +k8s:optional
81+
// +k8s:validateFalse="field Struct.MapTypedefField"
82+
MapTypedefField MapType `json:"mapTypedefField"`
7583
}
7684

7785
// +k8s:validateFalse="type StringType"
@@ -82,3 +90,9 @@ type IntType int
8290

8391
// +k8s:validateFalse="type OtherStruct"
8492
type OtherStruct struct{}
93+
94+
// +k8s:validateFalse="type SliceType"
95+
type SliceType []string
96+
97+
// +k8s:validateFalse="type MapType"
98+
type MapType map[string]string

staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/doc_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ func Test(t *testing.T) {
4040
IntTypedefPtrField: ptr.To(IntType(456)),
4141
OtherStructPtrField: &OtherStruct{},
4242
SliceField: []string{"a", "b"},
43+
SliceTypedefField: SliceType([]string{"a", "b"}),
4344
MapField: map[string]string{"a": "b", "c": "d"},
45+
MapTypedefField: MapType(map[string]string{"a": "b", "c": "d"}),
4446
}).ExpectValidateFalseByPath(map[string][]string{
4547
"stringField": {"field Struct.StringField"},
4648
"stringPtrField": {"field Struct.StringPtrField"},
@@ -52,6 +54,8 @@ func Test(t *testing.T) {
5254
"intTypedefPtrField": {"field Struct.IntTypedefPtrField", "type IntType"},
5355
"otherStructPtrField": {"type OtherStruct", "field Struct.OtherStructPtrField"},
5456
"sliceField": {"field Struct.SliceField"},
57+
"sliceTypedefField": {"field Struct.SliceTypedefField", "type SliceType"},
5558
"mapField": {"field Struct.MapField"},
59+
"mapTypedefField": {"field Struct.MapTypedefField", "type MapType"},
5660
})
5761
}

staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/optional/zz_generated.validations.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

staging/src/k8s.io/code-generator/cmd/validation-gen/validators/common.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,22 @@ func getMemberByJSON(t *types.Type, jsonName string) *types.Member {
4040

4141
// isNilableType returns true if the argument type can be compared to nil.
4242
func isNilableType(t *types.Type) bool {
43-
for t.Kind == types.Alias {
44-
t = t.Underlying
45-
}
46-
switch t.Kind {
43+
switch unaliasType(t).Kind {
4744
case types.Pointer, types.Map, types.Slice, types.Interface: // Note: Arrays are not nilable
4845
return true
4946
}
5047
return false
5148
}
5249

50+
// unaliasType returns the underlying type of the specified type if it is an
51+
// alias, otherwise returns the type itself.
52+
func unaliasType(t *types.Type) *types.Type {
53+
for t.Kind == types.Alias {
54+
t = t.Underlying
55+
}
56+
return t
57+
}
58+
5359
// realType returns the underlying type of a type, unwrapping aliases and
5460
// dropping pointerness.
5561
func realType(t *types.Type) *types.Type {

staging/src/k8s.io/code-generator/cmd/validation-gen/validators/required.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (rtv requirednessTagValidator) doRequired(context Context) (Validations, er
9090
// originally defined as a value-type or a pointer-type in the API. This
9191
// one does. Since Go doesn't do partial specialization of templates, we
9292
// do manual dispatch here.
93-
switch context.Type.Kind {
93+
switch unaliasType(context.Type).Kind {
9494
case types.Slice:
9595
return Validations{Functions: []FunctionGen{Function(requiredTagName, ShortCircuit, requiredSliceValidator)}}, nil
9696
case types.Map:
@@ -161,7 +161,7 @@ func (rtv requirednessTagValidator) doOptional(context Context) (Validations, er
161161
// originally defined as a value-type or a pointer-type in the API. This
162162
// one does. Since Go doesn't do partial specialization of templates, we
163163
// do manual dispatch here.
164-
switch context.Type.Kind {
164+
switch unaliasType(context.Type).Kind {
165165
case types.Slice:
166166
return Validations{Functions: []FunctionGen{Function(optionalTagName, ShortCircuit|NonError, optionalSliceValidator)}}, nil
167167
case types.Map:
@@ -261,7 +261,7 @@ func (requirednessTagValidator) doForbidden(context Context) (Validations, error
261261
// optional check and short-circuit (but without error). Why? For
262262
// example, this prevents any further validation from trying to run on a
263263
// nil pointer.
264-
switch context.Type.Kind {
264+
switch unaliasType(context.Type).Kind {
265265
case types.Slice:
266266
return Validations{
267267
Functions: []FunctionGen{

0 commit comments

Comments
 (0)