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  }