added support for *ast.ArrayType, *ast.MapType

This commit is contained in:
Jan Halfar 2018-09-02 18:09:04 +02:00
parent 4815f1a92a
commit 082639676f
7 changed files with 72 additions and 27 deletions

View File

@ -110,7 +110,7 @@ func Build(conf *config.Config, goPath string) {
os.Exit(2) os.Exit(2)
} }
ts, err := RenderTypeScriptServices(conf.ModuleKind, conf.TSClientFlavor, services, conf.Mappings, scalarTypes, target) ts, err := RenderTypeScriptServices(conf.ModuleKind, conf.TSClientFlavor, services, conf.Mappings, scalarTypes, structs, target)
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, " could not generate ts code", err) fmt.Fprintln(os.Stderr, " could not generate ts code", err)
os.Exit(3) os.Exit(3)

View File

@ -93,6 +93,8 @@ type Struct struct {
Package string Package string
Name string Name string
Fields []*Field Fields []*Field
Map *Map
Array *Array
} }
type Scalar struct { type Scalar struct {

View File

@ -410,6 +410,15 @@ func (s *Struct) DepsSatisfied(missingTypes map[string]bool, structs map[string]
} }
} }
} }
if s.Array != nil {
if s.Array.Value != nil {
if s.Array.Value.StructType != nil {
if needsWork(s.Array.Value.StructType.FullName()) {
return false
}
}
}
}
return !needsWork(s.FullName()) return !needsWork(s.FullName())
} }

View File

@ -362,11 +362,22 @@ func extractTypes(file *ast.File, packageName string, structs map[string]*Struct
Package: packageName, Package: packageName,
Type: getScalarFromAstIdent(scalarIdent), Type: getScalarFromAstIdent(scalarIdent),
} }
// case "*ast.ArrayType": case "*ast.ArrayType":
// arrayType := obj.Decl.(*ast.ArrayType) arrayValue := &Value{}
// case "*ast.MapType": arrayValue.loadExpr(typeSpec.Type, fileImports)
// mapType := obj.decl.(*ast.MapType) structs[structName] = &Struct{
Name: name,
Package: packageName,
Array: arrayValue.Array,
}
case "*ast.MapType":
mapValue := &Value{}
mapValue.loadExpr(typeSpec.Type, fileImports)
structs[structName] = &Struct{
Name: name,
Package: packageName,
Map: mapValue.Map,
}
default: default:
fmt.Println(" ignoring", obj.Name, typeSpecRefl.Type().String()) fmt.Println(" ignoring", obj.Name, typeSpecRefl.Type().String())
} }

View File

