GoPLS Viewer

Home|gopls/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
5package facts
6
7import (
8    "go/types"
9
10    "golang.org/x/tools/internal/typeparams"
11)
12
13// importMap computes the import map for a package by traversing the
14// entire exported API each of its imports.
15//
16// This is a workaround for the fact that we cannot access the map used
17// internally by the types.Importer returned by go/importer. The entries
18// in this map are the packages and objects that may be relevant to the
19// current analysis unit.
20//
21// Packages in the map that are only indirectly imported may be
22// incomplete (!pkg.Complete()).
23//
24// TODO(adonovan): opt: compute this information more efficiently
25// by obtaining it from the internals of the gcexportdata decoder.
26func importMap(imports []*types.Package) map[string]*types.Package {
27    objects := make(map[types.Object]bool)
28    packages := make(map[string]*types.Package)
29
30    var addObj func(obj types.Objectbool
31    var addType func(T types.Type)
32
33    addObj = func(obj types.Objectbool {
34        if !objects[obj] {
35            objects[obj] = true
36            addType(obj.Type())
37            if pkg := obj.Pkg(); pkg != nil {
38                packages[pkg.Path()] = pkg
39            }
40            return true
41        }
42        return false
43    }
44
45    addType = func(T types.Type) {
46        switch T := T.(type) {
47        case *types.Basic:
48            // nop
49        case *types.Named:
50            if addObj(T.Obj()) {
51                // TODO(taking): Investigate why the Underlying type is not added here.
52                for i := 0i < T.NumMethods(); i++ {
53                    addObj(T.Method(i))
54                }
55                if tparams := typeparams.ForNamed(T); tparams != nil {
56                    for i := 0i < tparams.Len(); i++ {
57                        addType(tparams.At(i))
58                    }
59                }
60                if targs := typeparams.NamedTypeArgs(T); targs != nil {
61                    for i := 0i < targs.Len(); i++ {
62                        addType(targs.At(i))
63                    }
64                }
65            }
66        case *types.Pointer:
67            addType(T.Elem())
68        case *types.Slice:
69            addType(T.Elem())
70        case *types.Array:
71            addType(T.Elem())
72        case *types.Chan:
73            addType(T.Elem())
74        case *types.Map:
75            addType(T.Key())
76            addType(T.Elem())
77        case *types.Signature:
78            addType(T.Params())
79            addType(T.Results())
80            if tparams := typeparams.ForSignature(T); tparams != nil {
81                for i := 0i < tparams.Len(); i++ {
82                    addType(tparams.At(i))
83                }
84            }
85        case *types.Struct:
86            for i := 0i < T.NumFields(); i++ {
87                addObj(T.Field(i))
88            }
89        case *types.Tuple:
90            for i := 0i < T.Len(); i++ {
91                addObj(T.At(i))
92            }
93        case *types.Interface:
94            for i := 0i < T.NumMethods(); i++ {
95                addObj(T.Method(i))
96            }
97            for i := 0i < T.NumEmbeddeds(); i++ {
98                addType(T.EmbeddedType(i)) // walk Embedded for implicits
99            }
100        case *typeparams.Union:
101            for i := 0i < T.Len(); i++ {
102                addType(T.Term(i).Type())
103            }
104        case *typeparams.TypeParam:
105            if addObj(T.Obj()) {
106                addType(T.Constraint())
107            }
108        }
109    }
110
111    for _imp := range imports {
112        packages[imp.Path()] = imp
113
114        scope := imp.Scope()
115        for _name := range scope.Names() {
116            addObj(scope.Lookup(name))
117        }
118    }
119
120    return packages
121}
122
MembersX
importMap.BlockStmt.BlockStmt.i
importMap.packages
importMap.BlockStmt.BlockStmt.BlockStmt.BlockStmt.i
importMap.RangeStmt_2863.BlockStmt.scope
importMap.BlockStmt.BlockStmt.tparams
importMap.RangeStmt_2863.imp
importMap.objects
importMap.BlockStmt.BlockStmt.BlockStmt.i
importMap
importMap.imports
importMap.BlockStmt.BlockStmt.BlockStmt.targs
importMap.RangeStmt_2863.BlockStmt.RangeStmt_2948.name
importMap.BlockStmt.BlockStmt.pkg
importMap.BlockStmt.BlockStmt.BlockStmt.tparams
Members
X