Browse Source

codecgen: Fix array decoding and generate code for Elem of seen reflect.Type

When we saw a reflect.Type, we recorded that a custom function for it
should be generated. However, we didn't record that possible Element types should
have generated code also. E.g. if we say [][2]int, we would generate
code for [][2]int, but not for [2]int, but the generated code for [][2]int
assumed that there was generated code for [2]int.

This is now fixed.

Also, the code generated for arrays kept some unused variables lurking.
This is now also fixed.

Fixes #118
Ugorji Nwoke 10 years ago
parent
commit
1fff025aa9
3 changed files with 28 additions and 5 deletions
  1. 3 1
      codec/gen-dec-array.go.tmpl
  2. 3 1
      codec/gen.generated.go
  3. 22 3
      codec/gen.go

+ 3 - 1
codec/gen-dec-array.go.tmpl

@@ -1,6 +1,7 @@
 {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
 var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
 if {{var "l"}} == 0 {
 	{{if isSlice }}if {{var "v"}} == nil {
 		{{var "v"}} = []{{ .Typ }}{}
@@ -26,6 +27,7 @@ if {{var "l"}} == 0 {
 	}
 	{{ else }}	var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
 	var {{var "rt"}} bool {{/* truncated */}}
+	_, _, _ = {{var "rr"}}, {{var "rl"}}, {{var "rt"}}
 	if {{var "l"}} > cap({{var "v"}}) {
 		{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
 		{{ else }}{{if not .Immutable }}

+ 3 - 1
codec/gen.generated.go

@@ -68,8 +68,9 @@ z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
 
 const genDecListTmpl = `
 {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
-{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
+{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
 var {{var "c"}} bool {{/* // changed */}}
+_ = {{var "c"}}{{end}}
 if {{var "l"}} == 0 {
 	{{if isSlice }}if {{var "v"}} == nil {
 		{{var "v"}} = []{{ .Typ }}{}
@@ -95,6 +96,7 @@ if {{var "l"}} == 0 {
 	}
 	{{ else }}	var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
 	var {{var "rt"}} bool {{/* truncated */}}
+	_, _, _ = {{var "rr"}}, {{var "rl"}}, {{var "rt"}}
 	if {{var "l"}} > cap({{var "v"}}) {
 		{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}})
 		{{ else }}{{if not .Immutable }}

+ 22 - 3
codec/gen.go

@@ -566,9 +566,28 @@ func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) {
 	} else {
 		x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname)
 	}
-	if _, ok := x.tm[t]; !ok {
-		x.tm[t] = struct{}{}
-		x.ts = append(x.ts, t)
+	x.registerXtraT(t)
+}
+
+func (x *genRunner) registerXtraT(t reflect.Type) {
+	// recursively register the types
+	if _, ok := x.tm[t]; ok {
+		return
+	}
+	var tkey reflect.Type
+	switch t.Kind() {
+	case reflect.Chan, reflect.Slice, reflect.Array:
+	case reflect.Map:
+		tkey = t.Key()
+	default:
+		return
+	}
+	x.tm[t] = struct{}{}
+	x.ts = append(x.ts, t)
+	// check if this refers to any xtra types eg. a slice of array: add the array
+	x.registerXtraT(t.Elem())
+	if tkey != nil {
+		x.registerXtraT(tkey)
 	}
 }