@@ -43,7 +43,7 @@ type structVM struct {
43
43
fieldsWithIndirectStructVM []* fieldVM
44
44
exprs map [string ]* Expr
45
45
exprSelectorList []string
46
- ifaceTagExprGetters []func (unsafe.Pointer ) ( te * TagExpr , ok bool )
46
+ ifaceTagExprGetters []func (unsafe.Pointer , func ( * TagExpr ) bool ) bool
47
47
}
48
48
49
49
// fieldVM tag expression set of struct field
@@ -77,6 +77,14 @@ func New(tagName ...string) *VM {
77
77
}
78
78
}
79
79
80
+ // MustWarmUp is similar to WarmUp, but panic when error.
81
+ func (vm * VM ) MustWarmUp (structOrStructPtrOrReflect ... interface {}) {
82
+ err := vm .WarmUp (structOrStructPtrOrReflect ... )
83
+ if err != nil {
84
+ panic (err )
85
+ }
86
+ }
87
+
80
88
// WarmUp preheating some interpreters of the struct type in batches,
81
89
// to improve the performance of the vm.Run.
82
90
func (vm * VM ) WarmUp (structOrStructPtrOrReflect ... interface {}) error {
@@ -101,12 +109,13 @@ func (vm *VM) WarmUp(structOrStructPtrOrReflect ...interface{}) error {
101
109
return nil
102
110
}
103
111
104
- // MustWarmUp is similar to WarmUp , but panic when error.
105
- func (vm * VM ) MustWarmUp ( structOrStructPtrOrReflect ... interface {}) {
106
- err := vm .WarmUp ( structOrStructPtrOrReflect ... )
112
+ // MustRun is similar to Run , but panic when error.
113
+ func (vm * VM ) MustRun ( structOrStructPtrOrReflectValue interface {}) * TagExpr {
114
+ te , err := vm .Run ( structOrStructPtrOrReflectValue )
107
115
if err != nil {
108
116
panic (err )
109
117
}
118
+ return te
110
119
}
111
120
112
121
// Run returns the tag expression handler of the @structOrStructPtrOrReflectValue.
@@ -150,13 +159,88 @@ func (vm *VM) Run(structOrStructPtrOrReflectValue interface{}) (*TagExpr, error)
150
159
return s .newTagExpr (ptr ), nil
151
160
}
152
161
153
- // MustRun is similar to Run, but panic when error.
154
- func (vm * VM ) MustRun (structOrStructPtrOrReflectValue interface {}) * TagExpr {
155
- te , err := vm .Run (structOrStructPtrOrReflectValue )
156
- if err != nil {
157
- panic (err )
162
+ func (vm * VM ) subRunAll (omitNil bool , value reflect.Value , fn func (* TagExpr ) bool ) bool {
163
+ rv := goutil .DereferenceIfaceValue (value )
164
+ rt := goutil .DereferenceType (rv .Type ())
165
+ rv = goutil .DereferenceValue (rv )
166
+ switch rt .Kind () {
167
+ case reflect .Struct :
168
+ if omitNil && ! rv .IsValid () {
169
+ return true
170
+ }
171
+ te , err := vm .subRun (rt , tpack .RuntimeTypeID (rt ), unsafe .Pointer (tpack .From (rv ).Pointer ()))
172
+ if err != nil {
173
+ return true
174
+ }
175
+ return fn (te )
176
+
177
+ case reflect .Slice , reflect .Array :
178
+ count := rv .Len ()
179
+ if count == 0 {
180
+ return true
181
+ }
182
+ switch goutil .DereferenceType (rv .Type ().Elem ()).Kind () {
183
+ case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
184
+ for i := count - 1 ; i >= 0 ; i -- {
185
+ if ! vm .subRunAll (omitNil , rv .Index (i ), fn ) {
186
+ return false
187
+ }
188
+ }
189
+ default :
190
+ return true
191
+ }
192
+
193
+ case reflect .Map :
194
+ if rv .Len () == 0 {
195
+ return true
196
+ }
197
+ var canKey , canValue bool
198
+ rt := rv .Type ()
199
+ switch goutil .DereferenceType (rt .Key ()).Kind () {
200
+ case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
201
+ canKey = true
202
+ }
203
+ switch goutil .DereferenceType (rt .Elem ()).Kind () {
204
+ case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
205
+ canValue = true
206
+ }
207
+ if ! canKey && ! canValue {
208
+ return true
209
+ }
210
+ for _ , key := range rv .MapKeys () {
211
+ if canKey {
212
+ if ! vm .subRunAll (omitNil , key , fn ) {
213
+ return false
214
+ }
215
+ }
216
+ if canValue {
217
+ if ! vm .subRunAll (omitNil , rv .MapIndex (key ), fn ) {
218
+ return false
219
+ }
220
+ }
221
+ }
158
222
}
159
- return te
223
+ return true
224
+ }
225
+
226
+ func (vm * VM ) subRun (t reflect.Type , tid int32 , ptr unsafe.Pointer ) (* TagExpr , error ) {
227
+ var err error
228
+ vm .rw .RLock ()
229
+ s , ok := vm .structJar [tid ]
230
+ vm .rw .RUnlock ()
231
+ if ! ok {
232
+ vm .rw .Lock ()
233
+ s , ok = vm .structJar [tid ]
234
+ if ! ok {
235
+ s , err = vm .registerStructLocked (t )
236
+ if err != nil {
237
+ vm .rw .Unlock ()
238
+ return nil , err
239
+ }
240
+ }
241
+ vm .rw .Unlock ()
242
+ }
243
+ return s .newTagExpr (ptr ), nil
160
244
}
161
245
162
246
func (vm * VM ) registerStructLocked (structType reflect.Type ) (* structVM , error ) {
@@ -313,6 +397,35 @@ func (f *fieldVM) ensureInit(v reflect.Value) {
313
397
}
314
398
}
315
399
400
+ func (s * structVM ) mergeSubStructVM (field * fieldVM , sub * structVM ) {
401
+ field .origin = sub
402
+ nameSpace := field .structField .Name
403
+ fieldsWithIndirectStructVM := make (map [* fieldVM ]struct {}, len (sub .fieldsWithIndirectStructVM ))
404
+ for _ , subField := range sub .fieldsWithIndirectStructVM {
405
+ fieldsWithIndirectStructVM [subField ] = struct {}{}
406
+ }
407
+ for _ , k := range sub .fieldSelectorList {
408
+ v := sub .fields [k ]
409
+ f := s .newChildField (field , v )
410
+ fieldSelector := nameSpace + FieldSeparator + k
411
+ s .fields [fieldSelector ] = f
412
+ s .fieldSelectorList = append (s .fieldSelectorList , fieldSelector )
413
+ if _ , ok := fieldsWithIndirectStructVM [v ]; ok {
414
+ s .fieldsWithIndirectStructVM = append (s .fieldsWithIndirectStructVM , f )
415
+ }
416
+ }
417
+ for _ , _subFn := range sub .ifaceTagExprGetters {
418
+ subFn := _subFn
419
+ s .ifaceTagExprGetters = append (s .ifaceTagExprGetters , func (ptr unsafe.Pointer , fn func (* TagExpr ) bool ) bool {
420
+ ptr = field .getElemPtr (ptr )
421
+ if ptr == nil {
422
+ return true
423
+ }
424
+ return subFn (ptr , fn )
425
+ })
426
+ }
427
+ }
428
+
316
429
func (s * structVM ) newChildField (parent * fieldVM , child * fieldVM ) * fieldVM {
317
430
f := & fieldVM {
318
431
structField : child .structField ,
@@ -324,8 +437,6 @@ func (s *structVM) newChildField(parent *fieldVM, child *fieldVM) *fieldVM {
324
437
mapKeyStructVM : child .mapKeyStructVM ,
325
438
mapOrSliceElemStructVM : child .mapOrSliceElemStructVM ,
326
439
mapOrSliceIfaceKinds : child .mapOrSliceIfaceKinds ,
327
- // valueGetter: child.valueGetter,
328
- // reflectValueGetter: child.reflectValueGetter,
329
440
}
330
441
331
442
f .getPtr = func (ptr unsafe.Pointer ) unsafe.Pointer {
@@ -387,26 +498,6 @@ func (s *structVM) newChildField(parent *fieldVM, child *fieldVM) *fieldVM {
387
498
return f
388
499
}
389
500
390
- func (s * structVM ) mergeSubStructVM (field * fieldVM , sub * structVM ) {
391
- field .origin = sub
392
- nameSpace := field .structField .Name
393
- fieldsWithIndirectStructVM := make (map [* fieldVM ]struct {}, len (sub .fieldsWithIndirectStructVM ))
394
- for _ , subField := range sub .fieldsWithIndirectStructVM {
395
- fieldsWithIndirectStructVM [subField ] = struct {}{}
396
- }
397
- // sub.ifaceTagExprGetters
398
- for _ , k := range sub .fieldSelectorList {
399
- v := sub .fields [k ]
400
- f := s .newChildField (field , v )
401
- fieldSelector := nameSpace + FieldSeparator + k
402
- s .fields [fieldSelector ] = f
403
- s .fieldSelectorList = append (s .fieldSelectorList , fieldSelector )
404
- if _ , ok := fieldsWithIndirectStructVM [v ]; ok {
405
- s .fieldsWithIndirectStructVM = append (s .fieldsWithIndirectStructVM , f )
406
- }
407
- }
408
- }
409
-
410
501
func (f * fieldVM ) getElemPtr (ptr unsafe.Pointer ) unsafe.Pointer {
411
502
ptr = f .getPtr (ptr )
412
503
for i := f .ptrDeep ; ptr != nil && i > 0 ; i -- {
@@ -427,44 +518,15 @@ func (s *structVM) setIfaceTagExprGetter(f *fieldVM) {
427
518
if f .tagOp == tagOmit {
428
519
return
429
520
}
430
- s .ifaceTagExprGetters = append (s .ifaceTagExprGetters , func (ptr unsafe.Pointer ) (* TagExpr , bool ) {
521
+ s .ifaceTagExprGetters = append (s .ifaceTagExprGetters , func (ptr unsafe.Pointer , fn func (* TagExpr ) bool ) bool {
431
522
v := f .packElemFrom (ptr )
432
523
if ! v .IsValid () || v .IsNil () {
433
- return nil , false
434
- }
435
- te , ok := s .vm .runFromValue (v )
436
- if ! ok {
437
- return nil , false
524
+ return true
438
525
}
439
- return te , true
526
+ return s . vm . subRunAll ( f . tagOp == tagOmitNil , v , fn )
440
527
})
441
528
}
442
529
443
- func (vm * VM ) runFromValue (v reflect.Value ) (* TagExpr , bool ) {
444
- u := tpack .From (v ).UnderlyingElem ()
445
- if u .Kind () != reflect .Struct {
446
- return nil , false
447
- }
448
- tid := u .RuntimeTypeID ()
449
- var err error
450
- vm .rw .RLock ()
451
- s , ok := vm .structJar [tid ]
452
- vm .rw .RUnlock ()
453
- if ! ok {
454
- vm .rw .Lock ()
455
- s , ok = vm .structJar [tid ]
456
- if ! ok {
457
- s , err = vm .registerStructLocked (v .Elem ().Type ())
458
- if err != nil {
459
- vm .rw .Unlock ()
460
- return nil , false
461
- }
462
- }
463
- vm .rw .Unlock ()
464
- }
465
- return s .newTagExpr (unsafe .Pointer (u .Pointer ())), true
466
- }
467
-
468
530
func (f * fieldVM ) setFloatGetter () {
469
531
if f .ptrDeep == 0 {
470
532
f .valueGetter = func (ptr unsafe.Pointer ) interface {} {
@@ -690,17 +752,6 @@ func (t *TagExpr) Range(fn func(es ExprSelector, eval func() interface{}) bool)
690
752
}
691
753
692
754
ptr := t .ptr
693
- if list := t .s .ifaceTagExprGetters ; len (list ) > 0 {
694
- var te * TagExpr
695
- var ok bool
696
- for _ , getter := range list {
697
- if te , ok = getter (ptr ); ok {
698
- if ! te .Range (fn ) {
699
- return false
700
- }
701
- }
702
- }
703
- }
704
755
705
756
if list := t .s .fieldsWithIndirectStructVM ; len (list ) > 0 {
706
757
for _ , f := range list {
@@ -759,91 +810,23 @@ func (t *TagExpr) Range(fn func(es ExprSelector, eval func() interface{}) bool)
759
810
}
760
811
}
761
812
}
762
- return true
763
- }
764
813
765
- func (t * TagExpr ) subRange (omitNil bool , value reflect.Value , fn func (es ExprSelector , eval func () interface {}) bool ) bool {
766
- rv := goutil .DereferenceIfaceValue (value )
767
- rt := goutil .DereferenceType (rv .Type ())
768
- rv = goutil .DereferenceValue (rv )
769
- switch rt .Kind () {
770
- case reflect .Struct :
771
- if omitNil && ! rv .IsValid () {
772
- return true
773
- }
774
- te , err := t .s .vm .subRun (rt , tpack .RuntimeTypeID (rt ), unsafe .Pointer (tpack .From (rv ).Pointer ()))
775
- if err != nil {
776
- return false
777
- }
778
- return te .Range (fn )
779
-
780
- case reflect .Slice , reflect .Array :
781
- count := rv .Len ()
782
- if count == 0 {
783
- return true
784
- }
785
- switch goutil .DereferenceType (rv .Type ().Elem ()).Kind () {
786
- case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
787
- for i := count - 1 ; i >= 0 ; i -- {
788
- if ! t .subRange (omitNil , rv .Index (i ), fn ) {
789
- return false
790
- }
791
- }
792
- default :
793
- return true
794
- }
795
-
796
- case reflect .Map :
797
- if rv .Len () == 0 {
798
- return true
799
- }
800
- var canKey , canValue bool
801
- rt := rv .Type ()
802
- switch goutil .DereferenceType (rt .Key ()).Kind () {
803
- case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
804
- canKey = true
805
- }
806
- switch goutil .DereferenceType (rt .Elem ()).Kind () {
807
- case reflect .Struct , reflect .Interface , reflect .Slice , reflect .Array , reflect .Map :
808
- canValue = true
809
- }
810
- if ! canKey && ! canValue {
811
- return true
812
- }
813
- for _ , key := range rv .MapKeys () {
814
- if canKey {
815
- if ! t .subRange (omitNil , key , fn ) {
816
- return false
817
- }
818
- }
819
- if canValue {
820
- if ! t .subRange (omitNil , rv .MapIndex (key ), fn ) {
821
- return false
822
- }
814
+ if list := t .s .ifaceTagExprGetters ; len (list ) > 0 {
815
+ for _ , getter := range list {
816
+ if ! getter (ptr , func (te * TagExpr ) bool {
817
+ return te .Range (fn )
818
+ }) {
819
+ return false
823
820
}
824
821
}
825
822
}
826
823
return true
827
824
}
828
825
829
- func (vm * VM ) subRun (t reflect.Type , tid int32 , ptr unsafe.Pointer ) (* TagExpr , error ) {
830
- var err error
831
- vm .rw .RLock ()
832
- s , ok := vm .structJar [tid ]
833
- vm .rw .RUnlock ()
834
- if ! ok {
835
- vm .rw .Lock ()
836
- s , ok = vm .structJar [tid ]
837
- if ! ok {
838
- s , err = vm .registerStructLocked (t )
839
- if err != nil {
840
- vm .rw .Unlock ()
841
- return nil , err
842
- }
843
- }
844
- vm .rw .Unlock ()
845
- }
846
- return s .newTagExpr (ptr ), nil
826
+ func (t * TagExpr ) subRange (omitNil bool , value reflect.Value , fn func (es ExprSelector , eval func () interface {}) bool ) bool {
827
+ return t .s .vm .subRunAll (omitNil , value , func (te * TagExpr ) bool {
828
+ return te .Range (fn )
829
+ })
847
830
}
848
831
849
832
var (
0 commit comments