Browse Source

set params in context

EUGENIO SOUZA CARVALHO 4 years ago
commit
e6940cc588
8 changed files with 2220 additions and 0 deletions
  1. 54 0
      def.json
  2. 523 0
      generator/gen.go
  3. 262 0
      generator/utils.go
  4. 872 0
      generators/typescript/typescript.go
  5. 463 0
      generators/typescript/utils.go
  6. 8 0
      go.mod
  7. 10 0
      go.sum
  8. 28 0
      main.go

File diff suppressed because it is too large
+ 54 - 0
def.json


+ 523 - 0
generator/gen.go

@@ -0,0 +1,523 @@
+package generator
+
+import (
+	"encoding/json"
+	"fmt"
+	"strings"
+	
+	"git.eugeniocarvalho.dev/eugeniucarvalho/utils"
+	G "github.com/dave/jennifer/jen"
+)
+
+const (
+	// UTILS          = "git.gojus.com.br/eugeniucarvalho/utils"
+	// GENERATOR_BASE = "git.gojus.com.br/eugeniucarvalho/gg/generator"
+)
+
+type Generator struct {
+	Language string              `json:"language"`
+	Keywords []string            `json:"keywords"`
+	Commands map[string]*Command `json:"commands"`
+	BuiltIn  map[string]*Command `json:"builtIn"`
+	Output   string
+}
+type Command struct {
+	Name               string  `json:"name"`
+	IgnoreGen          bool    `json:"ignoreGen"`
+	Delimiter          string  `json:"delimiter"`
+	MethodName         string  `json:"-"`
+	Template           string  `json:"template"`
+	ParamList          []Param `json:"paramList,omitempty"`
+	Description        string  `json:"description,omitempty"`
+	RenderChildrenAs   string  `json:"readChildrenAs,omitempty"`
+	ChildrenRenderMode string  `json:"childrenRenderMode,omitempty"`
+}
+type Param struct {
+	Name string `json:"name"`
+	Type string `json:"type"`
+}
+
+func New(file string) (*Generator, error) {
+	data, err := utils.FileGetContents(file)
+	if err == nil {
+		g := &Generator{}
+		if err = json.Unmarshal([]byte(data), g); err == nil {
+
+			// g.BuiltInRegister()
+
+			return g, nil
+		}
+	}
+	return nil, err
+}
+
+
+
+func (g *Generator) AddCommand(key string, cmd *Command) {
+	g.Keywords = append(g.Keywords, key)
+	g.Commands[key] = cmd
+}
+
+func (g *Generator) Gen(folder string) (err error) {
+	g.Output = folder
+	file := G.NewFile(g.Language)
+
+	// Cria interface com todos os metodos
+	if err = g.GenBaseInterface(file); err != nil {
+		return err
+	}
+
+	// Cria todas as funcoes staticas com os comandos basicos
+	// g.GenBuiltIn(file)
+
+	fmt.Printf("Filepath: %s\n", g.FilePath("struct.go"))
+
+	if err = file.Save(g.FilePath(g.Language + ".go")); err != nil {
+		panic(err)
+	}
+
+	return nil
+}
+
+func (g *Generator) FilePath(name string) string {
+	return fmt.Sprintf("%s/%s/%s", g.Output, g.Language, name)
+}
+
+func (g *Generator) GenBaseInterface(file *G.File) (err error) {
+
+	// file.Type().Id("File").StructFunc(func(g *G.Group) {
+	// 	g.Add(G.Id("Group"))
+	// 	g.Add(G.Id("Name").Id("string"))
+	// }).Line()
+
+	// file.Func().Id("NewFile").Params(G.Id("file").Id("string")).Params(G.Op("*").Id("File")).Block(
+	// 	G.Return(G.Op("&").Id("File").Values(G.Dict{
+	// 		G.Id("Name"): G.Id("file"),
+	// 	})),
+	// )
+
+	// file.Func().Params(G.Id("f").Op("*").Id("File")).Id("Save").Params().Params(G.Id("error")).Block(
+	// 	G.Return(G.Qual(UTILS, "FilePutContents").Call(
+	// 		G.Id("f").Dot("Name"),
+	// 		G.Id("f").Dot("GoString").Call(),
+	// 		G.Lit(777),
+	// 	)),
+	// )
+
+	// file.Comment("Entidade representa menor unidade de Statement.")
+
+	// file.Type().Id("Stmt").StructFunc(func(g *G.Group) {
+	// 	g.Add(G.Id("Group"))
+	// 	g.Add(G.Id("value").Id("interface{}"))
+	// 	g.Add(G.Id("template").Id("string"))
+	// 	g.Add(G.Id("Separete").Id("string"))
+	// 	// g.Add(G.Id("Childrens").Index().Id("CodeInterface"))
+	// }).Line()
+
+	// file.Func().Params(
+	// 	G.Id("s").Op("*").Id("Stmt"),
+	// ).Id("Render").Params(
+	// 	G.Id("buffer").Op("*").Qual("bytes", "Buffer"),
+	// 	// G.Id("buffer").Op("*").Id("bytes").Dot("Buffer"),
+	// ).Params(
+	// 	G.Id("err").Id("error"),
+	// ).Block(
+	// 	G.For(
+	// 		G.List(G.Id("_"), G.Id("s")).Op(":=").Range().Id("s").Dot("Stmts"),
+	// 	).Block(
+	// 		G.Id("err").Op("=").Id("s").Dot("Render").Call(G.Id("buffer")),
+	// 	).Line().Return(G.Empty()),
+	// )
+
+	// file.Comment("Root node group of Statement.")
+
+	// file.Type().Id("Group").StructFunc(func(g *G.Group) {
+	// 	g.Add(G.Qual(GENERATOR_BASE, "Group"))
+	// 	// g.Add(G.Id("Stmts").Index().Id("CodeInterface"))
+	// }).Line()
+
+	// file.Comment("Metodo realiza a renderização de um grupo e todos os seus statements.")
+	// file.Func().Params(
+	// 	G.Id("g").Op("*").Id("Group"),
+	// ).Id("Render").Params(
+	// 	G.Id("buffer").Op("*").Qual("bytes", "Buffer"),
+	// 	// G.Id("buffer").Op("*").Id("bytes").Dot("Buffer"),
+	// ).Params(
+	// 	G.Id("err").Id("error"),
+	// ).Block(
+	// 	G.For(
+	// 		G.List(G.Id("_"), G.Id("s")).Op(":=").Range().Id("g").Dot("Stmts"),
+	// 	).Block(
+	// 		G.Id("err").Op("=").Id("s").Dot("Render").Call(G.Id("buffer")),
+	// 	).Line().Return(G.Empty()),
+	// )
+	// file.Comment("Metodo Gera a string do arquivo.")
+	// file.Func().Params(
+	// 	G.Id("g").Op("*").Id("Group"),
+	// ).Id("GoString").Params().Params(
+	// 	G.Id("string"),
+	// ).Block(
+	// 	G.Id("buf").Op(":=").Qual("bytes", "Buffer").Values(),
+	// 	// G.Id("buf").Op(":=").Id("bytes").Dot("Buffer"),
+	// 	G.If(
+	// 		G.Id("err").Op(":=").Id("g").Dot("Render").Call(G.Op("&").Id("buf")),
+	// 		G.Id("err").Op("!=").Nil(),
+	// 	).Block(
+	// 		G.Id("panic").Call(G.Id("err")),
+	// 	).Line().Return(G.Id("buf").Dot("String").Call()),
+	// ).Line()
+
+	// file.Func().Id("NewGroup").Params().Op("*").Id("Group").Block(
+	// 	G.Return(G.Op("&").Id("Group").Values()),
+	// ).Line()
+
+	var (
+		cmd    *Command
+		uppKey string
+		found  bool
+		// interfacesMethods = []*G.Statement{}
+		method  *G.Statement
+		methods = []string{}
+	)
+
+	codeInterface := file.Type().Id("CodeInterface")
+	interfaces := G.Statement{}
+	// Adiciona a importacao da interface do gerador
+	// interfaces = append(interfaces, G.Qual(GENERATOR_BASE, "CodeInterface"))
+	interfaces = append(interfaces, G.Id("BaseCodeInterface"))
+
+	// interfaces = append(interfaces, G.Id("Render").Params(
+	// 	G.Id("buffer").Op("*").Qual("bytes", "Buffer"),
+	// ).Params(G.Id("error")))
+
+	for _, key := range g.Keywords {
+
+		uppKey = strings.Title(key)
+
+		methods = append(methods, uppKey)
+
+		if cmd, found = g.Commands[key]; found {
+
+			cmd.Name = key
+			cmd.MethodName = uppKey
+
+			interfaces = genCmd(file, cmd, interfaces)
+
+		} else {
+			// Todos os metodos para keywords genericas sem template
+			// são tratados aqui.
+			interfaces = append(interfaces, G.Id(uppKey).Params().Params(G.Op("*").Id("Group")))
+
+			method = G.Func().Params(
+				G.Id("g").Op("*").Id("Group"),
+			).Id(uppKey).Params().Params(G.Op("*").Id("Group"))
+
+			file.Add(method.Clone().Block(
+				G.Id("s").Op(":=").Op("&").Id("Stmt").Values(G.Dict{
+					G.Id("Value"):    G.Lit(key),
+					G.Id("Template"): G.Lit(" %s "),
+				}),
+
+				G.Id("g").Dot("Stmts").Op("=").Append(
+					G.Id("g").Dot("Stmts"),
+					G.Id("s"),
+				),
+				G.Return(G.Id("g")),
+			).Line())
+
+			ModuleFunction(file, uppKey, G.Statement{}, []string{})
+		}
+
+	}
+
+	codeInterface.Interface(interfaces...)
+
+	return
+}
+
+func genCmd(file *G.File, cmd *Command, interfaces G.Statement) G.Statement {
+
+	var (
+		p           *G.Statement
+		params      = G.Statement{}
+		paramsKeys  = []string{}
+		paramsTypes = []string{}
+	)
+
+	file.Func().Params(
+		G.Id("g").Op("*").Id("Group"),
+	).Id(cmd.MethodName).ParamsFunc(func(g *G.Group) {
+
+		if len(cmd.ParamList) == 0 {
+			return
+		}
+
+		for _, param := range cmd.ParamList {
+			p = G.Id(param.Name).Id(param.Type)
+			g.Add(p)
+			paramsKeys = append(paramsKeys, param.Name)
+			paramsTypes = append(paramsTypes, param.Type)
+			params = append(params, p)
+		}
+
+		interfaces = append(interfaces, G.Id(cmd.MethodName).Params(params...).Params(G.Op("*").Id("Group")))
+
+	}).Params(
+		G.Op("*").Id("Group"),
+	).BlockFunc(func(g *G.Group) {
+
+		// g.Add(G.Id("s").Op(":=").Op("&").Qual(GENERATOR_BASE, "Stmt").ValuesFunc(func(x *G.Group) {
+		g.Add(G.Id("s").Op(":=").Op("&").Id("Stmt").ValuesFunc(func(x *G.Group) {
+			var (
+				value interface{}
+				// lit   bool
+				lit = true
+			)
+
+			x.Add(G.Id("Template").Op(":").Lit(fmt.Sprintf(" %s ", cmd.Template)))
+
+			for k, typ := range paramsTypes {
+				// fmt.Println("---", k, typ, paramsKeys[k])
+
+				switch {
+				case typ == "string" || typ == "interface{}":
+
+					value = paramsKeys[k]
+					lit = false
+
+				case typ[0:3] == "...":
+					x.Add(
+						// G.Id("Group").Op(":").Id("Group").Values(
+						// G.Id("Group").Op(":").Qual(GENERATOR_BASE, "Group").Values(G.Dict{
+						G.Id("Group").Op(":").Id("Group").Values(G.Dict{
+							G.Id("Stmts"): G.Id(paramsKeys[k]),
+						}),
+					)
+					paramsKeys[k] += "..."
+				default:
+					// x.Add(G.Id("Group").Op(":").Id("Group").Values(
+					// 	G.Qual(GENERATOR_BASE, "Group").Op(":").Qual(GENERATOR_BASE, "Group").Values(G.Dict{
+					// 		G.Id("Stmts"): G.Index().Id("CodeInterface").Values(G.Id(paramsKeys[k])),
+					// 	}),
+					// ))
+					// x.Add(G.Id("Group").Op(":").Qual(GENERATOR_BASE, "Group").Values(G.Dict{
+					// 	G.Id("Stmts"): G.Index().Qual(GENERATOR_BASE, "CodeInterface").Values(G.Id(paramsKeys[k])),
+					// }))
+					x.Add(G.Id("Group").Op(":").Id("Group").Values(G.Dict{
+						G.Id("Stmts"): G.Index().Id("CodeInterface").Values(G.Id(paramsKeys[k])),
+					}))
+				}
+				break
+			}
+
+			if value == nil {
+				value = cmd.Name
+			}
+
+			if lit {
+				x.Add(G.Id("Value").Op(":").Lit(value))
+			} else {
+				x.Add(G.Id("Value").Op(":").Id(value.(string)))
+			}
+
+			if cmd.Delimiter != "" {
+				x.Add(G.Id("Delimiter").Op(":").Lit(cmd.Delimiter))
+			}
+
+		}))
+
+		g.Add(G.Id("g").Dot("Stmts").Op("=").Append(
+			G.Id("g").Dot("Stmts"),
+			G.Id("s"),
+		))
+		g.Add(G.Return(G.Id("g")))
+
+	}).Line()
+
+	ModuleFunction(file, cmd.MethodName, params, paramsKeys)
+	return interfaces
+
+}
+
+func ModuleFunction(file *G.File, method string, params G.Statement, paramsKeys []string) {
+
+	file.Func().Id(method).Params(params...).Params(G.Op("*").Id("Group")).Block(
+
+		G.Return(G.Id("NewGroup").Call().Dot(method).CallFunc(func(g *G.Group) {
+			for _, key := range paramsKeys {
+				g.Add(G.Id(key))
+			}
+		})),
+	).Line()
+}
+
+// func (g *Generator) BuiltInRegister() {
+
+// 	if g.BuiltIn == nil {
+// 		g.BuiltIn = map[string]*Command{}
+// 	}
+// 	fmt.Println("Add built in")
+
+// 	g.AddBuiltIn("params", &Command{
+// 		Template: "(%s)",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "params",
+// 				Type: "...CodeInterface",
+// 			},
+// 		},
+// 		Description: "Parameter definition in function declaration.",
+// 	})
+
+// 	g.AddBuiltIn("op", &Command{
+// 		Template: " %s ",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "op",
+// 				Type: "string",
+// 			},
+// 		},
+// 		Description: "Representa um operando {=,!=,>,<,>=,<=,-,+,*,/,%}.",
+// 	})
+
+// 	g.AddBuiltIn("block", &Command{
+// 		// Template:         " {\n%s\n}\n",
+// 		Template:         " {%s}\n",
+// 		RenderChildrenAs: "lines",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "stmts",
+// 				Type: "...CodeInterface",
+// 			},
+// 		},
+// 	})
+
+// 	g.AddBuiltIn("call", &Command{
+// 		Template: "(%s)",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "params",
+// 				Type: "CodeInterface",
+// 			},
+// 		},
+// 		Description: "Generete a call of function or method. The parameter is um List Stmt.",
+// 	})
+
+// 	g.AddBuiltIn("id", &Command{
+// 		Template: "%s",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "stmt",
+// 				Type: "string",
+// 			},
+// 		},
+// 	})
+
+// 	g.AddBuiltIn("comment", &Command{
+// 		Template:  "\n//%s\n",
+// 		IgnoreGen: true,
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "stmt",
+// 				Type: "string",
+// 			},
+// 		},
+// 	})
+
+// 	g.AddBuiltIn("lit", &Command{
+// 		Template:  "%s",
+// 		IgnoreGen: true,
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "stmt",
+// 				Type: "interface{}",
+// 			},
+// 		},
+// 	})
+
+// 	g.AddBuiltIn("index", &Command{
+// 		Template: "[%s]",
+// 		ParamList: []Param{
+// 			Param{
+// 				Name: "index",
+// 				Type: "CodeInterface",
+// 			},
+// 		},
+// 		Description: "Gen a index access. The parameter is a List",
+// 	})
+// }
+
+// func (g *Generator) AddBuiltIn(key string, cmd *Command) {
+// 	// g.BuiltIn = append(g.BuiltIn, key)
+// 	g.BuiltIn[key] = cmd
+// }
+// func (g *Generator) GenBuiltIn(file *G.File) {
+// 	var (
+// 		params     *G.Statement
+// 		paramsKeys []string
+// 		name       string
+// 		typ        string
+// 		ret        string
+// 	)
+// 	for method, cmd := range g.BuiltIn {
+
+// 		paramsKeys = []string{}
+// 		method = strings.Title(method)
+
+// 		params = &G.Statement{}
+
+// 		for _, param := range cmd.ParamList {
+
+// 			name = param.Name
+// 			typ = param.Type
+// 			ret = ""
+// 			if strings.Contains(typ, "...") {
+// 				ret = "..."
+// 				name += ret
+// 				typ = typ[3:]
+// 			}
+
+// 			if strings.Contains(param.Type, "CodeInterface") {
+
+// 				params.Add(G.Id(param.Name).Op(ret).Qual(GENERATOR_BASE, typ))
+// 			} else {
+// 				params.Add(G.Id(param.Name).Id(typ))
+
+// 			}
+
+// 			paramsKeys = append(paramsKeys, name)
+
+// 			// params = append(params, G.Id(param.Name).Id(param.Type))
+// 		}
+
+// 		file.Func().Params(
+// 			G.Id("g").Op("*").Id("Group"),
+// 		).Id(method).Params(*params...).Params(
+// 			G.Op("*").Id("Group"),
+// 		).Block(
+
+// 			// G.Id("g").Dot(method).CallFunc(func(g *G.Group) {
+// 			// 	for _, key := range paramsKeys {
+// 			// 		g.Add(G.Id(key))
+// 			// 	}
+// 			// }),
+// 			G.Id("g").Dot("Group").Dot(method).CallFunc(func(g *G.Group) {
+// 				for _, key := range paramsKeys {
+// 					g.Add(G.Id(key))
+// 				}
+// 			}),
+
+// 			G.Return(G.Id("g")),
+// 		).Line()
+
+// 		file.Func().Id(method).Params(*params...).Params(
+// 			G.Op("*").Id("Group"),
+// 		).Block(
+// 			G.Return(G.Id("NewGroup").Call().Dot(method).CallFunc(func(g *G.Group) {
+// 				for _, key := range paramsKeys {
+// 					g.Add(G.Id(key))
+// 				}
+// 			})),
+// 		).Line()
+// 	}
+// }

