mirror of
https://github.com/netbirdio/easyjson.git
synced 2026-05-22 18:44:42 -07:00
Merge pull request #35 from Barberrrry/camel_case_functions
Generate CamelCase function names instead of under_score to pass golint check
This commit is contained in:
@@ -5,3 +5,4 @@ go:
|
||||
install:
|
||||
- go get github.com/ugorji/go/codec
|
||||
- go get github.com/pquerna/ffjson/fflib/v1
|
||||
- go get github.com/golang/lint/golint
|
||||
|
||||
@@ -26,7 +26,7 @@ generate: root build
|
||||
.root/bin/easyjson -all .root/src/$(PKG)/tests/data.go
|
||||
.root/bin/easyjson -all .root/src/$(PKG)/tests/nothing.go
|
||||
.root/bin/easyjson -snake_case .root/src/$(PKG)/tests/snake.go
|
||||
.root/bin/easyjson -omit_empty .root/src/$(PKG)/tests/omitempty.go
|
||||
.root/bin/easyjson -omit_empty .root/src/$(PKG)/tests/omitempty.go
|
||||
.root/bin/easyjson -build_tags=use_easyjson .root/src/$(PKG)/benchmark/data.go
|
||||
|
||||
test: generate root
|
||||
@@ -36,6 +36,7 @@ test: generate root
|
||||
$(PKG)/gen \
|
||||
$(PKG)/buffer
|
||||
go test -benchmem -tags use_easyjson -bench . $(PKG)/benchmark
|
||||
golint -set_exit_status .root/src/$(PKG)/tests/*_easyjson.go
|
||||
|
||||
bench-other: generate root
|
||||
@go test -benchmem -bench . $(PKG)/benchmark
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ func generate(fname string) (err error) {
|
||||
if *specifiedName != "" {
|
||||
outName = *specifiedName
|
||||
}
|
||||
|
||||
|
||||
g := bootstrap.Generator{
|
||||
BuildTags: *buildTags,
|
||||
PkgPath: p.PkgPath,
|
||||
|
||||
+5
-3
@@ -14,7 +14,7 @@ import (
|
||||
const minSliceBytes = 64
|
||||
|
||||
func (g *Generator) getDecoderName(t reflect.Type) string {
|
||||
return g.functionName("decode_", t)
|
||||
return g.functionName("decode", t)
|
||||
}
|
||||
|
||||
var primitiveDecoders = map[reflect.Kind]string{
|
||||
@@ -169,7 +169,7 @@ func (g *Generator) genTypeDecoderNoCheck(t reflect.Type, out string, tags field
|
||||
}
|
||||
|
||||
func (g *Generator) genStructFieldDecoder(t reflect.Type, f reflect.StructField) error {
|
||||
jsonName := g.namer.GetJSONFieldName(t, f)
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if tags.omit {
|
||||
@@ -199,7 +199,7 @@ func (g *Generator) genRequiredFieldSet(t reflect.Type, f reflect.StructField) {
|
||||
}
|
||||
|
||||
func (g *Generator) genRequiredFieldCheck(t reflect.Type, f reflect.StructField) {
|
||||
jsonName := g.namer.GetJSONFieldName(t, f)
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if !tags.required {
|
||||
@@ -368,6 +368,7 @@ func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
|
||||
typ := g.getType(t)
|
||||
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "// UnmarshalJSON supports json.Unmarshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalJSON(data []byte) error {")
|
||||
fmt.Fprintln(g.out, " r := jlexer.Lexer{Data: data}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&r, v)")
|
||||
@@ -375,6 +376,7 @@ func (g *Generator) genStructUnmarshaller(t reflect.Type) error {
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "// UnmarshalEasyJSON supports easyjson.Unmarshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v *"+typ+") UnmarshalEasyJSON(l *jlexer.Lexer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(l, v)")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
+10
-8
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func (g *Generator) getEncoderName(t reflect.Type) string {
|
||||
return g.functionName("encode_", t)
|
||||
return g.functionName("encode", t)
|
||||
}
|
||||
|
||||
var primitiveEncoders = map[reflect.Kind]string{
|
||||
@@ -155,14 +155,14 @@ func (g *Generator) genTypeEncoderNoCheck(t reflect.Type, in string, tags fieldT
|
||||
fmt.Fprintln(g.out, ws+" out.RawString(`null`)")
|
||||
fmt.Fprintln(g.out, ws+"} else {")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte('{')")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"_first := true")
|
||||
fmt.Fprintln(g.out, ws+" for "+tmpVar+"_name, "+tmpVar+"_value := range "+in+" {")
|
||||
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"_first { out.RawByte(',') }")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"_first = false")
|
||||
fmt.Fprintln(g.out, ws+" out.String(string("+tmpVar+"_name))")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"First := true")
|
||||
fmt.Fprintln(g.out, ws+" for "+tmpVar+"Name, "+tmpVar+"Value := range "+in+" {")
|
||||
fmt.Fprintln(g.out, ws+" if !"+tmpVar+"First { out.RawByte(',') }")
|
||||
fmt.Fprintln(g.out, ws+" "+tmpVar+"First = false")
|
||||
fmt.Fprintln(g.out, ws+" out.String(string("+tmpVar+"Name))")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte(':')")
|
||||
|
||||
g.genTypeEncoder(t.Elem(), tmpVar+"_value", tags, indent+2)
|
||||
g.genTypeEncoder(t.Elem(), tmpVar+"Value", tags, indent+2)
|
||||
|
||||
fmt.Fprintln(g.out, ws+" }")
|
||||
fmt.Fprintln(g.out, ws+" out.RawByte('}')")
|
||||
@@ -207,7 +207,7 @@ func (g *Generator) notEmptyCheck(t reflect.Type, v string) string {
|
||||
}
|
||||
|
||||
func (g *Generator) genStructFieldEncoder(t reflect.Type, f reflect.StructField) error {
|
||||
jsonName := g.namer.GetJSONFieldName(t, f)
|
||||
jsonName := g.fieldNamer.GetJSONFieldName(t, f)
|
||||
tags := parseFieldTags(f)
|
||||
|
||||
if tags.omit {
|
||||
@@ -296,6 +296,7 @@ func (g *Generator) genStructMarshaller(t reflect.Type) error {
|
||||
typ := g.getType(t)
|
||||
|
||||
if !g.noStdMarshalers {
|
||||
fmt.Fprintln(g.out, "// MarshalJSON supports json.Marshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v "+typ+") MarshalJSON() ([]byte, error) {")
|
||||
fmt.Fprintln(g.out, " w := jwriter.Writer{}")
|
||||
fmt.Fprintln(g.out, " "+fname+"(&w, v)")
|
||||
@@ -303,6 +304,7 @@ func (g *Generator) genStructMarshaller(t reflect.Type) error {
|
||||
fmt.Fprintln(g.out, "}")
|
||||
}
|
||||
|
||||
fmt.Fprintln(g.out, "// MarshalEasyJSON supports easyjson.Marshaler interface")
|
||||
fmt.Fprintln(g.out, "func (v "+typ+") MarshalEasyJSON(w *jwriter.Writer) {")
|
||||
fmt.Fprintln(g.out, " "+fname+"(w, v)")
|
||||
fmt.Fprintln(g.out, "}")
|
||||
|
||||
+33
-14
@@ -27,13 +27,13 @@ type Generator struct {
|
||||
pkgName string
|
||||
pkgPath string
|
||||
buildTags string
|
||||
funcPrefix string
|
||||
hashString string
|
||||
|
||||
varCounter int
|
||||
|
||||
noStdMarshalers bool
|
||||
omitEmpty bool
|
||||
namer FieldNamer
|
||||
fieldNamer FieldNamer
|
||||
|
||||
// package path to local alias map for tracking imports
|
||||
imports map[string]string
|
||||
@@ -60,7 +60,7 @@ func NewGenerator(filename string) *Generator {
|
||||
pkgLexer: "jlexer",
|
||||
"encoding/json": "json",
|
||||
},
|
||||
namer: DefaultFieldNamer{},
|
||||
fieldNamer: DefaultFieldNamer{},
|
||||
marshallers: make(map[reflect.Type]bool),
|
||||
typesSeen: make(map[reflect.Type]bool),
|
||||
functionNames: make(map[string]reflect.Type),
|
||||
@@ -70,7 +70,7 @@ func NewGenerator(filename string) *Generator {
|
||||
// name clashes.
|
||||
hash := fnv.New32()
|
||||
hash.Write([]byte(filename))
|
||||
ret.funcPrefix = fmt.Sprintf("easyjson_%x_", hash.Sum32())
|
||||
ret.hashString = fmt.Sprintf("%x", hash.Sum32())
|
||||
|
||||
return ret
|
||||
}
|
||||
@@ -88,12 +88,12 @@ func (g *Generator) SetBuildTags(tags string) {
|
||||
|
||||
// SetFieldNamer sets field naming strategy.
|
||||
func (g *Generator) SetFieldNamer(n FieldNamer) {
|
||||
g.namer = n
|
||||
g.fieldNamer = n
|
||||
}
|
||||
|
||||
// UseSnakeCase sets snake_case field naming strategy.
|
||||
func (g *Generator) UseSnakeCase() {
|
||||
g.namer = SnakeCaseFieldNamer{}
|
||||
g.fieldNamer = SnakeCaseFieldNamer{}
|
||||
}
|
||||
|
||||
// NoStdMarshalers instructs not to generate standard MarshalJSON/UnmarshalJSON
|
||||
@@ -255,7 +255,7 @@ func (g *Generator) uniqueVarName() string {
|
||||
|
||||
// safeName escapes unsafe characters in pkg/type name and returns a string that can be used
|
||||
// in encoder/decoder names for the type.
|
||||
func safeName(t reflect.Type) string {
|
||||
func (g *Generator) safeName(t reflect.Type) string {
|
||||
name := t.PkgPath()
|
||||
if t.Name() == "" {
|
||||
name += "anonymous"
|
||||
@@ -263,15 +263,17 @@ func safeName(t reflect.Type) string {
|
||||
name += "." + t.Name()
|
||||
}
|
||||
|
||||
var ret []rune
|
||||
parts := []string{}
|
||||
part := []rune{}
|
||||
for _, c := range name {
|
||||
if unicode.IsLetter(c) || unicode.IsDigit(c) {
|
||||
ret = append(ret, c)
|
||||
} else {
|
||||
ret = append(ret, '_')
|
||||
part = append(part, c)
|
||||
} else if len(part) > 0 {
|
||||
parts = append(parts, string(part))
|
||||
part = []rune{}
|
||||
}
|
||||
}
|
||||
return string(ret)
|
||||
return joinFunctionNameParts(false, parts...)
|
||||
}
|
||||
|
||||
// functionName returns a function name for a given type with a given prefix. If a function
|
||||
@@ -279,8 +281,8 @@ func safeName(t reflect.Type) string {
|
||||
//
|
||||
// Method is used to track encoder/decoder names for the type.
|
||||
func (g *Generator) functionName(prefix string, t reflect.Type) string {
|
||||
prefix = g.funcPrefix + prefix
|
||||
name := prefix + safeName(t)
|
||||
prefix = joinFunctionNameParts(true, "easyjson", g.hashString, prefix)
|
||||
name := joinFunctionNameParts(true, prefix, g.safeName(t))
|
||||
|
||||
// Most of the names will be unique, try a shortcut first.
|
||||
if e, ok := g.functionNames[name]; !ok || e == t {
|
||||
@@ -374,3 +376,20 @@ func (SnakeCaseFieldNamer) GetJSONFieldName(t reflect.Type, f reflect.StructFiel
|
||||
|
||||
return camelToSnake(f.Name)
|
||||
}
|
||||
|
||||
func joinFunctionNameParts(keepFirst bool, parts ...string) string {
|
||||
buf := bytes.NewBufferString("")
|
||||
for i, part := range parts {
|
||||
if i == 0 && keepFirst {
|
||||
buf.WriteString(part)
|
||||
} else {
|
||||
if len(part) > 0 {
|
||||
buf.WriteString(strings.ToUpper(string(part[0])))
|
||||
}
|
||||
if len(part) > 1 {
|
||||
buf.WriteString(part[1:])
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
@@ -26,5 +26,24 @@ func TestCamelToSnake(t *testing.T) {
|
||||
t.Errorf("[%d] camelToSnake(%s) = %s; want %s", i, test.In, got, test.Out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoinFunctionNameParts(t *testing.T) {
|
||||
for i, test := range []struct {
|
||||
keepFirst bool
|
||||
parts []string
|
||||
out string
|
||||
}{
|
||||
{false, []string{}, ""},
|
||||
{false, []string{"a"}, "A"},
|
||||
{false, []string{"simple", "example"}, "SimpleExample"},
|
||||
{true, []string{"first", "example"}, "firstExample"},
|
||||
{false, []string{"some", "UPPER", "case"}, "SomeUPPERCase"},
|
||||
{false, []string{"number", "123"}, "Number123"},
|
||||
} {
|
||||
got := joinFunctionNameParts(test.keepFirst, test.parts...)
|
||||
if got != test.out {
|
||||
t.Errorf("[%d] joinFunctionNameParts(%v) = %s; want %s", i, test.parts, got, test.out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user