@ -23,15 +23,15 @@ func (f *Field) tsName() string {
return n return n
} }
func (v *Value) tsType(mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) { func (v *Value) tsType(mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, ts *code) {
switch true { switch true {
case v.Map != nil: case v.Map != nil:
ts.app("{[index:" + v.Map.KeyType + "]:") ts.app("{[index:" + v.Map.KeyType + "]:")
v.Map.Value.tsType(mappings, scalarTypes, ts) v.Map.Value.tsType(mappings, scalarTypes, structs, ts)
ts.app("}") ts.app("}")
case v.Array != nil: case v.Array != nil:
v.Array.Value.tsType(mappings, scalarTypes, ts) v.Array.Value.tsType(mappings, scalarTypes, structs, ts)
if v.Array.Value.ScalarType != ScalarTypeByte { if v.Array.Value.ScalarType != ScalarTypeByte {
ts.app("[]") ts.app("[]")
} }
@ -45,12 +45,24 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalarTypes map[strin
tsModule = mapping.TypeScriptModule tsModule = mapping.TypeScriptModule
} }
scalarName := v.StructType.FullName() scalarName := v.StructType.FullName()
// is it a hdden scalar ?! // is it a hidden scalar ?!
hiddenScalar, ok := scalarTypes[scalarName] hiddenScalar, ok := scalarTypes[scalarName]
if ok { if ok {
ts.app(tsTypeFromScalarType(hiddenScalar.Type)) ts.app(tsTypeFromScalarType(hiddenScalar.Type))
return return
} }
hiddenStruct, okHiddenStruct := structs[scalarName]
if okHiddenStruct && hiddenStruct.Array != nil {
hiddenMapping, hiddenMappingOK := mappings[hiddenStruct.Array.Value.StructType.Package]
var tsModule string
if hiddenMappingOK {
tsModule = hiddenMapping.TypeScriptModule
}
ts.app(tsModule + "." + hiddenStruct.Array.Value.StructType.Name + "[]")
return
}
ts.app(tsModule + "." + v.StructType.Name) ts.app(tsModule + "." + v.StructType.Name)
return return
} }
@ -58,7 +70,7 @@ func (v *Value) tsType(mappings config.TypeScriptMappings, scalarTypes map[strin
case v.Struct != nil: case v.Struct != nil:
//v.Struct.Value.tsType(mappings, ts) //v.Struct.Value.tsType(mappings, ts)
ts.l("{").ind(1) ts.l("{").ind(1)
renderStructFields(v.Struct.Fields, mappings, scalarTypes, ts) renderStructFields(v.Struct.Fields, mappings, scalarTypes, structs, ts)
ts.ind(-1).app("}") ts.ind(-1).app("}")
case len(v.ScalarType) > 0: case len(v.ScalarType) > 0:
ts.app(tsTypeFromScalarType(v.ScalarType)) ts.app(tsTypeFromScalarType(v.ScalarType))
@ -78,7 +90,7 @@ func tsTypeFromScalarType(scalarType ScalarType) string {
return string(scalarType) return string(scalarType)
} }
func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) { func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, ts *code) {
for _, f := range fields { for _, f := range fields {
if f.JSONInfo != nil && f.JSONInfo.Ignore { if f.JSONInfo != nil && f.JSONInfo.Ignore {
continue continue
@ -88,17 +100,28 @@ func renderStructFields(fields []*Field, mappings config.TypeScriptMappings, sca
ts.app("?") ts.app("?")
} }
ts.app(":") ts.app(":")
f.Value.tsType(mappings, scalarTypes, ts) f.Value.tsType(mappings, scalarTypes, structs, ts)
ts.app(";") ts.app(";")
ts.nl() ts.nl()
} }
} }
func renderTypescriptStruct(str *Struct, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) error { func renderTypescriptStruct(str *Struct, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, ts *code) error {
if str.Array != nil {
// skipping array type
return nil
}
ts.l("// " + str.FullName()) ts.l("// " + str.FullName())
ts.l("export interface " + str.Name + " {").ind(1) ts.l("export interface " + str.Name + " {").ind(1)
renderStructFields(str.Fields, mappings, scalarTypes, ts) if str.Map != nil {
ts.app("[index:" + str.Map.KeyType + "]:")
str.Map.Value.tsType(mappings, scalarTypes, structs, ts)
ts.app(";")
ts.nl()
} else {
renderStructFields(str.Fields, mappings, scalarTypes, structs, ts)
}
ts.ind(-1).l("}") ts.ind(-1).l("}")
return nil return nil
} }
@ -131,7 +154,7 @@ func renderTypescriptStructsToPackages(
if !(moduleKind == config.ModuleKindCommonJS) { if !(moduleKind == config.ModuleKindCommonJS) {
packageCodeMap[str.Name].ind(1) packageCodeMap[str.Name].ind(1)
} }
err = renderTypescriptStruct(str, mappings, scalarTypes, packageCodeMap[str.Name]) err = renderTypescriptStruct(str, mappings, scalarTypes, structs, packageCodeMap[str.Name])
if err != nil { if err != nil {
return return
} }
@ -219,7 +242,7 @@ func ucFirst(str string) string {
return constPrefix return constPrefix
} }
func RenderTypeScriptServices(moduleKind config.ModuleKind, tsClientFlavor config.TSClientFlavor, services ServiceList, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, target *config.Target) (typeScript string, err error) { func RenderTypeScriptServices(moduleKind config.ModuleKind, tsClientFlavor config.TSClientFlavor, services ServiceList, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, target *config.Target) (typeScript string, err error) {
ts := newCode(" ") ts := newCode(" ")
if !SkipGoTSRPC && tsClientFlavor == "" { if !SkipGoTSRPC && tsClientFlavor == "" {
@ -269,9 +292,9 @@ func RenderTypeScriptServices(moduleKind config.ModuleKind, tsClientFlavor confi
} }
switch tsClientFlavor { switch tsClientFlavor {
case config.TSClientFlavorAsync: case config.TSClientFlavorAsync:
err = renderTypescriptClientAsync(service, mappings, scalarTypes, ts) err = renderTypescriptClientAsync(service, mappings, scalarTypes, structs, ts)
default: default:
err = renderTypescriptClient(SkipGoTSRPC, moduleKind, service, mappings, scalarTypes, ts) err = renderTypescriptClient(SkipGoTSRPC, moduleKind, service, mappings, scalarTypes, structs, ts)
} }
if err != nil { if err != nil {
return return

View File

@ -7,7 +7,7 @@ import (
"github.com/foomo/gotsrpc/config" "github.com/foomo/gotsrpc/config"
) )
func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, service *Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) error { func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, service *Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, ts *code) error {
clientName := service.Name + "Client" clientName := service.Name + "Client"
ts.l("export class " + clientName + " {").ind(1) ts.l("export class " + clientName + " {").ind(1)
@ -54,7 +54,7 @@ func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, serv
ts.app(", ") ts.app(", ")
} }
ts.app(arg.tsName() + ":") ts.app(arg.tsName() + ":")
arg.Value.tsType(mappings, scalarTypes, ts) arg.Value.tsType(mappings, scalarTypes, structs, ts)
callArgs = append(callArgs, arg.Name) callArgs = append(callArgs, arg.Name)
argCount++ argCount++
} }
@ -76,7 +76,7 @@ func renderTypescriptClient(skipGoTSRPC bool, moduleKind config.ModuleKind, serv
ts.app(", ") ts.app(", ")
} }
ts.app(retArgName + ":") ts.app(retArgName + ":")
retField.Value.tsType(mappings, scalarTypes, ts) retField.Value.tsType(mappings, scalarTypes, structs, ts)
} }
ts.app(") => void") ts.app(") => void")

