Adding upstream version 0.10.5.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
104c0c203d
commit
e733edafba
141 changed files with 102352 additions and 0 deletions
319
internal/cmd/generator/main.go
Normal file
319
internal/cmd/generator/main.go
Normal file
|
@ -0,0 +1,319 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/format"
|
||||
"go/parser"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type opType struct {
|
||||
Op string
|
||||
Code string
|
||||
}
|
||||
|
||||
func createOpType(op, code string) opType {
|
||||
return opType{
|
||||
Op: op,
|
||||
Code: code,
|
||||
}
|
||||
}
|
||||
|
||||
func _main() error {
|
||||
tmpl, err := template.New("").Parse(`// Code generated by internal/cmd/generator. DO NOT EDIT!
|
||||
package encoder
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CodeType int
|
||||
|
||||
const (
|
||||
{{- range $index, $type := .CodeTypes }}
|
||||
Code{{ $type }} CodeType = {{ $index }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
var opTypeStrings = [{{ .OpLen }}]string{
|
||||
{{- range $type := .OpTypes }}
|
||||
"{{ $type.Op }}",
|
||||
{{- end }}
|
||||
}
|
||||
|
||||
type OpType uint16
|
||||
|
||||
const (
|
||||
{{- range $index, $type := .OpTypes }}
|
||||
Op{{ $type.Op }} OpType = {{ $index }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
func (t OpType) String() string {
|
||||
if int(t) >= {{ .OpLen }} {
|
||||
return ""
|
||||
}
|
||||
return opTypeStrings[int(t)]
|
||||
}
|
||||
|
||||
func (t OpType) CodeType() CodeType {
|
||||
if strings.Contains(t.String(), "Struct") {
|
||||
if strings.Contains(t.String(), "End") {
|
||||
return CodeStructEnd
|
||||
}
|
||||
return CodeStructField
|
||||
}
|
||||
switch t {
|
||||
case OpArray, OpArrayPtr:
|
||||
return CodeArrayHead
|
||||
case OpArrayElem:
|
||||
return CodeArrayElem
|
||||
case OpSlice, OpSlicePtr:
|
||||
return CodeSliceHead
|
||||
case OpSliceElem:
|
||||
return CodeSliceElem
|
||||
case OpMap, OpMapPtr:
|
||||
return CodeMapHead
|
||||
case OpMapKey:
|
||||
return CodeMapKey
|
||||
case OpMapValue:
|
||||
return CodeMapValue
|
||||
case OpMapEnd:
|
||||
return CodeMapEnd
|
||||
}
|
||||
|
||||
return CodeOp
|
||||
}
|
||||
|
||||
func (t OpType) HeadToPtrHead() OpType {
|
||||
if strings.Index(t.String(), "PtrHead") > 0 {
|
||||
return t
|
||||
}
|
||||
|
||||
idx := strings.Index(t.String(), "Head")
|
||||
if idx == -1 {
|
||||
return t
|
||||
}
|
||||
suffix := "PtrHead"+t.String()[idx+len("Head"):]
|
||||
|
||||
const toPtrOffset = 2
|
||||
if strings.Contains(OpType(int(t) + toPtrOffset).String(), suffix) {
|
||||
return OpType(int(t) + toPtrOffset)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t OpType) HeadToOmitEmptyHead() OpType {
|
||||
const toOmitEmptyOffset = 1
|
||||
if strings.Contains(OpType(int(t) + toOmitEmptyOffset).String(), "OmitEmpty") {
|
||||
return OpType(int(t) + toOmitEmptyOffset)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func (t OpType) PtrHeadToHead() OpType {
|
||||
idx := strings.Index(t.String(), "PtrHead")
|
||||
if idx == -1 {
|
||||
return t
|
||||
}
|
||||
suffix := t.String()[idx+len("Ptr"):]
|
||||
|
||||
const toPtrOffset = 2
|
||||
if strings.Contains(OpType(int(t) - toPtrOffset).String(), suffix) {
|
||||
return OpType(int(t) - toPtrOffset)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t OpType) FieldToEnd() OpType {
|
||||
idx := strings.Index(t.String(), "Field")
|
||||
if idx == -1 {
|
||||
return t
|
||||
}
|
||||
suffix := t.String()[idx+len("Field"):]
|
||||
if suffix == "" || suffix == "OmitEmpty" {
|
||||
return t
|
||||
}
|
||||
const toEndOffset = 2
|
||||
if strings.Contains(OpType(int(t) + toEndOffset).String(), "End"+suffix) {
|
||||
return OpType(int(t) + toEndOffset)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (t OpType) FieldToOmitEmptyField() OpType {
|
||||
const toOmitEmptyOffset = 1
|
||||
if strings.Contains(OpType(int(t) + toOmitEmptyOffset).String(), "OmitEmpty") {
|
||||
return OpType(int(t) + toOmitEmptyOffset)
|
||||
}
|
||||
return t
|
||||
}
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
codeTypes := []string{
|
||||
"Op",
|
||||
"ArrayHead",
|
||||
"ArrayElem",
|
||||
"SliceHead",
|
||||
"SliceElem",
|
||||
"MapHead",
|
||||
"MapKey",
|
||||
"MapValue",
|
||||
"MapEnd",
|
||||
"Recursive",
|
||||
"StructField",
|
||||
"StructEnd",
|
||||
}
|
||||
primitiveTypes := []string{
|
||||
"int", "uint", "float32", "float64", "bool", "string", "bytes", "number",
|
||||
"array", "map", "slice", "struct", "MarshalJSON", "MarshalText",
|
||||
"intString", "uintString", "float32String", "float64String", "boolString", "stringString", "numberString",
|
||||
"intPtr", "uintPtr", "float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "bytesPtr", "numberPtr",
|
||||
"arrayPtr", "mapPtr", "slicePtr", "marshalJSONPtr", "marshalTextPtr", "interfacePtr",
|
||||
"intPtrString", "uintPtrString", "float32PtrString", "float64PtrString", "boolPtrString", "stringPtrString", "numberPtrString",
|
||||
}
|
||||
primitiveTypesUpper := []string{}
|
||||
for _, typ := range primitiveTypes {
|
||||
primitiveTypesUpper = append(primitiveTypesUpper, strings.ToUpper(string(typ[0]))+typ[1:])
|
||||
}
|
||||
opTypes := []opType{
|
||||
createOpType("End", "Op"),
|
||||
createOpType("Interface", "Op"),
|
||||
createOpType("Ptr", "Op"),
|
||||
createOpType("SliceElem", "SliceElem"),
|
||||
createOpType("SliceEnd", "Op"),
|
||||
createOpType("ArrayElem", "ArrayElem"),
|
||||
createOpType("ArrayEnd", "Op"),
|
||||
createOpType("MapKey", "MapKey"),
|
||||
createOpType("MapValue", "MapValue"),
|
||||
createOpType("MapEnd", "Op"),
|
||||
createOpType("Recursive", "Op"),
|
||||
createOpType("RecursivePtr", "Op"),
|
||||
createOpType("RecursiveEnd", "Op"),
|
||||
createOpType("InterfaceEnd", "Op"),
|
||||
}
|
||||
for _, typ := range primitiveTypesUpper {
|
||||
typ := typ
|
||||
opTypes = append(opTypes, createOpType(typ, "Op"))
|
||||
}
|
||||
for _, typ := range append(primitiveTypesUpper, "") {
|
||||
for _, ptrOrNot := range []string{"", "Ptr"} {
|
||||
for _, opt := range []string{"", "OmitEmpty"} {
|
||||
ptrOrNot := ptrOrNot
|
||||
opt := opt
|
||||
typ := typ
|
||||
|
||||
op := fmt.Sprintf(
|
||||
"Struct%sHead%s%s",
|
||||
ptrOrNot,
|
||||
opt,
|
||||
typ,
|
||||
)
|
||||
opTypes = append(opTypes, opType{
|
||||
Op: op,
|
||||
Code: "StructField",
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, typ := range append(primitiveTypesUpper, "") {
|
||||
for _, opt := range []string{"", "OmitEmpty"} {
|
||||
opt := opt
|
||||
typ := typ
|
||||
|
||||
op := fmt.Sprintf(
|
||||
"StructField%s%s",
|
||||
opt,
|
||||
typ,
|
||||
)
|
||||
opTypes = append(opTypes, opType{
|
||||
Op: op,
|
||||
Code: "StructField",
|
||||
})
|
||||
}
|
||||
for _, opt := range []string{"", "OmitEmpty"} {
|
||||
opt := opt
|
||||
typ := typ
|
||||
|
||||
op := fmt.Sprintf(
|
||||
"StructEnd%s%s",
|
||||
opt,
|
||||
typ,
|
||||
)
|
||||
opTypes = append(opTypes, opType{
|
||||
Op: op,
|
||||
Code: "StructEnd",
|
||||
})
|
||||
}
|
||||
}
|
||||
var b bytes.Buffer
|
||||
if err := tmpl.Execute(&b, struct {
|
||||
CodeTypes []string
|
||||
OpTypes []opType
|
||||
OpLen int
|
||||
}{
|
||||
CodeTypes: codeTypes,
|
||||
OpTypes: opTypes,
|
||||
OpLen: len(opTypes),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
path := filepath.Join(repoRoot(), "internal", "encoder", "optype.go")
|
||||
buf, err := format.Source(b.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(path, buf, 0644)
|
||||
}
|
||||
|
||||
func generateVM() error {
|
||||
file, err := os.ReadFile("vm.go.tmpl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "", string(file), parser.ParseComments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, pkg := range []string{"vm", "vm_indent", "vm_color", "vm_color_indent"} {
|
||||
f.Name.Name = pkg
|
||||
var buf bytes.Buffer
|
||||
printer.Fprint(&buf, fset, f)
|
||||
path := filepath.Join(repoRoot(), "internal", "encoder", pkg, "vm.go")
|
||||
source, err := format.Source(buf.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(path, source, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func repoRoot() string {
|
||||
_, file, _, _ := runtime.Caller(0)
|
||||
relativePathFromRepoRoot := filepath.Join("internal", "cmd", "generator")
|
||||
return strings.TrimSuffix(filepath.Dir(file), relativePathFromRepoRoot)
|
||||
}
|
||||
|
||||
//go:generate go run main.go
|
||||
func main() {
|
||||
if err := generateVM(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := _main(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue