mirror of https://github.com/goccy/go-json.git
Refactor indent code
This commit is contained in:
parent
5de8891c0c
commit
5741c733a6
12
encode.go
12
encode.go
|
@ -200,26 +200,16 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
|
|||
// noescape trick for header.typ ( reflect.*rtype )
|
||||
copiedType := *(**rtype)(unsafe.Pointer(&typeptr))
|
||||
|
||||
codeIndent, err := e.compileHead(&encodeCompileContext{
|
||||
typ: copiedType,
|
||||
root: true,
|
||||
withIndent: true,
|
||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
code, err := e.compileHead(&encodeCompileContext{
|
||||
typ: copiedType,
|
||||
root: true,
|
||||
withIndent: false,
|
||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
codeIndent = copyOpcode(codeIndent)
|
||||
code = copyOpcode(code)
|
||||
codeIndent := toIndent(code)
|
||||
codeLength := code.totalLength()
|
||||
codeSet := &opcodeSet{
|
||||
codeIndent: codeIndent,
|
||||
|
|
|
@ -377,16 +377,6 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
|
|||
|
||||
end := newOpCode(ctx, opSliceEnd)
|
||||
ctx.incIndex()
|
||||
if ctx.withIndent {
|
||||
if ctx.root {
|
||||
header.op = opRootSliceHeadIndent
|
||||
elemCode.op = opRootSliceElemIndent
|
||||
} else {
|
||||
header.op = opSliceHeadIndent
|
||||
elemCode.op = opSliceElemIndent
|
||||
}
|
||||
end.op = opSliceEndIndent
|
||||
}
|
||||
|
||||
header.elem = elemCode
|
||||
header.end = end
|
||||
|
@ -421,12 +411,6 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
|
|||
end := newOpCode(ctx, opArrayEnd)
|
||||
ctx.incIndex()
|
||||
|
||||
if ctx.withIndent {
|
||||
header.op = opArrayHeadIndent
|
||||
elemCode.op = opArrayElemIndent
|
||||
end.op = opArrayEndIndent
|
||||
}
|
||||
|
||||
header.elem = elemCode
|
||||
header.end = end
|
||||
header.next = code
|
||||
|
@ -487,13 +471,6 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
|
|||
end := newMapEndCode(ctx, header)
|
||||
ctx.incIndex()
|
||||
|
||||
if ctx.withIndent {
|
||||
header.op = header.op.toIndent()
|
||||
key.op = key.op.toIndent()
|
||||
value.op = value.op.toIndent()
|
||||
end.op = end.op.toIndent()
|
||||
}
|
||||
|
||||
header.next = keyCode
|
||||
keyCode.beforeLastCode().next = (*opcode)(unsafe.Pointer(value))
|
||||
value.next = valueCode
|
||||
|
@ -587,88 +564,46 @@ func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode) opTy
|
|||
}
|
||||
case opInt:
|
||||
return opStructFieldHeadInt
|
||||
case opIntIndent:
|
||||
return opStructFieldHeadIntIndent
|
||||
case opInt8:
|
||||
return opStructFieldHeadInt8
|
||||
case opInt8Indent:
|
||||
return opStructFieldHeadInt8Indent
|
||||
case opInt16:
|
||||
return opStructFieldHeadInt16
|
||||
case opInt16Indent:
|
||||
return opStructFieldHeadInt16Indent
|
||||
case opInt32:
|
||||
return opStructFieldHeadInt32
|
||||
case opInt32Indent:
|
||||
return opStructFieldHeadInt32Indent
|
||||
case opInt64:
|
||||
return opStructFieldHeadInt64
|
||||
case opInt64Indent:
|
||||
return opStructFieldHeadInt64Indent
|
||||
case opUint:
|
||||
return opStructFieldHeadUint
|
||||
case opUintIndent:
|
||||
return opStructFieldHeadUintIndent
|
||||
case opUint8:
|
||||
return opStructFieldHeadUint8
|
||||
case opUint8Indent:
|
||||
return opStructFieldHeadUint8Indent
|
||||
case opUint16:
|
||||
return opStructFieldHeadUint16
|
||||
case opUint16Indent:
|
||||
return opStructFieldHeadUint16Indent
|
||||
case opUint32:
|
||||
return opStructFieldHeadUint32
|
||||
case opUint32Indent:
|
||||
return opStructFieldHeadUint32Indent
|
||||
case opUint64:
|
||||
return opStructFieldHeadUint64
|
||||
case opUint64Indent:
|
||||
return opStructFieldHeadUint64Indent
|
||||
case opFloat32:
|
||||
return opStructFieldHeadFloat32
|
||||
case opFloat32Indent:
|
||||
return opStructFieldHeadFloat32Indent
|
||||
case opFloat64:
|
||||
return opStructFieldHeadFloat64
|
||||
case opFloat64Indent:
|
||||
return opStructFieldHeadFloat64Indent
|
||||
case opString:
|
||||
return opStructFieldHeadString
|
||||
case opStringIndent:
|
||||
return opStructFieldHeadStringIndent
|
||||
case opBool:
|
||||
return opStructFieldHeadBool
|
||||
case opBoolIndent:
|
||||
return opStructFieldHeadBoolIndent
|
||||
case opMapHead:
|
||||
return opStructFieldHeadMap
|
||||
case opMapHeadLoad:
|
||||
return opStructFieldHeadMapLoad
|
||||
case opMapHeadIndent:
|
||||
return opStructFieldHeadMapIndent
|
||||
case opMapHeadLoadIndent:
|
||||
return opStructFieldHeadMapLoadIndent
|
||||
case opArrayHead:
|
||||
return opStructFieldHeadArray
|
||||
case opArrayHeadIndent:
|
||||
return opStructFieldHeadArrayIndent
|
||||
case opSliceHead:
|
||||
return opStructFieldHeadSlice
|
||||
case opSliceHeadIndent:
|
||||
return opStructFieldHeadSliceIndent
|
||||
case opStructFieldHead:
|
||||
return opStructFieldHeadStruct
|
||||
case opStructFieldHeadIndent:
|
||||
return opStructFieldHeadStructIndent
|
||||
case opMarshalJSON:
|
||||
return opStructFieldHeadMarshalJSON
|
||||
case opMarshalJSONIndent:
|
||||
return opStructFieldHeadMarshalJSONIndent
|
||||
case opMarshalText:
|
||||
return opStructFieldHeadMarshalText
|
||||
case opMarshalTextIndent:
|
||||
return opStructFieldHeadMarshalTextIndent
|
||||
}
|
||||
return opStructFieldHead
|
||||
}
|
||||
|
@ -753,93 +688,51 @@ func (e *Encoder) typeToFieldType(ctx *encodeCompileContext, code *opcode) opTyp
|
|||
}
|
||||
case opInt:
|
||||
return opStructFieldInt
|
||||
case opIntIndent:
|
||||
return opStructFieldIntIndent
|
||||
case opInt8:
|
||||
return opStructFieldInt8
|
||||
case opInt8Indent:
|
||||
return opStructFieldInt8Indent
|
||||
case opInt16:
|
||||
return opStructFieldInt16
|
||||
case opInt16Indent:
|
||||
return opStructFieldInt16Indent
|
||||
case opInt32:
|
||||
return opStructFieldInt32
|
||||
case opInt32Indent:
|
||||
return opStructFieldInt32Indent
|
||||
case opInt64:
|
||||
return opStructFieldInt64
|
||||
case opInt64Indent:
|
||||
return opStructFieldInt64Indent
|
||||
case opUint:
|
||||
return opStructFieldUint
|
||||
case opUintIndent:
|
||||
return opStructFieldUintIndent
|
||||
case opUint8:
|
||||
return opStructFieldUint8
|
||||
case opUint8Indent:
|
||||
return opStructFieldUint8Indent
|
||||
case opUint16:
|
||||
return opStructFieldUint16
|
||||
case opUint16Indent:
|
||||
return opStructFieldUint16Indent
|
||||
case opUint32:
|
||||
return opStructFieldUint32
|
||||
case opUint32Indent:
|
||||
return opStructFieldUint32Indent
|
||||
case opUint64:
|
||||
return opStructFieldUint64
|
||||
case opUint64Indent:
|
||||
return opStructFieldUint64Indent
|
||||
case opFloat32:
|
||||
return opStructFieldFloat32
|
||||
case opFloat32Indent:
|
||||
return opStructFieldFloat32Indent
|
||||
case opFloat64:
|
||||
return opStructFieldFloat64
|
||||
case opFloat64Indent:
|
||||
return opStructFieldFloat64Indent
|
||||
case opString:
|
||||
return opStructFieldString
|
||||
case opStringIndent:
|
||||
return opStructFieldStringIndent
|
||||
case opBool:
|
||||
return opStructFieldBool
|
||||
case opBoolIndent:
|
||||
return opStructFieldBoolIndent
|
||||
case opMapHead:
|
||||
return opStructFieldMap
|
||||
case opMapHeadLoad:
|
||||
return opStructFieldMapLoad
|
||||
case opMapHeadIndent:
|
||||
return opStructFieldMapIndent
|
||||
case opMapHeadLoadIndent:
|
||||
return opStructFieldMapLoadIndent
|
||||
case opArrayHead:
|
||||
return opStructFieldArray
|
||||
case opArrayHeadIndent:
|
||||
return opStructFieldArrayIndent
|
||||
case opSliceHead:
|
||||
return opStructFieldSlice
|
||||
case opSliceHeadIndent:
|
||||
return opStructFieldSliceIndent
|
||||
case opStructFieldHead:
|
||||
return opStructFieldStruct
|
||||
case opStructFieldHeadIndent:
|
||||
return opStructFieldStructIndent
|
||||
case opMarshalJSON:
|
||||
return opStructFieldMarshalJSON
|
||||
case opMarshalJSONIndent:
|
||||
return opStructFieldMarshalJSONIndent
|
||||
case opMarshalText:
|
||||
return opStructFieldMarshalText
|
||||
case opMarshalTextIndent:
|
||||
return opStructFieldMarshalTextIndent
|
||||
}
|
||||
return opStructField
|
||||
}
|
||||
|
||||
func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode, tag *structTag, withIndent bool) opType {
|
||||
func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode, tag *structTag) opType {
|
||||
headType := e.typeToHeaderType(ctx, code)
|
||||
switch {
|
||||
case tag.isOmitEmpty:
|
||||
|
@ -847,13 +740,10 @@ func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode,
|
|||
case tag.isString:
|
||||
headType = headType.headToStringTagHead()
|
||||
}
|
||||
if withIndent {
|
||||
return headType.toIndent()
|
||||
}
|
||||
return headType
|
||||
}
|
||||
|
||||
func (e *Encoder) optimizeStructField(ctx *encodeCompileContext, code *opcode, tag *structTag, withIndent bool) opType {
|
||||
func (e *Encoder) optimizeStructField(ctx *encodeCompileContext, code *opcode, tag *structTag) opType {
|
||||
fieldType := e.typeToFieldType(ctx, code)
|
||||
switch {
|
||||
case tag.isOmitEmpty:
|
||||
|
@ -861,9 +751,6 @@ func (e *Encoder) optimizeStructField(ctx *encodeCompileContext, code *opcode, t
|
|||
case tag.isString:
|
||||
fieldType = fieldType.fieldToStringTagField()
|
||||
}
|
||||
if withIndent {
|
||||
return fieldType.toIndent()
|
||||
}
|
||||
return fieldType
|
||||
}
|
||||
|
||||
|
@ -884,7 +771,7 @@ func (e *Encoder) compiledCode(ctx *encodeCompileContext) *opcode {
|
|||
|
||||
func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
|
||||
fieldCode.indent--
|
||||
op := e.optimizeStructHeader(ctx, valueCode, tag, ctx.withIndent)
|
||||
op := e.optimizeStructHeader(ctx, valueCode, tag)
|
||||
fieldCode.op = op
|
||||
fieldCode.ptrNum = valueCode.ptrNum
|
||||
switch op {
|
||||
|
@ -900,20 +787,7 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, val
|
|||
opStructFieldHeadOmitEmptyMap,
|
||||
opStructFieldHeadOmitEmptyMapLoad,
|
||||
opStructFieldHeadOmitEmptyStruct,
|
||||
opStructFieldHeadStringTag,
|
||||
opStructFieldHeadIndent,
|
||||
opStructFieldHeadSliceIndent,
|
||||
opStructFieldHeadArrayIndent,
|
||||
opStructFieldHeadMapIndent,
|
||||
opStructFieldHeadMapLoadIndent,
|
||||
opStructFieldHeadStructIndent,
|
||||
opStructFieldHeadOmitEmptyIndent,
|
||||
opStructFieldHeadOmitEmptySliceIndent,
|
||||
opStructFieldHeadOmitEmptyArrayIndent,
|
||||
opStructFieldHeadOmitEmptyMapIndent,
|
||||
opStructFieldHeadOmitEmptyMapLoadIndent,
|
||||
opStructFieldHeadOmitEmptyStructIndent,
|
||||
opStructFieldHeadStringTagIndent:
|
||||
opStructFieldHeadStringTag:
|
||||
return valueCode.beforeLastCode()
|
||||
}
|
||||
ctx.decOpcodeIndex()
|
||||
|
@ -922,7 +796,7 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, val
|
|||
|
||||
func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
|
||||
code := (*opcode)(unsafe.Pointer(fieldCode))
|
||||
op := e.optimizeStructField(ctx, valueCode, tag, ctx.withIndent)
|
||||
op := e.optimizeStructField(ctx, valueCode, tag)
|
||||
fieldCode.op = op
|
||||
fieldCode.ptrNum = valueCode.ptrNum
|
||||
switch op {
|
||||
|
@ -938,20 +812,7 @@ func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valu
|
|||
opStructFieldOmitEmptyMap,
|
||||
opStructFieldOmitEmptyMapLoad,
|
||||
opStructFieldOmitEmptyStruct,
|
||||
opStructFieldStringTag,
|
||||
opStructFieldIndent,
|
||||
opStructFieldSliceIndent,
|
||||
opStructFieldArrayIndent,
|
||||
opStructFieldMapIndent,
|
||||
opStructFieldMapLoadIndent,
|
||||
opStructFieldStructIndent,
|
||||
opStructFieldOmitEmptyIndent,
|
||||
opStructFieldOmitEmptySliceIndent,
|
||||
opStructFieldOmitEmptyArrayIndent,
|
||||
opStructFieldOmitEmptyMapIndent,
|
||||
opStructFieldOmitEmptyMapLoadIndent,
|
||||
opStructFieldOmitEmptyStructIndent,
|
||||
opStructFieldStringTagIndent:
|
||||
opStructFieldStringTag:
|
||||
return valueCode.beforeLastCode()
|
||||
}
|
||||
ctx.decIndex()
|
||||
|
@ -988,10 +849,10 @@ func (e *Encoder) optimizeAnonymousFields(head *opcode) {
|
|||
var prev *opcode
|
||||
removedFields := map[*opcode]struct{}{}
|
||||
for {
|
||||
if code.op == opStructEnd || code.op == opStructEndIndent {
|
||||
if code.op == opStructEnd {
|
||||
break
|
||||
}
|
||||
if code.op == opStructField || code.op == opStructFieldIndent {
|
||||
if code.op == opStructField {
|
||||
codeType := code.next.op.codeType()
|
||||
if codeType == codeStructField {
|
||||
if e.isNotExistsField(code.next) {
|
||||
|
@ -1252,9 +1113,6 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
|||
}
|
||||
structEndCode.prevField = head
|
||||
ctx.incIndex()
|
||||
if ctx.withIndent {
|
||||
head.op = opStructFieldHeadIndent
|
||||
}
|
||||
code = head
|
||||
}
|
||||
|
||||
|
@ -1262,10 +1120,6 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
|
|||
structEndCode.idx = opcodeOffset(ctx.ptrIndex)
|
||||
ctx.incIndex()
|
||||
|
||||
if ctx.withIndent {
|
||||
structEndCode.op = opStructEndIndent
|
||||
}
|
||||
|
||||
if prevField != nil && prevField.nextField == nil {
|
||||
prevField.nextField = structEndCode
|
||||
structEndCode.prevField = prevField
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
type encodeCompileContext struct {
|
||||
typ *rtype
|
||||
withIndent bool
|
||||
root bool
|
||||
opcodeIndex int
|
||||
ptrIndex int
|
||||
|
@ -19,7 +18,6 @@ type encodeCompileContext struct {
|
|||
func (c *encodeCompileContext) context() *encodeCompileContext {
|
||||
return &encodeCompileContext{
|
||||
typ: c.typ,
|
||||
withIndent: c.withIndent,
|
||||
root: c.root,
|
||||
opcodeIndex: c.opcodeIndex,
|
||||
ptrIndex: c.ptrIndex,
|
||||
|
|
|
@ -53,10 +53,21 @@ func copyOpcode(code *opcode) *opcode {
|
|||
return code.copy(codeMap)
|
||||
}
|
||||
|
||||
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||
if op != opEnd && ctx.withIndent {
|
||||
op = op.toIndent()
|
||||
func toIndent(c *opcode) *opcode {
|
||||
c = copyOpcode(c)
|
||||
for code := c; code.op != opEnd; {
|
||||
code.op = code.op.toIndent()
|
||||
switch code.op.codeType() {
|
||||
case codeArrayElem, codeSliceElem, codeMapKey:
|
||||
code = code.end
|
||||
default:
|
||||
code = code.next
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode {
|
||||
return &opcode{
|
||||
op: op,
|
||||
typ: ctx.typ,
|
||||
|
|
24
encode_vm.go
24
encode_vm.go
|
@ -319,13 +319,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
c, err := e.compileHead(&encodeCompileContext{
|
||||
typ: header.typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.enabledIndent {
|
||||
c = toIndent(c)
|
||||
}
|
||||
beforeLastCode := c.beforeLastCode()
|
||||
lastCode := beforeLastCode.next
|
||||
lastCode.idx = beforeLastCode.idx + uintptrSize
|
||||
|
@ -384,10 +386,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
var c *opcode
|
||||
if typ.Kind() == reflect.Map {
|
||||
code, err := e.compileMap(&encodeCompileContext{
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
indent: code.indent,
|
||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||
}, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -395,17 +397,19 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, code *opcode) ([]byte
|
|||
c = code
|
||||
} else {
|
||||
code, err := e.compile(&encodeCompileContext{
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
withIndent: e.enabledIndent,
|
||||
indent: code.indent,
|
||||
typ: typ,
|
||||
root: code.root,
|
||||
indent: code.indent,
|
||||
structTypeToCompiledCode: map[uintptr]*compiledCode{},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c = code
|
||||
}
|
||||
|
||||
if e.enabledIndent {
|
||||
c = toIndent(c)
|
||||
}
|
||||
beforeLastCode := c.beforeLastCode()
|
||||
lastCode := beforeLastCode.next
|
||||
lastCode.idx = beforeLastCode.idx + uintptrSize
|
||||
|
|
Loading…
Reference in New Issue