github.com/gopherd/gonum@v0.0.4/unit/constant/generate_defined_types.go (about) 1 // Copyright ©2019 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 // +build ignore 7 8 package main 9 10 import ( 11 "bytes" 12 "go/ast" 13 "go/format" 14 "go/parser" 15 "go/token" 16 "log" 17 "os" 18 "path/filepath" 19 "strings" 20 "text/template" 21 ) 22 23 const definedTemplate = `// Code generated by "go generate github.com/gopherd/gonum/unit/constant”; DO NOT EDIT. 24 25 // Copyright ©2019 The Gonum Authors. All rights reserved. 26 // Use of this source code is governed by a BSD-style 27 // license that can be found in the LICENSE file. 28 29 //go:build ignore 30 // +build ignore 31 32 package main 33 34 import "github.com/gopherd/gonum/unit" 35 36 var definedTypes = []struct{ 37 unit unit.Uniter 38 name string 39 }{ 40 {{range .}} {unit: unit.{{.}}(1), name: "unit.{{.}}"{{"}"}}, 41 {{end}}} 42 43 func definedEquivalentOf(q unit.Uniter) string { 44 for _, u := range definedTypes { 45 if unit.DimensionsMatch(q, u.unit) { 46 return u.name 47 } 48 } 49 return "" 50 } 51 ` 52 53 var defined = template.Must(template.New("defined").Parse(definedTemplate)) 54 55 func main() { 56 names, err := filepath.Glob("../*.go") 57 if err != nil { 58 log.Fatal(err) 59 } 60 61 var units []string 62 fset := token.NewFileSet() 63 for _, fn := range names { 64 if strings.Contains(fn, "_test") { 65 continue 66 } 67 b, err := os.ReadFile(fn) 68 if bytes.Contains(b, []byte("+build ignore")) { 69 continue 70 } 71 f, err := parser.ParseFile(fset, fn, nil, 0) 72 if err != nil { 73 log.Fatal("failed to parse %q: %v", fn, err) // parse error 74 } 75 if f.Name.Name != "unit" { 76 log.Fatalf("not parsing unit package: %q", f.Name.Name) 77 } 78 for _, d := range f.Decls { 79 if decl, ok := d.(*ast.GenDecl); ok { 80 for _, s := range decl.Specs { 81 if ts, ok := s.(*ast.TypeSpec); ok { 82 if id, ok := ts.Type.(*ast.Ident); !ok || id.Name != "float64" { 83 continue 84 } 85 units = append(units, ts.Name.Name) 86 } 87 } 88 } 89 } 90 } 91 92 f, err := os.Create("defined_types.go") 93 if err != nil { 94 log.Fatal(err) 95 } 96 defer f.Close() 97 98 var buf bytes.Buffer 99 err = defined.Execute(&buf, units) 100 if err != nil { 101 log.Fatal(err) 102 } 103 104 b, err := format.Source(buf.Bytes()) 105 if err != nil { 106 f.Write(buf.Bytes()) // This is here to debug bad format. 107 log.Fatalf("error formatting %q: %s", f.Name(), err) 108 } 109 110 f.Write(b) 111 }