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