Parcourir la source

#66 Make extension api like the java version

Tao Wen il y a 8 ans
Parent
commit
be221df432
4 fichiers modifiés avec 229 ajouts et 220 suppressions
  1. 2 13
      feature_config.go
  2. 151 27
      feature_reflect_extension.go
  3. 34 147
      feature_reflect_object.go
  4. 42 33
      jsoniter_customize_test.go

+ 2 - 13
feature_config.go

@@ -12,7 +12,6 @@ import (
 type Config struct {
 	IndentionStep                 int
 	MarshalFloatWith6Digits       bool
-	SupportUnexportedStructFields bool
 	EscapeHtml                    bool
 	SortMapKeys                   bool
 	UseNumber                     bool
@@ -24,7 +23,7 @@ type frozenConfig struct {
 	indentionStep      int
 	decoderCache       unsafe.Pointer
 	encoderCache       unsafe.Pointer
-	extensions         []ExtensionFunc
+	extensions         []Extension
 	streamPool         chan *Stream
 	iteratorPool       chan *Iterator
 }
@@ -65,9 +64,6 @@ func (cfg Config) Froze() *frozenConfig {
 	if cfg.MarshalFloatWith6Digits {
 		frozenConfig.marshalFloatWith6Digits()
 	}
-	if cfg.SupportUnexportedStructFields {
-		frozenConfig.supportUnexportedStructFields()
-	}
 	if cfg.EscapeHtml {
 		frozenConfig.escapeHtml()
 	}
@@ -88,17 +84,10 @@ func (cfg *frozenConfig) useNumber() {
 	}})
 }
 
-// RegisterExtension can register a custom extension
-func (cfg *frozenConfig) registerExtension(extension ExtensionFunc) {
+func (cfg *frozenConfig) registerExtension(extension Extension) {
 	cfg.extensions = append(cfg.extensions, extension)
 }
 
-func (cfg *frozenConfig) supportUnexportedStructFields() {
-	cfg.registerExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc) {
-		return []string{field.Name}, nil, nil
-	})
-}
-
 type lossyFloat32Encoder struct {
 }
 

+ 151 - 27
feature_reflect_extension.go

@@ -4,26 +4,52 @@ import (
 	"reflect"
 	"fmt"
 	"unsafe"
+	"strings"
+	"unicode"
 )
 
-var typeDecoders map[string]ValDecoder
-var fieldDecoders map[string]ValDecoder
-var typeEncoders map[string]ValEncoder
-var fieldEncoders map[string]ValEncoder
-var extensions []ExtensionFunc
+var typeDecoders = map[string]ValDecoder{}
+var fieldDecoders = map[string]ValDecoder{}
+var typeEncoders = map[string]ValEncoder{}
+var fieldEncoders = map[string]ValEncoder{}
+var extensions = []Extension{}
 
-type ExtensionFunc func(typ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc)
+type StructDescriptor struct {
+	Type   reflect.Type
+	Fields map[string]*Binding
+}
 
