Browse Source

codecgen: fix packageName to use valid go identifier

Previously, an import path like github.com/ugorji/go-codec would fail
during codecgen. This is because we used the last part of the path to
determine the packageName. However, package names can only contain
unicode letters, digits and underscores.

We now take the last path, and coerce it into a valid go identifier.

Fixes #127
Ugorji Nwoke 10 năm trước cách đây
mục cha
commit
53d1166d60
1 tập tin đã thay đổi với 23 bổ sung1 xóa
  1. 23 1
      codec/gen.go

+ 23 - 1
codec/gen.go

@@ -21,6 +21,8 @@ import (
 	"sync"
 	"text/template"
 	"time"
+	"unicode"
+	"unicode/utf8"
 )
 
 // ---------------------------------------------------
@@ -377,7 +379,7 @@ func (x *genRunner) genRefPkgs(t reflect.Type) {
 				x.imn[tpkg] = tpkg
 			} else {
 				x.imc++
-				x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + tpkg[idx+1:]
+				x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false)
 			}
 		}
 	}
@@ -1639,6 +1641,26 @@ func genImportPath(t reflect.Type) (s string) {
 	return
 }
 
+// A go identifier is (letter|_)[letter|number|_]*
+func genGoIdentifier(s string, checkFirstChar bool) string {
+	b := make([]byte, 0, len(s))
+	t := make([]byte, 4)
+	var n int
+	for i, r := range s {
+		if checkFirstChar && i == 0 && !unicode.IsLetter(r) {
+			b = append(b, '_')
+		}
+		// r must be unicode_letter, unicode_digit or _
+		if unicode.IsLetter(r) || unicode.IsNumber(r) {
+			n = utf8.EncodeRune(t, r)
+			b = append(b, t[:n]...)
+		} else {
+			b = append(b, '_')
+		}
+	}
+	return string(b)
+}
+
 func genNonPtr(t reflect.Type) reflect.Type {
 	for t.Kind() == reflect.Ptr {
 		t = t.Elem()