Kaynağa Gözat

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 yıl önce
ebeveyn
işleme
53d1166d60
1 değiştirilmiş dosya ile 23 ekleme ve 1 silme
  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()