...
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 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
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
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 }
140
View as plain text