diff options
author | Joe Tsai <joetsai@digital-static.net> | 2019-02-16 21:39:33 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-16 21:39:33 -0800 |
commit | 8ca8745eefdc2a98d5e00dab0e88b036d7bcd62c (patch) | |
tree | c968a52a585811a945cdc1965a1e26602dacbfa1 /cmp/compare.go | |
parent | fb7c318bbf8ca09bdddb5fbd1d721927abca6077 (diff) | |
download | go-cmp-8ca8745eefdc2a98d5e00dab0e88b036d7bcd62c.tar.gz |
Reorder logic to be consistent (#107)
Reorder logic to consistently handle steps in the order of:
StructField, SliceIndex, MapIndex, Indirect, TypeAssertion
Diffstat (limited to 'cmp/compare.go')
-rw-r--r-- | cmp/compare.go | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/cmp/compare.go b/cmp/compare.go index 30196a4..7d172ba 100644 --- a/cmp/compare.go +++ b/cmp/compare.go @@ -240,6 +240,21 @@ func (s *state) compareAny(vx, vy reflect.Value) { case reflect.Func: s.report(vx.IsNil() && vy.IsNil(), vx, vy) return + case reflect.Struct: + s.compareStruct(vx, vy, t) + return + case reflect.Slice: + if vx.IsNil() || vy.IsNil() { + s.report(vx.IsNil() && vy.IsNil(), vx, vy) + return + } + fallthrough + case reflect.Array: + s.compareSlice(vx, vy, t) + return + case reflect.Map: + s.compareMap(vx, vy, t) + return case reflect.Ptr: if vx.IsNil() || vy.IsNil() { s.report(vx.IsNil() && vy.IsNil(), vx, vy) @@ -262,21 +277,6 @@ func (s *state) compareAny(vx, vy reflect.Value) { defer s.curPath.pop() s.compareAny(vx.Elem(), vy.Elem()) return - case reflect.Slice: - if vx.IsNil() || vy.IsNil() { - s.report(vx.IsNil() && vy.IsNil(), vx, vy) - return - } - fallthrough - case reflect.Array: - s.compareArray(vx, vy, t) - return - case reflect.Map: - s.compareMap(vx, vy, t) - return - case reflect.Struct: - s.compareStruct(vx, vy, t) - return default: panic(fmt.Sprintf("%v kind not handled", t.Kind())) } @@ -393,7 +393,42 @@ func sanitizeValue(v reflect.Value, t reflect.Type) reflect.Value { return v } -func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) { +func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) { + var vax, vay reflect.Value // Addressable versions of vx and vy + + step := &structField{} + s.curPath.push(step) + defer s.curPath.pop() + for i := 0; i < t.NumField(); i++ { + vvx := vx.Field(i) + vvy := vy.Field(i) + step.typ = t.Field(i).Type + step.name = t.Field(i).Name + step.idx = i + step.unexported = !isExported(step.name) + if step.unexported { + if step.name == "_" { + continue + } + // Defer checking of unexported fields until later to give an + // Ignore a chance to ignore the field. + if !vax.IsValid() || !vay.IsValid() { + // For unsafeRetrieveField to work, the parent struct must + // be addressable. Create a new copy of the values if + // necessary to make them addressable. + vax = makeAddressable(vx) + vay = makeAddressable(vy) + } + step.force = s.exporters[t] + step.pvx = vax + step.pvy = vay + step.field = t.Field(i) + } + s.compareAny(vvx, vvy) + } +} + +func (s *state) compareSlice(vx, vy reflect.Value, t reflect.Type) { step := &sliceIndex{pathStep{t.Elem()}, 0, 0} s.curPath.push(step) @@ -477,41 +512,6 @@ func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) { } } -func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) { - var vax, vay reflect.Value // Addressable versions of vx and vy - - step := &structField{} - s.curPath.push(step) - defer s.curPath.pop() - for i := 0; i < t.NumField(); i++ { - vvx := vx.Field(i) - vvy := vy.Field(i) - step.typ = t.Field(i).Type - step.name = t.Field(i).Name - step.idx = i - step.unexported = !isExported(step.name) - if step.unexported { - if step.name == "_" { - continue - } - // Defer checking of unexported fields until later to give an - // Ignore a chance to ignore the field. - if !vax.IsValid() || !vay.IsValid() { - // For unsafeRetrieveField to work, the parent struct must - // be addressable. Create a new copy of the values if - // necessary to make them addressable. - vax = makeAddressable(vx) - vay = makeAddressable(vy) - } - step.force = s.exporters[t] - step.pvx = vax - step.pvy = vay - step.field = t.Field(i) - } - s.compareAny(vvx, vvy) - } -} - // report records the result of a single comparison. // It also calls Report if any reporter is registered. func (s *state) report(eq bool, vx, vy reflect.Value) { |