-type funcDecoder struct {
-	fun DecoderFunc
+type Binding struct {
+	Field           *reflect.StructField
+	FromNames       []string
+	ToNames         []string
+	ShouldOmitEmpty bool
+	Encoder         ValEncoder
+	Decoder         ValDecoder
+}
+
+type Extension interface {
+	UpdateStructDescriptor(structDescriptor *StructDescriptor)
+	CreateDecoder(typ reflect.Type) ValDecoder
+	CreateEncoder(typ reflect.Type) ValEncoder
 }
 
-func init() {
-	typeDecoders = map[string]ValDecoder{}
-	fieldDecoders = map[string]ValDecoder{}
-	typeEncoders = map[string]ValEncoder{}
-	fieldEncoders = map[string]ValEncoder{}
-	extensions = []ExtensionFunc{}
+type DummyExtension struct {
+}
+
+func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
+}
+
+func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder {
+	return nil
+}
+
+func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
+	return nil
+}
+
+type funcDecoder struct {
+	fun DecoderFunc
 }
 
 func RegisterTypeDecoderFunc(typ string, fun DecoderFunc) {
@@ -58,36 +84,134 @@ func RegisterFieldEncoder(typ string, field string, encoder ValEncoder) {
 	fieldEncoders[fmt.Sprintf("%s/%s", typ, field)] = encoder
 }
 
-func RegisterExtension(extension ExtensionFunc) {
+func RegisterExtension(extension Extension) {
 	extensions = append(extensions, extension)
 }
 
 func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
+	for _, extension := range extensions {
+		decoder := extension.CreateDecoder(typ)
+		if decoder != nil {
+			return decoder
+		}
+	}
 	typeName := typ.String()
-	typeDecoder := typeDecoders[typeName]
-	if typeDecoder != nil {
-		return typeDecoder
+	decoder := typeDecoders[typeName]
+	if decoder != nil {
+		return decoder
 	}
 	if typ.Kind() == reflect.Ptr {
-		typeDecoder := typeDecoders[typ.Elem().String()]
-		if typeDecoder != nil {
-			return &optionalDecoder{typ.Elem(), typeDecoder}
+		decoder := typeDecoders[typ.Elem().String()]
+		if decoder != nil {
+			return &optionalDecoder{typ.Elem(), decoder}
 		}
 	}
 	return nil
 }
 
 func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
+	for _, extension := range extensions {
+		encoder := extension.CreateEncoder(typ)
+		if encoder != nil {
+			return encoder
+		}
+	}
 	typeName := typ.String()
-	typeEncoder := typeEncoders[typeName]
-	if typeEncoder != nil {
-		return typeEncoder
+	encoder := typeEncoders[typeName]
+	if encoder != nil {
+		return encoder
 	}
 	if typ.Kind() == reflect.Ptr {
-		typeEncoder := typeEncoders[typ.Elem().String()]
-		if typeEncoder != nil {
-			return &optionalEncoder{typeEncoder}
+		encoder := typeEncoders[typ.Elem().String()]
+		if encoder != nil {
+			return &optionalEncoder{encoder}
 		}
 	}
 	return nil
+}
+
+func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
+	bindings := map[string]*Binding{}
+	for _, field := range listStructFields(typ) {
+		tagParts := strings.Split(field.Tag.Get("json"), ",")
+		fieldNames := calcFieldNames(field.Name, tagParts[0])
+		fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
+		decoder := fieldDecoders[fieldCacheKey]
+		if decoder == nil && len(fieldNames) > 0 {
+			var err error
+			decoder, err = decoderOfType(cfg, field.Type)
+			if err != nil {
+				return nil, err
+			}
+		}
+		encoder := fieldEncoders[fieldCacheKey]
+		if encoder == nil && len(fieldNames) > 0 {
+			var err error
+			encoder, err = encoderOfType(cfg, field.Type)
+			if err != nil {
+				return nil, err
+			}
+			// map is stored as pointer in the struct
+			if field.Type.Kind() == reflect.Map {
+				encoder = &optionalEncoder{encoder}
+			}
+		}
+		binding := &Binding{
+			Field:     field,
+			FromNames: fieldNames,
+			ToNames:   fieldNames,
+			Decoder:   decoder,
+			Encoder:   encoder,
+		}
+		for _, tagPart := range tagParts[1:] {
+			if tagPart == "omitempty" {
+				binding.ShouldOmitEmpty = true
+			} else if tagPart == "string" {
+				binding.Decoder = &stringModeDecoder{binding.Decoder}
+				binding.Encoder = &stringModeEncoder{binding.Encoder}
+			}
+		}
+		bindings[field.Name] = binding
+	}
+	structDescriptor := &StructDescriptor{
+		Type:   typ,
+		Fields: bindings,
+	}
+	for _, extension := range extensions {
+		extension.UpdateStructDescriptor(structDescriptor)
+	}
+	return structDescriptor, nil
+}
+
+func listStructFields(typ reflect.Type) []*reflect.StructField {
+	fields := []*reflect.StructField{}
+	for i := 0; i < typ.NumField(); i++ {
+		field := typ.Field(i)
+		if field.Anonymous {
+			fields = append(fields, listStructFields(field.Type)...)
+		} else {
+			fields = append(fields, &field)
+		}
+	}
+	return fields
+}
+
+func calcFieldNames(originalFieldName string, tagProvidedFieldName string) []string {
+	// tag => exported? => original
+	isNotExported := unicode.IsLower(rune(originalFieldName[0]))
+	var fieldNames []string
+	/// tagParts[0] always present, even if no tags
+	switch tagProvidedFieldName {
+	case "":
+		if isNotExported {
+			fieldNames = []string{}
+		} else {
+			fieldNames = []string{originalFieldName}
+		}
+	case "-":
+		fieldNames = []string{}
+	default:
+		fieldNames = []string{tagProvidedFieldName}
+	}
+	return fieldNames
 }

+ 34 - 147
feature_reflect_object.go

@@ -4,64 +4,19 @@ import (
 	"fmt"
 	"io"
 	"reflect"
-	"strings"
-	"unicode"
 	"unsafe"
 )
 
 func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
 	structEncoder_ := &structEncoder{}
 	fields := map[string]*structFieldEncoder{}
-	for _, field := range listStructFields(typ) {
-		fieldEncoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
-		var extensionProvidedFieldNames []string
-		for _, extension := range extensions {
-			alternativeFieldNames, fun, _ := extension(typ, field)
-			if alternativeFieldNames != nil {
-				extensionProvidedFieldNames = alternativeFieldNames
-			}
-			if fun != nil {
-				fieldEncoders[fieldEncoderKey] = &funcEncoder{fun, nil}
-			}
-		}
-		for _, extension := range cfg.extensions {
-			alternativeFieldNames, fun, _ := extension(typ, field)
-			if alternativeFieldNames != nil {
-				extensionProvidedFieldNames = alternativeFieldNames
-			}
-			if fun != nil {
-				fieldEncoders[fieldEncoderKey] = &funcEncoder{fun, nil}
-			}
-		}
-		tagParts := strings.Split(field.Tag.Get("json"), ",")
-		// if fieldNames set by extension, use theirs, otherwise try tags
-		fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProvidedFieldNames)
-		omitempty := false
-		stringMode := false
-		for _, tagPart := range tagParts[1:] {
-			if tagPart == "omitempty" {
-				omitempty = true
-			} else if tagPart == "string" {
-				stringMode = true
-			}
-		}
-		encoder := fieldEncoders[fieldEncoderKey]
-		var err error
-		if encoder == nil && len(fieldNames) > 0 {
-			encoder, err = encoderOfType(cfg, field.Type)
-			if err != nil {
-				return prefix(fmt.Sprintf("{%s}", field.Name)).addToEncoder(encoder, err)
-			}
-			// map is stored as pointer in the struct
-			if field.Type.Kind() == reflect.Map {
-				encoder = &optionalEncoder{encoder}
-			}
-		}
-		if stringMode {
-			encoder = &stringModeEncoder{encoder}
-		}
-		for _, fieldName := range fieldNames {
-			fields[fieldName] = &structFieldEncoder{field, fieldName, encoder, omitempty}
+	structDescriptor, err := describeStruct(cfg, typ)
+	if err != nil {
+		return nil, err
+	}
+	for _, binding := range structDescriptor.Fields {
+		for _, fieldName := range binding.ToNames {
+			fields[fieldName] = &structFieldEncoder{binding.Field, fieldName, binding.Encoder, binding.ShouldOmitEmpty}
 		}
 	}
 	if len(fields) == 0 {
@@ -73,86 +28,18 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
 	return structEncoder_, nil
 }
 
-func listStructFields(typ reflect.Type) []*reflect.StructField {
-	fields := []*reflect.StructField{}
-	for i := 0; i < typ.NumField(); i++ {
-		field := typ.Field(i)
-		if field.Anonymous {
-			fields = append(fields, listStructFields(field.Type)...)
-		} else {
-			fields = append(fields, &field)
-		}
-	}
-	return fields
-}
-
 func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
 	fields := map[string]*structFieldDecoder{}
-	for _, field := range listStructFields(typ) {
-		fieldDecoderKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
-		var extensionProviedFieldNames []string
-		for _, extension := range extensions {
-			alternativeFieldNames, _, fun := extension(typ, field)
-			if alternativeFieldNames != nil {
-				extensionProviedFieldNames = alternativeFieldNames
-			}
-			if fun != nil {
-				fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
-			}
-		}
-		for _, extension := range cfg.extensions {
-			alternativeFieldNames, _, fun := extension(typ, field)
-			if alternativeFieldNames != nil {
-				extensionProviedFieldNames = alternativeFieldNames
-			}
-			if fun != nil {
-				fieldDecoders[fieldDecoderKey] = &funcDecoder{fun}
-			}
-		}
-		decoder := fieldDecoders[fieldDecoderKey]
-		tagParts := strings.Split(field.Tag.Get("json"), ",")
-		fieldNames := calcFieldNames(field.Name, tagParts[0], extensionProviedFieldNames)
-		if decoder == nil && len(fieldNames) > 0 {
-			var err error
-			decoder, err = decoderOfType(cfg, field.Type)
-			if err != nil {
-				return prefix(fmt.Sprintf("{%s}", field.Name)).addToDecoder(decoder, err)
-			}
-		}
-		for _, tagPart := range tagParts[1:] {
-			if tagPart == "string" {
-				decoder = &stringModeDecoder{decoder}
-			}
-		}
-		for _, fieldName := range fieldNames {
-			fields[fieldName] = &structFieldDecoder{field, decoder}
-		}
+	structDescriptor, err := describeStruct(cfg, typ)
+	if err != nil {
+		return nil, err
 	}
-	return createStructDecoder(typ, fields)
-}
-
-func calcFieldNames(originalFieldName string, tagProvidedFieldName string, extensionProvidedFieldNames []string) []string {
-	// tag => extension => exported? => original
-	isNotExported := unicode.IsLower(rune(originalFieldName[0]))
-	var fieldNames []string
-	/// tagParts[0] always present, even if no tags
-	switch tagProvidedFieldName {
-	case "":
-		if extensionProvidedFieldNames != nil {
-			fieldNames = extensionProvidedFieldNames
-		} else {
-			if isNotExported {
-				fieldNames = []string{}
-			} else {
-				fieldNames = []string{originalFieldName}
-			}
+	for _, binding := range structDescriptor.Fields {
+		for _, fieldName := range binding.FromNames {
+			fields[fieldName] = &structFieldDecoder{binding.Field, binding.Decoder}
 		}
-	case "-":
-		fieldNames = []string{}
-	default:
-		fieldNames = []string{tagProvidedFieldName}
 	}
-	return fieldNames
+	return createStructDecoder(typ, fields)
 }
 
 func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
@@ -222,7 +109,7 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &threeFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
+										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
 	case 4:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -255,8 +142,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &fourFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4}, nil
+										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+										fieldName4, fieldDecoder4}, nil
 	case 5:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -294,8 +181,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &fiveFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
+										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+										fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
 	case 6:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -338,8 +225,8 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &sixFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
+									   fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+									   fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
 	case 7:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -387,9 +274,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &sevenFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7}, nil
+										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+										 fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+										 fieldName7, fieldDecoder7}, nil
 	case 8:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -442,9 +329,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &eightFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
+										 fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+										 fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+										 fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
 	case 9:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -502,9 +389,9 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &nineFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
+										fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+										fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+										fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
 	case 10:
 		var fieldName1 int32
 		var fieldName2 int32
@@ -567,10 +454,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
 			}
 		}
 		return &tenFieldsStructDecoder{typ,
-			fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
-			fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
-			fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
-			fieldName10, fieldDecoder10}, nil
+									   fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
+									   fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
+									   fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
+									   fieldName10, fieldDecoder10}, nil
 	}
 	return &generalStructDecoder{typ, fields}, nil
 }

