188 lines
4.4 KiB
Go
188 lines
4.4 KiB
Go
// exportable typescript generated from golang
|
|
// Copyright (C) 2022 Fabio Prada
|
|
|
|
package tsrpc
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
)
|
|
|
|
type TSSField struct {
|
|
Name string
|
|
Type string
|
|
TsType string
|
|
Json TSTagJson
|
|
Ts TSTagTs
|
|
DependOn bool
|
|
SourceInfo string
|
|
}
|
|
|
|
type TSStruct struct {
|
|
Name string
|
|
Typescript bool
|
|
Fields []TSSField
|
|
SourceInfo string
|
|
}
|
|
|
|
func IsNativeType(t string) bool {
|
|
switch t {
|
|
case "uint8", "uint16", "uint32", "uint64", "uint",
|
|
"int8", "int16", "int32", "int64", "int",
|
|
"float32", "float64":
|
|
return true
|
|
case "bool":
|
|
return true
|
|
case "string":
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func toBeImported(t ast.Expr) bool {
|
|
switch ft := t.(type) {
|
|
case *ast.Ident:
|
|
return !IsNativeType(ft.Name)
|
|
case *ast.SelectorExpr:
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func typeToTypescript(k string) string {
|
|
switch k {
|
|
case "uint8", "uint16", "uint32", "uint64", "uint",
|
|
"int8", "int16", "int32", "int64", "int",
|
|
"float32", "float64":
|
|
return "number"
|
|
case "bool":
|
|
return "boolean"
|
|
case "string":
|
|
return "string"
|
|
}
|
|
return k
|
|
}
|
|
|
|
func getFieldInfo(t ast.Expr) string {
|
|
result := ""
|
|
switch ft := t.(type) {
|
|
case *ast.Ident:
|
|
result = ft.Name
|
|
case *ast.SelectorExpr:
|
|
result = fmt.Sprintf("%s.%s", ft.X, ft.Sel)
|
|
case *ast.ArrayType:
|
|
result = fmt.Sprintf("[]%s", getFieldInfo(ft.Elt))
|
|
case *ast.StarExpr:
|
|
result = fmt.Sprintf("*%s", (ft.X))
|
|
case *ast.MapType:
|
|
result = fmt.Sprintf("map[%s]%s", ft.Key, getFieldInfo(ft.Value))
|
|
case *ast.InterfaceType:
|
|
result = "interface{}"
|
|
default:
|
|
f := fmt.Sprintf("this go type: %T is not evaluated", ft)
|
|
fmt.Println(f)
|
|
//exitOnError(fmt.Errorf("this go type: %T is not evaluated", ft))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func getFieldTsInfo(t ast.Expr) string {
|
|
result := ""
|
|
switch ft := t.(type) {
|
|
case *ast.Ident:
|
|
result = typeToTypescript(ft.Name)
|
|
case *ast.SelectorExpr:
|
|
result = typeToTypescript(fmt.Sprintf("%s.%s", ft.X, ft.Sel))
|
|
case *ast.ArrayType:
|
|
result = fmt.Sprintf("%s[]", typeToTypescript(getFieldTsInfo(ft.Elt)))
|
|
case *ast.StarExpr:
|
|
result = fmt.Sprintf("Nullable<%s>", typeToTypescript(getFieldTsInfo(ft.X)))
|
|
case *ast.MapType:
|
|
result = fmt.Sprintf("Record<%s , %s>", typeToTypescript(fmt.Sprintf("%s", ft.Key)), typeToTypescript(("ft.Value")))
|
|
case *ast.InterfaceType:
|
|
result = "unknown"
|
|
case *ast.FuncType:
|
|
fmt.Println("*ast.FuncType found, skipping...")
|
|
default:
|
|
//f := fmt.Sprintf("getFieldTsInfo can't evaluate type: %T %T", t, ft)
|
|
//fmt.Println(f)
|
|
exitOnError(fmt.Errorf("getFieldTsInfo can't evaluate type: %T %T", t, ft))
|
|
}
|
|
return result
|
|
}
|
|
|
|
func getSourceInfo(pos int, src []TSSourceFile) string {
|
|
for _, v := range src {
|
|
for _, l := range v.Lines {
|
|
if pos >= l.Pos && pos <= l.End {
|
|
return fmt.Sprintf("%s Line: %d", v.Name, l.Line)
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (s *TSStruct) getStruct(ts *ast.TypeSpec, src []TSSourceFile) {
|
|
if st, ok := ts.Type.(*ast.StructType); ok {
|
|
for _, field := range st.Fields.List {
|
|
|
|
tag := ""
|
|
if field.Tag != nil {
|
|
tag = field.Tag.Value
|
|
}
|
|
|
|
tagJson := TSTagJson{}
|
|
tagJson.parse(tag)
|
|
|
|
tagTs := TSTagTs{}
|
|
tagTs.parse(tag)
|
|
|
|
tsType := ""
|
|
|
|
if len(field.Names) > 0 {
|
|
tsType = getFieldTsInfo(field.Type)
|
|
var f = TSSField{
|
|
Name: field.Names[0].String(),
|
|
Json: tagJson,
|
|
Ts: tagTs,
|
|
Type: getFieldInfo(field.Type),
|
|
TsType: tsType,
|
|
DependOn: toBeImported(field.Type),
|
|
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
|
}
|
|
s.Fields = append(s.Fields, f)
|
|
} else {
|
|
if se, ok := field.Type.(*ast.SelectorExpr); ok {
|
|
var f = TSSField{
|
|
Name: fmt.Sprintf("%s.%s", se.X, se.Sel),
|
|
Json: tagJson,
|
|
Ts: tagTs,
|
|
Type: getFieldInfo(field.Type),
|
|
TsType: tsType,
|
|
DependOn: toBeImported(field.Type),
|
|
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
|
}
|
|
s.Fields = append(s.Fields, f)
|
|
} else {
|
|
if se, ok := field.Type.(*ast.Ident); ok {
|
|
var f = TSSField{
|
|
Name: se.Name,
|
|
Json: tagJson,
|
|
Ts: tagTs,
|
|
Type: se.Name,
|
|
TsType: tsType,
|
|
DependOn: false,
|
|
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
|
}
|
|
s.Fields = append(s.Fields, f)
|
|
|
|
fmt.Println(f)
|
|
} else {
|
|
exitOnError(fmt.Errorf("this typescript type: %T is not evaluated", field.Type))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|