From a5d6fa15a3669ef52fd4a57e76e00b8d73745196 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Thu, 12 Sep 2024 15:47:30 +0200 Subject: [PATCH] Refactor class/type --- class.go | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 91 +------------------------------ types.go | 72 ------------------------ 3 files changed, 164 insertions(+), 162 deletions(-) create mode 100644 class.go delete mode 100644 types.go diff --git a/class.go b/class.go new file mode 100644 index 0000000..e367db3 --- /dev/null +++ b/class.go @@ -0,0 +1,163 @@ +package main + +import ( + "fmt" + "log" + "os" + "path/filepath" + "strings" + "text/template" + + "github.com/PuerkitoBio/goquery" + "github.com/davecgh/go-spew/spew" +) + +type ( + Class struct { + ClassName string + Fields []Field + Methods []Method + Constructors []Constructor + } + Field struct { + Name string + Type string + Comment string + } + Method struct { + Name string + Params []Param + Returns []Return + Comment string + } + Param struct { + Name string + Type string + Comment string + } + Return struct { + Type string + Comment string + } + Constructor struct { + Params []Param + Comment string + } +) + +func (c *Class) GetOutFile(root string) (*os.File, error) { + if c.ClassName == "" { + return nil, fmt.Errorf("ClassName is empty") + } + filename := fmt.Sprintf("%s.lua", c.ClassName) + filename = strings.ReplaceAll(filename, " ", "") + filename = strings.ReplaceAll(filename, "-", "") + filename = strings.ReplaceAll(filename, ",", "") + filename = strings.ReplaceAll(filename, ":", "") + filePath := filepath.Join(root, filename) + filePath = filepath.Clean(filePath) + f, err := os.Create(filePath) + if err != nil { + return nil, err + } + return f, nil +} + +func (c *Class) Write(root string, tmpl *template.Template) error { + outfile, err := c.GetOutFile(root) + if err != nil { + return fmt.Errorf("error creating output file %v: %v", c.ClassName, err) + } + err = tmpl.Execute(outfile, c) + if err != nil { + return fmt.Errorf("error writing output file %v: %v", c.ClassName, err) + } + return nil +} + +func ParseClass(file string) (*Class, error) { + log.Printf("Parsing file: '%s'", file) + res := Class{ + Fields: []Field{}, + Methods: []Method{}, + Constructors: []Constructor{}, + } + filehandle, err := os.Open(file) + if err != nil { + return nil, fmt.Errorf("error opening file: %w", err) + } + defer filehandle.Close() + + doc, err := goquery.NewDocumentFromReader(filehandle) + if err != nil { + return nil, fmt.Errorf("error parsing file: %w", err) + } + + class := doc.Find("div.floatright > h1") + if class.Length() == 0 { + return nil, fmt.Errorf("no class found") + } + res.ClassName = strings.TrimSpace(class.Text()) + + codeblocks := doc.Find("div.floatright > div.codecontainer") + if codeblocks.Length() == 0 { + return nil, fmt.Errorf("no codeblocks found") + } + + // The first code block should be the constructor + // So far I have not found any classes with overloaded constructors... + // So I can not handle that case yet + constructorBlock := codeblocks.Eq(0) + constructor := constructorBlock.Find("div.function") + paramTypes := constructor.Find("span.type") + paramNames := constructor.Find("span.parameter") + + resConstructor := Constructor{} + paramTypes.Each(func(i int, s *goquery.Selection) { + pname := strings.TrimSpace(paramNames.Eq(i).Text()) + ptype := strings.TrimSpace(paramTypes.Eq(i).Text()) + ptype = MapType(ptype) + + resConstructor.Params = append(resConstructor.Params, Param{ + Name: pname, + Type: ptype, + Comment: "", + }) + }) + res.Constructors = append(res.Constructors, resConstructor) + + properties := doc.Find("div.floatright > div.codecontainer#Properties") + properties.ChildrenFiltered("div").Each(func(i int, s *goquery.Selection) { + property := Field{} + property.Name = strings.TrimSpace(s.Find("span.property").Text()) + property.Type = strings.TrimSpace(s.Find("span.type").Text()) + property.Type = MapType(property.Type) + comment := s.Find("td[align='right']").Text() + if comment != "" { + property.Comment = strings.TrimSpace(comment) + } + res.Fields = append(res.Fields, property) + }) + + codeblocks.ChildrenFiltered("div.function").Each(func(i int, s *goquery.Selection) { + method := Method{} + method.Name = strings.TrimSpace(s.AttrOr("id", "")) + method.Comment = strings.TrimSpace(s.Find("span.comment").Text()) + + types := s.Find("span.type") + parameters := s.Find("span.parameter") + types.Each(func(i int, s *goquery.Selection) { + param := Param{} + param.Name = strings.TrimSpace(parameters.Eq(i).Text()) + param.Type = strings.TrimSpace(types.Eq(i).Text()) + param.Type = MapType(param.Type) + method.Params = append(method.Params, param) + }) + + res.Methods = append(res.Methods, method) + }) + + spew.Dump(res) + + return &res, nil +} diff --git a/main.go b/main.go index fcf7883..b71c90a 100644 --- a/main.go +++ b/main.go @@ -6,11 +6,9 @@ import ( "io" "log" "os" - "strings" "sync" "text/template" - "github.com/PuerkitoBio/goquery" "github.com/davecgh/go-spew/spew" _ "embed" @@ -65,7 +63,7 @@ func main() { wg.Add(1) go func(file string) { defer wg.Done() - class, err := ParseFile(file) + class, err := ParseClass(file) if err != nil { Error.Printf("Error parsing file: %v", err) return @@ -76,93 +74,6 @@ func main() { wg.Wait() } -func ParseFile(filename string) (*Class, error) { - log.Printf("Parsing file: '%s'", filename) - res := Class{ - Fields: []Field{}, - Methods: []Method{}, - Constructors: []Constructor{}, - } - file, err := os.Open(filename) - if err != nil { - return nil, fmt.Errorf("error opening file: %w", err) - } - defer file.Close() - - doc, err := goquery.NewDocumentFromReader(file) - if err != nil { - return nil, fmt.Errorf("error parsing file: %w", err) - } - - class := doc.Find("div.floatright > h1") - if class.Length() == 0 { - return nil, fmt.Errorf("no class found") - } - res.ClassName = strings.TrimSpace(class.Text()) - - codeblocks := doc.Find("div.floatright > div.codecontainer") - if codeblocks.Length() == 0 { - return nil, fmt.Errorf("no codeblocks found") - } - - // The first code block should be the constructor - // So far I have not found any classes with overloaded constructors... - // So I can not handle that case yet - constructorBlock := codeblocks.Eq(0) - constructor := constructorBlock.Find("div.function") - paramTypes := constructor.Find("span.type") - paramNames := constructor.Find("span.parameter") - - resConstructor := Constructor{} - paramTypes.Each(func(i int, s *goquery.Selection) { - pname := strings.TrimSpace(paramNames.Eq(i).Text()) - ptype := strings.TrimSpace(paramTypes.Eq(i).Text()) - ptype = MapType(ptype) - - resConstructor.Params = append(resConstructor.Params, Param{ - Name: pname, - Type: ptype, - Comment: "", - }) - }) - res.Constructors = append(res.Constructors, resConstructor) - - properties := doc.Find("div.floatright > div.codecontainer#Properties") - properties.ChildrenFiltered("div").Each(func(i int, s *goquery.Selection) { - property := Field{} - property.Name = strings.TrimSpace(s.Find("span.property").Text()) - property.Type = strings.TrimSpace(s.Find("span.type").Text()) - property.Type = MapType(property.Type) - comment := s.Find("td[align='right']").Text() - if comment != "" { - property.Comment = strings.TrimSpace(comment) - } - res.Fields = append(res.Fields, property) - }) - - codeblocks.ChildrenFiltered("div.function").Each(func(i int, s *goquery.Selection) { - method := Method{} - method.Name = strings.TrimSpace(s.AttrOr("id", "")) - method.Comment = strings.TrimSpace(s.Find("span.comment").Text()) - - types := s.Find("span.type") - parameters := s.Find("span.parameter") - types.Each(func(i int, s *goquery.Selection) { - param := Param{} - param.Name = strings.TrimSpace(parameters.Eq(i).Text()) - param.Type = strings.TrimSpace(types.Eq(i).Text()) - param.Type = MapType(param.Type) - method.Params = append(method.Params, param) - }) - - res.Methods = append(res.Methods, method) - }) - - spew.Dump(res) - - return &res, nil -} - func MapType(t string) string { switch t { case "var": diff --git a/types.go b/types.go deleted file mode 100644 index a932e12..0000000 --- a/types.go +++ /dev/null @@ -1,72 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "strings" - "text/template" -) - -type ( - Class struct { - ClassName string - Fields []Field - Methods []Method - Constructors []Constructor - } - Field struct { - Name string - Type string - Comment string - } - Method struct { - Name string - Params []Param - Returns []Return - Comment string - } - Param struct { - Name string - Type string - Comment string - } - Return struct { - Type string - Comment string - } - Constructor struct { - Params []Param - Comment string - } -) - -func (c *Class) GetOutFile(root string) (*os.File, error) { - if c.ClassName == "" { - return nil, fmt.Errorf("ClassName is empty") - } - filename := fmt.Sprintf("%s.lua", c.ClassName) - filename = strings.ReplaceAll(filename, " ", "") - filename = strings.ReplaceAll(filename, "-", "") - filename = strings.ReplaceAll(filename, ",", "") - filename = strings.ReplaceAll(filename, ":", "") - filePath := filepath.Join(root, filename) - filePath = filepath.Clean(filePath) - f, err := os.Create(filePath) - if err != nil { - return nil, err - } - return f, nil -} - -func (c *Class) Write(root string, tmpl *template.Template) error { - outfile, err := c.GetOutFile(root) - if err != nil { - return fmt.Errorf("error creating output file %v: %v", c.ClassName, err) - } - err = tmpl.Execute(outfile, c) - if err != nil { - return fmt.Errorf("error writing output file %v: %v", c.ClassName, err) - } - return nil -}