src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

doc.go (12441B)


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