utils.go 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. package typescript
  2. import (
  3. bytes "bytes"
  4. "fmt"
  5. "os/exec"
  6. "reflect"
  7. "strings"
  8. "git.eugeniocarvalho.dev/eugeniucarvalho/utils"
  9. )
  10. var (
  11. LitTemplates = map[string]string{
  12. "string": " '%s' ",
  13. "int": " %d ",
  14. "int8": " %d ",
  15. "int16": " %d ",
  16. "int32": " %d ",
  17. "int64": " %d ",
  18. "float32": " %.2f ",
  19. "float64": " %.2f ",
  20. "bool": " %.2f ",
  21. }
  22. )
  23. const (
  24. STMT_QUAL = "qual"
  25. )
  26. type File struct {
  27. Group
  28. Imports map[string][]string
  29. Name string
  30. }
  31. func NewFile(file string) *File {
  32. f := &File{
  33. Name: file,
  34. Imports: map[string][]string{},
  35. }
  36. // f.Group.File = f
  37. return f
  38. }
  39. // Entidade representa menor unidade de Statement.
  40. type Stmt struct {
  41. Group
  42. Value interface{}
  43. Template string
  44. Delimiter string
  45. // Separete string
  46. StmtType string
  47. }
  48. // Root node group of Statement.
  49. type Group struct {
  50. Delimiter string
  51. // File *File
  52. Stmts []CodeInterface
  53. }
  54. // Metodo realiza a renderização de um grupo e todos os seus statements.
  55. func (g *Group) Render(buffer *bytes.Buffer) (err error) {
  56. var del = ""
  57. for _, s := range g.Stmts {
  58. buffer.WriteString(del)
  59. err = s.Render(buffer)
  60. del = g.Delimiter
  61. }
  62. return
  63. }
  64. func (f *File) GoString() string {
  65. return f.Group.GoString()
  66. }
  67. // Metodo Gera a string do arquivo.
  68. func (g *Group) GoString() string {
  69. buf := bytes.Buffer{}
  70. if err := g.Render(&buf); err != nil {
  71. panic(err)
  72. }
  73. return buf.String()
  74. }
  75. func NewGroup() *Group {
  76. return &Group{}
  77. }
  78. func (f *File) Save() (err error) {
  79. var (
  80. out bytes.Buffer
  81. stderr bytes.Buffer
  82. )
  83. if err = utils.FilePutContents(f.Name, f.GoString(), 0777); err != nil {
  84. return err
  85. }
  86. // fmt.Println("Slve ts")
  87. // Formate code with https://www.npmjs.com/package/typescript-formatter
  88. fmt.Println("format", f.Name)
  89. // cmd := exec.Command()
  90. // cmd.Stdin = strings.NewReader("")
  91. // cmd.Stdout = &out
  92. // cmd := exec.Command("find", "/", "-maxdepth", "1", "-exec", "wc", "-c", "{}", "\\")
  93. cmd := exec.Command("tsfmt", "-r", "--no-tsfmt", "--no-tslint", f.Name)
  94. // cmd := exec.Command("tsfmt", "-r", f.Name)
  95. cmd.Stdout = &out
  96. cmd.Stderr = &stderr
  97. if err = cmd.Run(); err != nil {
  98. fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
  99. return
  100. }
  101. fmt.Println("Result: " + out.String())
  102. return
  103. }
  104. func (s *Stmt) Render(buffer *bytes.Buffer) (err error) {
  105. var (
  106. Value interface{}
  107. bufLocal *bytes.Buffer
  108. bufLocalMaster = &bytes.Buffer{}
  109. wbv string
  110. delim string
  111. )
  112. if len(s.Stmts) > 0 {
  113. delim = ""
  114. for _, stmt := range s.Stmts {
  115. bufLocal = &bytes.Buffer{}
  116. stmt.Render(bufLocal)
  117. bufLocalMaster.WriteString(delim + bufLocal.String())
  118. delim = s.Delimiter
  119. }
  120. Value = bufLocalMaster.String()
  121. } else {
  122. Value = s.Value
  123. }
  124. if strings.Contains(s.Template, "%") {
  125. if f, ok := Value.(func(g *Group)); ok {
  126. g := &Group{}
  127. g.Delimiter = s.Delimiter
  128. f(g)
  129. Value = g.GoString()
  130. }
  131. wbv = fmt.Sprintf(s.Template, Value)
  132. } else {
  133. wbv = s.Template
  134. }
  135. buffer.WriteString(wbv)
  136. return
  137. }
  138. func (g *Group) Lit(stmt interface{}) *Group {
  139. var (
  140. Template string
  141. typ = reflect.TypeOf(stmt).Name()
  142. )
  143. if t, ok := LitTemplates[typ]; ok {
  144. Template = t
  145. } else {
  146. Template = " %v "
  147. }
  148. s := &Stmt{
  149. Template: Template,
  150. Value: stmt,
  151. }
  152. g.Stmts = append(g.Stmts, s)
  153. return g
  154. }
  155. func Lit(stmt interface{}) *Group {
  156. return NewGroup().Lit(stmt)
  157. }
  158. func (g *Group) Comment(stmt string) *Group {
  159. var (
  160. Template string
  161. )
  162. if strings.Contains(stmt, "\n") {
  163. Template = " \n/* \n%s\n */\n "
  164. } else {
  165. Template = " \n// %s\n "
  166. }
  167. s := &Stmt{
  168. Template: Template,
  169. Value: stmt,
  170. }
  171. g.Stmts = append(g.Stmts, s)
  172. return g
  173. }
  174. func Comment(stmt string) *Group {
  175. return NewGroup().Comment(stmt)
  176. }
  177. func Dot(stmt string) *Group {
  178. return NewGroup().Dot(stmt)
  179. }
  180. func (g *Group) Dot(stmt string) *Group {
  181. s := &Stmt{
  182. Template: ".%s ",
  183. Value: stmt,
  184. }
  185. g.Stmts = append(g.Stmts, s)
  186. return g
  187. }
  188. func Raw(stmt string) *Group {
  189. return NewGroup().Raw(stmt)
  190. }
  191. func (g *Group) Raw(stmt string) *Group {
  192. s := &Stmt{
  193. Template: " %s ",
  194. Value: stmt,
  195. }
  196. g.Stmts = append(g.Stmts, s)
  197. return g
  198. }
  199. func (g *Group) Add(gin *Group) *Group {
  200. s := &Stmt{
  201. Template: " %s ",
  202. Group: *gin,
  203. Value: "",
  204. }
  205. // s.Group.File = g.File
  206. g.Stmts = append(g.Stmts, s)
  207. return g
  208. }
  209. func (g *Group) Params(params ...CodeInterface) *Group {
  210. s := &Stmt{
  211. Template: " (%s) ",
  212. Group: Group{
  213. Stmts: params,
  214. // File: g.File,
  215. },
  216. Value: "",
  217. Delimiter: ", ",
  218. }
  219. g.Stmts = append(g.Stmts, s)
  220. return g
  221. }
  222. func (g *Group) ParamsFun(fun func(g *Group)) *Group {
  223. s := &Stmt{Template: " (%s) ", Value: fun}
  224. g.Stmts = append(g.Stmts, s)
  225. return g
  226. }
  227. func Params(params ...CodeInterface) *Group {
  228. return NewGroup().Params(params...)
  229. }
  230. func ParamsFun(fun func(g *Group)) *Group {
  231. return NewGroup().ParamsFun(fun)
  232. }
  233. func (g *Group) Op(op string) *Group {
  234. s := &Stmt{Template: " %s ", Value: op}
  235. g.Stmts = append(g.Stmts, s)
  236. return g
  237. }
  238. func Op(op string) *Group {
  239. return NewGroup().Op(op)
  240. }
  241. func (g *Group) Line() *Group {
  242. s := &Stmt{
  243. Template: "\n",
  244. Value: "",
  245. }
  246. g.Stmts = append(g.Stmts, s)
  247. return g
  248. }
  249. func Line() *Group {
  250. return NewGroup().Line()
  251. }
  252. func (g *Group) Block(stmts ...CodeInterface) *Group {
  253. s := &Stmt{
  254. Template: " {%s} ",
  255. Group: Group{
  256. Stmts: stmts,
  257. },
  258. Value: "",
  259. Delimiter: "\n",
  260. }
  261. g.Stmts = append(g.Stmts, s)
  262. return g
  263. }
  264. func (g *Group) InlineBlock(stmts ...CodeInterface) *Group {
  265. s := &Stmt{
  266. Template: " {%s} ",
  267. Group: Group{
  268. Stmts: stmts,
  269. },
  270. Value: "",
  271. Delimiter: ", ",
  272. }
  273. g.Stmts = append(g.Stmts, s)
  274. return g
  275. }
  276. func (g *Group) BlockFun(fun func(g *Group)) *Group {
  277. s := &Stmt{
  278. Template: " {%s}\n ",
  279. Value: fun,
  280. }
  281. g.Stmts = append(g.Stmts, s)
  282. return g
  283. }
  284. func Block(stmts ...CodeInterface) *Group {
  285. return NewGroup().Block(stmts...)
  286. }
  287. func InlineBlock(stmts ...CodeInterface) *Group {
  288. return NewGroup().InlineBlock(stmts...)
  289. }
  290. func BlockFun(fun func(g *Group)) *Group {
  291. return NewGroup().BlockFun(fun)
  292. }
  293. func (g *Group) Call(params ...CodeInterface) *Group {
  294. s := &Stmt{
  295. Template: " (%s) ",
  296. Group: Group{
  297. // Stmts: []CodeInterface{params},
  298. Stmts: params,
  299. },
  300. Delimiter: ", ",
  301. Value: "",
  302. }
  303. g.Stmts = append(g.Stmts, s)
  304. return g
  305. }
  306. func (g *Group) CallFun(fun func(g *Group)) *Group {
  307. s := &Stmt{Template: " (%s) ", Value: fun}
  308. g.Stmts = append(g.Stmts, s)
  309. return g
  310. }
  311. func Call(params ...CodeInterface) *Group {
  312. return NewGroup().Call(params...)
  313. }
  314. func CallFun(fun func(g *Group)) *Group {
  315. return NewGroup().CallFun(fun)
  316. }
  317. func (g *Group) Id(stmt string) *Group {
  318. s := &Stmt{Template: " %s ", Value: stmt}
  319. g.Stmts = append(g.Stmts, s)
  320. return g
  321. }
  322. func Id(stmt string) *Group {
  323. return NewGroup().Id(stmt)
  324. }
  325. func (g *Group) Index(index ...CodeInterface) *Group {
  326. s := &Stmt{
  327. Template: " [%s] ",
  328. Group: Group{Stmts: index},
  329. Value: "",
  330. Delimiter: ", ",
  331. }
  332. g.Stmts = append(g.Stmts, s)
  333. return g
  334. }
  335. func (g *Group) IndexFun(fun func(g *Group)) *Group {
  336. s := &Stmt{Template: " [%s] ", Value: fun, Delimiter: ", "}
  337. g.Stmts = append(g.Stmts, s)
  338. return g
  339. }
  340. func Index(index ...CodeInterface) *Group {
  341. return NewGroup().Index(index...)
  342. }
  343. func IndexFun(fun func(g *Group)) *Group {
  344. return NewGroup().IndexFun(fun)
  345. }
  346. func (g *Group) Produce(f func(g *Group)) *Group {
  347. s := &Stmt{
  348. Template: " %s ",
  349. Value: f,
  350. }
  351. g.Stmts = append(g.Stmts, s)
  352. return g
  353. }
  354. func Produce(f func(g *Group)) *Group {
  355. return NewGroup().Produce(f)
  356. }
  357. type BaseCodeInterface interface {
  358. Render(buffer *bytes.Buffer) error
  359. GoString() string
  360. Block(stmts ...CodeInterface) *Group
  361. Call(params ...CodeInterface) *Group
  362. Comment(stmt string) *Group
  363. Id(stmt string) *Group
  364. Index(index ...CodeInterface) *Group
  365. Lit(stmt interface{}) *Group
  366. Op(op string) *Group
  367. Params(params ...CodeInterface) *Group
  368. Produce(f func(g *Group)) *Group
  369. }
  370. func ConvType(typ string) string {
  371. ntype := strings.Replace(typ, "*", "", -1)
  372. switch ntype {
  373. case "int", "int8", "int16", "int32", "int64", "float32", "float64":
  374. ntype = "number"
  375. case "bool":
  376. ntype = "boolean"
  377. case "bson.ObjectId":
  378. fallthrough
  379. case "primitive.ObjectID":
  380. ntype = "string"
  381. case "interface{}":
  382. ntype = "any"
  383. case "T":
  384. ntype = "T"
  385. default:
  386. if ntype[0:3] == "map" {
  387. parts := strings.Split(ntype, "|")
  388. // if parts[2] == "interface{}" {
  389. // parts[2] = "any"
  390. // }
  391. ntype = fmt.Sprintf("Map<%s,%s>", parts[1], ConvType(parts[2]))
  392. }
  393. }
  394. return ntype
  395. }