Merge pull request #74 from goccy/feature/add-escaped-op

Optimize about HTML Escape processing
This commit is contained in:
Masaaki Goshima 2020-12-25 22:39:59 +09:00 committed by GitHub
commit 1d1572fb55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 132275 additions and 9818 deletions

View File

@ -12,36 +12,35 @@ import (
) )
type opType struct { type opType struct {
Op string Op string
IndentOp string Code string
Code string Indent func() string
Escaped func() string
HeadToPtrHead func() string
HeadToNPtrHead func() string
HeadToAnonymousHead func() string
HeadToOmitEmptyHead func() string
HeadToStringTagHead func() string
PtrHeadToHead func() string
FieldToOmitEmptyField func() string
FieldToStringTagField func() string
} }
type headType struct { func createOpType(op, code string) opType {
Head string return opType{
PtrHead string Op: op,
NPtrHead string Code: code,
AnonymousHead string Indent: func() string { return fmt.Sprintf("%sIndent", op) },
AnonymousPtrHead string Escaped: func() string { return op },
AnonymousNPtrHead string HeadToPtrHead: func() string { return op },
OmitEmptyHead string HeadToNPtrHead: func() string { return op },
OmitEmptyPtrHead string HeadToAnonymousHead: func() string { return op },
OmitEmptyNPtrHead string HeadToOmitEmptyHead: func() string { return op },
AnonymousOmitEmptyHead string HeadToStringTagHead: func() string { return op },
AnonymousOmitEmptyPtrHead string PtrHeadToHead: func() string { return op },
AnonymousOmitEmptyNPtrHead string FieldToOmitEmptyField: func() string { return op },
StringTagHead string FieldToStringTagField: func() string { return op },
StringTagPtrHead string }
StringTagNPtrHead string
AnonymousStringTagHead string
AnonymousStringTagPtrHead string
AnonymousStringTagNPtrHead string
}
type fieldType struct {
Field string
OmitEmptyField string
StringTagField string
} }
func _main() error { func _main() error {
@ -88,7 +87,17 @@ func (t opType) toIndent() opType {
switch t { switch t {
{{- range $type := .OpTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Op }}: case op{{ $type.Op }}:
return op{{ $type.IndentOp }} return op{{ call $type.Indent }}
{{- end }}
}
return t
}
func (t opType) toEscaped() opType {
switch t {
{{- range $type := .OpTypes }}
case op{{ $type.Op }}:
return op{{ call $type.Escaped }}
{{- end }} {{- end }}
} }
return t return t
@ -96,19 +105,9 @@ func (t opType) toIndent() opType {
func (t opType) headToPtrHead() opType { func (t opType) headToPtrHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Head }}: case op{{ $type.Op }}:
return op{{ $type.PtrHead }} return op{{ call $type.HeadToPtrHead }}
case op{{ $type.AnonymousHead }}:
return op{{ $type.AnonymousPtrHead }}
case op{{ $type.OmitEmptyHead }}:
return op{{ $type.OmitEmptyPtrHead }}
case op{{ $type.AnonymousOmitEmptyHead }}:
return op{{ $type.AnonymousOmitEmptyPtrHead }}
case op{{ $type.StringTagHead }}:
return op{{ $type.StringTagPtrHead }}
case op{{ $type.AnonymousStringTagHead }}:
return op{{ $type.AnonymousStringTagPtrHead }}
{{- end }} {{- end }}
} }
return t return t
@ -116,19 +115,9 @@ func (t opType) headToPtrHead() opType {
func (t opType) headToNPtrHead() opType { func (t opType) headToNPtrHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Head }}: case op{{ $type.Op }}:
return op{{ $type.NPtrHead }} return op{{ call $type.HeadToNPtrHead }}
case op{{ $type.AnonymousHead }}:
return op{{ $type.AnonymousNPtrHead }}
case op{{ $type.OmitEmptyHead }}:
return op{{ $type.OmitEmptyNPtrHead }}
case op{{ $type.AnonymousOmitEmptyHead }}:
return op{{ $type.AnonymousOmitEmptyNPtrHead }}
case op{{ $type.StringTagHead }}:
return op{{ $type.StringTagNPtrHead }}
case op{{ $type.AnonymousStringTagHead }}:
return op{{ $type.AnonymousStringTagNPtrHead }}
{{- end }} {{- end }}
} }
return t return t
@ -136,19 +125,9 @@ func (t opType) headToNPtrHead() opType {
func (t opType) headToAnonymousHead() opType { func (t opType) headToAnonymousHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Head }}: case op{{ $type.Op }}:
return op{{ $type.AnonymousHead }} return op{{ call $type.HeadToAnonymousHead }}
case op{{ $type.PtrHead }}:
return op{{ $type.AnonymousPtrHead }}
case op{{ $type.OmitEmptyHead }}:
return op{{ $type.AnonymousOmitEmptyHead }}
case op{{ $type.OmitEmptyPtrHead }}:
return op{{ $type.AnonymousOmitEmptyPtrHead }}
case op{{ $type.StringTagHead }}:
return op{{ $type.AnonymousStringTagHead }}
case op{{ $type.StringTagPtrHead }}:
return op{{ $type.AnonymousStringTagPtrHead }}
{{- end }} {{- end }}
} }
return t return t
@ -156,11 +135,9 @@ func (t opType) headToAnonymousHead() opType {
func (t opType) headToOmitEmptyHead() opType { func (t opType) headToOmitEmptyHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Head }}: case op{{ $type.Op }}:
return op{{ $type.OmitEmptyHead }} return op{{ call $type.HeadToOmitEmptyHead }}
case op{{ $type.PtrHead }}:
return op{{ $type.OmitEmptyPtrHead }}
{{- end }} {{- end }}
} }
return t return t
@ -168,11 +145,9 @@ func (t opType) headToOmitEmptyHead() opType {
func (t opType) headToStringTagHead() opType { func (t opType) headToStringTagHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Head }}: case op{{ $type.Op }}:
return op{{ $type.StringTagHead }} return op{{ call $type.HeadToStringTagHead }}
case op{{ $type.PtrHead }}:
return op{{ $type.StringTagPtrHead }}
{{- end }} {{- end }}
} }
return t return t
@ -180,19 +155,9 @@ func (t opType) headToStringTagHead() opType {
func (t opType) ptrHeadToHead() opType { func (t opType) ptrHeadToHead() opType {
switch t { switch t {
{{- range $type := .HeadTypes }} {{- range $type := .OpTypes }}
case op{{ $type.PtrHead }}, op{{ $type.NPtrHead }}: case op{{ $type.Op }}:
return op{{ $type.Head }} return op{{ call $type.PtrHeadToHead }}
case op{{ $type.AnonymousPtrHead }}, op{{ $type.AnonymousNPtrHead }}:
return op{{ $type.AnonymousHead }}
case op{{ $type.OmitEmptyPtrHead }}, op{{ $type.OmitEmptyNPtrHead }}:
return op{{ $type.OmitEmptyHead }}
case op{{ $type.AnonymousOmitEmptyPtrHead }}, op{{ $type.AnonymousOmitEmptyNPtrHead }}:
return op{{ $type.AnonymousOmitEmptyHead }}
case op{{ $type.StringTagPtrHead }}, op{{ $type.StringTagNPtrHead }}:
return op{{ $type.StringTagHead }}
case op{{ $type.AnonymousStringTagPtrHead }}, op{{ $type.AnonymousStringTagNPtrHead }}:
return op{{ $type.AnonymousStringTagHead }}
{{- end }} {{- end }}
} }
return t return t
@ -200,9 +165,9 @@ func (t opType) ptrHeadToHead() opType {
func (t opType) fieldToOmitEmptyField() opType { func (t opType) fieldToOmitEmptyField() opType {
switch t { switch t {
{{- range $type := .FieldTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Field }}: case op{{ $type.Op }}:
return op{{ $type.OmitEmptyField }} return op{{ call $type.FieldToOmitEmptyField }}
{{- end }} {{- end }}
} }
return t return t
@ -210,9 +175,9 @@ func (t opType) fieldToOmitEmptyField() opType {
func (t opType) fieldToStringTagField() opType { func (t opType) fieldToStringTagField() opType {
switch t { switch t {
{{- range $type := .FieldTypes }} {{- range $type := .OpTypes }}
case op{{ $type.Field }}: case op{{ $type.Op }}:
return op{{ $type.StringTagField }} return op{{ call $type.FieldToStringTagField }}
{{- end }} {{- end }}
} }
return t return t
@ -238,210 +203,256 @@ func (t opType) fieldToStringTagField() opType {
primitiveTypes := []string{ primitiveTypes := []string{
"int", "int8", "int16", "int32", "int64", "int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64", "uint", "uint8", "uint16", "uint32", "uint64",
"float32", "float64", "bool", "string", "bytes", "float32", "float64", "bool", "string", "escapedString", "bytes",
"array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive", "array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive",
"intString", "int8String", "int16String", "int32String", "int64String", "intString", "int8String", "int16String", "int32String", "int64String",
"uintString", "uint8String", "uint16String", "uint32String", "uint64String", "uintString", "uint8String", "uint16String", "uint32String", "uint64String",
"intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr", "intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr",
"uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr", "uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr",
"float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "bytesPtr", "float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "escapedStringPtr", "bytesPtr",
"intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr", "intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr",
"uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr", "uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr",
"float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "bytesNPtr", "float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "escapedStringNPtr", "bytesNPtr",
} }
primitiveTypesUpper := []string{} primitiveTypesUpper := []string{}
for _, typ := range primitiveTypes { for _, typ := range primitiveTypes {
primitiveTypesUpper = append(primitiveTypesUpper, strings.ToUpper(string(typ[0]))+typ[1:]) primitiveTypesUpper = append(primitiveTypesUpper, strings.ToUpper(string(typ[0]))+typ[1:])
} }
opTypes := []opType{ opTypes := []opType{
{"End", "EndIndent", "Op"}, createOpType("End", "Op"),
{"Interface", "InterfaceIndent", "Op"}, createOpType("Interface", "Op"),
{"InterfaceEnd", "InterfaceEndIndent", "Op"}, createOpType("InterfaceEnd", "Op"),
{"Ptr", "PtrIndent", "Op"}, createOpType("Ptr", "Op"),
{"NPtr", "NPtrIndent", "Op"}, createOpType("NPtr", "Op"),
{"SliceHead", "SliceHeadIndent", "SliceHead"}, createOpType("SliceHead", "SliceHead"),
{"RootSliceHead", "RootSliceHeadIndent", "SliceHead"}, createOpType("RootSliceHead", "SliceHead"),
{"SliceElem", "SliceElemIndent", "SliceElem"}, createOpType("SliceElem", "SliceElem"),
{"RootSliceElem", "RootSliceElemIndent", "SliceElem"}, createOpType("RootSliceElem", "SliceElem"),
{"SliceEnd", "SliceEndIndent", "Op"}, createOpType("SliceEnd", "Op"),
{"ArrayHead", "ArrayHeadIndent", "ArrayHead"}, createOpType("ArrayHead", "ArrayHead"),
{"ArrayElem", "ArrayElemIndent", "ArrayElem"}, createOpType("ArrayElem", "ArrayElem"),
{"ArrayEnd", "ArrayEndIndent", "Op"}, createOpType("ArrayEnd", "Op"),
{"MapHead", "MapHeadIndent", "MapHead"}, createOpType("MapHead", "MapHead"),
{"MapHeadLoad", "MapHeadLoadIndent", "MapHead"}, createOpType("MapHeadLoad", "MapHead"),
{"MapKey", "MapKeyIndent", "MapKey"}, createOpType("MapKey", "MapKey"),
{"MapValue", "MapValueIndent", "MapValue"}, createOpType("MapValue", "MapValue"),
{"MapEnd", "MapEndIndent", "Op"}, createOpType("MapEnd", "Op"),
{"StructFieldHead", "StructFieldHeadIndent", "StructField"}, createOpType("StructFieldRecursiveEnd", "Op"),
{"StructFieldHeadOmitEmpty", "StructFieldHeadOmitEmptyIndent", "StructField"}, createOpType("StructEnd", "StructField"),
{"StructFieldHeadStringTag", "StructFieldHeadStringTagIndent", "StructField"}, createOpType("StructAnonymousEnd", "StructField"),
{"StructFieldAnonymousHead", "StructFieldAnonymousHeadIndent", "StructField"},
{"StructFieldAnonymousHeadOmitEmpty", "StructFieldAnonymousHeadOmitEmptyIndent", "StructField"},
{"StructFieldPtrAnonymousHeadOmitEmpty", "StructFieldPtrAnonymousHeadOmitEmptyIndent", "StructField"},
{"StructFieldNPtrAnonymousHeadOmitEmpty", "StructFieldNPtrAnonymousHeadOmitEmptyIndent", "StructField"},
{"StructFieldAnonymousHeadStringTag", "StructFieldAnonymousHeadStringTagIndent", "StructField"},
{"StructFieldPtrAnonymousHeadStringTag", "StructFieldPtrAnonymousHeadStringTagIndent", "StructField"},
{"StructFieldNPtrAnonymousHeadStringTag", "StructFieldNPtrAnonymousHeadStringTagIndent", "StructField"},
{"StructFieldPtrHead", "StructFieldPtrHeadIndent", "StructField"},
{"StructFieldPtrHeadOmitEmpty", "StructFieldPtrHeadOmitEmptyIndent", "StructField"},
{"StructFieldPtrHeadStringTag", "StructFieldPtrHeadStringTagIndent", "StructField"},
{"StructFieldPtrAnonymousHead", "StructFieldPtrAnonymousHeadIndent", "StructField"},
{"StructFieldNPtrHead", "StructFieldNPtrHeadIndent", "StructField"},
{"StructFieldNPtrHeadOmitEmpty", "StructFieldNPtrHeadOmitEmptyIndent", "StructField"},
{"StructFieldNPtrHeadStringTag", "StructFieldNPtrHeadStringTagIndent", "StructField"},
{"StructFieldNPtrAnonymousHead", "StructFieldNPtrAnonymousHeadIndent", "StructField"},
{"StructField", "StructFieldIndent", "StructField"},
{"StructFieldOmitEmpty", "StructFieldOmitEmptyIndent", "StructField"},
{"StructFieldStringTag", "StructFieldStringTagIndent", "StructField"},
{"StructFieldRecursiveEnd", "StructFieldRecursiveEndIndent", "Op"},
{"StructEnd", "StructEndIndent", "StructField"},
{"StructAnonymousEnd", "StructAnonymousEndIndent", "StructField"},
} }
for _, typ := range primitiveTypesUpper { for _, typ := range primitiveTypesUpper {
opTypes = append(opTypes, opType{ typ := typ
Op: typ, optype := createOpType(typ, "Op")
IndentOp: fmt.Sprintf("%sIndent", typ), switch typ {
Code: "Op", case "String", "StringPtr", "StringNPtr":
}) optype.Escaped = func() string {
return fmt.Sprintf("Escaped%s", typ)
}
}
opTypes = append(opTypes, optype)
} }
for _, prefix := range []string{ for _, escapedOrNot := range []string{"", "Escaped"} {
"StructFieldHead", for _, ptrOrNot := range []string{"", "Ptr", "NPtr"} {
"StructFieldHeadOmitEmpty", for _, headType := range []string{"", "Anonymous"} {
"StructFieldHeadStringTag", for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
"StructFieldAnonymousHead", for _, typ := range append(primitiveTypesUpper, "") {
"StructFieldAnonymousHeadOmitEmpty", escapedOrNot := escapedOrNot
"StructFieldAnonymousHeadStringTag", ptrOrNot := ptrOrNot
"StructFieldPtrHead", headType := headType
"StructFieldPtrHeadOmitEmpty", opt := opt
"StructFieldPtrHeadStringTag", typ := typ
"StructFieldPtrAnonymousHead",
"StructFieldPtrAnonymousHeadOmitEmpty", op := fmt.Sprintf(
"StructFieldPtrAnonymousHeadStringTag", "Struct%sField%s%sHead%s%s",
"StructFieldNPtrHead", escapedOrNot,
"StructFieldNPtrHeadOmitEmpty", ptrOrNot,
"StructFieldNPtrHeadStringTag", headType,
"StructFieldNPtrAnonymousHead", opt,
"StructFieldNPtrAnonymousHeadOmitEmpty", typ,
"StructFieldNPtrAnonymousHeadStringTag", )
"StructField", opTypes = append(opTypes, opType{
//"StructFieldPtr", Op: op,
//"StructFieldNPtr", Code: "StructField",
"StructFieldOmitEmpty", Indent: func() string { return fmt.Sprintf("%sIndent", op) },
"StructFieldStringTag", Escaped: func() string {
} { switch typ {
for _, typ := range primitiveTypesUpper { case "String", "StringPtr", "StringNPtr":
opTypes = append(opTypes, opType{ return fmt.Sprintf(
Op: fmt.Sprintf("%s%s", prefix, typ), "StructEscapedField%s%sHead%sEscaped%s",
IndentOp: fmt.Sprintf("%s%sIndent", prefix, typ), ptrOrNot,
Code: "StructField", headType,
}) opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedField%s%sHead%s%s",
ptrOrNot,
headType,
opt,
typ,
)
},
HeadToPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldPtr%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToNPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldNPtr%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToAnonymousHead: func() string {
return fmt.Sprintf(
"Struct%sField%sAnonymousHead%s%s",
escapedOrNot,
ptrOrNot,
opt,
typ,
)
},
HeadToOmitEmptyHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadOmitEmpty%s",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
HeadToStringTagHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadStringTag%s",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
PtrHeadToHead: func() string {
return fmt.Sprintf(
"Struct%sField%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
})
}
}
}
} }
} }
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, typ := range append(primitiveTypesUpper, "") {
escapedOrNot := escapedOrNot
opt := opt
typ := typ
op := fmt.Sprintf(
"Struct%sField%s%s",
escapedOrNot,
opt,
typ,
)
opTypes = append(opTypes, opType{
Op: op,
Code: "StructField",
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
Escaped: func() string {
switch typ {
case "String", "StringPtr", "StringNPtr":
return fmt.Sprintf(
"StructEscapedField%sEscaped%s",
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedField%s%s",
opt,
typ,
)
},
HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op },
HeadToOmitEmptyHead: func() string { return op },
HeadToStringTagHead: func() string { return op },
PtrHeadToHead: func() string { return op },
FieldToOmitEmptyField: func() string {
return fmt.Sprintf(
"Struct%sFieldOmitEmpty%s",
escapedOrNot,
typ,
)
},
FieldToStringTagField: func() string {
return fmt.Sprintf(
"Struct%sFieldStringTag%s",
escapedOrNot,
typ,
)
},
})
}
}
}
indentOpTypes := []opType{}
for _, typ := range opTypes { for _, typ := range opTypes {
opTypes = append(opTypes, opType{ typ := typ
Op: typ.IndentOp, indentOpTypes = append(indentOpTypes, opType{
IndentOp: typ.IndentOp, Op: fmt.Sprintf("%sIndent", typ.Op),
Code: typ.Code, Code: typ.Code,
Indent: func() string { return fmt.Sprintf("%sIndent", typ.Op) },
Escaped: func() string { return fmt.Sprintf("%sIndent", typ.Escaped()) },
HeadToPtrHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToPtrHead())
},
HeadToNPtrHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToNPtrHead())
},
HeadToAnonymousHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToAnonymousHead())
},
HeadToOmitEmptyHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToOmitEmptyHead())
},
HeadToStringTagHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToStringTagHead())
},
PtrHeadToHead: func() string {
return fmt.Sprintf("%sIndent", typ.PtrHeadToHead())
},
FieldToOmitEmptyField: func() string {
return fmt.Sprintf("%sIndent", typ.FieldToOmitEmptyField())
},
FieldToStringTagField: func() string {
return fmt.Sprintf("%sIndent", typ.FieldToStringTagField())
},
}) })
} }
base := headType{
Head: "StructFieldHead",
PtrHead: "StructFieldPtrHead",
NPtrHead: "StructFieldNPtrHead",
AnonymousHead: "StructFieldAnonymousHead",
AnonymousPtrHead: "StructFieldPtrAnonymousHead",
AnonymousNPtrHead: "StructFieldNPtrAnonymousHead",
OmitEmptyHead: "StructFieldHeadOmitEmpty",
OmitEmptyPtrHead: "StructFieldPtrHeadOmitEmpty",
OmitEmptyNPtrHead: "StructFieldNPtrHeadOmitEmpty",
StringTagHead: "StructFieldHeadStringTag",
StringTagPtrHead: "StructFieldPtrHeadStringTag",
StringTagNPtrHead: "StructFieldNPtrHeadStringTag",
AnonymousOmitEmptyHead: "StructFieldAnonymousHeadOmitEmpty",
AnonymousOmitEmptyPtrHead: "StructFieldPtrAnonymousHeadOmitEmpty",
AnonymousOmitEmptyNPtrHead: "StructFieldNPtrAnonymousHeadOmitEmpty",
AnonymousStringTagHead: "StructFieldAnonymousHeadStringTag",
AnonymousStringTagPtrHead: "StructFieldPtrAnonymousHeadStringTag",
AnonymousStringTagNPtrHead: "StructFieldNPtrAnonymousHeadStringTag",
}
headTypes := []headType{base}
for _, prim := range primitiveTypesUpper {
headTypes = append(headTypes, headType{
Head: fmt.Sprintf("%s%s", base.Head, prim),
PtrHead: fmt.Sprintf("%s%s", base.PtrHead, prim),
NPtrHead: fmt.Sprintf("%s%s", base.NPtrHead, prim),
AnonymousHead: fmt.Sprintf("%s%s", base.AnonymousHead, prim),
AnonymousPtrHead: fmt.Sprintf("%s%s", base.AnonymousPtrHead, prim),
AnonymousNPtrHead: fmt.Sprintf("%s%s", base.AnonymousNPtrHead, prim),
OmitEmptyHead: fmt.Sprintf("%s%s", base.OmitEmptyHead, prim),
OmitEmptyPtrHead: fmt.Sprintf("%s%s", base.OmitEmptyPtrHead, prim),
OmitEmptyNPtrHead: fmt.Sprintf("%s%s", base.OmitEmptyNPtrHead, prim),
AnonymousOmitEmptyHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyHead, prim),
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyPtrHead, prim),
AnonymousOmitEmptyNPtrHead: fmt.Sprintf("%s%s", base.AnonymousOmitEmptyNPtrHead, prim),
StringTagHead: fmt.Sprintf("%s%s", base.StringTagHead, prim),
StringTagPtrHead: fmt.Sprintf("%s%s", base.StringTagPtrHead, prim),
StringTagNPtrHead: fmt.Sprintf("%s%s", base.StringTagNPtrHead, prim),
AnonymousStringTagHead: fmt.Sprintf("%s%s", base.AnonymousStringTagHead, prim),
AnonymousStringTagPtrHead: fmt.Sprintf("%s%s", base.AnonymousStringTagPtrHead, prim),
AnonymousStringTagNPtrHead: fmt.Sprintf("%s%s", base.AnonymousStringTagNPtrHead, prim),
})
}
for _, typ := range headTypes {
headTypes = append(headTypes, headType{
Head: fmt.Sprintf("%sIndent", typ.Head),
PtrHead: fmt.Sprintf("%sIndent", typ.PtrHead),
NPtrHead: fmt.Sprintf("%sIndent", typ.NPtrHead),
AnonymousHead: fmt.Sprintf("%sIndent", typ.AnonymousHead),
AnonymousPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousPtrHead),
AnonymousNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousNPtrHead),
OmitEmptyHead: fmt.Sprintf("%sIndent", typ.OmitEmptyHead),
OmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.OmitEmptyPtrHead),
OmitEmptyNPtrHead: fmt.Sprintf("%sIndent", typ.OmitEmptyNPtrHead),
AnonymousOmitEmptyHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyHead),
AnonymousOmitEmptyPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyPtrHead),
AnonymousOmitEmptyNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousOmitEmptyNPtrHead),
StringTagHead: fmt.Sprintf("%sIndent", typ.StringTagHead),
StringTagPtrHead: fmt.Sprintf("%sIndent", typ.StringTagPtrHead),
StringTagNPtrHead: fmt.Sprintf("%sIndent", typ.StringTagNPtrHead),
AnonymousStringTagHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagHead),
AnonymousStringTagPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagPtrHead),
AnonymousStringTagNPtrHead: fmt.Sprintf("%sIndent", typ.AnonymousStringTagNPtrHead),
})
}
baseField := fieldType{
Field: "StructField",
OmitEmptyField: "StructFieldOmitEmpty",
StringTagField: "StructFieldStringTag",
}
fieldTypes := []fieldType{baseField}
for _, prim := range primitiveTypesUpper {
fieldTypes = append(fieldTypes, fieldType{
Field: fmt.Sprintf("%s%s", baseField.Field, prim),
OmitEmptyField: fmt.Sprintf("%s%s", baseField.OmitEmptyField, prim),
StringTagField: fmt.Sprintf("%s%s", baseField.StringTagField, prim),
})
}
for _, typ := range fieldTypes {
fieldTypes = append(fieldTypes, fieldType{
Field: fmt.Sprintf("%sIndent", typ.Field),
OmitEmptyField: fmt.Sprintf("%sIndent", typ.OmitEmptyField),
StringTagField: fmt.Sprintf("%sIndent", typ.StringTagField),
})
}
var b bytes.Buffer var b bytes.Buffer
if err := tmpl.Execute(&b, struct { if err := tmpl.Execute(&b, struct {
CodeTypes []string CodeTypes []string
OpTypes []opType OpTypes []opType
HeadTypes []headType
FieldTypes []fieldType
}{ }{
CodeTypes: codeTypes, CodeTypes: codeTypes,
OpTypes: opTypes, OpTypes: append(opTypes, indentOpTypes...),
HeadTypes: headTypes,
FieldTypes: fieldTypes,
}); err != nil { }); err != nil {
return err return err
} }

