...

Source file src/cmd/vendor/golang.org/x/tools/go/analysis/internal/facts/imports.go

     1	// Copyright 2018 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 facts
     6	
     7	import "go/types"
     8	
     9	// importMap computes the import map for a package by traversing the
    10	// entire exported API each of its imports.
    11	//
    12	// This is a workaround for the fact that we cannot access the map used
    13	// internally by the types.Importer returned by go/importer. The entries
    14	// in this map are the packages and objects that may be relevant to the
    15	// current analysis unit.
    16	//
    17	// Packages in the map that are only indirectly imported may be
    18	// incomplete (!pkg.Complete()).
    19	//
    20	func importMap(imports []*types.Package) map[string]*types.Package {
    21		objects := make(map[types.Object]bool)
    22		packages := make(map[string]*types.Package)
    23	
    24		var addObj func(obj types.Object) bool
    25		var addType func(T types.Type)
    26	
    27		addObj = func(obj types.Object) bool {
    28			if !objects[obj] {
    29				objects[obj] = true
    30				addType(obj.Type())
    31				if pkg := obj.Pkg(); pkg != nil {
    32					packages[pkg.Path()] = pkg
    33				}
    34				return true
    35			}
    36			return false
    37		}
    38	
    39		addType = func(T types.Type) {
    40			switch T := T.(type) {
    41			case *types.Basic:
    42				// nop
    43			case *types.Named:
    44				if addObj(T.Obj()) {
    45					for i := 0; i < T.NumMethods(); i++ {
    46						addObj(T.Method(i))
    47					}
    48				}
    49			case *types.Pointer:
    50				addType(T.Elem())
    51			case *types.Slice:
    52				addType(T.Elem())
    53			case *types.Array:
    54				addType(T.Elem())
    55			case *types.Chan:
    56				addType(T.Elem())
    57			case *types.Map:
    58				addType(T.Key())
    59				addType(T.Elem())
    60			case *types.Signature:
    61				addType(T.Params())
    62				addType(T.Results())
    63			case *types.Struct:
    64				for i := 0; i < T.NumFields(); i++ {
    65					addObj(T.Field(i))
    66				}
    67			case *types.Tuple:
    68				for i := 0; i < T.Len(); i++ {
    69					addObj(T.At(i))
    70				}
    71			case *types.Interface:
    72				for i := 0; i < T.NumMethods(); i++ {
    73					addObj(T.Method(i))
    74				}
    75			}
    76		}
    77	
    78		for _, imp := range imports {
    79			packages[imp.Path()] = imp
    80	
    81			scope := imp.Scope()
    82			for _, name := range scope.Names() {
    83				addObj(scope.Lookup(name))
    84			}
    85		}
    86	
    87		return packages
    88	}
    89	

View as plain text