gopkg.in/alecthomas/gometalinter.v3@v3.0.0/_linters/src/golang.org/x/tools/go/packages/doc.go (about)

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