View File

@ -34,10 +34,19 @@ const (
bufSize = 1024 bufSize = 1024
) )
const (
opCodeEscapedType = iota
opCodeEscapedIndentType
opCodeNoEscapeType
opCodeNoEscapeIndentType
)
type opcodeSet struct { type opcodeSet struct {
codeIndent *opcode escapedCode *opcode
code *opcode escapedCodeIndent *opcode
codeLength int code *opcode
codeIndent *opcode
codeLength int
} }
func loadOpcodeMap() map[uintptr]*opcodeSet { func loadOpcodeMap() map[uintptr]*opcodeSet {
@ -187,9 +196,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
if codeSet, exists := opcodeMap[typeptr]; exists { if codeSet, exists := opcodeMap[typeptr]; exists {
var code *opcode var code *opcode
if e.enabledIndent { if e.enabledIndent {
code = codeSet.codeIndent if e.enabledHTMLEscape {
code = codeSet.escapedCodeIndent
} else {
code = codeSet.codeIndent
}
} else { } else {
code = codeSet.code if e.enabledHTMLEscape {
code = codeSet.escapedCode
} else {
code = codeSet.code
}
} }
ctx := e.ctx ctx := e.ctx
p := uintptr(header.ptr) p := uintptr(header.ptr)
@ -200,31 +217,23 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
// noescape trick for header.typ ( reflect.*rtype ) // noescape trick for header.typ ( reflect.*rtype )
copiedType := *(**rtype)(unsafe.Pointer(&typeptr)) 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{ code, err := e.compileHead(&encodeCompileContext{
typ: copiedType, typ: copiedType,
root: true, root: true,
withIndent: false,
structTypeToCompiledCode: map[uintptr]*compiledCode{}, structTypeToCompiledCode: map[uintptr]*compiledCode{},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
codeIndent = copyOpcode(codeIndent)
code = copyOpcode(code) code = copyOpcode(code)
codeIndent := toIndent(code)
codeLength := code.totalLength() codeLength := code.totalLength()
codeSet := &opcodeSet{ codeSet := &opcodeSet{
codeIndent: codeIndent, escapedCode: toEscaped(code),
code: code, escapedCodeIndent: toEscaped(codeIndent),
codeLength: codeLength, code: code,
codeIndent: codeIndent,
codeLength: codeLength,
} }
storeOpcodeSet(typeptr, codeSet, opcodeMap) storeOpcodeSet(typeptr, codeSet, opcodeMap)
@ -234,9 +243,17 @@ func (e *Encoder) encode(v interface{}) ([]byte, error) {
var c *opcode var c *opcode
if e.enabledIndent { if e.enabledIndent {
c = codeIndent if e.enabledHTMLEscape {
c = codeSet.escapedCodeIndent
} else {
c = codeSet.codeIndent
}
} else { } else {
c = code if e.enabledHTMLEscape {
c = codeSet.escapedCode
} else {
c = codeSet.code
}
} }
b, err = e.run(ctx, b, c) b, err = e.run(ctx, b, c)
@ -295,20 +312,6 @@ func encodeIndentComma(b []byte) []byte {
return append(b, ',', '\n') return append(b, ',', '\n')
} }
func (e *Encoder) encodeKey(b []byte, code *opcode) []byte {
if e.enabledHTMLEscape {
return append(b, code.escapedKey...)
}
return append(b, code.key...)
}
func (e *Encoder) encodeString(b []byte, s string) []byte {
if e.enabledHTMLEscape {
return encodeEscapedString(b, s)
}
return encodeNoEscapedString(b, s)
}
func encodeByteSlice(b []byte, src []byte) []byte { func encodeByteSlice(b []byte, src []byte) []byte {
encodedLen := base64.StdEncoding.EncodedLen(len(src)) encodedLen := base64.StdEncoding.EncodedLen(len(src))
b = append(b, '"') b = append(b, '"')

View File

@ -377,16 +377,6 @@ func (e *Encoder) compileSlice(ctx *encodeCompileContext) (*opcode, error) {
end := newOpCode(ctx, opSliceEnd) end := newOpCode(ctx, opSliceEnd)
ctx.incIndex() 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.elem = elemCode
header.end = end header.end = end
@ -421,12 +411,6 @@ func (e *Encoder) compileArray(ctx *encodeCompileContext) (*opcode, error) {
end := newOpCode(ctx, opArrayEnd) end := newOpCode(ctx, opArrayEnd)
ctx.incIndex() ctx.incIndex()
if ctx.withIndent {
header.op = opArrayHeadIndent
elemCode.op = opArrayElemIndent
end.op = opArrayEndIndent
}
header.elem = elemCode header.elem = elemCode
header.end = end header.end = end
header.next = code header.next = code
@ -487,13 +471,6 @@ func (e *Encoder) compileMap(ctx *encodeCompileContext, withLoad bool) (*opcode,
end := newMapEndCode(ctx, header) end := newMapEndCode(ctx, header)
ctx.incIndex() 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 header.next = keyCode
keyCode.beforeLastCode().next = (*opcode)(unsafe.Pointer(value)) keyCode.beforeLastCode().next = (*opcode)(unsafe.Pointer(value))
value.next = valueCode value.next = valueCode
@ -587,88 +564,46 @@ func (e *Encoder) typeToHeaderType(ctx *encodeCompileContext, code *opcode) opTy
} }
case opInt: case opInt:
return opStructFieldHeadInt return opStructFieldHeadInt
case opIntIndent:
return opStructFieldHeadIntIndent
case opInt8: case opInt8:
return opStructFieldHeadInt8 return opStructFieldHeadInt8
case opInt8Indent:
return opStructFieldHeadInt8Indent
case opInt16: case opInt16:
return opStructFieldHeadInt16 return opStructFieldHeadInt16
case opInt16Indent:
return opStructFieldHeadInt16Indent
case opInt32: case opInt32:
return opStructFieldHeadInt32 return opStructFieldHeadInt32
case opInt32Indent:
return opStructFieldHeadInt32Indent
case opInt64: case opInt64:
return opStructFieldHeadInt64 return opStructFieldHeadInt64
case opInt64Indent:
return opStructFieldHeadInt64Indent
case opUint: case opUint:
return opStructFieldHeadUint return opStructFieldHeadUint
case opUintIndent:
return opStructFieldHeadUintIndent
case opUint8: case opUint8:
return opStructFieldHeadUint8 return opStructFieldHeadUint8
case opUint8Indent:
return opStructFieldHeadUint8Indent
case opUint16: case opUint16:
return opStructFieldHeadUint16 return opStructFieldHeadUint16
case opUint16Indent:
return opStructFieldHeadUint16Indent
case opUint32: case opUint32:
return opStructFieldHeadUint32 return opStructFieldHeadUint32
case opUint32Indent:
return opStructFieldHeadUint32Indent
case opUint64: case opUint64:
return opStructFieldHeadUint64 return opStructFieldHeadUint64
case opUint64Indent:
return opStructFieldHeadUint64Indent
case opFloat32: case opFloat32:
return opStructFieldHeadFloat32 return opStructFieldHeadFloat32
case opFloat32Indent:
return opStructFieldHeadFloat32Indent
case opFloat64: case opFloat64:
return opStructFieldHeadFloat64 return opStructFieldHeadFloat64
case opFloat64Indent:
return opStructFieldHeadFloat64Indent
case opString: case opString:
return opStructFieldHeadString return opStructFieldHeadString
case opStringIndent:
return opStructFieldHeadStringIndent
case opBool: case opBool:
return opStructFieldHeadBool return opStructFieldHeadBool
case opBoolIndent:
return opStructFieldHeadBoolIndent
case opMapHead: case opMapHead:
return opStructFieldHeadMap return opStructFieldHeadMap
case opMapHeadLoad: case opMapHeadLoad:
return opStructFieldHeadMapLoad return opStructFieldHeadMapLoad
case opMapHeadIndent:
return opStructFieldHeadMapIndent
case opMapHeadLoadIndent:
return opStructFieldHeadMapLoadIndent
case opArrayHead: case opArrayHead:
return opStructFieldHeadArray return opStructFieldHeadArray
case opArrayHeadIndent:
return opStructFieldHeadArrayIndent
case opSliceHead: case opSliceHead:
return opStructFieldHeadSlice return opStructFieldHeadSlice
case opSliceHeadIndent:
return opStructFieldHeadSliceIndent
case opStructFieldHead: case opStructFieldHead:
return opStructFieldHeadStruct return opStructFieldHeadStruct
case opStructFieldHeadIndent:
return opStructFieldHeadStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldHeadMarshalJSON return opStructFieldHeadMarshalJSON
case opMarshalJSONIndent:
return opStructFieldHeadMarshalJSONIndent
case opMarshalText: case opMarshalText:
return opStructFieldHeadMarshalText return opStructFieldHeadMarshalText
case opMarshalTextIndent:
return opStructFieldHeadMarshalTextIndent
} }
return opStructFieldHead return opStructFieldHead
} }
@ -753,93 +688,51 @@ func (e *Encoder) typeToFieldType(ctx *encodeCompileContext, code *opcode) opTyp
} }
case opInt: case opInt:
return opStructFieldInt return opStructFieldInt
case opIntIndent:
return opStructFieldIntIndent
case opInt8: case opInt8:
return opStructFieldInt8 return opStructFieldInt8
case opInt8Indent:
return opStructFieldInt8Indent
case opInt16: case opInt16:
return opStructFieldInt16 return opStructFieldInt16
case opInt16Indent:
return opStructFieldInt16Indent
case opInt32: case opInt32:
return opStructFieldInt32 return opStructFieldInt32
case opInt32Indent:
return opStructFieldInt32Indent
case opInt64: case opInt64:
return opStructFieldInt64 return opStructFieldInt64
case opInt64Indent:
return opStructFieldInt64Indent
case opUint: case opUint:
return opStructFieldUint return opStructFieldUint
case opUintIndent:
return opStructFieldUintIndent
case opUint8: case opUint8:
return opStructFieldUint8 return opStructFieldUint8
case opUint8Indent:
return opStructFieldUint8Indent
case opUint16: case opUint16:
return opStructFieldUint16 return opStructFieldUint16
case opUint16Indent:
return opStructFieldUint16Indent
case opUint32: case opUint32:
return opStructFieldUint32 return opStructFieldUint32
case opUint32Indent:
return opStructFieldUint32Indent
case opUint64: case opUint64:
return opStructFieldUint64 return opStructFieldUint64
case opUint64Indent:
return opStructFieldUint64Indent
case opFloat32: case opFloat32:
return opStructFieldFloat32 return opStructFieldFloat32
case opFloat32Indent:
return opStructFieldFloat32Indent
case opFloat64: case opFloat64:
return opStructFieldFloat64 return opStructFieldFloat64
case opFloat64Indent:
return opStructFieldFloat64Indent
case opString: case opString:
return opStructFieldString return opStructFieldString
case opStringIndent:
return opStructFieldStringIndent
case opBool: case opBool:
return opStructFieldBool return opStructFieldBool
case opBoolIndent:
return opStructFieldBoolIndent
case opMapHead: case opMapHead:
return opStructFieldMap return opStructFieldMap
case opMapHeadLoad: case opMapHeadLoad:
return opStructFieldMapLoad return opStructFieldMapLoad
case opMapHeadIndent:
return opStructFieldMapIndent
case opMapHeadLoadIndent:
return opStructFieldMapLoadIndent
case opArrayHead: case opArrayHead:
return opStructFieldArray return opStructFieldArray
case opArrayHeadIndent:
return opStructFieldArrayIndent
case opSliceHead: case opSliceHead:
return opStructFieldSlice return opStructFieldSlice
case opSliceHeadIndent:
return opStructFieldSliceIndent
case opStructFieldHead: case opStructFieldHead:
return opStructFieldStruct return opStructFieldStruct
case opStructFieldHeadIndent:
return opStructFieldStructIndent
case opMarshalJSON: case opMarshalJSON:
return opStructFieldMarshalJSON return opStructFieldMarshalJSON
case opMarshalJSONIndent:
return opStructFieldMarshalJSONIndent
case opMarshalText: case opMarshalText:
return opStructFieldMarshalText return opStructFieldMarshalText
case opMarshalTextIndent:
return opStructFieldMarshalTextIndent
} }
return opStructField 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) headType := e.typeToHeaderType(ctx, code)
switch { switch {
case tag.isOmitEmpty: case tag.isOmitEmpty:
@ -847,13 +740,10 @@ func (e *Encoder) optimizeStructHeader(ctx *encodeCompileContext, code *opcode,
case tag.isString: case tag.isString:
headType = headType.headToStringTagHead() headType = headType.headToStringTagHead()
} }
if withIndent {
return headType.toIndent()
}
return headType 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) fieldType := e.typeToFieldType(ctx, code)
switch { switch {
case tag.isOmitEmpty: case tag.isOmitEmpty:
@ -861,9 +751,6 @@ func (e *Encoder) optimizeStructField(ctx *encodeCompileContext, code *opcode, t
case tag.isString: case tag.isString:
fieldType = fieldType.fieldToStringTagField() fieldType = fieldType.fieldToStringTagField()
} }
if withIndent {
return fieldType.toIndent()
}
return fieldType 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 { func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
fieldCode.indent-- fieldCode.indent--
op := e.optimizeStructHeader(ctx, valueCode, tag, ctx.withIndent) op := e.optimizeStructHeader(ctx, valueCode, tag)
fieldCode.op = op fieldCode.op = op
fieldCode.ptrNum = valueCode.ptrNum fieldCode.ptrNum = valueCode.ptrNum
switch op { switch op {
@ -900,20 +787,7 @@ func (e *Encoder) structHeader(ctx *encodeCompileContext, fieldCode *opcode, val
opStructFieldHeadOmitEmptyMap, opStructFieldHeadOmitEmptyMap,
opStructFieldHeadOmitEmptyMapLoad, opStructFieldHeadOmitEmptyMapLoad,
opStructFieldHeadOmitEmptyStruct, opStructFieldHeadOmitEmptyStruct,
opStructFieldHeadStringTag, opStructFieldHeadStringTag:
opStructFieldHeadIndent,
opStructFieldHeadSliceIndent,
opStructFieldHeadArrayIndent,
opStructFieldHeadMapIndent,
opStructFieldHeadMapLoadIndent,
opStructFieldHeadStructIndent,
opStructFieldHeadOmitEmptyIndent,
opStructFieldHeadOmitEmptySliceIndent,
opStructFieldHeadOmitEmptyArrayIndent,
opStructFieldHeadOmitEmptyMapIndent,
opStructFieldHeadOmitEmptyMapLoadIndent,
opStructFieldHeadOmitEmptyStructIndent,
opStructFieldHeadStringTagIndent:
return valueCode.beforeLastCode() return valueCode.beforeLastCode()
} }
ctx.decOpcodeIndex() 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 { func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valueCode *opcode, tag *structTag) *opcode {
code := (*opcode)(unsafe.Pointer(fieldCode)) code := (*opcode)(unsafe.Pointer(fieldCode))
op := e.optimizeStructField(ctx, valueCode, tag, ctx.withIndent) op := e.optimizeStructField(ctx, valueCode, tag)
fieldCode.op = op fieldCode.op = op
fieldCode.ptrNum = valueCode.ptrNum fieldCode.ptrNum = valueCode.ptrNum
switch op { switch op {
@ -938,20 +812,7 @@ func (e *Encoder) structField(ctx *encodeCompileContext, fieldCode *opcode, valu
opStructFieldOmitEmptyMap, opStructFieldOmitEmptyMap,
opStructFieldOmitEmptyMapLoad, opStructFieldOmitEmptyMapLoad,
opStructFieldOmitEmptyStruct, opStructFieldOmitEmptyStruct,
opStructFieldStringTag, opStructFieldStringTag:
opStructFieldIndent,
opStructFieldSliceIndent,
opStructFieldArrayIndent,
opStructFieldMapIndent,
opStructFieldMapLoadIndent,
opStructFieldStructIndent,
opStructFieldOmitEmptyIndent,
opStructFieldOmitEmptySliceIndent,
opStructFieldOmitEmptyArrayIndent,
opStructFieldOmitEmptyMapIndent,
opStructFieldOmitEmptyMapLoadIndent,
opStructFieldOmitEmptyStructIndent,
opStructFieldStringTagIndent:
return valueCode.beforeLastCode() return valueCode.beforeLastCode()
} }
ctx.decIndex() ctx.decIndex()
@ -988,10 +849,10 @@ func (e *Encoder) optimizeAnonymousFields(head *opcode) {
var prev *opcode var prev *opcode
removedFields := map[*opcode]struct{}{} removedFields := map[*opcode]struct{}{}
for { for {
if code.op == opStructEnd || code.op == opStructEndIndent { if code.op == opStructEnd {
break break
} }
if code.op == opStructField || code.op == opStructFieldIndent { if code.op == opStructField {
codeType := code.next.op.codeType() codeType := code.next.op.codeType()
if codeType == codeStructField { if codeType == codeStructField {
if e.isNotExistsField(code.next) { if e.isNotExistsField(code.next) {
@ -1252,9 +1113,6 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
} }
structEndCode.prevField = head structEndCode.prevField = head
ctx.incIndex() ctx.incIndex()
if ctx.withIndent {
head.op = opStructFieldHeadIndent
}
code = head code = head
} }
@ -1262,10 +1120,6 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode,
structEndCode.idx = opcodeOffset(ctx.ptrIndex) structEndCode.idx = opcodeOffset(ctx.ptrIndex)
ctx.incIndex() ctx.incIndex()
if ctx.withIndent {
structEndCode.op = opStructEndIndent
}
if prevField != nil && prevField.nextField == nil { if prevField != nil && prevField.nextField == nil {
prevField.nextField = structEndCode prevField.nextField = structEndCode
structEndCode.prevField = prevField structEndCode.prevField = prevField

View File

@ -6,7 +6,6 @@ import (
type encodeCompileContext struct { type encodeCompileContext struct {
typ *rtype typ *rtype
withIndent bool
root bool root bool
opcodeIndex int opcodeIndex int
ptrIndex int ptrIndex int
@ -19,7 +18,6 @@ type encodeCompileContext struct {
func (c *encodeCompileContext) context() *encodeCompileContext { func (c *encodeCompileContext) context() *encodeCompileContext {
return &encodeCompileContext{ return &encodeCompileContext{
typ: c.typ, typ: c.typ,
withIndent: c.withIndent,
root: c.root, root: c.root,
opcodeIndex: c.opcodeIndex, opcodeIndex: c.opcodeIndex,
ptrIndex: c.ptrIndex, ptrIndex: c.ptrIndex,

View File

@ -53,10 +53,35 @@ func copyOpcode(code *opcode) *opcode {
return code.copy(codeMap) return code.copy(codeMap)
} }
func newOpCodeWithNext(ctx *encodeCompileContext, op opType, next *opcode) *opcode { func toIndent(c *opcode) *opcode {
if op != opEnd && ctx.withIndent { c = copyOpcode(c)
op = op.toIndent() 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 toEscaped(c *opcode) *opcode {
c = copyOpcode(c)
for code := c; code.op != opEnd; {
code.op = code.op.toEscaped()
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{ return &opcode{
op: op, op: op,
typ: ctx.typ, typ: ctx.typ,

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff