preparing better demo

This commit is contained in:
Jan Halfar 2016-07-22 09:24:33 +02:00
parent eff3d56c95
commit df6b3449b1
8 changed files with 101 additions and 99 deletions

View File

@ -83,7 +83,7 @@ func main() {
fmt.Fprintln(os.Stderr, "an error occured while trying to understand your code", err)
os.Exit(2)
}
ts, err := gotsrpc.RenderTypeScript(services, structs, target.TypeScriptModule)
ts, err := gotsrpc.RenderTypeScriptServices(services, conf.Mappings, target.TypeScriptModule)
if err != nil {
fmt.Fprintln(os.Stderr, "could not generate ts code", err)
os.Exit(3)
@ -91,6 +91,17 @@ func main() {
fmt.Println(os.Stdout, ts)
mappedCode, err := gotsrpc.RenderStructsToPackages(structs, conf.Mappings)
if err != nil {
fmt.Println("struct gen err", err)
os.Exit(4)
}
for tsModule, code := range mappedCode {
fmt.Println("-----------------", tsModule, "--------------------")
fmt.Println(code)
}
gocode, goerr := gotsrpc.RenderGo(services, packageName)
if goerr != nil {
fmt.Fprintln(os.Stderr, "could not generate go code", goerr)

View File

@ -19,9 +19,11 @@ type Mapping struct {
TypeScriptModule string `yaml:"module"`
}
type TypeScriptMappings map[string]*Mapping
type Config struct {
Targets map[string]*Target
Mappings map[string]*Mapping
Mappings TypeScriptMappings
}
func LoadConfigFile(file string) (conf *Config, err error) {

View File

@ -1,6 +1,7 @@
---
targets:
demo:
module: GoTSRPC.Demo
services:
- Service
package: github.com/foomo/gotsrpc/demo
@ -9,3 +10,6 @@ mappings:
github.com/foomo/gotsrpc/demo:
module: GoTSRPC.Demo
out: /tmp/test-files.ts
github.com/foomo/gotsrpc/demo/nested:
module: GoTSRPC.Demo.Nested
out: /tmp/test-files.ts

View File

@ -2,30 +2,48 @@
package demo
import (
"github.com/foomo/gotsrpc"
"net/http"
gotsrpc "github.com/foomo/gotsrpc"
demo "github.com/foomo/gotsrpc/demo"
http "net/http"
)
type ServiceGoTSRPCProxy struct {
EndPoint string
service *Service
EndPoint string
allowOrigin []string
service *Service
}
func NewServiceGoTSRPCProxy(service *Service, endpoint string) *ServiceGoTSRPCProxy {
func NewServiceGoTSRPCProxy(service *Service, endpoint string, allowOrigin []string) *ServiceGoTSRPCProxy {
return &ServiceGoTSRPCProxy{
EndPoint: endpoint,
service: service,
EndPoint: endpoint,
allowOrigin: allowOrigin,
service: service,
}
}
// ServeHTTP exposes your service
func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
for _, origin := range p.allowOrigin {
w.Header().Add("Access-Control-Allow-Origin", origin)
}
w.Header().Set("Access-Control-Allow-Credentials", "true")
if r.Method != "POST" {
gotsrpc.ErrorMethodNotAllowed(w)
return
}
var args []interface{}
switch gotsrpc.GetCalledFunc(r, p.EndPoint) {
case "ExtractAddress":
args = []interface{}{&Person{}}
err := gotsrpc.LoadArgs(args, r)
if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w)
return
}
extractAddressAddr, extractAddressE := p.service.ExtractAddress(args[0].(*demo.Person))
gotsrpc.Reply([]interface{}{extractAddressAddr, extractAddressE}, w)
return
case "Hello":
args = []interface{}{""}
err := gotsrpc.LoadArgs(args, r)
@ -40,48 +58,5 @@ func (p *ServiceGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
p.service.NothingInNothinOut()
gotsrpc.Reply([]interface{}{}, w)
return
case "ExtractAddress":
args = []interface{}{&Person{}}
err := gotsrpc.LoadArgs(args, r)
if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w)
return
}
extractAddressAddr, extractAddressE := p.service.ExtractAddress(args[0].(*Person))
gotsrpc.Reply([]interface{}{extractAddressAddr, extractAddressE}, w)
return
}
}
type FooGoTSRPCProxy struct {
EndPoint string
service *Foo
}
func NewFooGoTSRPCProxy(service *Foo, endpoint string) *FooGoTSRPCProxy {
return &FooGoTSRPCProxy{
EndPoint: endpoint,
service: service,
}
}
// ServeHTTP exposes your service
func (p *FooGoTSRPCProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
gotsrpc.ErrorMethodNotAllowed(w)
return
}
var args []interface{}
switch gotsrpc.GetCalledFunc(r, p.EndPoint) {
case "Hello":
args = []interface{}{int64(0)}
err := gotsrpc.LoadArgs(args, r)
if err != nil {
gotsrpc.ErrorCouldNotLoadArgs(w)
return
}
helloRet := p.service.Hello(args[0].(int64))
gotsrpc.Reply([]interface{}{helloRet}, w)
return
}
}

10
go.go
View File

@ -70,14 +70,6 @@ func ucfirst(str string) string {
}
func strfirst(str string, strfunc func(string) string) string {
/*
if len(str) == 0 {
return ""
} else if len(str) == 1 {
return strfunc(str)
}
return strfunc(str[0:1]) + str[1:]
*/
res := ""
for i, char := range str {
if i == 0 {
@ -190,11 +182,9 @@ func renderServiceProxies(services []*Service, packageName string, g *code) erro
for argI, arg := range method.Args {
if argI == 0 && arg.Value.isHTTPResponseWriter() {
trace("skipping first arg is a http.ResponseWriter")
continue
}
if argI == 1 && arg.Value.isHTTPRequest() {
trace("skipping second arg is a *http.Request")
isSessionRequest = true
continue
}

View File

@ -154,7 +154,6 @@ func Read(goPath string, packageName string, serviceNames []string) (services []
return
}
jsonTrace(services)
structTypes := map[string]*StructType{}
for _, s := range services {
for _, m := range s.Methods {
@ -162,7 +161,6 @@ func Read(goPath string, packageName string, serviceNames []string) (services []
collecStructTypes(m.Args, structTypes)
}
}
jsonTrace(structTypes)
structs = map[string]*Struct{}
for wantedName := range structTypes {
structs[wantedName] = nil
@ -172,13 +170,13 @@ func Read(goPath string, packageName string, serviceNames []string) (services []
err = errors.New("error while collecting structs: " + collectErr.Error())
}
jsonTrace(structs)
return
}
func collectStructs(goPath string, structs map[string]*Struct) error {
scannedPackages := map[string]map[string]*Struct{}
for structsPending(structs) {
trace("pending", len(structs))
for fullName, strct := range structs {
if strct != nil {
continue
@ -190,7 +188,7 @@ func collectStructs(goPath string, structs map[string]*Struct) error {
packageName := strings.Join(fullNameParts, ".")
//trace(fullName, "==========================>", fullNameParts, "=============>", packageName)
// trace(fullName, "==========================>", fullNameParts, "=============>", packageName)
packageStructs, ok := scannedPackages[packageName]
if !ok {
@ -202,6 +200,7 @@ func collectStructs(goPath string, structs map[string]*Struct) error {
scannedPackages[packageName] = packageStructs
}
for packageStructName, packageStruct := range packageStructs {
// trace("------------------------------------>", packageStructName, packageStruct)
existingStruct, needed := structs[packageStructName]
if needed && existingStruct == nil {
structs[packageStructName] = packageStruct
@ -213,8 +212,12 @@ func collectStructs(goPath string, structs map[string]*Struct) error {
}
func structsPending(structs map[string]*Struct) bool {
for _, structType := range structs {
if structType == nil || !structType.DepsSatisfied(structs) {
for name, structType := range structs {
if structType == nil {
trace("missing", name)
return true
}
if !structType.DepsSatisfied(structs) {
return true
}
}
@ -227,10 +230,11 @@ func (s *Struct) DepsSatisfied(structs map[string]*Struct) bool {
if !ok {
// hey there is more todo
structs[fullName] = nil
trace("need work ----------------------" + fullName)
return true
}
if strct == nil {
trace("need work " + fullName)
trace("need work ----------------------" + fullName)
return true
}
return false
@ -249,7 +253,6 @@ func (s *Struct) DepsSatisfied(structs map[string]*Struct) bool {
if needsWork(fieldStructType.FullName()) {
return false
}
}
}
return !needsWork(s.FullName())
@ -277,7 +280,6 @@ func getStructsInPackage(goPath string, packageName string) (structs map[string]
pkg, err = parsePackage(runtime.GOROOT(), packageName)
if err != nil {
return nil, err
}
}
structs, err = readStructs(pkg, packageName)

View File

@ -30,7 +30,7 @@ func trace(args ...interface{}) {
fmt.Fprintln(os.Stderr, args...)
}
}
func jsonTrace(args ...interface{}) {
func traceJSON(args ...interface{}) {
if ReaderTrace {
for _, arg := range args {
jsonBytes, jsonErr := json.MarshalIndent(arg, "", " ")
@ -231,7 +231,7 @@ func readField(astField *ast.Field, fileImports fileImportSpecMap) (name string,
name = astField.Names[0].Name
}
trace(" reading field with name", name, "of type", astField.Type)
// trace(" reading field with name", name, "of type", astField.Type)
v = &Value{}
v.loadExpr(astField.Type, fileImports)
if astField.Tag != nil {
@ -264,11 +264,7 @@ func readFieldList(fieldList []*ast.Field, fileImports fileImportSpecMap) (field
}
func extractStructs(file *ast.File, packageName string, structs map[string]*Struct) error {
trace("reading file", file.Name.Name)
//for _, imp := range file.Imports {
// fmt.Println("import", imp.Name, imp.Path)
//}
fileImports := getFileImports(file, packageName)
for name, obj := range file.Scope.Objects {
//fmt.Println(name, obj.Kind, obj.Data)

View File

@ -4,6 +4,8 @@ import (
"errors"
"fmt"
"strings"
"github.com/foomo/gotsrpc/config"
)
func (f *Field) tsName() string {
@ -14,18 +16,23 @@ func (f *Field) tsName() string {
return n
}
func (v *Value) tsType() string {
func (v *Value) tsType(mappings config.TypeScriptMappings) string {
switch true {
case v.IsPtr:
if v.StructType != nil {
if len(v.StructType.Package) > 0 {
return v.StructType.Package + "." + v.StructType.Name
mapping, ok := mappings[v.StructType.Package]
var tsModule string
if ok {
tsModule = mapping.TypeScriptModule
}
return tsModule + "." + v.StructType.Name
}
return v.StructType.Name
}
return string(v.ScalarType)
case v.Array != nil:
return v.Array.Value.tsType() + "[]"
return v.Array.Value.tsType(mappings) + "[]"
case len(v.ScalarType) > 0:
switch v.ScalarType {
case ScalarTypeBool:
@ -39,8 +46,8 @@ func (v *Value) tsType() string {
}
}
func renderStruct(str *Struct, ts *code) error {
ts.l("// " + str.Package + "." + str.Name).ind(1)
func renderStruct(str *Struct, mappings config.TypeScriptMappings, ts *code) error {
ts.l("// " + str.FullName())
ts.l("export interface " + str.Name + " {").ind(1)
for _, f := range str.Fields {
if f.JSONInfo != nil && f.JSONInfo.Ignore {
@ -50,7 +57,7 @@ func renderStruct(str *Struct, ts *code) error {
if f.Value.IsPtr {
ts.app("?")
}
ts.app(":" + f.Value.tsType())
ts.app(":" + f.Value.tsType(mappings))
ts.app(";")
ts.nl()
}
@ -68,7 +75,7 @@ func renderStruct(str *Struct, ts *code) error {
}
*/
func renderService(service *Service, ts *code) error {
func renderService(service *Service, mappings config.TypeScriptMappings, ts *code) error {
clientName := service.Name + "Client"
ts.l("export class " + clientName + " {").ind(1).
l("static defaultInst = new " + clientName + ";").
@ -90,7 +97,7 @@ func renderService(service *Service, ts *code) error {
continue
}
args = append(args, arg.tsName()+":"+arg.Value.tsType())
args = append(args, arg.tsName()+":"+arg.Value.tsType(mappings))
callArgs = append(callArgs, arg.Name)
}
ts.app(strings.Join(args, ", "))
@ -104,7 +111,7 @@ func renderService(service *Service, ts *code) error {
retArgName += "_" + fmt.Sprint(index)
}
}
retArgs = append(retArgs, retArgName+":"+retField.Value.tsType())
retArgs = append(retArgs, retArgName+":"+retField.Value.tsType(mappings))
}
if len(args) > 0 {
ts.app(", ")
@ -122,8 +129,33 @@ func renderService(service *Service, ts *code) error {
ts.l("}")
return nil
}
func RenderTypeScript(services []*Service, structs map[string]*Struct, tsModuleName string) (typeScript string, err error) {
func RenderStructsToPackages(structs map[string]*Struct, mappings config.TypeScriptMappings) (mappedTypeScript map[string]string, err error) {
mappedTypeScript = map[string]string{}
codeMap := map[string]*code{}
for _, mapping := range mappings {
codeMap[mapping.GoPackage] = newCode().l("module " + mapping.TypeScriptModule + " {").ind(1)
}
for name, str := range structs {
if str == nil {
err = errors.New("could not resolve: " + name)
return
}
ts, ok := codeMap[str.Package]
if !ok {
err = errors.New("missing code mapping for: " + str.Package)
return
}
err = renderStruct(str, mappings, ts)
if err != nil {
return
}
}
for _, mapping := range mappings {
mappedTypeScript[mapping.TypeScriptModule] = codeMap[mapping.GoPackage].ind(-1).l("}").string()
}
return
}
func RenderTypeScriptServices(services []*Service, mappings config.TypeScriptMappings, tsModuleName string) (typeScript string, err error) {
ts := newCode()
ts.l(`module GoTSRPC {
export function call(endPoint:string, method:string, args:any[], success:any, err:any) {
@ -153,18 +185,8 @@ func RenderTypeScript(services []*Service, structs map[string]*Struct, tsModuleN
ts.l("module " + tsModuleName + " {")
ts.ind(1)
for name, str := range structs {
if str == nil {
return "", errors.New("could not resolve: " + name)
}
err = renderStruct(str, ts)
if err != nil {
return
}
}
for _, service := range services {
err = renderService(service, ts)
err = renderService(service, mappings, ts)
if err != nil {
return
}