+ 42 - 33
jsoniter_customize_test.go

@@ -3,7 +3,6 @@ package jsoniter
 import (
 	"encoding/json"
 	"github.com/json-iterator/go/require"
-	"reflect"
 	"strconv"
 	"testing"
 	"time"
@@ -86,22 +85,30 @@ type TestObject1 struct {
 	field1 string
 }
 
+type testExtension struct {
+	DummyExtension
+}
+
+func (extension *testExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
+	if structDescriptor.Type.String() != "jsoniter.TestObject1" {
+		return
+	}
+	binding := structDescriptor.Fields["field1"]
+	binding.Encoder = &funcEncoder{fun: func(ptr unsafe.Pointer, stream *Stream) {
+		str := *((*string)(ptr))
+		val, _ := strconv.Atoi(str)
+		stream.WriteInt(val)
+	}}
+	binding.Decoder = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
+		*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
+	}}
+	binding.ToNames = []string{"field-1"}
+	binding.FromNames = []string{"field-1"}
+}
+
 func Test_customize_field_by_extension(t *testing.T) {
 	should := require.New(t)
-	RegisterExtension(func(type_ reflect.Type, field *reflect.StructField) ([]string, EncoderFunc, DecoderFunc) {
-		if type_.String() == "jsoniter.TestObject1" && field.Name == "field1" {
-			encode := func(ptr unsafe.Pointer, stream *Stream) {
-				str := *((*string)(ptr))
-				val, _ := strconv.Atoi(str)
-				stream.WriteInt(val)
-			}
-			decode := func(ptr unsafe.Pointer, iter *Iterator) {
-				*((*string)(ptr)) = strconv.Itoa(iter.ReadInt())
-			}
-			return []string{"field-1"}, encode, decode
-		}
-		return nil, nil, nil
-	})
+	RegisterExtension(&testExtension{})
 	obj := TestObject1{}
 	err := UnmarshalFromString(`{"field-1": 100}`, &obj)
 	should.Nil(err)
@@ -111,24 +118,24 @@ func Test_customize_field_by_extension(t *testing.T) {
 	should.Equal(`{"field-1":100}`, str)
 }
 
-func Test_unexported_fields(t *testing.T) {
-	jsoniter := Config{SupportUnexportedStructFields: true}.Froze()
-	should := require.New(t)
-	type TestObject struct {
-		field1 string
-		field2 string `json:"field-2"`
-	}
-	obj := TestObject{}
-	obj.field1 = "hello"
-	should.Nil(jsoniter.UnmarshalFromString(`{}`, &obj))
-	should.Equal("hello", obj.field1)
-	should.Nil(jsoniter.UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj))
-	should.Equal("world", obj.field1)
-	should.Equal("abc", obj.field2)
-	str, err := jsoniter.MarshalToString(obj)
-	should.Nil(err)
-	should.Contains(str, `"field-2":"abc"`)
-}
+//func Test_unexported_fields(t *testing.T) {
+//	jsoniter := Config{SupportUnexportedStructFields: true}.Froze()
+//	should := require.New(t)
+//	type TestObject struct {
+//		field1 string
+//		field2 string `json:"field-2"`
+//	}
+//	obj := TestObject{}
+//	obj.field1 = "hello"
+//	should.Nil(jsoniter.UnmarshalFromString(`{}`, &obj))
+//	should.Equal("hello", obj.field1)
+//	should.Nil(jsoniter.UnmarshalFromString(`{"field1": "world", "field-2": "abc"}`, &obj))
+//	should.Equal("world", obj.field1)
+//	should.Equal("abc", obj.field2)
+//	str, err := jsoniter.MarshalToString(obj)
+//	should.Nil(err)
+//	should.Contains(str, `"field-2":"abc"`)
+//}
 
 type ObjectImplementedMarshaler int
 
@@ -155,6 +162,7 @@ func Test_marshaler_and_encoder(t *testing.T) {
 	type TestObject struct {
 		Field *ObjectImplementedMarshaler
 	}
+	ConfigDefault.cleanEncoders()
 	should := require.New(t)
 	RegisterTypeEncoderFunc("jsoniter.ObjectImplementedMarshaler", func(ptr unsafe.Pointer, stream *Stream) {
 		stream.WriteString("hello from encoder")
@@ -198,6 +206,7 @@ func Test_unmarshaler_and_decoder(t *testing.T) {
 		Field  *ObjectImplementedUnmarshaler
 		Field2 string
 	}
+	ConfigDefault.cleanDecoders()
 	should := require.New(t)
 	RegisterTypeDecoderFunc("jsoniter.ObjectImplementedUnmarshaler", func(ptr unsafe.Pointer, iter *Iterator) {
 		*(*ObjectImplementedUnmarshaler)(ptr) = 10