github.com/apipluspower/gqlgen@v0.15.2/codegen/templates/import.go (about) 1 package templates 2 3 import ( 4 "fmt" 5 "go/types" 6 "strconv" 7 "strings" 8 9 "github.com/apipluspower/gqlgen/internal/code" 10 ) 11 12 type Import struct { 13 Name string 14 Path string 15 Alias string 16 } 17 18 type Imports struct { 19 imports []*Import 20 destDir string 21 packages *code.Packages 22 } 23 24 func (i *Import) String() string { 25 if strings.HasSuffix(i.Path, i.Alias) { 26 return strconv.Quote(i.Path) 27 } 28 29 return i.Alias + " " + strconv.Quote(i.Path) 30 } 31 32 func (s *Imports) String() string { 33 res := "" 34 for i, imp := range s.imports { 35 if i != 0 { 36 res += "\n" 37 } 38 res += imp.String() 39 } 40 return res 41 } 42 43 func (s *Imports) Reserve(path string, aliases ...string) (string, error) { 44 if path == "" { 45 panic("empty ambient import") 46 } 47 48 // if we are referencing our own package we dont need an import 49 if code.ImportPathForDir(s.destDir) == path { 50 return "", nil 51 } 52 53 name := s.packages.NameForPackage(path) 54 var alias string 55 if len(aliases) != 1 { 56 alias = name 57 } else { 58 alias = aliases[0] 59 } 60 61 if existing := s.findByPath(path); existing != nil { 62 if existing.Alias == alias { 63 return "", nil 64 } 65 return "", fmt.Errorf("ambient import already exists") 66 } 67 68 if alias := s.findByAlias(alias); alias != nil { 69 return "", fmt.Errorf("ambient import collides on an alias") 70 } 71 72 s.imports = append(s.imports, &Import{ 73 Name: name, 74 Path: path, 75 Alias: alias, 76 }) 77 78 return "", nil 79 } 80 81 func (s *Imports) Lookup(path string) string { 82 if path == "" { 83 return "" 84 } 85 86 path = code.NormalizeVendor(path) 87 88 // if we are referencing our own package we dont need an import 89 if code.ImportPathForDir(s.destDir) == path { 90 return "" 91 } 92 93 if existing := s.findByPath(path); existing != nil { 94 return existing.Alias 95 } 96 97 imp := &Import{ 98 Name: s.packages.NameForPackage(path), 99 Path: path, 100 } 101 s.imports = append(s.imports, imp) 102 103 alias := imp.Name 104 i := 1 105 for s.findByAlias(alias) != nil { 106 alias = imp.Name + strconv.Itoa(i) 107 i++ 108 if i > 1000 { 109 panic(fmt.Errorf("too many collisions, last attempt was %s", alias)) 110 } 111 } 112 imp.Alias = alias 113 114 return imp.Alias 115 } 116 117 func (s *Imports) LookupType(t types.Type) string { 118 return types.TypeString(t, func(i *types.Package) string { 119 return s.Lookup(i.Path()) 120 }) 121 } 122 123 func (s Imports) findByPath(importPath string) *Import { 124 for _, imp := range s.imports { 125 if imp.Path == importPath { 126 return imp 127 } 128 } 129 return nil 130 } 131 132 func (s Imports) findByAlias(alias string) *Import { 133 for _, imp := range s.imports { 134 if imp.Alias == alias { 135 return imp 136 } 137 } 138 return nil 139 }