...

Source file src/go/importer/importer.go

     1	// Copyright 2015 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// Package importer provides access to export data importers.
     6	package importer
     7	
     8	import (
     9		"go/build"
    10		"go/internal/gccgoimporter"
    11		"go/internal/gcimporter"
    12		"go/internal/srcimporter"
    13		"go/token"
    14		"go/types"
    15		"io"
    16		"runtime"
    17	)
    18	
    19	// A Lookup function returns a reader to access package data for
    20	// a given import path, or an error if no matching package is found.
    21	type Lookup func(path string) (io.ReadCloser, error)
    22	
    23	// ForCompiler returns an Importer for importing from installed packages
    24	// for the compilers "gc" and "gccgo", or for importing directly
    25	// from the source if the compiler argument is "source". In this
    26	// latter case, importing may fail under circumstances where the
    27	// exported API is not entirely defined in pure Go source code
    28	// (if the package API depends on cgo-defined entities, the type
    29	// checker won't have access to those).
    30	//
    31	// The lookup function is called each time the resulting importer needs
    32	// to resolve an import path. In this mode the importer can only be
    33	// invoked with canonical import paths (not relative or absolute ones);
    34	// it is assumed that the translation to canonical import paths is being
    35	// done by the client of the importer.
    36	//
    37	// A lookup function must be provided for correct module-aware operation.
    38	// Deprecated: If lookup is nil, for backwards-compatibility, the importer
    39	// will attempt to resolve imports in the $GOPATH workspace.
    40	func ForCompiler(fset *token.FileSet, compiler string, lookup Lookup) types.Importer {
    41		switch compiler {
    42		case "gc":
    43			return &gcimports{
    44				fset:     fset,
    45				packages: make(map[string]*types.Package),
    46				lookup:   lookup,
    47			}
    48	
    49		case "gccgo":
    50			var inst gccgoimporter.GccgoInstallation
    51			if err := inst.InitFromDriver("gccgo"); err != nil {
    52				return nil
    53			}
    54			return &gccgoimports{
    55				packages: make(map[string]*types.Package),
    56				importer: inst.GetImporter(nil, nil),
    57				lookup:   lookup,
    58			}
    59	
    60		case "source":
    61			if lookup != nil {
    62				panic("source importer for custom import path lookup not supported (issue #13847).")
    63			}
    64	
    65			return srcimporter.New(&build.Default, fset, make(map[string]*types.Package))
    66		}
    67	
    68		// compiler not supported
    69		return nil
    70	}
    71	
    72	// For calls ForCompiler with a new FileSet.
    73	//
    74	// Deprecated: Use ForCompiler, which populates a FileSet
    75	// with the positions of objects created by the importer.
    76	func For(compiler string, lookup Lookup) types.Importer {
    77		return ForCompiler(token.NewFileSet(), compiler, lookup)
    78	}
    79	
    80	// Default returns an Importer for the compiler that built the running binary.
    81	// If available, the result implements types.ImporterFrom.
    82	func Default() types.Importer {
    83		return For(runtime.Compiler, nil)
    84	}
    85	
    86	// gc importer
    87	
    88	type gcimports struct {
    89		fset     *token.FileSet
    90		packages map[string]*types.Package
    91		lookup   Lookup
    92	}
    93	
    94	func (m *gcimports) Import(path string) (*types.Package, error) {
    95		return m.ImportFrom(path, "" /* no vendoring */, 0)
    96	}
    97	
    98	func (m *gcimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) {
    99		if mode != 0 {
   100			panic("mode must be 0")
   101		}
   102		return gcimporter.Import(m.fset, m.packages, path, srcDir, m.lookup)
   103	}
   104	
   105	// gccgo importer
   106	
   107	type gccgoimports struct {
   108		packages map[string]*types.Package
   109		importer gccgoimporter.Importer
   110		lookup   Lookup
   111	}
   112	
   113	func (m *gccgoimports) Import(path string) (*types.Package, error) {
   114		return m.ImportFrom(path, "" /* no vendoring */, 0)
   115	}
   116	
   117	func (m *gccgoimports) ImportFrom(path, srcDir string, mode types.ImportMode) (*types.Package, error) {
   118		if mode != 0 {
   119			panic("mode must be 0")
   120		}
   121		return m.importer(m.packages, path, srcDir, m.lookup)
   122	}
   123	

View as plain text