GoPLS Viewer

Home|gopls/go/packages/doc.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/*
6Package packages loads Go packages for inspection and analysis.
7
8The Load function takes as input a list of patterns and return a list of Package
9structs describing individual packages matched by those patterns.
10The LoadMode controls the amount of detail in the loaded packages.
11
12Load passes most patterns directly to the underlying build tool,
13but all patterns with the prefix "query=", where query is a
14non-empty string of letters from [a-z], are reserved and may be
15interpreted as query operators.
16
17Two query operators are currently supported: "file" and "pattern".
18
19The query "file=path/to/file.go" matches the package or packages enclosing
20the Go source file path/to/file.go.  For example "file=~/go/src/fmt/print.go"
21might return the packages "fmt" and "fmt [fmt.test]".
22
23The query "pattern=string" causes "string" to be passed directly to
24the underlying build tool. In most cases this is unnecessary,
25but an application can use Load("pattern=" + x) as an escaping mechanism
26to ensure that x is not interpreted as a query operator if it contains '='.
27
28All other query operators are reserved for future use and currently
29cause Load to report an error.
30
31The Package struct provides basic information about the package, including
32
33  - ID, a unique identifier for the package in the returned set;
34  - GoFiles, the names of the package's Go source files;
35  - Imports, a map from source import strings to the Packages they name;
36  - Types, the type information for the package's exported symbols;
37  - Syntax, the parsed syntax trees for the package's source code; and
38  - TypeInfo, the result of a complete type-check of the package syntax trees.
39
40(See the documentation for type Package for the complete list of fields
41and more detailed descriptions.)
42
43For example,
44
45    Load(nil, "bytes", "unicode...")
46
47returns four Package structs describing the standard library packages
48bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern
49can match multiple packages and that a package might be matched by
50multiple patterns: in general it is not possible to determine which
51packages correspond to which patterns.
52
53Note that the list returned by Load contains only the packages matched
54by the patterns. Their dependencies can be found by walking the import
55graph using the Imports fields.
56
57The Load function can be configured by passing a pointer to a Config as
58the first argument. A nil Config is equivalent to the zero Config, which
59causes Load to run in LoadFiles mode, collecting minimal information.
60See the documentation for type Config for details.
61
62As noted earlier, the Config.Mode controls the amount of detail
63reported about the loaded packages. See the documentation for type LoadMode
64for details.
65
66Most tools should pass their command-line arguments (after any flags)
67uninterpreted to the loader, so that the loader can interpret them
68according to the conventions of the underlying build system.
69See the Example function for typical usage.
70*/
71package packages // import "golang.org/x/tools/go/packages"
72
73/*
74
75Motivation and design considerations
76
77The new package's design solves problems addressed by two existing
78packages: go/build, which locates and describes packages, and
79golang.org/x/tools/go/loader, which loads, parses and type-checks them.
80The go/build.Package structure encodes too much of the 'go build' way
81of organizing projects, leaving us in need of a data type that describes a
82package of Go source code independent of the underlying build system.
83We wanted something that works equally well with go build and vgo, and
84also other build systems such as Bazel and Blaze, making it possible to
85construct analysis tools that work in all these environments.
86Tools such as errcheck and staticcheck were essentially unavailable to
87the Go community at Google, and some of Google's internal tools for Go
88are unavailable externally.
89This new package provides a uniform way to obtain package metadata by
90querying each of these build systems, optionally supporting their
91preferred command-line notations for packages, so that tools integrate
92neatly with users' build environments. The Metadata query function
93executes an external query tool appropriate to the current workspace.
94
95Loading packages always returns the complete import graph "all the way down",
96even if all you want is information about a single package, because the query
97mechanisms of all the build systems we currently support ({go,vgo} list, and
98blaze/bazel aspect-based query) cannot provide detailed information
99about one package without visiting all its dependencies too, so there is
100no additional asymptotic cost to providing transitive information.
101(This property might not be true of a hypothetical 5th build system.)
102
103In calls to TypeCheck, all initial packages, and any package that
104transitively depends on one of them, must be loaded from source.
105Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from
106source; D may be loaded from export data, and E may not be loaded at all
107(though it's possible that D's export data mentions it, so a
108types.Package may be created for it and exposed.)
109
110The old loader had a feature to suppress type-checking of function
111bodies on a per-package basis, primarily intended to reduce the work of
112obtaining type information for imported packages. Now that imports are
113satisfied by export data, the optimization no longer seems necessary.
114
115Despite some early attempts, the old loader did not exploit export data,
116instead always using the equivalent of WholeProgram mode. This was due
117to the complexity of mixing source and export data packages (now
118resolved by the upward traversal mentioned above), and because export data
119files were nearly always missing or stale. Now that 'go build' supports
120caching, all the underlying build systems can guarantee to produce
121export data in a reasonable (amortized) time.
122
123Test "main" packages synthesized by the build system are now reported as
124first-class packages, avoiding the need for clients (such as go/ssa) to
125reinvent this generation logic.
126
127One way in which go/packages is simpler than the old loader is in its
128treatment of in-package tests. In-package tests are packages that
129consist of all the files of the library under test, plus the test files.
130The old loader constructed in-package tests by a two-phase process of
131mutation called "augmentation": first it would construct and type check
132all the ordinary library packages and type-check the packages that
133depend on them; then it would add more (test) files to the package and
134type-check again. This two-phase approach had four major problems:
1351) in processing the tests, the loader modified the library package,
136   leaving no way for a client application to see both the test
137   package and the library package; one would mutate into the other.
1382) because test files can declare additional methods on types defined in
139   the library portion of the package, the dispatch of method calls in
140   the library portion was affected by the presence of the test files.
141   This should have been a clue that the packages were logically
142   different.
1433) this model of "augmentation" assumed at most one in-package test
144   per library package, which is true of projects using 'go build',
145   but not other build systems.
1464) because of the two-phase nature of test processing, all packages that
147   import the library package had to be processed before augmentation,
148   forcing a "one-shot" API and preventing the client from calling Load
149   in several times in sequence as is now possible in WholeProgram mode.
150   (TypeCheck mode has a similar one-shot restriction for a different reason.)
151
152Early drafts of this package supported "multi-shot" operation.
153Although it allowed clients to make a sequence of calls (or concurrent
154calls) to Load, building up the graph of Packages incrementally,
155it was of marginal value: it complicated the API
156(since it allowed some options to vary across calls but not others),
157it complicated the implementation,
158it cannot be made to work in Types mode, as explained above,
159and it was less efficient than making one combined call (when this is possible).
160Among the clients we have inspected, none made multiple calls to load
161but could not be easily and satisfactorily modified to make only a single call.
162However, applications changes may be required.
163For example, the ssadump command loads the user-specified packages
164and in addition the runtime package.  It is tempting to simply append
165"runtime" to the user-provided list, but that does not work if the user
166specified an ad-hoc package such as [a.go b.go].
167Instead, ssadump no longer requests the runtime package,
168but seeks it among the dependencies of the user-specified packages,
169and emits an error if it is not found.
170
171Overlays: The Overlay field in the Config allows providing alternate contents
172for Go source files, by providing a mapping from file path to contents.
173go/packages will pull in new imports added in overlay files when go/packages
174is run in LoadImports mode or greater.
175Overlay support for the go list driver isn't complete yet: if the file doesn't
176exist on disk, it will only be recognized in an overlay if it is a non-test file
177and the package would be reported even without the overlay.
178
179Questions & Tasks
180
181- Add GOARCH/GOOS?
182  They are not portable concepts, but could be made portable.
183  Our goal has been to allow users to express themselves using the conventions
184  of the underlying build system: if the build system honors GOARCH
185  during a build and during a metadata query, then so should
186  applications built atop that query mechanism.
187  Conversely, if the target architecture of the build is determined by
188  command-line flags, the application can pass the relevant
189  flags through to the build system using a command such as:
190    myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin"
191  However, this approach is low-level, unwieldy, and non-portable.
192  GOOS and GOARCH seem important enough to warrant a dedicated option.
193
194- How should we handle partial failures such as a mixture of good and
195  malformed patterns, existing and non-existent packages, successful and
196  failed builds, import failures, import cycles, and so on, in a call to
197  Load?
198
199- Support bazel, blaze, and go1.10 list, not just go1.11 list.
200
201- Handle (and test) various partial success cases, e.g.
202  a mixture of good packages and:
203  invalid patterns
204  nonexistent packages
205  empty packages
206  packages with malformed package or import declarations
207  unreadable files
208  import cycles
209  other parse errors
210  type errors
211  Make sure we record errors at the correct place in the graph.
212
213- Missing packages among initial arguments are not reported.
214  Return bogus packages for them, like golist does.
215
216- "undeclared name" errors (for example) are reported out of source file
217  order. I suspect this is due to the breadth-first resolution now used
218  by go/types. Is that a bug? Discuss with gri.
219
220*/
221
MembersX
Members
X