tons of code

This commit is contained in:
Egor Aristov 2025-10-25 14:28:32 +03:00
parent 3ebfa08350
commit de8c9aedf7
Signed by: egor3f
GPG Key ID: 40482A264AAEC85F
8 changed files with 115 additions and 103 deletions

35
kitcom/api/api.go Normal file
View File

@ -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
}

View File

@ -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)

View File

@ -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
}

View File

@ -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 "":

View File

@ -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}}
}

View File

@ -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)

View File

@ -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
}