View File

@ -8,7 +8,7 @@ import (
"github.com/foomo/gotsrpc/config" "github.com/foomo/gotsrpc/config"
) )
func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, ts *code) error { func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMappings, scalarTypes map[string]*Scalar, structs map[string]*Struct, ts *code) error {
clientName := service.Name + "Client" clientName := service.Name + "Client"
ts.l("export class " + clientName + " {") ts.l("export class " + clientName + " {")
@ -48,7 +48,7 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap
ts.app(", ") ts.app(", ")
} }
ts.app(arg.tsName() + ":") ts.app(arg.tsName() + ":")
arg.Value.tsType(mappings, scalarTypes, ts) arg.Value.tsType(mappings, scalarTypes, structs, ts)
callArgs = append(callArgs, arg.Name) callArgs = append(callArgs, arg.Name)
argCount++ argCount++
} }
@ -85,7 +85,7 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap
} }
innerReturnTypeTS.app(strconv.Itoa(index) + ":") innerReturnTypeTS.app(strconv.Itoa(index) + ":")
retField.Value.tsType(mappings, scalarTypes, innerReturnTypeTS) retField.Value.tsType(mappings, scalarTypes, structs, innerReturnTypeTS)
if index == len(method.Return)-1 && retField.Value.IsError { if index == len(method.Return)-1 && retField.Value.IsError {
throwLastError = true throwLastError = true
@ -94,14 +94,14 @@ func renderTypescriptClientAsync(service *Service, mappings config.TypeScriptMap
} else { } else {
if index == 0 { if index == 0 {
firstReturnTypeTS := newCode(" ") firstReturnTypeTS := newCode(" ")
retField.Value.tsType(mappings, scalarTypes, firstReturnTypeTS) retField.Value.tsType(mappings, scalarTypes, structs, firstReturnTypeTS)
firstReturnType = firstReturnTypeTS.string() firstReturnType = firstReturnTypeTS.string()
//firstReturnFieldName = retArgName //firstReturnFieldName = retArgName
} }
countReturns++ countReturns++
returnTypeTS.app(retArgName + ":") returnTypeTS.app(retArgName + ":")
responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]" responseObject += responseObjectPrefix + retArgName + " : response[" + strconv.Itoa(index) + "]"
retField.Value.tsType(mappings, scalarTypes, returnTypeTS) retField.Value.tsType(mappings, scalarTypes, structs, returnTypeTS)
} }
responseObjectPrefix = ", " responseObjectPrefix = ", "
} }