diff --git a/_generated/def.go b/_generated/def.go index 34cd871e..eac1d5ec 100644 --- a/_generated/def.go +++ b/_generated/def.go @@ -63,7 +63,7 @@ type X struct { type TestType struct { F *float64 `msg:"float"` Els map[string]string `msg:"elements"` - Obj struct { // test anonymous struct + Obj struct { // test anonymous struct ValueA string `msg:"value_a"` ValueB []byte `msg:"value_b"` } `msg:"object"` @@ -356,3 +356,21 @@ type Numberwang int8 type ExternalString string type ExternalArr [4]byte type ExternalInt int + +//msgp:ignore regex:IGNORE + +type RegexIGNORETest struct{} + +// Will fail to compile if also generated +func (z *RegexIGNORETest) Msgsize() int { + return 0 +} + +//msgp:size ignore regex:IGNSIZE + +type RegexIGNSIZETest struct{} + +// Will fail to compile if also generated +func (z *RegexIGNSIZETest) Msgsize() int { + return 0 +} diff --git a/gen/spec.go b/gen/spec.go index 45b514ad..b28f5420 100644 --- a/gen/spec.go +++ b/gen/spec.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "math" + "regexp" "strings" ) @@ -128,6 +129,19 @@ type TransformPass func(Elem) Elem // IgnoreTypename is a pass that just ignores // types of a given name. func IgnoreTypename(name string) TransformPass { + if name, ok := strings.CutPrefix(name, "regex:"); ok { + name = strings.TrimPrefix(name, "regex:") + rx, err := regexp.Compile(name) + if err != nil { + panic(fmt.Sprintf("Error compiling ignore regex %q: %v", name, err)) + } + return func(e Elem) Elem { + if rx.MatchString(e.TypeName()) { + return nil + } + return e + } + } return func(e Elem) Elem { if e.TypeName() == name { return nil @@ -193,17 +207,17 @@ func (c contextVar) Arg() string { } type Context struct { - path []contextItem - compFloats bool - clearOmitted bool - newTime bool - asUTC bool - arrayLimit uint32 - mapLimit uint32 - marshalLimits bool - limitPrefix string - currentFieldArrayLimit uint32 // Current field's array limit (0 = no field-level limit) - currentFieldMapLimit uint32 // Current field's map limit (0 = no field-level limit) + path []contextItem + compFloats bool + clearOmitted bool + newTime bool + asUTC bool + arrayLimit uint32 + mapLimit uint32 + marshalLimits bool + limitPrefix string + currentFieldArrayLimit uint32 // Current field's array limit (0 = no field-level limit) + currentFieldMapLimit uint32 // Current field's map limit (0 = no field-level limit) } func (c *Context) PushString(s string) { diff --git a/parse/directives.go b/parse/directives.go index 09474a6f..05a1597d 100644 --- a/parse/directives.go +++ b/parse/directives.go @@ -4,6 +4,7 @@ import ( "fmt" "go/ast" "go/parser" + "regexp" "strconv" "strings" @@ -167,6 +168,22 @@ func ignore(text []string, f *FileSet) error { } for _, item := range text[1:] { name := strings.TrimSpace(item) + if name, ok := strings.CutPrefix(name, "regex:"); ok { + name = strings.TrimPrefix(name, "regex:") + rx, err := regexp.Compile(name) + if err != nil { + panic(fmt.Sprintf("Error compiling ignore regex %q: %v", name, err)) + } + for name := range f.Identities { + if !rx.MatchString(name) { + continue + } + delete(f.Identities, name) + infof("ignoring %s\n", name) + } + continue + } + if _, ok := f.Identities[name]; ok { delete(f.Identities, name) infof("ignoring %s\n", name)