diff --git a/kitcom/api/api.go b/kitcom/api/api.go new file mode 100644 index 0000000..8d27360 --- /dev/null +++ b/kitcom/api/api.go @@ -0,0 +1,35 @@ +package api + +// todo check TInt size < 64 +// todo check not float + +type ValType int + +const ( + TInt ValType = 1 + TString ValType = 2 + TBool ValType = 3 + TBlob ValType = 4 + TArray ValType = 5 +) + +type Val struct { + Name string + Type ValType + Children []Val +} + +type Method struct { + Name string + Params []Val + Ret []Val +} + +type Endpoint struct { + Name string + Methods []Method +} + +type Api struct { + Endpoints []Endpoint +} diff --git a/kitcom/go_gen.tmpl b/kitcom/golang/go_gen.tmpl similarity index 100% rename from kitcom/go_gen.tmpl rename to kitcom/golang/go_gen.tmpl diff --git a/kitcom/gogen.go b/kitcom/golang/gogen.go similarity index 71% rename from kitcom/gogen.go rename to kitcom/golang/gogen.go index 19d0dee..f149847 100644 --- a/kitcom/gogen.go +++ b/kitcom/golang/gogen.go @@ -1,4 +1,4 @@ -package main +package golang import ( "bytes" @@ -7,21 +7,23 @@ import ( "os" "strings" "text/template" + + "efprojects.com/kitten-ipc/kitcom/api" ) type goGenData struct { PkgName string - Api *Api + Api *api.Api } type GoApiGenerator struct { - pkgName string + PkgName string } -func (g *GoApiGenerator) Generate(api *Api, destFile string) error { +func (g *GoApiGenerator) Generate(apis *api.Api, destFile string) error { tplCtx := goGenData{ - PkgName: g.pkgName, - Api: api, + PkgName: g.PkgName, + Api: apis, } tpl := template.New("gogen") @@ -29,22 +31,22 @@ func (g *GoApiGenerator) Generate(api *Api, destFile string) error { "receiver": func(name string) string { return strings.ToLower(name)[0:1] }, - "typedef": func(t ValType) (string, error) { - td, ok := map[ValType]string{ - TInt: "int", - TString: "string", - TBool: "bool", + "typedef": func(t api.ValType) (string, error) { + td, ok := map[api.ValType]string{ + api.TInt: "int", + api.TString: "string", + api.TBool: "bool", }[t] if !ok { return "", fmt.Errorf("cannot generate type %v", t) } return td, nil }, - "zerovalue": func(t ValType) (string, error) { - v, ok := map[ValType]string{ - TInt: "0", - TString: `""`, - TBool: "false", + "zerovalue": func(t api.ValType) (string, error) { + v, ok := map[api.ValType]string{ + api.TInt: "0", + api.TString: `""`, + api.TBool: "false", }[t] if !ok { return "", fmt.Errorf("cannot generate zero value for type %v", t) diff --git a/kitcom/goparser.go b/kitcom/golang/goparser.go similarity index 79% rename from kitcom/goparser.go rename to kitcom/golang/goparser.go index 4a99282..be28405 100644 --- a/kitcom/goparser.go +++ b/kitcom/golang/goparser.go @@ -1,4 +1,4 @@ -package main +package golang import ( "fmt" @@ -6,6 +6,8 @@ import ( "go/parser" "go/token" "regexp" + + "efprojects.com/kitten-ipc/kitcom/api" ) var decorComment = regexp.MustCompile(`^//\s?kittenipc:api$`) @@ -13,9 +15,9 @@ var decorComment = regexp.MustCompile(`^//\s?kittenipc:api$`) type GoApiParser struct { } -func (g *GoApiParser) Parse(sourceFile string) (*Api, error) { +func (g *GoApiParser) Parse(sourceFile string) (*api.Api, error) { - var api Api + var apis api.Api fileSet := token.NewFileSet() astFile, err := parser.ParseFile(fileSet, sourceFile, nil, parser.ParseComments|parser.SkipObjectResolution) @@ -50,12 +52,12 @@ func (g *GoApiParser) Parse(sourceFile string) (*Api, error) { } _ = structType - api.Endpoints = append(api.Endpoints, Endpoint{ + apis.Endpoints = append(apis.Endpoints, api.Endpoint{ Name: typeSpec.Name.Name, }) } - if len(api.Endpoints) == 0 { + if len(apis.Endpoints) == 0 { return nil, fmt.Errorf("no api struct found") } @@ -86,20 +88,20 @@ func (g *GoApiParser) Parse(sourceFile string) (*Api, error) { continue } - for i, endpoint := range api.Endpoints { + for i, endpoint := range apis.Endpoints { if recvIdent.Name == endpoint.Name { - var apiMethod Method + var apiMethod api.Method apiMethod.Name = funcDecl.Name.Name for _, param := range funcDecl.Type.Params.List { - var apiPar Val + var apiPar api.Val ident := param.Type.(*ast.Ident) switch ident.Name { case "int": - apiPar.Type = TInt + apiPar.Type = api.TInt case "string": - apiPar.Type = TString + apiPar.Type = api.TString case "bool": - apiPar.Type = TBool + apiPar.Type = api.TBool default: return nil, fmt.Errorf("parameter type %s is not supported yet", ident.Name) } @@ -110,15 +112,15 @@ func (g *GoApiParser) Parse(sourceFile string) (*Api, error) { apiMethod.Params = append(apiMethod.Params, apiPar) } for _, ret := range funcDecl.Type.Results.List { - var apiRet Val + var apiRet api.Val ident := ret.Type.(*ast.Ident) switch ident.Name { case "int": - apiRet.Type = TInt + apiRet.Type = api.TInt case "string": - apiRet.Type = TString + apiRet.Type = api.TString case "bool": - apiRet.Type = TBool + apiRet.Type = api.TBool case "error": // errors are processed other way continue @@ -130,10 +132,10 @@ func (g *GoApiParser) Parse(sourceFile string) (*Api, error) { } apiMethod.Ret = append(apiMethod.Ret, apiRet) } - api.Endpoints[i].Methods = append(api.Endpoints[i].Methods, apiMethod) + apis.Endpoints[i].Methods = append(apis.Endpoints[i].Methods, apiMethod) } } } - return &api, nil + return &apis, nil } diff --git a/kitcom/main.go b/kitcom/main.go index 29d5a88..2b90e29 100644 --- a/kitcom/main.go +++ b/kitcom/main.go @@ -8,48 +8,18 @@ import ( "os" "path" "path/filepath" + + "efprojects.com/kitten-ipc/kitcom/api" + "efprojects.com/kitten-ipc/kitcom/golang" + "efprojects.com/kitten-ipc/kitcom/ts" ) -type ValType int - -// todo check TInt size < 64 -// todo check not float - -const ( - TInt ValType = 1 - TString ValType = 2 - TBool ValType = 3 - TBlob ValType = 4 - TArray ValType = 5 -) - -type Val struct { - Name string - Type ValType - Children []Val -} - -type Method struct { - Name string - Params []Val - Ret []Val -} - -type Endpoint struct { - Name string - Methods []Method -} - -type Api struct { - Endpoints []Endpoint -} - type ApiParser interface { - Parse(sourceFile string) (*Api, error) + Parse(sourceFile string) (*api.Api, error) } type ApiGenerator interface { - Generate(api *Api, destFile string) error + Generate(api *api.Api, destFile string) error } func main() { @@ -116,9 +86,9 @@ func checkIsFile(src string) error { func apiParserByExt(src string) (ApiParser, error) { switch path.Ext(src) { case ".go": - return &GoApiParser{}, nil + return &golang.GoApiParser{}, nil case ".ts": - return &TypescriptApiParser{}, nil + return &ts.TypescriptApiParser{}, nil case ".js": return nil, fmt.Errorf("vanilla javascript is not supported and never will be") case "": @@ -137,11 +107,11 @@ func apiGeneratorByExt(dest string, pkgName string) (ApiGenerator, error) { if !token.IsIdentifier(pkgName) { return nil, fmt.Errorf("invalid package name: %s", pkgName) } - return &GoApiGenerator{ - pkgName: pkgName, + return &golang.GoApiGenerator{ + PkgName: pkgName, }, nil case ".ts": - return &TypescriptApiGenerator{}, nil + return &ts.TypescriptApiGenerator{}, nil case ".js": return nil, fmt.Errorf("vanilla javascript is not supported and never will be") case "": diff --git a/kitcom/ts_gen.tmpl b/kitcom/ts/ts_gen.tmpl similarity index 78% rename from kitcom/ts_gen.tmpl rename to kitcom/ts/ts_gen.tmpl index 2276a1f..655e341 100644 --- a/kitcom/ts_gen.tmpl +++ b/kitcom/ts/ts_gen.tmpl @@ -1,7 +1,6 @@ -{{- /*gotype: efprojects.com/kitten-ipc/kitcom.tsGenData*/ -}} - import {ParentIPC, ChildIPC} from 'kitten-ipc'; +{{- /*gotype: efprojects.com/kitten-ipc/kitcom/ts.tsGenData*/ -}} {{range $e := .Api.Endpoints}} export default class {{$e.Name}} { private ipc: ParentIPC | ChildIPC; @@ -14,9 +13,10 @@ export default class {{$e.Name}} { async {{ $mtd.Name }}( {{ range $par := $mtd.Params }}{{$par.Name}}: {{$par.Type | typedef }}, {{end}} ): Promise<{{if len $mtd.Ret}}{{(index $mtd.Ret 0).Type | typedef }}{{else}}void{{end}}> { - return await this.ipc.call('{{$mtd.Name}}', + const results = await this.ipc.call('{{$mtd.Name}}', {{range $par := $mtd.Params}}{{$par.Name}}, {{end}} ); + return {{range $ret := $mtd.}} } {{end}} } diff --git a/kitcom/tsgen.go b/kitcom/ts/tsgen.go similarity index 78% rename from kitcom/tsgen.go rename to kitcom/ts/tsgen.go index f3c59e0..8affaf1 100644 --- a/kitcom/tsgen.go +++ b/kitcom/ts/tsgen.go @@ -1,4 +1,4 @@ -package main +package ts import ( "bytes" @@ -7,27 +7,29 @@ import ( "os" "os/exec" "text/template" + + "efprojects.com/kitten-ipc/kitcom/api" ) type tsGenData struct { - Api *Api + Api *api.Api } type TypescriptApiGenerator struct { } -func (g *TypescriptApiGenerator) Generate(api *Api, destFile string) error { +func (g *TypescriptApiGenerator) Generate(apis *api.Api, destFile string) error { tplCtx := tsGenData{ - Api: api, + Api: apis, } tpl := template.New("tsgen") tpl = tpl.Funcs(map[string]any{ - "typedef": func(t ValType) (string, error) { - td, ok := map[ValType]string{ - TInt: "number", - TString: "string", - TBool: "boolean", + "typedef": func(t api.ValType) (string, error) { + td, ok := map[api.ValType]string{ + api.TInt: "number", + api.TString: "string", + api.TBool: "boolean", }[t] if !ok { return "", fmt.Errorf("cannot generate type %v", t) diff --git a/kitcom/tsparser.go b/kitcom/ts/tsparser.go similarity index 83% rename from kitcom/tsparser.go rename to kitcom/ts/tsparser.go index ba4db89..06e6db4 100644 --- a/kitcom/tsparser.go +++ b/kitcom/ts/tsparser.go @@ -1,4 +1,4 @@ -package main +package ts import ( "fmt" @@ -6,6 +6,7 @@ import ( "os" "strings" + "efprojects.com/kitten-ipc/kitcom/api" "efprojects.com/kitten-ipc/kitcom/internal/tsgo/ast" "efprojects.com/kitten-ipc/kitcom/internal/tsgo/core" "efprojects.com/kitten-ipc/kitcom/internal/tsgo/parser" @@ -18,7 +19,7 @@ const TagComment = "api" type TypescriptApiParser struct { } -func (t *TypescriptApiParser) Parse(sourceFilePath string) (*Api, error) { +func (t *TypescriptApiParser) Parse(sourceFilePath string) (*api.Api, error) { f, err := os.Open(sourceFilePath) if err != nil { @@ -40,7 +41,7 @@ func (t *TypescriptApiParser) Parse(sourceFilePath string) (*Api, error) { }, string(fileContents), core.ScriptKindTS) _ = sourceFile - var api Api + var apis api.Api sourceFile.ForEachChild(func(node *ast.Node) bool { if node.Kind != ast.KindClassDeclaration { @@ -74,7 +75,7 @@ func (t *TypescriptApiParser) Parse(sourceFilePath string) (*Api, error) { return false } - var endpoint Endpoint + var endpoint api.Endpoint endpoint.Name = cls.Name().Text() @@ -84,42 +85,42 @@ func (t *TypescriptApiParser) Parse(sourceFilePath string) (*Api, error) { } method := member.AsMethodDeclaration() - var apiMethod Method + var apiMethod api.Method apiMethod.Name = method.Name().Text() for _, parNode := range method.ParameterList().Nodes { par := parNode.AsParameterDeclaration() - var apiPar Val + var apiPar api.Val apiPar.Name = par.Name().Text() switch par.Type.Kind { case ast.KindNumberKeyword: - apiPar.Type = TInt + apiPar.Type = api.TInt case ast.KindStringKeyword: - apiPar.Type = TString + apiPar.Type = api.TString case ast.KindBooleanKeyword: - apiPar.Type = TBool + apiPar.Type = api.TBool default: err = fmt.Errorf("parameter type %s is not supported yet", par.Type.Kind) return false } apiMethod.Params = append(apiMethod.Params, apiPar) } - var apiRet Val + var apiRet api.Val switch method.Type.Kind { case ast.KindNumberKeyword: - apiRet.Type = TInt + apiRet.Type = api.TInt case ast.KindStringKeyword: - apiRet.Type = TString + apiRet.Type = api.TString case ast.KindBooleanKeyword: - apiRet.Type = TBool + apiRet.Type = api.TBool default: err = fmt.Errorf("return type %s is not supported yet", method.Type.Kind) return false } - apiMethod.Ret = []Val{apiRet} + apiMethod.Ret = []api.Val{apiRet} endpoint.Methods = append(endpoint.Methods, apiMethod) } - api.Endpoints = append(api.Endpoints, endpoint) + apis.Endpoints = append(apis.Endpoints, endpoint) return false }) @@ -128,9 +129,9 @@ func (t *TypescriptApiParser) Parse(sourceFilePath string) (*Api, error) { return nil, err } - if len(api.Endpoints) == 0 { + if len(apis.Endpoints) == 0 { return nil, fmt.Errorf("no api class found") } - return &api, nil + return &apis, nil }