Update Context comments and fix some usage

Audit all Context creation sites and update the comments to better
describe.

Pass the raw type in Context, not the `NativeType()`.
This commit is contained in:
Tim Hockin
2025-07-16 13:28:23 -07:00
committed by yongruilin
parent 9e71a07abf
commit f51d57042e
4 changed files with 23 additions and 17 deletions

View File

@@ -627,9 +627,9 @@ func (td *typeDiscoverer) discoverStruct(thisNode *typeNode, fldPath *field.Path
context := validators.Context{
Scope: validators.ScopeField,
Type: childType,
ParentPath: fldPath,
Member: &memb,
Path: childPath,
Member: &memb,
ParentPath: fldPath,
}
tags, err := td.validator.ExtractTags(context, memb.CommentLines)

View File

@@ -401,13 +401,15 @@ func (evtv eachValTagValidator) GetValidations(context Context, tag codetags.Tag
switch nt.Kind {
case types.Slice, types.Array, types.Map:
default:
return Validations{}, fmt.Errorf("can only be used on list or map types (%s)", t.Kind)
return Validations{}, fmt.Errorf("can only be used on list or map types (%s)", nt.Kind)
}
elemContext := Context{
// Scope is initialized below.
Type: nt.Elem,
Path: context.Path.Key("(vals)"),
Member: nil, // NA for list/map values
ParentPath: context.Path,
Path: context.Path.Key("*"),
}
switch nt.Kind {
case types.Slice, types.Array:
@@ -571,16 +573,18 @@ var (
func (ektv eachKeyTagValidator) GetValidations(context Context, tag codetags.Tag) (Validations, error) {
// NOTE: pointers to lists are not supported, so we should never see a pointer here.
t := util.NativeType(context.Type)
if t.Kind != types.Map {
return Validations{}, fmt.Errorf("can only be used on map types (%s)", t.Kind)
t := context.Type
nt := util.NativeType(t)
if nt.Kind != types.Map {
return Validations{}, fmt.Errorf("can only be used on map types (%s)", nt.Kind)
}
elemContext := Context{
Scope: ScopeMapKey,
Type: t.Elem,
Type: nt.Elem,
Path: context.Path.Key("(keys)"),
Member: nil, // NA for map keys
ParentPath: context.Path,
Path: context.Path.Child("(keys)"),
}
if validations, err := ektv.validator.ExtractValidations(elemContext, *tag.ValueTag); err != nil {
@@ -595,12 +599,13 @@ func (ektv eachKeyTagValidator) GetValidations(context Context, tag codetags.Tag
}
func (ektv eachKeyTagValidator) getValidations(t *types.Type, validations Validations) (Validations, error) {
nt := util.NativeType(t)
result := Validations{}
result.OpaqueKeyType = validations.OpaqueType
for _, vfn := range validations.Functions {
comm := vfn.Comments
vfn.Comments = nil
f := Function(eachKeyTagName, vfn.Flags, validateEachMapKey, WrapperFunction{vfn, t.Key}).WithComments(comm...)
f := Function(eachKeyTagName, vfn.Flags, validateEachMapKey, WrapperFunction{vfn, nt.Key}).WithComments(comm...)
result.AddFunction(f)
}
return result, nil

View File

@@ -261,8 +261,8 @@ func (iv itemValidator) GetValidations(context Context) (Validations, error) {
Scope: ScopeListVal,
Type: elemT,
Path: context.Path.Key(subContextPath),
Member: nil, // NA for list items
ParentPath: context.Path,
Member: nil,
}
validations, err := iv.validator.ExtractValidations(subContext, item.valueTag)

View File

@@ -59,12 +59,13 @@ func (stv subfieldTagValidator) GetValidations(context Context, tag codetags.Tag
args := tag.Args
// This tag can apply to value and pointer fields, as well as typedefs
// (which should never be pointers). We need to check the concrete type.
t := util.NonPointer(util.NativeType(context.Type))
if t.Kind != types.Struct {
return Validations{}, fmt.Errorf("can only be used on struct types")
t := context.Type
nt := util.NonPointer(util.NativeType(t))
if nt.Kind != types.Struct {
return Validations{}, fmt.Errorf("can only be used on struct types: %v", nt.Kind)
}
subname := args[0].Value
submemb := util.GetMemberByJSON(t, subname)
submemb := util.GetMemberByJSON(nt, subname)
if submemb == nil {
return Validations{}, fmt.Errorf("no field for json name %q", subname)
}
@@ -72,9 +73,9 @@ func (stv subfieldTagValidator) GetValidations(context Context, tag codetags.Tag
subContext := Context{
Scope: ScopeField,
Type: submemb.Type,
ParentPath: context.Path,
Member: submemb,
Path: context.Path.Child(subname),
Member: submemb,
ParentPath: context.Path,
}
if validations, err := stv.validator.ExtractValidations(subContext, *tag.ValueTag); err != nil {
return Validations{}, err