+ 262 - 0
generator/utils.go

@@ -0,0 +1,262 @@
+package generator
+
+import (
+	bytes "bytes"
+	"fmt"
+	"os/exec"
+	"reflect"
+	"strings"
+
+	"git.eugeniocarvalho.dev/eugeniucarvalho/utils"
+)
+
+var (
+	LitTemplates = map[string]string{
+		"string":  " '%s' ",
+		"int":     " %d ",
+		"int8":    " %d ",
+		"int16":   " %d ",
+		"int32":   " %d ",
+		"int64":   " %d ",
+		"float32": " %.2f ",
+		"float64": " %.2f ",
+		"bool":    " %.2f ",
+	}
+)
+
+type File struct {
+	Group
+	Name string
+}
+
+func NewFile(file string) *File {
+	return &File{Name: file}
+}
+
+// Entidade representa menor unidade de Statement.
+type Stmt struct {
+	Group
+	Value    interface{}
+	Template string
+	Separete string
+}
+
+// Root node group of Statement.
+type Group struct {
+	Stmts []CodeInterface
+}
+
+// Metodo realiza a renderização de um grupo e todos os seus statements.
+func (g *Group) Render(buffer *bytes.Buffer) (err error) {
+	for _, s := range g.Stmts {
+		err = s.Render(buffer)
+	}
+	return
+}
+
+// Metodo Gera a string do arquivo.
+func (g *Group) GoString() string {
+	buf := bytes.Buffer{}
+	if err := g.Render(&buf); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func NewGroup() *Group {
+	return &Group{}
+}
+
+func (f *File) Save() (err error) {
+
+	fmt.Println("Save in :", f.Name)
+
+	if err = utils.FilePutContents(f.Name, f.GoString(), 777); err != nil {
+		return
+	}
+	// Formate code with https://www.npmjs.com/package/typescript-formatter
+
+	var out bytes.Buffer
+
+	cmd := exec.Command("tsfmt", "-r", f.Name)
+	cmd.Stdin = strings.NewReader("")
+	cmd.Stdout = &out
+
+	if err = cmd.Run(); err != nil {
+		panic(err)
+	}
+	fmt.Printf("in all caps: %q\n", out.String())
+	return
+}
+
+func (s *Stmt) Render(buffer *bytes.Buffer) (err error) {
+	// fmt.Println("Render stmt")
+	// spew.Dump(s)
+
+	var (
+		Value          interface{}
+		bufLocal       *bytes.Buffer
+		bufLocalMaster = &bytes.Buffer{}
+		wbv            string
+	)
+
+	if len(s.Stmts) > 0 {
+		for _, stmt := range s.Stmts {
+			bufLocal = &bytes.Buffer{}
+			stmt.Render(bufLocal)
+			bufLocalMaster.WriteString(bufLocal.String())
+		}
+		Value = bufLocalMaster.String()
+	} else {
+		Value = s.Value
+	}
+
+	if strings.Contains(s.Template, "%") {
+		// switch Value.(type) {
+		// case string:
+		// 	wbv = fmt.Sprintf(s.Template, Value.(string))
+		// case :
+		// }
+		wbv = fmt.Sprintf(s.Template, Value)
+
+	} else {
+		wbv = s.Template
+	}
+
+	buffer.WriteString(wbv)
+
+	return
+}
+
+func (g *Group) Lit(stmt interface{}) *Group {
+	var (
+		Template string
+		typ      = reflect.TypeOf(stmt).Name()
+	)
+	if t, ok := LitTemplates[typ]; ok {
+		Template = t
+	} else {
+		Template = " %v "
+	}
+
+	s := &Stmt{
+		Template: Template,
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+
+	return g
+}
+
+func Lit(stmt interface{}) *Group {
+	return NewGroup().Lit(stmt)
+}
+
+func (g *Group) Comment(stmt string) *Group {
+	var (
+		Template string
+	)
+	if strings.Contains(stmt, "\n") {
+		Template = " \n/*\n%s\n*/\n "
+
+	} else {
+		Template = " \n//%s\n "
+	}
+	s := &Stmt{
+		Template: Template,
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Comment(stmt string) *Group {
+	return NewGroup().Comment(stmt)
+}
+
+func (g *Group) Params(params ...CodeInterface) *Group {
+	s := &Stmt{Template: " (%s) ", Group: Group{Stmts: params}, Value: "params"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Params(params ...CodeInterface) *Group {
+	return NewGroup().Params(params...)
+}
+
+func (g *Group) Op(op string) *Group {
+	s := &Stmt{Template: "  %s  ", Value: op}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Op(op string) *Group {
+	return NewGroup().Op(op)
+}
+
+func (g *Group) Block(stmts ...CodeInterface) *Group {
+	s := &Stmt{Template: "  {%s}\n ", Group: Group{Stmts: stmts}, Value: "block"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Block(stmts ...CodeInterface) *Group {
+	return NewGroup().Block(stmts...)
+}
+
+func (g *Group) Call(params CodeInterface) *Group {
+	s := &Stmt{Template: " (%s) ", Group: Group{Stmts: []CodeInterface{params}}, Value: "call"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Call(params CodeInterface) *Group {
+	return NewGroup().Call(params)
+}
+
+func (g *Group) Id(stmt string) *Group {
+	s := &Stmt{Template: " %s ", Value: stmt}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Id(stmt string) *Group {
+	return NewGroup().Id(stmt)
+}
+
+func (g *Group) Index(index CodeInterface) *Group {
+	s := &Stmt{Template: " [%s] ", Group: Group{Stmts: []CodeInterface{index}}, Value: "index"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Index(index CodeInterface) *Group {
+	return NewGroup().Index(index)
+}
+
+func (g *Group) Produce(f func(g *Group)) *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    f,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Produce(f func(g *Group)) *Group {
+	return NewGroup().Produce(f)
+}
+
+type CodeInterface interface {
+	Render(buffer *bytes.Buffer) error
+	GoString() string
+	Block(stmts ...CodeInterface) *Group
+	Call(params CodeInterface) *Group
+	Comment(stmt string) *Group
+	Id(stmt string) *Group
+	Index(index CodeInterface) *Group
+	Lit(stmt interface{}) *Group
+	Op(op string) *Group
+	Params(params ...CodeInterface) *Group
+	Produce(f func(g *Group)) *Group
+}

+ 872 - 0
generators/typescript/typescript.go

@@ -0,0 +1,872 @@
+package typescript
+
+type CodeInterface interface {
+	BaseCodeInterface
+	TypeAliase(test string) *Group
+	Any() *Group
+	As() *Group
+	Boolean() *Group
+	Case() *Group
+	Catch() *Group
+	Class() *Group
+	Const() *Group
+	Constructor(stmt ...CodeInterface) *Group
+	Debugger() *Group
+	Declare() *Group
+	Default() *Group
+	Delete() *Group
+	Do() *Group
+	Else() *Group
+	Enum() *Group
+	Export() *Group
+	Extends() *Group
+	False() *Group
+	Finally() *Group
+	For() *Group
+	From() *Group
+	Function() *Group
+	Get() *Group
+	If(test CodeInterface) *Group
+	Implements() *Group
+	Import() *Group
+	In() *Group
+	Instanceof() *Group
+	Interface() *Group
+	Let() *Group
+	Module() *Group
+	New() *Group
+	Null() *Group
+	Number() *Group
+	Of() *Group
+	Package() *Group
+	Private() *Group
+	Protected() *Group
+	Public() *Group
+	Require() *Group
+	Return() *Group
+	Set() *Group
+	Static() *Group
+	String() *Group
+	Super() *Group
+	Switch() *Group
+	Symbol() *Group
+	This() *Group
+	Throw() *Group
+	True() *Group
+	Try() *Group
+	Type() *Group
+	Typeof() *Group
+	Var() *Group
+	Void() *Group
+	While() *Group
+	With() *Group
+	Yield() *Group
+}
+
+func (g *Group) TypeAliase(test string) *Group {
+	s := &Stmt{Template: " <%s> ", Value: test}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func TypeAliase(test string) *Group {
+	return NewGroup().TypeAliase(test)
+}
+
+func (g *Group) Endnl() *Group {
+	s := &Stmt{Template: " ;\n ", Value: "endnl"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Endnl() *Group {
+	return NewGroup().Endnl()
+}
+
+func (g *Group) Injetable(inject string) *Group {
+	s := &Stmt{Template: " @Injectable(" + inject + ")\n ", Value: "injetable"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Injetable(inject string) *Group {
+	return NewGroup().Injetable(inject)
+}
+
+func (g *Group) Any() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "any",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Any() *Group {
+	return NewGroup().Any()
+}
+
+func (g *Group) As() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "as",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func As() *Group {
+	return NewGroup().As()
+}
+
+func (g *Group) Boolean() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "boolean",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Boolean() *Group {
+	return NewGroup().Boolean()
+}
+
+func (g *Group) Break() *Group {
+	s := &Stmt{Template: " break; ", Value: "break"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Break() *Group {
+	return NewGroup().Break()
+}
+
+func (g *Group) Case() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "case",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Case() *Group {
+	return NewGroup().Case()
+}
+
+func (g *Group) Catch() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "catch",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Catch() *Group {
+	return NewGroup().Catch()
+}
+
+func (g *Group) Class() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "class",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Class() *Group {
+	return NewGroup().Class()
+}
+
+func (g *Group) Const() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "const",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Const() *Group {
+	return NewGroup().Const()
+}
+
+func (g *Group) Constructor(stmt ...CodeInterface) *Group {
+	s := &Stmt{Template: " constructor(%s) ", Group: Group{Stmts: stmt}, Value: "constructor", Delimiter: ", "}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Constructor(stmt ...CodeInterface) *Group {
+	return NewGroup().Constructor(stmt...)
+}
+
+func (g *Group) Continue() *Group {
+	s := &Stmt{Template: " continue; ", Value: "continue"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Continue() *Group {
+	return NewGroup().Continue()
+}
+
+func (g *Group) Debugger() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "debugger",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Debugger() *Group {
+	return NewGroup().Debugger()
+}
+
+func (g *Group) Declare() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "declare",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Declare() *Group {
+	return NewGroup().Declare()
+}
+
+func (g *Group) Default() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "default",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Default() *Group {
+	return NewGroup().Default()
+}
+
+func (g *Group) Delete() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "delete",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Delete() *Group {
+	return NewGroup().Delete()
+}
+
+func (g *Group) Do() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "do",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Do() *Group {
+	return NewGroup().Do()
+}
+
+func (g *Group) Else() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "else",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Else() *Group {
+	return NewGroup().Else()
+}
+
+func (g *Group) Endl() *Group {
+	s := &Stmt{Template: " ; ", Value: "endl"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Endl() *Group {
+	return NewGroup().Endl()
+}
+
+func (g *Group) Enum() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "enum",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Enum() *Group {
+	return NewGroup().Enum()
+}
+
+func (g *Group) Export() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "export",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Export() *Group {
+	return NewGroup().Export()
+}
+
+func (g *Group) Extends() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "extends",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Extends() *Group {
+	return NewGroup().Extends()
+}
+
+func (g *Group) False() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "false",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func False() *Group {
+	return NewGroup().False()
+}
+
+func (g *Group) Finally() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "finally",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Finally() *Group {
+	return NewGroup().Finally()
+}
+
+func (g *Group) For() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "for",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func For() *Group {
+	return NewGroup().For()
+}
+
+func (g *Group) From() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "from",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func From() *Group {
+	return NewGroup().From()
+}
+
+func (g *Group) Function() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "function",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Function() *Group {
+	return NewGroup().Function()
+}
+
+func (g *Group) Get() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "get",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Get() *Group {
+	return NewGroup().Get()
+}
+
+func (g *Group) If(test CodeInterface) *Group {
+	s := &Stmt{Template: " if (%s) ", Group: Group{Stmts: []CodeInterface{test}}, Value: "if"}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func If(test CodeInterface) *Group {
+	return NewGroup().If(test)
+}
+
+func (g *Group) Implements() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "implements",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Implements() *Group {
+	return NewGroup().Implements()
+}
+
+func (g *Group) Import() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "import",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Import() *Group {
+	return NewGroup().Import()
+}
+
+func (g *Group) In() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "in",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func In() *Group {
+	return NewGroup().In()
+}
+
+func (g *Group) Instanceof() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "instanceof",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Instanceof() *Group {
+	return NewGroup().Instanceof()
+}
+
+func (g *Group) Interface() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "interface",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Interface() *Group {
+	return NewGroup().Interface()
+}
+
+func (g *Group) Let() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "let",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Let() *Group {
+	return NewGroup().Let()
+}
+
+func (g *Group) Module() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "module",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Module() *Group {
+	return NewGroup().Module()
+}
+
+func (g *Group) New() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "new",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func New() *Group {
+	return NewGroup().New()
+}
+
+func (g *Group) Null() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "null",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Null() *Group {
+	return NewGroup().Null()
+}
+
+func (g *Group) Number() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "number",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Number() *Group {
+	return NewGroup().Number()
+}
+
+func (g *Group) Of() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "of",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Of() *Group {
+	return NewGroup().Of()
+}
+
+func (g *Group) Package() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "package",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Package() *Group {
+	return NewGroup().Package()
+}
+
+func (g *Group) Private() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "private",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Private() *Group {
+	return NewGroup().Private()
+}
+
+func (g *Group) Protected() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "protected",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Protected() *Group {
+	return NewGroup().Protected()
+}
+
+func (g *Group) Public() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "public",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Public() *Group {
+	return NewGroup().Public()
+}
+
+func (g *Group) Require() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "require",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Require() *Group {
+	return NewGroup().Require()
+}
+
+func (g *Group) Return() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "return",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Return() *Group {
+	return NewGroup().Return()
+}
+
+func (g *Group) Set() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "set",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Set() *Group {
+	return NewGroup().Set()
+}
+
+func (g *Group) Static() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "static",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Static() *Group {
+	return NewGroup().Static()
+}
+
+func (g *Group) String() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "string",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func String() *Group {
+	return NewGroup().String()
+}
+
+func (g *Group) Super() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "super",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Super() *Group {
+	return NewGroup().Super()
+}
+
+func (g *Group) Switch() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "switch",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Switch() *Group {
+	return NewGroup().Switch()
+}
+
+func (g *Group) Symbol() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "symbol",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Symbol() *Group {
+	return NewGroup().Symbol()
+}
+
+func (g *Group) This() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "this",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func This() *Group {
+	return NewGroup().This()
+}
+
+func (g *Group) Throw() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "throw",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Throw() *Group {
+	return NewGroup().Throw()
+}
+
+func (g *Group) True() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "true",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func True() *Group {
+	return NewGroup().True()
+}
+
+func (g *Group) Try() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "try",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Try() *Group {
+	return NewGroup().Try()
+}
+
+func (g *Group) Type() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "type",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Type() *Group {
+	return NewGroup().Type()
+}
+
+func (g *Group) Typeof() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "typeof",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Typeof() *Group {
+	return NewGroup().Typeof()
+}
+
+func (g *Group) Var() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "var",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Var() *Group {
+	return NewGroup().Var()
+}
+
+func (g *Group) Void() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "void",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Void() *Group {
+	return NewGroup().Void()
+}
+
+func (g *Group) While() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "while",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func While() *Group {
+	return NewGroup().While()
+}
+
+func (g *Group) With() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "with",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func With() *Group {
+	return NewGroup().With()
+}
+
+func (g *Group) Yield() *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    "yield",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Yield() *Group {
+	return NewGroup().Yield()
+}

+ 463 - 0
generators/typescript/utils.go

@@ -0,0 +1,463 @@
+package typescript
+
+import (
+	bytes "bytes"
+	"fmt"
+	"os/exec"
+	"reflect"
+	"strings"
+
+	"git.eugeniocarvalho.dev/eugeniucarvalho/utils"
+)
+
+var (
+	LitTemplates = map[string]string{
+		"string":  " '%s' ",
+		"int":     " %d ",
+		"int8":    " %d ",
+		"int16":   " %d ",
+		"int32":   " %d ",
+		"int64":   " %d ",
+		"float32": " %.2f ",
+		"float64": " %.2f ",
+		"bool":    " %.2f ",
+	}
+)
+
+const (
+	STMT_QUAL = "qual"
+)
+
+type File struct {
+	Group
+	Imports map[string][]string
+	Name    string
+}
+
+func NewFile(file string) *File {
+	f := &File{
+		Name:    file,
+		Imports: map[string][]string{},
+	}
+	// f.Group.File = f
+	return f
+}
+
+// Entidade representa menor unidade de Statement.
+type Stmt struct {
+	Group
+	Value     interface{}
+	Template  string
+	Delimiter string
+	// Separete string
+	StmtType string
+}
+
+// Root node group of Statement.
+type Group struct {
+	Delimiter string
+	// File  *File
+	Stmts []CodeInterface
+}
+
+// Metodo realiza a renderização de um grupo e todos os seus statements.
+func (g *Group) Render(buffer *bytes.Buffer) (err error) {
+	var del = ""
+	for _, s := range g.Stmts {
+		buffer.WriteString(del)
+		err = s.Render(buffer)
+		del = g.Delimiter
+	}
+	return
+}
+
+func (f *File) GoString() string {
+	return f.Group.GoString()
+}
+
+// Metodo Gera a string do arquivo.
+func (g *Group) GoString() string {
+	buf := bytes.Buffer{}
+
+	if err := g.Render(&buf); err != nil {
+		panic(err)
+	}
+	return buf.String()
+}
+
+func NewGroup() *Group {
+	return &Group{}
+}
+
+func (f *File) Save() (err error) {
+	var (
+		out    bytes.Buffer
+		stderr bytes.Buffer
+	)
+
+	if err = utils.FilePutContents(f.Name, f.GoString(), 0777); err != nil {
+		return err
+	}
+	// fmt.Println("Slve ts")
+	// Formate code with https://www.npmjs.com/package/typescript-formatter
+
+	fmt.Println("format", f.Name)
+
+	// cmd := exec.Command()
+	// cmd.Stdin = strings.NewReader("")
+	// cmd.Stdout = &out
+
+	// cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
+	cmd := exec.Command("tsfmt", "-r", "--no-tsfmt", "--no-tslint", f.Name)
+	// cmd := exec.Command("tsfmt", "-r", f.Name)
+	cmd.Stdout = &out
+	cmd.Stderr = &stderr
+
+	if err = cmd.Run(); err != nil {
+		fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
+		return
+	}
+	fmt.Println("Result: " + out.String())
+	return
+}
+
+func (s *Stmt) Render(buffer *bytes.Buffer) (err error) {
+
+	var (
+		Value          interface{}
+		bufLocal       *bytes.Buffer
+		bufLocalMaster = &bytes.Buffer{}
+		wbv            string
+		delim          string
+	)
+
+	if len(s.Stmts) > 0 {
+
+		delim = ""
+		for _, stmt := range s.Stmts {
+			bufLocal = &bytes.Buffer{}
+			stmt.Render(bufLocal)
+			bufLocalMaster.WriteString(delim + bufLocal.String())
+			delim = s.Delimiter
+		}
+		Value = bufLocalMaster.String()
+	} else {
+		Value = s.Value
+	}
+
+	if strings.Contains(s.Template, "%") {
+
+		if f, ok := Value.(func(g *Group)); ok {
+			g := &Group{}
+			g.Delimiter = s.Delimiter
+			f(g)
+			Value = g.GoString()
+		}
+
+		wbv = fmt.Sprintf(s.Template, Value)
+
+	} else {
+		wbv = s.Template
+	}
+
+	buffer.WriteString(wbv)
+	return
+}
+
+func (g *Group) Lit(stmt interface{}) *Group {
+	var (
+		Template string
+		typ      = reflect.TypeOf(stmt).Name()
+	)
+	if t, ok := LitTemplates[typ]; ok {
+		Template = t
+	} else {
+		Template = " %v "
+	}
+
+	s := &Stmt{
+		Template: Template,
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+
+	return g
+}
+
+func Lit(stmt interface{}) *Group {
+	return NewGroup().Lit(stmt)
+}
+
+func (g *Group) Comment(stmt string) *Group {
+	var (
+		Template string
+	)
+	if strings.Contains(stmt, "\n") {
+		Template = " \n/* \n%s\n */\n "
+
+	} else {
+		Template = " \n// %s\n "
+	}
+	s := &Stmt{
+		Template: Template,
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Comment(stmt string) *Group {
+	return NewGroup().Comment(stmt)
+}
+
+func Dot(stmt string) *Group {
+	return NewGroup().Dot(stmt)
+}
+
+func (g *Group) Dot(stmt string) *Group {
+
+	s := &Stmt{
+		Template: ".%s ",
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Raw(stmt string) *Group {
+	return NewGroup().Raw(stmt)
+}
+
+func (g *Group) Raw(stmt string) *Group {
+
+	s := &Stmt{
+		Template: " %s ",
+		Value:    stmt,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) Add(gin *Group) *Group {
+
+	s := &Stmt{
+		Template: " %s ",
+		Group:    *gin,
+		Value:    "",
+	}
+	// s.Group.File = g.File
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) Params(params ...CodeInterface) *Group {
+	s := &Stmt{
+		Template: " (%s) ",
+		Group: Group{
+			Stmts: params,
+			// File:  g.File,
+		},
+		Value:     "",
+		Delimiter: ", ",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) ParamsFun(fun func(g *Group)) *Group {
+	s := &Stmt{Template: " (%s) ", Value: fun}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Params(params ...CodeInterface) *Group {
+	return NewGroup().Params(params...)
+}
+func ParamsFun(fun func(g *Group)) *Group {
+	return NewGroup().ParamsFun(fun)
+}
+
+func (g *Group) Op(op string) *Group {
+	s := &Stmt{Template: "  %s  ", Value: op}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Op(op string) *Group {
+	return NewGroup().Op(op)
+}
+
+func (g *Group) Line() *Group {
+	s := &Stmt{
+		Template: "\n",
+		Value:    "",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Line() *Group {
+	return NewGroup().Line()
+}
+
+func (g *Group) Block(stmts ...CodeInterface) *Group {
+	s := &Stmt{
+		Template: " {%s} ",
+		Group: Group{
+			Stmts: stmts,
+		},
+		Value:     "",
+		Delimiter: "\n",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) InlineBlock(stmts ...CodeInterface) *Group {
+	s := &Stmt{
+		Template: " {%s} ",
+		Group: Group{
+			Stmts: stmts,
+		},
+		Value:     "",
+		Delimiter: ", ",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) BlockFun(fun func(g *Group)) *Group {
+	s := &Stmt{
+		Template: "  {%s}\n ",
+		Value:    fun,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Block(stmts ...CodeInterface) *Group {
+	return NewGroup().Block(stmts...)
+}
+
+func InlineBlock(stmts ...CodeInterface) *Group {
+	return NewGroup().InlineBlock(stmts...)
+}
+
+func BlockFun(fun func(g *Group)) *Group {
+	return NewGroup().BlockFun(fun)
+}
+
+func (g *Group) Call(params ...CodeInterface) *Group {
+	s := &Stmt{
+		Template: " (%s) ",
+		Group: Group{
+			// Stmts: []CodeInterface{params},
+			Stmts: params,
+		},
+		Delimiter: ", ",
+		Value:     "",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+func (g *Group) CallFun(fun func(g *Group)) *Group {
+	s := &Stmt{Template: " (%s) ", Value: fun}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Call(params ...CodeInterface) *Group {
+	return NewGroup().Call(params...)
+}
+func CallFun(fun func(g *Group)) *Group {
+	return NewGroup().CallFun(fun)
+}
+
+func (g *Group) Id(stmt string) *Group {
+	s := &Stmt{Template: " %s ", Value: stmt}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Id(stmt string) *Group {
+	return NewGroup().Id(stmt)
+}
+
+func (g *Group) Index(index ...CodeInterface) *Group {
+	s := &Stmt{
+		Template:  " [%s] ",
+		Group:     Group{Stmts: index},
+		Value:     "",
+		Delimiter: ", ",
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func (g *Group) IndexFun(fun func(g *Group)) *Group {
+	s := &Stmt{Template: " [%s] ", Value: fun, Delimiter: ", "}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Index(index ...CodeInterface) *Group {
+	return NewGroup().Index(index...)
+}
+
+func IndexFun(fun func(g *Group)) *Group {
+	return NewGroup().IndexFun(fun)
+}
+
+func (g *Group) Produce(f func(g *Group)) *Group {
+	s := &Stmt{
+		Template: " %s ",
+		Value:    f,
+	}
+	g.Stmts = append(g.Stmts, s)
+	return g
+}
+
+func Produce(f func(g *Group)) *Group {
+	return NewGroup().Produce(f)
+}
+
+type BaseCodeInterface interface {
+	Render(buffer *bytes.Buffer) error
+	GoString() string
+	Block(stmts ...CodeInterface) *Group
+	Call(params ...CodeInterface) *Group
+	Comment(stmt string) *Group
+	Id(stmt string) *Group
+	Index(index ...CodeInterface) *Group
+	Lit(stmt interface{}) *Group
+	Op(op string) *Group
+	Params(params ...CodeInterface) *Group
+	Produce(f func(g *Group)) *Group
+}
+
+func ConvType(typ string) string {
+	ntype := strings.Replace(typ, "*", "", -1)
+
+	switch ntype {
+	case "int", "int8", "int16", "int32", "int64", "float32", "float64":
+		ntype = "number"
+	case "bool":
+		ntype = "boolean"
+	case "bson.ObjectId":
+		fallthrough
+	case "primitive.ObjectID":
+		ntype = "string"
+	case "interface{}":
+		ntype = "any"
+	default:
+		if ntype[0:3] == "map" {
+			parts := strings.Split(ntype, "|")
+			// if parts[2] == "interface{}" {
+			// 	parts[2] = "any"
+			// }
+			ntype = fmt.Sprintf("Map<%s,%s>", parts[1], ConvType(parts[2]))
+		}
+	}
+
+	return ntype
+}

+ 8 - 0
go.mod

@@ -0,0 +1,8 @@
+module git.eugeniocarvalho.dev/eugeniucarvalho/gg
+
+go 1.13
+
+require (
+	git.eugeniocarvalho.dev/eugeniucarvalho/utils v1.0.2
+	github.com/dave/jennifer v1.4.0
+)

+ 10 - 0
go.sum

@@ -0,0 +1,10 @@
+git.eugeniocarvalho.dev/eugeniucarvalho/utils v1.0.2 h1:pi9aCd86+20NXV+QYITfUuEhY9rqv14mWeuBoT9sLq0=
+git.eugeniocarvalho.dev/eugeniucarvalho/utils v1.0.2/go.mod h1:GoSSifraiFtzF/IVzcqFhy5DKR/npEiTNvpKeL1/Jc4=
+github.com/dave/jennifer v1.4.0 h1:tNJFJmLDVTLu+v05mVZ88RINa3vQqnyyWkTKWYz0CwE=
+github.com/dave/jennifer v1.4.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

+ 28 - 0
main.go

@@ -0,0 +1,28 @@
+package main
+
+import (
+	"flag"
+	"git.eugeniocarvalho.dev/eugeniucarvalho/gg/generator"
+)
+
+var (
+	Input = flag.String("input", "def.json", "Arquivo de descrição do projeto no formato JSON.")
+	Out   = flag.String("out", "./generators", "Destino dos arquivos gerados.")
+)
+
+//a.replace(/[\n\r]/g,";").replace(/\s+/g,'').split(";").map(function(k,v){dic[k]=1}); console.log(Object.getOwnPropertyNames(dic).sort())
+
+func main() {
+	var (
+		err         error
+		description *generator.Generator
+	)
+
+	flag.Parse()
+
+	if description, err = generator.New(*Input); err != nil {
+		panic(err)
+	}
+
+	description.Gen(*Out)
+}