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  }