github.com/jingcheng-WU/gonum@v0.9.1-0.20210323123734-f1a2a11a8f7b/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 // +build ignore 6 7 package main 8 9 import ( 10 "bytes" 11 "go/ast" 12 "go/format" 13 "go/parser" 14 "go/token" 15 "io/ioutil" 16 "log" 17 "os" 18 "path/filepath" 19 "strings" 20 "text/template" 21 ) 22 23 const definedTemplate = `// Code generated by "go generate github.com/jingcheng-WU/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 // +build ignore 30 31 package main 32 33 import "github.com/jingcheng-WU/gonum/unit" 34 35 var definedTypes = []struct{ 36 unit unit.Uniter 37 name string 38 }{ 39 {{range .}} {unit: unit.{{.}}(1), name: "unit.{{.}}"{{"}"}}, 40 {{end}}} 41 42 func definedEquivalentOf(q unit.Uniter) string { 43 for _, u := range definedTypes { 44 if unit.DimensionsMatch(q, u.unit) { 45 return u.name 46 } 47 } 48 return "" 49 } 50 ` 51 52 var defined = template.Must(template.New("defined").Parse(definedTemplate)) 53 54 func main() { 55 names, err := filepath.Glob("../*.go") 56 if err != nil { 57 log.Fatal(err) 58 } 59 60 var units []string 61 fset := token.NewFileSet() 62 for _, fn := range names { 63 if strings.Contains(fn, "_test") { 64 continue 65 } 66 b, err := ioutil.ReadFile(fn) 67 if bytes.Contains(b, []byte("+build ignore")) { 68 continue 69 } 70 f, err := parser.ParseFile(fset, fn, nil, 0) 71 if err != nil { 72 log.Fatal("failed to parse %q: %v", fn, err) // parse error 73 } 74 if f.Name.Name != "unit" { 75 log.Fatalf("not parsing unit package: %q", f.Name.Name) 76 } 77 for _, d := range f.Decls { 78 if decl, ok := d.(*ast.GenDecl); ok { 79 for _, s := range decl.Specs { 80 if ts, ok := s.(*ast.TypeSpec); ok { 81 if id, ok := ts.Type.(*ast.Ident); !ok || id.Name != "float64" { 82 continue 83 } 84 units = append(units, ts.Name.Name) 85 } 86 } 87 } 88 } 89 } 90 91 f, err := os.Create("defined_types.go") 92 if err != nil { 93 log.Fatal(err) 94 } 95 defer f.Close() 96 97 var buf bytes.Buffer 98 err = defined.Execute(&buf, units) 99 if err != nil { 100 log.Fatal(err) 101 } 102 103 b, err := format.Source(buf.Bytes()) 104 if err != nil { 105 f.Write(buf.Bytes()) // This is here to debug bad format. 106 log.Fatalf("error formatting %q: %s", f.Name(), err) 107 } 108 109 f.Write(b) 110 }